summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio15
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio-distance-srf0822
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt13
-rw-r--r--Documentation/block/queue-sysfs.txt6
-rw-r--r--Documentation/devicetree/bindings/i2c/trivial-devices.txt1
-rw-r--r--Documentation/devicetree/bindings/iio/accel/lis302.txt2
-rw-r--r--Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt32
-rw-r--r--Documentation/devicetree/bindings/iio/adc/avia-hx711.txt18
-rw-r--r--Documentation/devicetree/bindings/iio/adc/max11100.txt18
-rw-r--r--Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt99
-rw-r--r--Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt23
-rw-r--r--Documentation/devicetree/bindings/iio/imu/bmi160.txt36
-rw-r--r--Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt26
-rw-r--r--Documentation/devicetree/bindings/iio/light/cm3605.txt41
-rw-r--r--Documentation/devicetree/bindings/iio/potentiometer/max5481.txt23
-rw-r--r--Documentation/devicetree/bindings/iio/st-sensors.txt2
-rw-r--r--Documentation/devicetree/bindings/iio/temperature/tmp007.txt35
-rw-r--r--Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt4
-rw-r--r--Documentation/devicetree/bindings/power/supply/tps65217_charger.txt7
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt3
-rw-r--r--Documentation/driver-api/infrastructure.rst15
-rw-r--r--Documentation/networking/mpls-sysctl.txt4
-rw-r--r--Documentation/unaligned-memory-access.txt2
-rw-r--r--Documentation/vfio-mediated-device.txt27
-rw-r--r--MAINTAINERS28
-rw-r--r--Makefile2
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/boot/dts/Makefile1
-rw-r--r--arch/arm/boot/dts/am335x-bone-common.dtsi8
-rw-r--r--arch/arm/boot/dts/am33xx.dtsi1
-rw-r--r--arch/arm/boot/dts/am4372.dtsi1
-rw-r--r--arch/arm/boot/dts/am571x-idk.dts10
-rw-r--r--arch/arm/boot/dts/am572x-idk.dts14
-rw-r--r--arch/arm/boot/dts/am57xx-idk-common.dtsi9
-rw-r--r--arch/arm/boot/dts/dm814x.dtsi1
-rw-r--r--arch/arm/boot/dts/dm816x.dtsi1
-rw-r--r--arch/arm/boot/dts/dra7.dtsi1
-rw-r--r--arch/arm/boot/dts/dra72-evm-tps65917.dtsi16
-rw-r--r--arch/arm/boot/dts/imx31.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi1
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi1
-rw-r--r--arch/arm/boot/dts/imx6sl.dtsi1
-rw-r--r--arch/arm/boot/dts/imx6sx.dtsi1
-rw-r--r--arch/arm/boot/dts/omap2.dtsi1
-rw-r--r--arch/arm/boot/dts/omap3-n900.dts2
-rw-r--r--arch/arm/boot/dts/omap3.dtsi1
-rw-r--r--arch/arm/boot/dts/omap4.dtsi1
-rw-r--r--arch/arm/boot/dts/omap5.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom-apq8064.dtsi4
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts2
-rw-r--r--arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts2
-rw-r--r--arch/arm/boot/dts/vf610-zii-dev-rev-b.dts3
-rw-r--r--arch/arm/mach-davinci/clock.c12
-rw-r--r--arch/arm/mach-davinci/clock.h2
-rw-r--r--arch/arm/mach-davinci/da850.c32
-rw-r--r--arch/arm/mach-davinci/usb-da8xx.c34
-rw-r--r--arch/arm/mach-exynos/platsmp.c31
-rw-r--r--arch/arm/mach-imx/mach-imx1.c1
-rw-r--r--arch/arm/mach-omap2/Makefile2
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/gpio.c160
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c8
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.h4
-rw-r--r--arch/arm/mach-omap2/prm_common.c4
-rw-r--r--arch/arm/mach-omap2/timer.c9
-rw-r--r--arch/arm/mach-s3c24xx/common.c76
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gx.dtsi16
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts16
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi16
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi4
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts16
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxl.dtsi6
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts16
-rw-r--r--arch/arm64/boot/dts/amlogic/meson-gxm.dtsi4
-rw-r--r--arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts2
-rw-r--r--arch/arm64/boot/dts/qcom/msm8996.dtsi10
-rw-r--r--arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts2
-rw-r--r--arch/arm64/configs/defconfig1
-rw-r--r--arch/arm64/include/asm/asm-uaccess.h65
-rw-r--r--arch/arm64/include/asm/current.h10
-rw-r--r--arch/arm64/include/asm/uaccess.h64
-rw-r--r--arch/arm64/kernel/entry.S2
-rw-r--r--arch/arm64/lib/clear_user.S2
-rw-r--r--arch/arm64/lib/copy_from_user.S2
-rw-r--r--arch/arm64/lib/copy_in_user.S2
-rw-r--r--arch/arm64/lib/copy_to_user.S2
-rw-r--r--arch/arm64/mm/cache.S2
-rw-r--r--arch/arm64/mm/dma-mapping.c3
-rw-r--r--arch/arm64/mm/fault.c8
-rw-r--r--arch/arm64/mm/init.c3
-rw-r--r--arch/arm64/xen/hypercall.S2
-rw-r--r--arch/mips/kvm/entry.c5
-rw-r--r--arch/mips/kvm/mips.c4
-rw-r--r--arch/openrisc/kernel/vmlinux.lds.S2
-rw-r--r--arch/parisc/include/asm/thread_info.h1
-rw-r--r--arch/parisc/kernel/time.c23
-rw-r--r--arch/parisc/mm/fault.c2
-rw-r--r--arch/s390/include/asm/asm-prototypes.h8
-rw-r--r--arch/s390/kernel/vtime.c8
-rw-r--r--arch/x86/include/asm/bitops.h13
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c3
-rw-r--r--arch/x86/kernel/pci-swiotlb.c6
-rw-r--r--arch/x86/kvm/vmx.c14
-rw-r--r--arch/x86/kvm/x86.c9
-rw-r--r--arch/x86/xen/pci-swiotlb-xen.c2
-rw-r--r--arch/x86/xen/setup.c6
-rw-r--r--block/blk-wbt.c13
-rw-r--r--crypto/testmgr.c30
-rw-r--r--drivers/acpi/acpi_watchdog.c2
-rw-r--r--drivers/acpi/glue.c11
-rw-r--r--drivers/acpi/internal.h1
-rw-r--r--drivers/acpi/scan.c1
-rw-r--r--drivers/acpi/sysfs.c56
-rw-r--r--drivers/base/power/domain.c1
-rw-r--r--drivers/clk/clk-stm32f4.c4
-rw-r--r--drivers/clk/renesas/clk-mstp.c27
-rw-r--r--drivers/cpufreq/cpufreq-dt-platdev.c2
-rw-r--r--drivers/cpufreq/intel_pstate.c53
-rw-r--r--drivers/crypto/marvell/cesa.h3
-rw-r--r--drivers/crypto/marvell/hash.c34
-rw-r--r--drivers/crypto/marvell/tdma.c9
-rw-r--r--drivers/devfreq/devfreq.c15
-rw-r--r--drivers/devfreq/exynos-bus.c2
-rw-r--r--drivers/firmware/arm_scpi.c10
-rw-r--r--drivers/firmware/psci_checker.c4
-rw-r--r--drivers/gpu/drm/i915/gvt/cfg_space.c4
-rw-r--r--drivers/gpu/drm/i915/gvt/gtt.c55
-rw-r--r--drivers/gpu/drm/i915/gvt/gtt.h4
-rw-r--r--drivers/gpu/drm/i915/gvt/gvt.h1
-rw-r--r--drivers/gpu/drm/i915/gvt/kvmgt.c64
-rw-r--r--drivers/gpu/drm/i915/gvt/opregion.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c33
-rw-r--r--drivers/gpu/drm/i915/i915_gem_request.h19
-rw-r--r--drivers/gpu/drm/i915/intel_display.c32
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c41
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c9
-rw-r--r--drivers/hid/hid-asus.c17
-rw-r--r--drivers/hid/hid-ids.h4
-rw-r--r--drivers/hid/hid-sensor-hub.c3
-rw-r--r--drivers/hid/hid-sony.c36
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
-rw-r--r--drivers/hwmon/lm90.c2
-rw-r--r--drivers/iio/accel/Kconfig2
-rw-r--r--drivers/iio/accel/bmc150-accel-core.c3
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c104
-rw-r--r--drivers/iio/accel/mma8452.c4
-rw-r--r--drivers/iio/accel/ssp_accel_sensor.c13
-rw-r--r--drivers/iio/accel/st_accel.h18
-rw-r--r--drivers/iio/accel/st_accel_core.c12
-rw-r--r--drivers/iio/accel/st_accel_i2c.c78
-rw-r--r--drivers/iio/accel/st_accel_spi.c9
-rw-r--r--drivers/iio/adc/Kconfig80
-rw-r--r--drivers/iio/adc/Makefile6
-rw-r--r--drivers/iio/adc/axp288_adc.c32
-rw-r--r--drivers/iio/adc/exynos_adc.c2
-rw-r--r--drivers/iio/adc/fsl-imx25-gcq.c1
-rw-r--r--drivers/iio/adc/hx711.c532
-rw-r--r--drivers/iio/adc/ina2xx-adc.c2
-rw-r--r--drivers/iio/adc/max11100.c181
-rw-r--r--drivers/iio/adc/max1363.c1
-rw-r--r--drivers/iio/adc/meson_saradc.c922
-rw-r--r--drivers/iio/adc/qcom-spmi-vadc.c481
-rw-r--r--drivers/iio/adc/rcar-gyroadc.c631
-rw-r--r--drivers/iio/adc/stx104.c22
-rw-r--r--drivers/iio/adc/ti-ads1015.c4
-rw-r--r--drivers/iio/adc/ti-ads7950.c490
-rw-r--r--drivers/iio/adc/ti-tlc4541.c271
-rw-r--r--drivers/iio/buffer/industrialio-buffer-cb.c3
-rw-r--r--drivers/iio/buffer/kfifo_buf.c3
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-attributes.c36
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_iio.c1
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_buffer.c4
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_core.c13
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_i2c.c20
-rw-r--r--drivers/iio/counter/104-quad-8.c13
-rw-r--r--drivers/iio/dac/ad5592r.c8
-rw-r--r--drivers/iio/dac/ad5593r.c8
-rw-r--r--drivers/iio/dummy/iio_simple_dummy.h8
-rw-r--r--drivers/iio/dummy/iio_simple_dummy_buffer.c4
-rw-r--r--drivers/iio/gyro/ssp_gyro_sensor.c13
-rw-r--r--drivers/iio/health/max30100.c2
-rw-r--r--drivers/iio/humidity/hts221_i2c.c8
-rw-r--r--drivers/iio/imu/Kconfig1
-rw-r--r--drivers/iio/imu/Makefile2
-rw-r--r--drivers/iio/imu/bmi160/bmi160_core.c33
-rw-r--r--drivers/iio/imu/bmi160/bmi160_i2c.c14
-rw-r--r--drivers/iio/imu/bmi160/bmi160_spi.c18
-rw-r--r--drivers/iio/imu/st_lsm6dsx/Kconfig22
-rw-r--r--drivers/iio/imu/st_lsm6dsx/Makefile5
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h141
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c454
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c720
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c101
-rw-r--r--drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c118
-rw-r--r--drivers/iio/industrialio-buffer.c321
-rw-r--r--drivers/iio/industrialio-core.c2
-rw-r--r--drivers/iio/industrialio-trigger.c92
-rw-r--r--drivers/iio/inkern.c10
-rw-r--r--drivers/iio/light/Kconfig10
-rw-r--r--drivers/iio/light/Makefile1
-rw-r--r--drivers/iio/light/cm3232.c2
-rw-r--r--drivers/iio/light/cm3605.c330
-rw-r--r--drivers/iio/light/hid-sensor-als.c24
-rw-r--r--drivers/iio/light/max44000.c2
-rw-r--r--drivers/iio/light/opt3001.c1
-rw-r--r--drivers/iio/magnetometer/ak8974.c8
-rw-r--r--drivers/iio/magnetometer/mag3110.c30
-rw-r--r--drivers/iio/potentiometer/Kconfig11
-rw-r--r--drivers/iio/potentiometer/Makefile1
-rw-r--r--drivers/iio/potentiometer/max5481.c223
-rw-r--r--drivers/iio/potentiometer/mcp4531.c1
-rw-r--r--drivers/iio/pressure/Kconfig10
-rw-r--r--drivers/iio/pressure/Makefile1
-rw-r--r--drivers/iio/pressure/bmp280-core.c14
-rw-r--r--drivers/iio/pressure/cros_ec_baro.c220
-rw-r--r--drivers/iio/pressure/ms5611_core.c12
-rw-r--r--drivers/iio/pressure/st_pressure.h8
-rw-r--r--drivers/iio/pressure/st_pressure_core.c12
-rw-r--r--drivers/iio/pressure/st_pressure_i2c.c51
-rw-r--r--drivers/iio/proximity/Kconfig13
-rw-r--r--drivers/iio/proximity/Makefile1
-rw-r--r--drivers/iio/proximity/pulsedlight-lidar-lite-v2.c2
-rw-r--r--drivers/iio/proximity/srf08.c398
-rw-r--r--drivers/iio/proximity/sx9500.c10
-rw-r--r--drivers/iio/temperature/Kconfig10
-rw-r--r--drivers/iio/temperature/Makefile1
-rw-r--r--drivers/iio/temperature/tmp007.c345
-rw-r--r--drivers/iio/trigger/iio-trig-interrupt.c8
-rw-r--r--drivers/iio/trigger/iio-trig-sysfs.c2
-rw-r--r--drivers/infiniband/hw/mlx4/main.c14
-rw-r--r--drivers/iommu/amd_iommu.c2
-rw-r--r--drivers/iommu/dmar.c6
-rw-r--r--drivers/iommu/intel-iommu.c42
-rw-r--r--drivers/misc/mei/bus.c2
-rw-r--r--drivers/misc/mei/client.c20
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.c23
-rw-r--r--drivers/net/ethernet/cadence/macb_pci.c27
-rw-r--r--drivers/net/ethernet/cavium/Kconfig2
-rw-r--r--drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c12
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c4
-rw-r--r--drivers/net/ethernet/freescale/dpaa/dpaa_eth.c6
-rw-r--r--drivers/net/ethernet/korina.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_clock.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_netdev.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/icm.c7
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c18
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c28
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c3
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c17
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c51
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_stats.h32
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/main.c15
-rw-r--r--drivers/net/ethernet/realtek/r8169.c1
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c3
-rw-r--r--drivers/net/ethernet/sfc/ef10.c3
-rw-r--r--drivers/net/ethernet/sfc/ethtool.c2
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h2
-rw-r--r--drivers/net/ethernet/sfc/siena.c1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c89
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c23
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c4
-rw-r--r--drivers/net/ipvlan/ipvlan.h5
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c60
-rw-r--r--drivers/net/ipvlan/ipvlan_main.c7
-rw-r--r--drivers/net/usb/asix_devices.c1
-rw-r--r--drivers/net/vrf.c3
-rw-r--r--drivers/net/wan/slic_ds26522.c2
-rw-r--r--drivers/nvme/host/core.c17
-rw-r--r--drivers/nvme/host/fc.c19
-rw-r--r--drivers/nvme/host/nvme.h1
-rw-r--r--drivers/nvme/host/pci.c13
-rw-r--r--drivers/nvme/host/scsi.c27
-rw-r--r--drivers/nvme/target/admin-cmd.c4
-rw-r--r--drivers/nvme/target/fcloop.c4
-rw-r--r--drivers/nvmem/core.c4
-rw-r--r--drivers/nvmem/imx-ocotp.c2
-rw-r--r--drivers/nvmem/qfprom.c14
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson.c2
-rw-r--r--drivers/pinctrl/pinctrl-amd.c19
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.c91
-rw-r--r--drivers/pinctrl/samsung/pinctrl-exynos.h31
-rw-r--r--drivers/platform/chrome/cros_ec_dev.c3
-rw-r--r--drivers/platform/x86/Kconfig2
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c42
-rw-r--r--drivers/staging/Kconfig4
-rw-r--r--drivers/staging/Makefile3
-rw-r--r--drivers/staging/android/ion/ion-ioctl.c3
-rw-r--r--drivers/staging/android/ion/ion_cma_heap.c6
-rw-r--r--drivers/staging/android/ion/ion_of.c1
-rw-r--r--drivers/staging/android/ion/ion_priv.h40
-rw-r--r--drivers/staging/bcm2835-audio/Kconfig7
-rw-r--r--drivers/staging/bcm2835-audio/Makefile5
-rw-r--r--drivers/staging/bcm2835-audio/bcm2835-ctl.c346
-rw-r--r--drivers/staging/bcm2835-audio/bcm2835-pcm.c560
-rw-r--r--drivers/staging/bcm2835-audio/bcm2835-vchiq.c903
-rw-r--r--drivers/staging/bcm2835-audio/bcm2835.c519
-rw-r--r--drivers/staging/bcm2835-audio/bcm2835.h169
-rw-r--r--drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h121
-rw-r--r--drivers/staging/comedi/Kconfig10
-rw-r--r--drivers/staging/comedi/comedi_compat32.h3
-rw-r--r--drivers/staging/comedi/comedi_fops.c10
-rw-r--r--drivers/staging/comedi/comedi_internal.h9
-rw-r--r--drivers/staging/comedi/comedi_pci.h18
-rw-r--r--drivers/staging/comedi/comedi_pcmcia.c3
-rw-r--r--drivers/staging/comedi/comedi_pcmcia.h22
-rw-r--r--drivers/staging/comedi/comedi_usb.h16
-rw-r--r--drivers/staging/comedi/comedidev.h55
-rw-r--r--drivers/staging/comedi/drivers/addi_watchdog.h2
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c140
-rw-r--r--drivers/staging/comedi/drivers/comedi_8254.h30
-rw-r--r--drivers/staging/comedi/drivers/comedi_isadma.h10
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c401
-rw-r--r--drivers/staging/comedi/drivers/mite.h37
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c10
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_at_ao.c62
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h4
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c173
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.h42
-rw-r--r--drivers/staging/comedi/drivers/ni_tio_internal.h14
-rw-r--r--drivers/staging/comedi/proc.c6
-rw-r--r--drivers/staging/dgnc/TODO3
-rw-r--r--drivers/staging/emxx_udc/emxx_udc.c30
-rw-r--r--drivers/staging/fbtft/fb_agm1264k-fl.c18
-rw-r--r--drivers/staging/fbtft/fb_hx8340bn.c2
-rw-r--r--drivers/staging/fbtft/fb_pcd8544.c4
-rw-r--r--drivers/staging/fbtft/fb_ra8875.c14
-rw-r--r--drivers/staging/fbtft/fb_ssd1289.c2
-rw-r--r--drivers/staging/fbtft/fb_ssd1306.c37
-rw-r--r--drivers/staging/fbtft/fb_tls8204.c2
-rw-r--r--drivers/staging/fbtft/fb_uc1611.c12
-rw-r--r--drivers/staging/fbtft/fb_watterott.c2
-rw-r--r--drivers/staging/fbtft/fbtft-core.c32
-rw-r--r--drivers/staging/fbtft/fbtft-io.c4
-rw-r--r--drivers/staging/fbtft/fbtft-sysfs.c7
-rw-r--r--drivers/staging/fbtft/fbtft.h1
-rw-r--r--drivers/staging/fbtft/fbtft_device.c38
-rw-r--r--drivers/staging/fbtft/flexfb.c34
-rw-r--r--drivers/staging/gdm724x/gdm_endian.c24
-rw-r--r--drivers/staging/gdm724x/gdm_endian.h15
-rw-r--r--drivers/staging/gdm724x/gdm_lte.c27
-rw-r--r--drivers/staging/gdm724x/hci_packet.h46
-rw-r--r--drivers/staging/greybus/Makefile4
-rw-r--r--drivers/staging/greybus/arche-apb-ctrl.c4
-rw-r--r--drivers/staging/greybus/arche_platform.h2
-rw-r--r--drivers/staging/greybus/audio_codec.c46
-rw-r--r--drivers/staging/greybus/audio_codec.h46
-rw-r--r--drivers/staging/greybus/audio_gb.c4
-rw-r--r--drivers/staging/greybus/audio_module.c2
-rw-r--r--drivers/staging/greybus/audio_topology.c104
-rw-r--r--drivers/staging/greybus/camera.c10
-rw-r--r--drivers/staging/greybus/connection.c6
-rw-r--r--drivers/staging/greybus/control.c50
-rw-r--r--drivers/staging/greybus/control.h7
-rw-r--r--drivers/staging/greybus/core.c11
-rw-r--r--drivers/staging/greybus/es2.c132
-rw-r--r--drivers/staging/greybus/gpio.c24
-rw-r--r--drivers/staging/greybus/greybus.h1
-rw-r--r--drivers/staging/greybus/greybus_protocols.h47
-rw-r--r--drivers/staging/greybus/greybus_trace.h28
-rw-r--r--drivers/staging/greybus/hd.h7
-rw-r--r--drivers/staging/greybus/interface.c56
-rw-r--r--drivers/staging/greybus/interface.h5
-rw-r--r--drivers/staging/greybus/log.c6
-rw-r--r--drivers/staging/greybus/loopback.c29
-rw-r--r--drivers/staging/greybus/sdio.c2
-rw-r--r--drivers/staging/greybus/svc.c87
-rw-r--r--drivers/staging/greybus/svc.h7
-rw-r--r--drivers/staging/greybus/svc_watchdog.c4
-rw-r--r--drivers/staging/greybus/timesync.c1357
-rw-r--r--drivers/staging/greybus/timesync.h45
-rw-r--r--drivers/staging/greybus/timesync_platform.c82
-rw-r--r--drivers/staging/greybus/tools/loopback_test.c5
-rw-r--r--drivers/staging/greybus/uart.c1
-rw-r--r--drivers/staging/i4l/Documentation/README.act2000104
-rw-r--r--drivers/staging/i4l/Documentation/README.icn148
-rw-r--r--drivers/staging/i4l/Documentation/README.pcbit40
-rw-r--r--drivers/staging/i4l/Documentation/README.sc281
-rw-r--r--drivers/staging/i4l/Kconfig13
-rw-r--r--drivers/staging/i4l/Makefile5
-rw-r--r--drivers/staging/i4l/TODO3
-rw-r--r--drivers/staging/i4l/act2000/Kconfig9
-rw-r--r--drivers/staging/i4l/act2000/Makefile9
-rw-r--r--drivers/staging/i4l/act2000/act2000.h202
-rw-r--r--drivers/staging/i4l/act2000/act2000_isa.c444
-rw-r--r--drivers/staging/i4l/act2000/act2000_isa.h136
-rw-r--r--drivers/staging/i4l/act2000/capi.c1187
-rw-r--r--drivers/staging/i4l/act2000/capi.h357
-rw-r--r--drivers/staging/i4l/act2000/module.c816
-rw-r--r--drivers/staging/i4l/icn/Kconfig12
-rw-r--r--drivers/staging/i4l/icn/Makefile5
-rw-r--r--drivers/staging/i4l/icn/icn.c1696
-rw-r--r--drivers/staging/i4l/icn/icn.h252
-rw-r--r--drivers/staging/i4l/pcbit/Kconfig10
-rw-r--r--drivers/staging/i4l/pcbit/Makefile9
-rw-r--r--drivers/staging/i4l/pcbit/callbacks.c345
-rw-r--r--drivers/staging/i4l/pcbit/callbacks.h44
-rw-r--r--drivers/staging/i4l/pcbit/capi.c646
-rw-r--r--drivers/staging/i4l/pcbit/capi.h81
-rw-r--r--drivers/staging/i4l/pcbit/drv.c1070
-rw-r--r--drivers/staging/i4l/pcbit/edss1.c310
-rw-r--r--drivers/staging/i4l/pcbit/edss1.h99
-rw-r--r--drivers/staging/i4l/pcbit/layer2.c710
-rw-r--r--drivers/staging/i4l/pcbit/layer2.h281
-rw-r--r--drivers/staging/i4l/pcbit/module.c125
-rw-r--r--drivers/staging/i4l/pcbit/pcbit.h177
-rw-r--r--drivers/staging/iio/accel/adis16201_core.c4
-rw-r--r--drivers/staging/iio/accel/adis16203_core.c6
-rw-r--r--drivers/staging/iio/accel/adis16209_core.c4
-rw-r--r--drivers/staging/iio/adc/ad7606.c79
-rw-r--r--drivers/staging/iio/adc/ad7816.c10
-rw-r--r--drivers/staging/iio/addac/adt7316-i2c.c2
-rw-r--r--drivers/staging/iio/addac/adt7316.c3
-rw-r--r--drivers/staging/iio/cdc/ad7150.c34
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c4
-rw-r--r--drivers/staging/iio/light/isl29028.c415
-rw-r--r--drivers/staging/iio/meter/ade7753.c2
-rw-r--r--drivers/staging/iio/meter/ade7753.h2
-rw-r--r--drivers/staging/iio/meter/ade7754.c2
-rw-r--r--drivers/staging/iio/meter/ade7754.h2
-rw-r--r--drivers/staging/iio/meter/ade7758.h2
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c2
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c1
-rw-r--r--drivers/staging/iio/meter/ade7759.c2
-rw-r--r--drivers/staging/iio/meter/ade7759.h2
-rw-r--r--drivers/staging/iio/meter/ade7854.c2
-rw-r--r--drivers/staging/iio/meter/ade7854.h2
-rw-r--r--drivers/staging/iio/trigger/iio-trig-bfin-timer.c6
-rw-r--r--drivers/staging/ks7010/ks7010_sdio.h4
-rw-r--r--drivers/staging/ks7010/ks_wlan_net.c5
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-lnet.h14
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-types.h10
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lnetst.h198
-rw-r--r--drivers/staging/lustre/include/linux/lnet/socklnd.h2
-rw-r--r--drivers/staging/lustre/include/linux/lnet/types.h70
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h6
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c2
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c10
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h2
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c14
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c26
-rw-r--r--drivers/staging/lustre/lnet/libcfs/module.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/acceptor.c6
-rw-r--r--drivers/staging/lustre/lnet/lnet/api-ni.c170
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-move.c20
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-msg.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-ptl.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/net_fault.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/router.c10
-rw-r--r--drivers/staging/lustre/lnet/selftest/brw_test.c2
-rw-r--r--drivers/staging/lustre/lnet/selftest/conctl.c76
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.c36
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.h4
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.c56
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.h24
-rw-r--r--drivers/staging/lustre/lnet/selftest/framework.c18
-rw-r--r--drivers/staging/lustre/lnet/selftest/rpc.c6
-rw-r--r--drivers/staging/lustre/lnet/selftest/rpc.h38
-rw-r--r--drivers/staging/lustre/lnet/selftest/selftest.h10
-rw-r--r--drivers/staging/lustre/lustre/include/lu_object.h3
-rw-r--r--drivers/staging/lustre/lustre/include/lustre/lustre_idl.h46
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_obdo.h54
-rw-r--r--drivers/staging/lustre/lustre/include/obd.h5
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_flock.c2
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_lock.c5
-rw-r--r--drivers/staging/lustre/lustre/llite/dir.c2
-rw-r--r--drivers/staging/lustre/lustre/llite/file.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_lib.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/lproc_llite.c27
-rw-r--r--drivers/staging/lustre/lustre/llite/namei.c4
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_internal.h2
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_obd.c58
-rw-r--r--drivers/staging/lustre/lustre/lov/lov_pack.c3
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_io.c4
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_object.c3
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obdo.c54
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cache.c30
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cl_internal.h11
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_internal.h4
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_io.c62
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_object.c19
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_request.c45
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/events.c2
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/nrs.c3
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/pack_generic.c1
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h3
-rw-r--r--drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c2
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.c93
-rw-r--r--drivers/staging/most/hdm-usb/hdm_usb.c10
-rw-r--r--drivers/staging/nvec/nvec_power.c2
-rw-r--r--drivers/staging/octeon/ethernet.c2
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.c14
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c4
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ap.c144
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_cmd.c3
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_efuse.c8
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ieee80211.c9
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ioctl_set.c5
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_led.c1
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme.c3
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme_ext.c43
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_pwrctrl.c5
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_recv.c137
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_security.c146
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_sta_mgt.c1
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_wlan_util.c3
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_xmit.c8
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c2
-rw-r--r--drivers/staging/rtl8188eu/include/drv_types.h1
-rw-r--r--drivers/staging/rtl8188eu/include/osdep_service.h7
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_debug.h2
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_mlme.h185
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_recv.h13
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_security.h36
-rw-r--r--drivers/staging/rtl8188eu/include/wifi.h101
-rw-r--r--drivers/staging/rtl8188eu/os_dep/ioctl_linux.c15
-rw-r--r--drivers/staging/rtl8188eu/os_dep/os_intfs.c2
-rw-r--r--drivers/staging/rtl8188eu/os_dep/osdep_service.c14
-rw-r--r--drivers/staging/rtl8188eu/os_dep/recv_linux.c15
-rw-r--r--drivers/staging/rtl8188eu/os_dep/rtw_android.c1
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_intf.c1
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c22
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_core.c12
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c18
-rw-r--r--drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c8
-rw-r--r--drivers/staging/rtl8192u/r8180_93cx6.h27
-rw-r--r--drivers/staging/rtl8192u/r819xU_cmdpkt.c31
-rw-r--r--drivers/staging/rtl8712/hal_init.c12
-rw-r--r--drivers/staging/rtl8712/ieee80211.c18
-rw-r--r--drivers/staging/rtl8712/mlme_linux.c6
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmd.c7
-rw-r--r--drivers/staging/rtl8712/rtl8712_event.h2
-rw-r--r--drivers/staging/rtl8712/rtl8712_recv.c14
-rw-r--r--drivers/staging/rtl8712/rtl8712_recv.h28
-rw-r--r--drivers/staging/rtl8712/rtl8712_xmit.c2
-rw-r--r--drivers/staging/rtl8712/rtl8712_xmit.h16
-rw-r--r--drivers/staging/rtl8712/rtl871x_cmd.h6
-rw-r--r--drivers/staging/rtl8712/rtl871x_event.h2
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_linux.c4
-rw-r--r--drivers/staging/rtl8712/rtl871x_mlme.c15
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_ioctl.c4
-rw-r--r--drivers/staging/rtl8712/rtl871x_recv.c9
-rw-r--r--drivers/staging/rtl8712/rtl871x_security.c28
-rw-r--r--drivers/staging/rtl8712/usb_ops.c18
-rw-r--r--drivers/staging/rtl8712/usb_ops_linux.c5
-rw-r--r--drivers/staging/rtl8712/wifi.h4
-rw-r--r--drivers/staging/rtl8712/wlan_bssdef.h2
-rw-r--r--drivers/staging/rts5208/rtsx_transport.c4
-rw-r--r--drivers/staging/skein/skein_base.c16
-rw-r--r--drivers/staging/skein/skein_base.h112
-rw-r--r--drivers/staging/skein/skein_block.c32
-rw-r--r--drivers/staging/skein/skein_block.h20
-rw-r--r--drivers/staging/skein/skein_iv.h24
-rw-r--r--drivers/staging/sm750fb/ddk750_chip.c6
-rw-r--r--drivers/staging/sm750fb/sm750.c7
-rw-r--r--drivers/staging/speakup/kobjects.c54
-rw-r--r--drivers/staging/unisys/include/channel.h134
-rw-r--r--drivers/staging/unisys/visorbus/controlvmchannel.h87
-rw-r--r--drivers/staging/unisys/visorbus/visorbus_main.c48
-rw-r--r--drivers/staging/unisys/visorbus/visorchipset.c236
-rw-r--r--drivers/staging/unisys/visorbus/vmcallinterface.h8
-rw-r--r--drivers/staging/unisys/visorhba/visorhba_main.c4
-rw-r--r--drivers/staging/unisys/visornic/visornic_main.c11
-rw-r--r--drivers/staging/vc04_services/interface/vchi/connections/connection.h3
-rw-r--r--drivers/staging/vc04_services/interface/vchi/message_drivers/message.h9
-rw-r--r--drivers/staging/vc04_services/interface/vchi/vchi.h18
-rw-r--r--drivers/staging/vc04_services/interface/vchi/vchi_common.h9
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h42
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c49
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c132
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h2
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c102
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h3
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c14
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c24
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c9
-rw-r--r--drivers/staging/vme/devices/vme_user.c3
-rw-r--r--drivers/staging/vt6656/card.h34
-rw-r--r--drivers/staging/vt6656/int.c2
-rw-r--r--drivers/staging/vt6656/key.c14
-rw-r--r--drivers/staging/vt6656/mac.c46
-rw-r--r--drivers/staging/vt6656/main_usb.c63
-rw-r--r--drivers/staging/vt6656/wcmd.h4
-rw-r--r--drivers/staging/wilc1000/host_interface.c3
-rw-r--r--drivers/staging/wilc1000/linux_wlan.c4
-rw-r--r--drivers/staging/wilc1000/wilc_debugfs.c4
-rw-r--r--drivers/staging/wilc1000/wilc_sdio.c5
-rw-r--r--drivers/staging/wilc1000/wilc_wfi_cfgoperations.c19
-rw-r--r--drivers/staging/wlan-ng/cfg80211.c6
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h4
-rw-r--r--drivers/staging/wlan-ng/prism2mib.c2
-rw-r--r--drivers/staging/xgifb/XGI_main_26.c31
-rw-r--r--drivers/staging/xgifb/vb_init.c3
-rw-r--r--drivers/usb/core/config.c10
-rw-r--r--drivers/usb/core/hub.c59
-rw-r--r--drivers/usb/dwc2/gadget.c2
-rw-r--r--drivers/usb/dwc2/params.c30
-rw-r--r--drivers/usb/dwc3/core.h10
-rw-r--r--drivers/usb/dwc3/dwc3-omap.c6
-rw-r--r--drivers/usb/dwc3/dwc3-pci.c17
-rw-r--r--drivers/usb/dwc3/ep0.c46
-rw-r--r--drivers/usb/dwc3/gadget.c24
-rw-r--r--drivers/usb/gadget/composite.c12
-rw-r--r--drivers/usb/gadget/function/f_fs.c14
-rw-r--r--drivers/usb/gadget/function/f_hid.c2
-rw-r--r--drivers/usb/gadget/legacy/inode.c18
-rw-r--r--drivers/usb/gadget/udc/core.c6
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c6
-rw-r--r--drivers/usb/host/ohci-at91.c24
-rw-r--r--drivers/usb/host/xhci-mem.c46
-rw-r--r--drivers/usb/host/xhci-mtk.c4
-rw-r--r--drivers/usb/host/xhci-pci.c3
-rw-r--r--drivers/usb/host/xhci-ring.c251
-rw-r--r--drivers/usb/host/xhci.c4
-rw-r--r--drivers/usb/host/xhci.h5
-rw-r--r--drivers/usb/musb/blackfin.c1
-rw-r--r--drivers/usb/musb/musb_core.c2
-rw-r--r--drivers/usb/musb/musb_core.h7
-rw-r--r--drivers/usb/musb/musb_dsps.c12
-rw-r--r--drivers/usb/musb/musb_host.c10
-rw-r--r--drivers/usb/musb/musbhsdma.h2
-rw-r--r--drivers/usb/serial/cyberjack.c10
-rw-r--r--drivers/usb/serial/f81534.c8
-rw-r--r--drivers/usb/serial/garmin_gps.c1
-rw-r--r--drivers/usb/serial/io_edgeport.c5
-rw-r--r--drivers/usb/serial/io_ti.c22
-rw-r--r--drivers/usb/serial/iuu_phoenix.c11
-rw-r--r--drivers/usb/serial/keyspan_pda.c14
-rw-r--r--drivers/usb/serial/kobil_sct.c12
-rw-r--r--drivers/usb/serial/mos7720.c56
-rw-r--r--drivers/usb/serial/mos7840.c24
-rw-r--r--drivers/usb/serial/omninet.c13
-rw-r--r--drivers/usb/serial/oti6858.c16
-rw-r--r--drivers/usb/serial/pl2303.c8
-rw-r--r--drivers/usb/serial/quatech2.c4
-rw-r--r--drivers/usb/serial/spcp8x5.c14
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c7
-rw-r--r--drivers/usb/storage/unusual_devs.h7
-rw-r--r--drivers/vfio/mdev/mdev_core.c100
-rw-r--r--drivers/vfio/mdev/mdev_private.h29
-rw-r--r--drivers/vfio/mdev/mdev_sysfs.c8
-rw-r--r--drivers/vfio/mdev/vfio_mdev.c12
-rw-r--r--drivers/vfio/pci/vfio_pci.c4
-rw-r--r--drivers/vfio/pci/vfio_pci_rdwr.c5
-rw-r--r--drivers/vfio/vfio_iommu_type1.c98
-rw-r--r--drivers/video/fbdev/cobalt_lcdfb.c5
-rw-r--r--drivers/xen/arm-device.c8
-rw-r--r--drivers/xen/events/events_fifo.c3
-rw-r--r--drivers/xen/evtchn.c4
-rw-r--r--drivers/xen/swiotlb-xen.c8
-rw-r--r--drivers/xen/xenbus/xenbus_comms.h1
-rw-r--r--drivers/xen/xenbus/xenbus_dev_frontend.c49
-rw-r--r--fs/block_dev.c3
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/crypto/keyinfo.c3
-rw-r--r--fs/crypto/policy.c5
-rw-r--r--fs/dax.c243
-rw-r--r--fs/ext2/inode.c3
-rw-r--r--fs/ext4/file.c48
-rw-r--r--fs/notify/mark.c12
-rw-r--r--fs/xfs/libxfs/xfs_ag_resv.c3
-rw-r--r--fs/xfs/libxfs/xfs_refcount_btree.c9
-rw-r--r--fs/xfs/libxfs/xfs_refcount_btree.h3
-rw-r--r--fs/xfs/libxfs/xfs_rmap_btree.c14
-rw-r--r--fs/xfs/libxfs/xfs_rmap_btree.h3
-rw-r--r--fs/xfs/xfs_fsops.c14
-rw-r--r--fs/xfs/xfs_icache.c3
-rw-r--r--fs/xfs/xfs_refcount_item.c3
-rw-r--r--fs/xfs/xfs_sysfs.c4
-rw-r--r--include/asm-generic/asm-prototypes.h6
-rw-r--r--include/dt-bindings/mfd/tps65217.h26
-rw-r--r--include/linux/dax.h3
-rw-r--r--include/linux/filter.h1
-rw-r--r--include/linux/fsnotify_backend.h2
-rw-r--r--include/linux/genhd.h9
-rw-r--r--include/linux/hid-sensor-hub.h4
-rw-r--r--include/linux/hid-sensor-ids.h4
-rw-r--r--include/linux/iio/buffer.h160
-rw-r--r--include/linux/iio/buffer_impl.h162
-rw-r--r--include/linux/iio/common/st_sensors.h12
-rw-r--r--include/linux/iio/common/st_sensors_i2c.h9
-rw-r--r--include/linux/iio/kfifo_buf.h5
-rw-r--r--include/linux/mdev.h56
-rw-r--r--include/linux/mfd/cros_ec_commands.h3
-rw-r--r--include/linux/mlx4/device.h2
-rw-r--r--include/linux/mlx5/device.h5
-rw-r--r--include/linux/mlx5/driver.h1
-rw-r--r--include/linux/mlx5/mlx5_ifc.h93
-rw-r--r--include/linux/page-flags.h2
-rw-r--r--include/linux/radix-tree.h4
-rw-r--r--include/linux/swiotlb.h11
-rw-r--r--include/net/netns/ipv4.h1
-rw-r--r--include/net/tcp.h1
-rw-r--r--include/trace/events/swiotlb.h17
-rw-r--r--include/uapi/linux/iio/types.h1
-rw-r--r--include/uapi/linux/usb/functionfs.h1
-rw-r--r--kernel/audit_tree.c18
-rw-r--r--kernel/cpu.c9
-rw-r--r--lib/radix-tree.c11
-rw-r--r--lib/swiotlb.c52
-rw-r--r--mm/filemap.c36
-rw-r--r--mm/memory.c47
-rw-r--r--mm/truncate.c75
-rw-r--r--mm/workingset.c3
-rw-r--r--net/atm/lec.c2
-rw-r--r--net/core/drop_monitor.c39
-rw-r--r--net/core/filter.c6
-rw-r--r--net/core/flow_dissector.c5
-rw-r--r--net/core/rtnetlink.c6
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/igmp.c7
-rw-r--r--net/ipv4/ip_sockglue.c8
-rw-r--r--net/ipv4/route.c3
-rw-r--r--net/ipv4/sysctl_net_ipv4.c14
-rw-r--r--net/ipv4/tcp_ipv4.c4
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/l2tp/l2tp_ip.c19
-rw-r--r--net/l2tp/l2tp_ip6.c24
-rw-r--r--net/mac80211/tx.c3
-rw-r--r--net/openvswitch/datapath.c1
-rw-r--r--net/openvswitch/flow.c54
-rw-r--r--net/sched/cls_api.c4
-rw-r--r--net/sched/cls_flower.c4
-rw-r--r--net/socket.c2
-rw-r--r--net/tipc/socket.c24
-rw-r--r--samples/Kconfig7
-rw-r--r--samples/Makefile3
-rw-r--r--samples/vfio-mdev/Makefile14
-rw-r--r--samples/vfio-mdev/mtty.c32
-rw-r--r--scripts/gcc-plugins/gcc-common.h85
-rw-r--r--scripts/gcc-plugins/latent_entropy_plugin.c4
-rw-r--r--sound/firewire/fireworks/fireworks_stream.c2
-rw-r--r--sound/firewire/tascam/tascam-stream.c2
-rw-r--r--sound/pci/hda/patch_realtek.c2
-rw-r--r--sound/usb/endpoint.c20
-rw-r--r--sound/usb/endpoint.h2
-rw-r--r--sound/usb/pcm.c10
-rw-r--r--tools/iio/iio_event_monitor.c2
-rw-r--r--usr/Makefile16
745 files changed, 16707 insertions, 17542 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index b8f220f978dd..530809ccfacf 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -170,6 +170,16 @@ Description:
Has all of the equivalent parameters as per voltageY. Units
after application of scale and offset are m/s^2.
+What: /sys/bus/iio/devices/iio:deviceX/in_gravity_x_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_gravity_y_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_gravity_z_raw
+KernelVersion: 4.11
+Contact: linux-iio@vger.kernel.org
+Description:
+ Gravity in direction x, y or z (may be arbitrarily assigned
+ but should match other such assignments on device).
+ Units after application of scale and offset are m/s^2.
+
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_x_raw
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_raw
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_raw
@@ -805,7 +815,7 @@ Description:
attribute. E.g. if in_voltage0_raw_thresh_rising_value is set to 1200
and in_voltage0_raw_thresh_rising_hysteresis is set to 50. The event
will get activated once in_voltage0_raw goes above 1200 and will become
- deactived again once the value falls below 1150.
+ deactivated again once the value falls below 1150.
What: /sys/.../events/in_accel_x_raw_roc_rising_value
What: /sys/.../events/in_accel_x_raw_roc_falling_value
@@ -1245,7 +1255,8 @@ Description:
reflectivity of infrared or ultrasound emitted.
Often these sensors are unit less and as such conversion
to SI units is not possible. Higher proximity measurements
- indicate closer objects, and vice versa.
+ indicate closer objects, and vice versa. Units after
+ application of scale and offset are meters.
What: /sys/.../iio:deviceX/in_illuminance_input
What: /sys/.../iio:deviceX/in_illuminance_raw
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08 b/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08
new file mode 100644
index 000000000000..0a1ca1487fa9
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-distance-srf08
@@ -0,0 +1,22 @@
+What /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity
+Date: January 2017
+KernelVersion: 4.11
+Contact: linux-iio@vger.kernel.org
+Description:
+ Show or set the gain boost of the amp, from 0-31 range.
+ default 31
+
+What /sys/bus/iio/devices/iio:deviceX/sensor_max_range
+Date: January 2017
+KernelVersion: 4.11
+Contact: linux-iio@vger.kernel.org
+Description:
+ Show or set the maximum range between the sensor and the
+ first object echoed in meters. Default value is 6.020.
+ This setting limits the time the driver is waiting for a
+ echo.
+ Showing the range of available values is represented as the
+ minimum value, the step and the maximum value, all enclosed
+ in square brackets.
+ Example:
+ [0.043 0.043 11.008]
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index c75e5d6b8fa8..a6eb7dcd4dd5 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -12,7 +12,7 @@ DOCBOOKS := z8530book.xml \
kernel-api.xml filesystems.xml lsm.xml kgdb.xml \
gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
- 80211.xml sh.xml regulator.xml w1.xml \
+ sh.xml regulator.xml w1.xml \
writing_musb_glue_layer.xml iio.xml
ifeq ($(DOCBOOKS),)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 21e2d8863705..be7c0d9506b1 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -106,6 +106,16 @@
use by PCI
Format: <irq>,<irq>...
+ acpi_mask_gpe= [HW,ACPI]
+ Due to the existence of _Lxx/_Exx, some GPEs triggered
+ by unsupported hardware/firmware features can result in
+ GPE floodings that cannot be automatically disabled by
+ the GPE dispatcher.
+ This facility can be used to prevent such uncontrolled
+ GPE floodings.
+ Format: <int>
+ Support masking of GPEs numbered from 0x00 to 0x7f.
+
acpi_no_auto_serialize [HW,ACPI]
Disable auto-serialization of AML methods
AML control methods that contain the opcodes to create
@@ -3811,10 +3821,11 @@
it if 0 is given (See Documentation/cgroup-v1/memory.txt)
swiotlb= [ARM,IA-64,PPC,MIPS,X86]
- Format: { <int> | force }
+ Format: { <int> | force | noforce }
<int> -- Number of I/O TLB slabs
force -- force using of bounce buffers even if they
wouldn't be automatically used by the kernel
+ noforce -- Never use bounce buffers (for debugging)
switches= [HW,M68k]
diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt
index 51642159aedb..c0a3bb5a6e4e 100644
--- a/Documentation/block/queue-sysfs.txt
+++ b/Documentation/block/queue-sysfs.txt
@@ -54,9 +54,9 @@ This is the hardware sector size of the device, in bytes.
io_poll (RW)
------------
-When read, this file shows the total number of block IO polls and how
-many returned success. Writing '0' to this file will disable polling
-for this device. Writing any non-zero value will enable this feature.
+When read, this file shows whether polling is enabled (1) or disabled
+(0). Writing '0' to this file will disable polling for this device.
+Writing any non-zero value will enable this feature.
io_poll_delay (RW)
------------------
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index cdd7b48826c3..ad10fbe61562 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -36,6 +36,7 @@ dallas,ds1775 Tiny Digital Thermometer and Thermostat
dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM
dallas,ds4510 CPU Supervisor with Nonvolatile Memory and Programmable I/O
dallas,ds75 Digital Thermometer and Thermostat
+devantech,srf08 Devantech SRF08 ultrasonic ranger
dlg,da9053 DA9053: flexible system level PMIC with multicore support
dlg,da9063 DA9063: system PMIC for quad-core application processors
domintech,dmard09 DMARD09: 3-axis Accelerometer
diff --git a/Documentation/devicetree/bindings/iio/accel/lis302.txt b/Documentation/devicetree/bindings/iio/accel/lis302.txt
index 2a19bff9693f..dfdce67826ba 100644
--- a/Documentation/devicetree/bindings/iio/accel/lis302.txt
+++ b/Documentation/devicetree/bindings/iio/accel/lis302.txt
@@ -5,7 +5,7 @@ that apply in on the generic device (independent from the bus).
Required properties for the SPI bindings:
- - compatible: should be set to "st,lis3lv02d_spi"
+ - compatible: should be set to "st,lis3lv02d-spi"
- reg: the chipselect index
- spi-max-frequency: maximal bus speed, should be set to 1000000 unless
constrained by external circuitry
diff --git a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt
new file mode 100644
index 000000000000..f9e3ff2c656e
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt
@@ -0,0 +1,32 @@
+* Amlogic Meson SAR (Successive Approximation Register) A/D converter
+
+Required properties:
+- compatible: depending on the SoC this should be one of:
+ - "amlogic,meson-gxbb-saradc" for GXBB
+ - "amlogic,meson-gxl-saradc" for GXL
+ - "amlogic,meson-gxm-saradc" for GXM
+ along with the generic "amlogic,meson-saradc"
+- reg: the physical base address and length of the registers
+- clocks: phandle and clock identifier (see clock-names)
+- clock-names: mandatory clocks:
+ - "clkin" for the reference clock (typically XTAL)
+ - "core" for the SAR ADC core clock
+ optional clocks:
+ - "sana" for the analog clock
+ - "adc_clk" for the ADC (sampling) clock
+ - "adc_sel" for the ADC (sampling) clock mux
+- vref-supply: the regulator supply for the ADC reference voltage
+- #io-channel-cells: must be 1, see ../iio-bindings.txt
+
+Example:
+ saradc: adc@8680 {
+ compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc";
+ #io-channel-cells = <1>;
+ reg = <0x0 0x8680 0x0 0x34>;
+ clocks = <&xtal>,
+ <&clkc CLKID_SAR_ADC>,
+ <&clkc CLKID_SANA>,
+ <&clkc CLKID_SAR_ADC_CLK>,
+ <&clkc CLKID_SAR_ADC_SEL>;
+ clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel";
+ };
diff --git a/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt
new file mode 100644
index 000000000000..b3629405f568
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/avia-hx711.txt
@@ -0,0 +1,18 @@
+* AVIA HX711 ADC chip for weight cells
+ Bit-banging driver
+
+Required properties:
+ - compatible: Should be "avia,hx711"
+ - sck-gpios: Definition of the GPIO for the clock
+ - dout-gpios: Definition of the GPIO for data-out
+ See Documentation/devicetree/bindings/gpio/gpio.txt
+ - avdd-supply: Definition of the regulator used as analog supply
+
+Example:
+weight@0 {
+ compatible = "avia,hx711";
+ sck-gpios = <&gpio3 10 GPIO_ACTIVE_HIGH>;
+ dout-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
+ avdd-suppy = <&avdd>;
+};
+
diff --git a/Documentation/devicetree/bindings/iio/adc/max11100.txt b/Documentation/devicetree/bindings/iio/adc/max11100.txt
new file mode 100644
index 000000000000..b7f7177b8aca
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/max11100.txt
@@ -0,0 +1,18 @@
+* Maxim max11100 Analog to Digital Converter (ADC)
+
+Required properties:
+ - compatible: Should be "maxim,max11100"
+ - reg: the adc unit address
+ - vref-supply: phandle to the regulator that provides reference voltage
+
+Optional properties:
+ - spi-max-frequency: SPI maximum frequency
+
+Example:
+
+max11100: adc@0 {
+ compatible = "maxim,max11100";
+ reg = <0>;
+ vref-supply = <&adc0_vref>;
+ spi-max-frequency = <240000>;
+};
diff --git a/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt b/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt
new file mode 100644
index 000000000000..f5b0adae6010
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/renesas,gyroadc.txt
@@ -0,0 +1,99 @@
+* Renesas RCar GyroADC device driver
+
+The GyroADC block is a reduced SPI block with up to 8 chipselect lines,
+which supports the SPI protocol of a selected few SPI ADCs. The SPI ADCs
+are sampled by the GyroADC block in a round-robin fashion and the result
+presented in the GyroADC registers.
+
+Required properties:
+- compatible: Should be "<soc-specific>", "renesas,rcar-gyroadc".
+ The <soc-specific> should be one of:
+ renesas,r8a7791-gyroadc - for the GyroADC block present
+ in r8a7791 SoC
+ renesas,r8a7792-gyroadc - for the GyroADC with interrupt
+ block present in r8a7792 SoC
+- reg: Address and length of the register set for the device
+- clocks: References to all the clocks specified in the clock-names
+ property as specified in
+ Documentation/devicetree/bindings/clock/clock-bindings.txt.
+- clock-names: Shall contain "fck" and "if". The "fck" is the GyroADC block
+ clock, the "if" is the interface clock.
+- power-domains: Must contain a reference to the PM domain, if available.
+- #address-cells: Should be <1> (setting for the subnodes) for all ADCs
+ except for "fujitsu,mb88101a". Should be <0> (setting for
+ only subnode) for "fujitsu,mb88101a".
+- #size-cells: Should be <0> (setting for the subnodes)
+
+Sub-nodes:
+You must define subnode(s) which select the connected ADC type and reference
+voltage for the GyroADC channels.
+
+Required properties for subnodes:
+- compatible: Should be either of:
+ "fujitsu,mb88101a"
+ - Fujitsu MB88101A compatible mode,
+ 12bit sampling, up to 4 channels can be sampled in
+ round-robin fashion. One Fujitsu chip supplies four
+ GyroADC channels with data as it contains four ADCs
+ on the chip and thus for 4-channel operation, single
+ MB88101A is required. The Cx chipselect lines of the
+ MB88101A connect directly to two CHS lines of the
+ GyroADC, no demuxer is required. The data out line
+ of each MB88101A connects to a shared input pin of
+ the GyroADC.
+ "ti,adcs7476" or "ti,adc121" or "adi,ad7476"
+ - TI ADCS7476 / TI ADC121 / ADI AD7476 compatible mode,
+ 15bit sampling, up to 8 channels can be sampled in
+ round-robin fashion. One TI/ADI chip supplies single
+ ADC channel with data, thus for 8-channel operation,
+ 8 chips are required. A 3:8 chipselect demuxer is
+ required to connect the nCS line of the TI/ADI chips
+ to the GyroADC, while MISO line of each TI/ADI ADC
+ connects to a shared input pin of the GyroADC.
+ "maxim,max1162" or "maxim,max11100"
+ - Maxim MAX1162 / Maxim MAX11100 compatible mode,
+ 16bit sampling, up to 8 channels can be sampled in
+ round-robin fashion. One Maxim chip supplies single
+ ADC channel with data, thus for 8-channel operation,
+ 8 chips are required. A 3:8 chipselect demuxer is
+ required to connect the nCS line of the MAX chips
+ to the GyroADC, while MISO line of each Maxim ADC
+ connects to a shared input pin of the GyroADC.
+- reg: Should be the number of the analog input. Should be present
+ for all ADCs except "fujitsu,mb88101a".
+- vref-supply: Reference to the channel reference voltage regulator.
+
+Example:
+ vref_max1162: regulator-vref-max1162 {
+ compatible = "regulator-fixed";
+
+ regulator-name = "MAX1162 Vref";
+ regulator-min-microvolt = <4096000>;
+ regulator-max-microvolt = <4096000>;
+ };
+
+ adc@e6e54000 {
+ compatible = "renesas,r8a7791-gyroadc", "renesas,rcar-gyroadc";
+ reg = <0 0xe6e54000 0 64>;
+ clocks = <&mstp9_clks R8A7791_CLK_GYROADC>, <&clk_65m>;
+ clock-names = "fck", "if";
+ power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
+
+ pinctrl-0 = <&adc_pins>;
+ pinctrl-names = "default";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc@0 {
+ reg = <0>;
+ compatible = "maxim,max1162";
+ vref-supply = <&vref_max1162>;
+ };
+
+ adc@1 {
+ reg = <1>;
+ compatible = "maxim,max1162";
+ vref-supply = <&vref_max1162>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt b/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt
new file mode 100644
index 000000000000..e77a6f7e1001
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/ti-ads7950.txt
@@ -0,0 +1,23 @@
+* Texas Instruments ADS7950 family of A/DC chips
+
+Required properties:
+ - compatible: Must be one of "ti,ads7950", "ti,ads7951", "ti,ads7952",
+ "ti,ads7953", "ti,ads7954", "ti,ads7955", "ti,ads7956", "ti,ads7957",
+ "ti,ads7958", "ti,ads7959", "ti,ads7960", or "ti,ads7961"
+ - reg: SPI chip select number for the device
+ - #io-channel-cells: Must be 1 as per ../iio-bindings.txt
+ - vref-supply: phandle to a regulator node that supplies the 2.5V or 5V
+ reference voltage
+
+Recommended properties:
+ - spi-max-frequency: Definition as per
+ Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Example:
+adc@0 {
+ compatible = "ti,ads7957";
+ reg = <0>;
+ #io-channel-cells = <1>;
+ vref-supply = <&refin_supply>;
+ spi-max-frequency = <10000000>;
+};
diff --git a/Documentation/devicetree/bindings/iio/imu/bmi160.txt b/Documentation/devicetree/bindings/iio/imu/bmi160.txt
new file mode 100644
index 000000000000..ae0112c7debc
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/imu/bmi160.txt
@@ -0,0 +1,36 @@
+Bosch BMI160 - Inertial Measurement Unit with Accelerometer, Gyroscope
+and externally connectable Magnetometer
+
+https://www.bosch-sensortec.com/bst/products/all_products/bmi160
+
+Required properties:
+ - compatible : should be "bosch,bmi160"
+ - reg : the I2C address or SPI chip select number of the sensor
+ - spi-max-frequency : set maximum clock frequency (only for SPI)
+
+Optional properties:
+ - interrupt-parent : should be the phandle of the interrupt controller
+ - interrupts : interrupt mapping for IRQ, must be IRQ_TYPE_LEVEL_LOW
+ - interrupt-names : set to "INT1" if INT1 pin should be used as interrupt
+ input, set to "INT2" if INT2 pin should be used instead
+
+Examples:
+
+bmi160@68 {
+ compatible = "bosch,bmi160";
+ reg = <0x68>;
+
+ interrupt-parent = <&gpio4>;
+ interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "INT1";
+};
+
+bmi160@0 {
+ compatible = "bosch,bmi160";
+ reg = <0>;
+ spi-max-frequency = <10000000>;
+
+ interrupt-parent = <&gpio2>;
+ interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-names = "INT2";
+};
diff --git a/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt
new file mode 100644
index 000000000000..cf81afdf7803
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/imu/st_lsm6dsx.txt
@@ -0,0 +1,26 @@
+* ST_LSM6DSx driver for STM 6-axis (acc + gyro) imu Mems sensors
+
+Required properties:
+- compatible: must be one of:
+ "st,lsm6ds3"
+ "st,lsm6dsm"
+- reg: i2c address of the sensor / spi cs line
+
+Optional properties:
+- st,drdy-int-pin: the pin on the package that will be used to signal
+ "data ready" (valid values: 1 or 2).
+- interrupt-parent: should be the phandle for the interrupt controller
+- interrupts: interrupt mapping for IRQ. It should be configured with
+ flags IRQ_TYPE_LEVEL_HIGH or IRQ_TYPE_EDGE_RISING.
+
+ Refer to interrupt-controller/interrupts.txt for generic interrupt
+ client node bindings.
+
+Example:
+
+lsm6dsm@6b {
+ compatible = "st,lsm6dsm";
+ reg = <0x6b>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <0 IRQ_TYPE_EDGE_RISING>;
+};
diff --git a/Documentation/devicetree/bindings/iio/light/cm3605.txt b/Documentation/devicetree/bindings/iio/light/cm3605.txt
new file mode 100644
index 000000000000..56331a79f9ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/light/cm3605.txt
@@ -0,0 +1,41 @@
+Capella Microsystems CM3605
+Ambient Light and Short Distance Proximity Sensor
+
+The CM3605 is an entirely analog part which however require quite a bit of
+software logic to interface a host operating system.
+
+This ALS and proximity sensor was one of the very first deployed in mobile
+handsets, notably it is used in the very first Nexus One Android phone from
+2010.
+
+Required properties:
+- compatible: must be: "capella,cm3605"
+- aset-gpios: GPIO line controlling the ASET line (drive low
+ to activate the ALS, should be flagged GPIO_ACTIVE_LOW)
+- interrupts: the IRQ line (such as a GPIO) that is connected to
+ the POUT (proximity sensor out) line. The edge detection must
+ be set to IRQ_TYPE_EDGE_BOTH so as to detect movements toward
+ and away from the proximity sensor.
+- io-channels: the ADC channel used for converting the voltage from
+ AOUT to a digital representation.
+- io-channel-names: must be "aout"
+
+Optional properties:
+- vdd-supply: regulator supplying VDD power to the component.
+- capella,aset-resistance-ohms: the sensitivity calibration resistance,
+ in Ohms. Valid values are: 50000, 100000, 300000 and 600000,
+ as these are the resistance values that we are supplied with
+ calibration curves for. If not supplied, 100 kOhm will be assumed
+ but it is strongly recommended to supply this.
+
+Example:
+
+cm3605 {
+ compatible = "capella,cm3605";
+ vdd-supply = <&foo_reg>;
+ aset-gpios = <&foo_gpio 1 GPIO_ACTIVE_LOW>;
+ capella,aset-resistance-ohms = <100000>;
+ interrupts = <1 IRQ_TYPE_EDGE_BOTH>;
+ io-channels = <&adc 0x01>;
+ io-channel-names = "aout";
+};
diff --git a/Documentation/devicetree/bindings/iio/potentiometer/max5481.txt b/Documentation/devicetree/bindings/iio/potentiometer/max5481.txt
new file mode 100644
index 000000000000..6a91b106e076
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/potentiometer/max5481.txt
@@ -0,0 +1,23 @@
+* Maxim Linear-Taper Digital Potentiometer MAX5481-MAX5484
+
+The node for this driver must be a child node of a SPI controller, hence
+all mandatory properties described in
+
+ Documentation/devicetree/bindings/spi/spi-bus.txt
+
+must be specified.
+
+Required properties:
+ - compatible: Must be one of the following, depending on the
+ model:
+ "maxim,max5481"
+ "maxim,max5482"
+ "maxim,max5483"
+ "maxim,max5484"
+
+Example:
+max548x: max548x@0 {
+ compatible = "maxim,max5482";
+ spi-max-frequency = <7000000>;
+ reg = <0>; /* chip-select */
+};
diff --git a/Documentation/devicetree/bindings/iio/st-sensors.txt b/Documentation/devicetree/bindings/iio/st-sensors.txt
index c040c9ad1889..eaa8fbba34e2 100644
--- a/Documentation/devicetree/bindings/iio/st-sensors.txt
+++ b/Documentation/devicetree/bindings/iio/st-sensors.txt
@@ -27,6 +27,8 @@ standard bindings from pinctrl/pinctrl-bindings.txt.
Valid compatible strings:
Accelerometers:
+- st,lis3lv02d (deprecated, use st,lis3lv02dl-accel)
+- st,lis302dl-spi (deprecated, use st,lis3lv02dl-accel)
- st,lis3lv02dl-accel
- st,lsm303dlh-accel
- st,lsm303dlhc-accel
diff --git a/Documentation/devicetree/bindings/iio/temperature/tmp007.txt b/Documentation/devicetree/bindings/iio/temperature/tmp007.txt
new file mode 100644
index 000000000000..b63aba91ef03
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/temperature/tmp007.txt
@@ -0,0 +1,35 @@
+* TI TMP007 - IR thermopile sensor with integrated math engine
+
+Link to datasheet: http://www.ti.com/lit/ds/symlink/tmp007.pdf
+
+Required properties:
+
+ - compatible: should be "ti,tmp007"
+ - reg: the I2C address of the sensor (changeable via ADR pins)
+ ------------------------------
+ |ADR1 | ADR0 | Device Address|
+ ------------------------------
+ 0 0 0x40
+ 0 1 0x41
+ 0 SDA 0x42
+ 0 SCL 0x43
+ 1 0 0x44
+ 1 1 0x45
+ 1 SDA 0x46
+ 1 SCL 0x47
+
+Optional properties:
+
+ - interrupt-parent: should be the phandle for the interrupt controller
+
+ - interrupts: interrupt mapping for GPIO IRQ (level active low)
+
+Example:
+
+tmp007@40 {
+ compatible = "ti,tmp007";
+ reg = <0x40>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <5 0x08>;
+};
+
diff --git a/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
index 3e5b9793341f..8682ab6d4a50 100644
--- a/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
+++ b/Documentation/devicetree/bindings/input/tps65218-pwrbutton.txt
@@ -8,8 +8,9 @@ This driver provides a simple power button event via an Interrupt.
Required properties:
- compatible: should be "ti,tps65217-pwrbutton" or "ti,tps65218-pwrbutton"
-Required properties for TPS65218:
+Required properties:
- interrupts: should be one of the following
+ - <2>: For controllers compatible with tps65217
- <3 IRQ_TYPE_EDGE_BOTH>: For controllers compatible with tps65218
Examples:
@@ -17,6 +18,7 @@ Examples:
&tps {
tps65217-pwrbutton {
compatible = "ti,tps65217-pwrbutton";
+ interrupts = <2>;
};
};
diff --git a/Documentation/devicetree/bindings/power/supply/tps65217_charger.txt b/Documentation/devicetree/bindings/power/supply/tps65217_charger.txt
index 98d131acee95..a11072c5a866 100644
--- a/Documentation/devicetree/bindings/power/supply/tps65217_charger.txt
+++ b/Documentation/devicetree/bindings/power/supply/tps65217_charger.txt
@@ -2,11 +2,16 @@ TPS65217 Charger
Required Properties:
-compatible: "ti,tps65217-charger"
+-interrupts: TPS65217 interrupt numbers for the AC and USB charger input change.
+ Should be <0> for the USB charger and <1> for the AC adapter.
+-interrupt-names: Should be "USB" and "AC"
This node is a subnode of the tps65217 PMIC.
Example:
tps65217-charger {
- compatible = "ti,tps65090-charger";
+ compatible = "ti,tps65217-charger";
+ interrupts = <0>, <1>;
+ interrupt-names = "USB", "AC";
};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 16d3b5e7f5d1..cf1c36616507 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -40,6 +40,7 @@ atmel Atmel Corporation
auo AU Optronics Corporation
auvidea Auvidea GmbH
avago Avago Technologies
+avia avia semiconductor
avic Shanghai AVIC Optoelectronics Co., Ltd.
axentia Axentia Technologies AB
axis Axis Communications AB
@@ -75,6 +76,7 @@ dallas Maxim Integrated Products (formerly Dallas Semiconductor)
davicom DAVICOM Semiconductor, Inc.
delta Delta Electronics, Inc.
denx Denx Software Engineering
+devantech Devantech, Ltd.
digi Digi International Inc.
digilent Diglent, Inc.
dlg Dialog Semiconductor
@@ -118,6 +120,7 @@ gmt Global Mixed-mode Technology, Inc.
goodix Shenzhen Huiding Technology Co., Ltd.
google Google, Inc.
grinn Grinn
+grmn Garmin Limited
gumstix Gumstix, Inc.
gw Gateworks Corporation
hannstar HannStar Display Corporation
diff --git a/Documentation/driver-api/infrastructure.rst b/Documentation/driver-api/infrastructure.rst
index 0bb0b5fc9512..6d9ff316b608 100644
--- a/Documentation/driver-api/infrastructure.rst
+++ b/Documentation/driver-api/infrastructure.rst
@@ -55,21 +55,6 @@ Device Drivers DMA Management
.. kernel-doc:: drivers/base/dma-mapping.c
:export:
-Device Drivers Power Management
--------------------------------
-
-.. kernel-doc:: drivers/base/power/main.c
- :export:
-
-Device Drivers ACPI Support
----------------------------
-
-.. kernel-doc:: drivers/acpi/scan.c
- :export:
-
-.. kernel-doc:: drivers/acpi/scan.c
- :internal:
-
Device drivers PnP support
--------------------------
diff --git a/Documentation/networking/mpls-sysctl.txt b/Documentation/networking/mpls-sysctl.txt
index 9ed15f86c17c..15d8d16934fd 100644
--- a/Documentation/networking/mpls-sysctl.txt
+++ b/Documentation/networking/mpls-sysctl.txt
@@ -5,8 +5,8 @@ platform_labels - INTEGER
possible to configure forwarding for label values equal to or
greater than the number of platform labels.
- A dense utliziation of the entries in the platform label table
- is possible and expected aas the platform labels are locally
+ A dense utilization of the entries in the platform label table
+ is possible and expected as the platform labels are locally
allocated.
If the number of platform label table entries is set to 0 no
diff --git a/Documentation/unaligned-memory-access.txt b/Documentation/unaligned-memory-access.txt
index a445da098bc6..3f76c0c37920 100644
--- a/Documentation/unaligned-memory-access.txt
+++ b/Documentation/unaligned-memory-access.txt
@@ -151,7 +151,7 @@ bool ether_addr_equal(const u8 *addr1, const u8 *addr2)
#else
const u16 *a = (const u16 *)addr1;
const u16 *b = (const u16 *)addr2;
- return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0;
+ return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) == 0;
#endif
}
diff --git a/Documentation/vfio-mediated-device.txt b/Documentation/vfio-mediated-device.txt
index b38afec35edc..d226c7a5ba8b 100644
--- a/Documentation/vfio-mediated-device.txt
+++ b/Documentation/vfio-mediated-device.txt
@@ -127,22 +127,22 @@ the VFIO when devices are unbound from the driver.
Physical Device Driver Interface
--------------------------------
-The physical device driver interface provides the parent_ops[3] structure to
-define the APIs to manage work in the mediated core driver that is related to
-the physical device.
+The physical device driver interface provides the mdev_parent_ops[3] structure
+to define the APIs to manage work in the mediated core driver that is related
+to the physical device.
-The structures in the parent_ops structure are as follows:
+The structures in the mdev_parent_ops structure are as follows:
* dev_attr_groups: attributes of the parent device
* mdev_attr_groups: attributes of the mediated device
* supported_config: attributes to define supported configurations
-The functions in the parent_ops structure are as follows:
+The functions in the mdev_parent_ops structure are as follows:
* create: allocate basic resources in a driver for a mediated device
* remove: free resources in a driver when a mediated device is destroyed
-The callbacks in the parent_ops structure are as follows:
+The callbacks in the mdev_parent_ops structure are as follows:
* open: open callback of mediated device
* close: close callback of mediated device
@@ -151,14 +151,14 @@ The callbacks in the parent_ops structure are as follows:
* write: write emulation callback
* mmap: mmap emulation callback
-A driver should use the parent_ops structure in the function call to register
-itself with the mdev core driver:
+A driver should use the mdev_parent_ops structure in the function call to
+register itself with the mdev core driver:
extern int mdev_register_device(struct device *dev,
- const struct parent_ops *ops);
+ const struct mdev_parent_ops *ops);
-However, the parent_ops structure is not required in the function call that a
-driver should use to unregister itself with the mdev core driver:
+However, the mdev_parent_ops structure is not required in the function call
+that a driver should use to unregister itself with the mdev core driver:
extern void mdev_unregister_device(struct device *dev);
@@ -223,6 +223,9 @@ Directories and files under the sysfs for Each Physical Device
sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name);
+ (or using mdev_parent_dev(mdev) to arrive at the parent device outside
+ of the core mdev code)
+
* device_api
This attribute should show which device API is being created, for example,
@@ -394,5 +397,5 @@ References
[1] See Documentation/vfio.txt for more information on VFIO.
[2] struct mdev_driver in include/linux/mdev.h
-[3] struct parent_ops in include/linux/mdev.h
+[3] struct mdev_parent_ops in include/linux/mdev.h
[4] struct vfio_iommu_driver_ops in include/linux/vfio.h
diff --git a/MAINTAINERS b/MAINTAINERS
index cfff2c9e3d94..89e0877e1399 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3800,6 +3800,7 @@ F: include/linux/devcoredump.h
DEVICE FREQUENCY (DEVFREQ)
M: MyungJoo Ham <myungjoo.ham@samsung.com>
M: Kyungmin Park <kyungmin.park@samsung.com>
+R: Chanwoo Choi <cw00.choi@samsung.com>
L: linux-pm@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq.git
S: Maintained
@@ -5080,9 +5081,11 @@ F: drivers/net/wan/dlci.c
F: drivers/net/wan/sdla.c
FRAMEBUFFER LAYER
+M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
L: linux-fbdev@vger.kernel.org
+T: git git://github.com/bzolnier/linux.git
Q: http://patchwork.kernel.org/project/linux-fbdev/list/
-S: Orphan
+S: Maintained
F: Documentation/fb/
F: drivers/video/
F: include/video/
@@ -5504,6 +5507,7 @@ M: Alex Elder <elder@kernel.org>
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
S: Maintained
F: drivers/staging/greybus/
+L: greybus-dev@lists.linaro.org
GREYBUS AUDIO PROTOCOLS DRIVERS
M: Vaibhav Agarwal <vaibhav.sr@gmail.com>
@@ -5961,6 +5965,7 @@ F: drivers/media/platform/sti/hva
Hyper-V CORE AND DRIVERS
M: "K. Y. Srinivasan" <kys@microsoft.com>
M: Haiyang Zhang <haiyangz@microsoft.com>
+M: Stephen Hemminger <sthemmin@microsoft.com>
L: devel@linuxdriverproject.org
S: Maintained
F: arch/x86/include/asm/mshyperv.h
@@ -8852,17 +8857,22 @@ F: drivers/video/fbdev/nvidia/
NVM EXPRESS DRIVER
M: Keith Busch <keith.busch@intel.com>
M: Jens Axboe <axboe@fb.com>
+M: Christoph Hellwig <hch@lst.de>
+M: Sagi Grimberg <sagi@grimberg.me>
L: linux-nvme@lists.infradead.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
-W: https://kernel.googlesource.com/pub/scm/linux/kernel/git/axboe/linux-block/
+T: git://git.infradead.org/nvme.git
+W: http://git.infradead.org/nvme.git
S: Supported
F: drivers/nvme/host/
F: include/linux/nvme.h
+F: include/uapi/linux/nvme_ioctl.h
NVM EXPRESS TARGET DRIVER
M: Christoph Hellwig <hch@lst.de>
M: Sagi Grimberg <sagi@grimberg.me>
L: linux-nvme@lists.infradead.org
+T: git://git.infradead.org/nvme.git
+W: http://git.infradead.org/nvme.git
S: Supported
F: drivers/nvme/target/
@@ -9842,7 +9852,7 @@ M: Mark Rutland <mark.rutland@arm.com>
M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
L: linux-arm-kernel@lists.infradead.org
S: Maintained
-F: drivers/firmware/psci.c
+F: drivers/firmware/psci*.c
F: include/linux/psci.h
F: include/uapi/linux/psci.h
@@ -10429,6 +10439,12 @@ L: linux-renesas-soc@vger.kernel.org
F: drivers/net/ethernet/renesas/
F: include/linux/sh_eth.h
+RENESAS R-CAR GYROADC DRIVER
+M: Marek Vasut <marek.vasut@gmail.com>
+L: linux-iio@vger.kernel.org
+S: Supported
+F: drivers/iio/adc/rcar_gyro_adc.c
+
RENESAS USB2 PHY DRIVER
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
L: linux-renesas-soc@vger.kernel.org
@@ -13527,11 +13543,11 @@ F: arch/x86/xen/*swiotlb*
F: drivers/xen/*swiotlb*
XFS FILESYSTEM
-M: Dave Chinner <david@fromorbit.com>
+M: Darrick J. Wong <darrick.wong@oracle.com>
M: linux-xfs@vger.kernel.org
L: linux-xfs@vger.kernel.org
W: http://xfs.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git
+T: git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git
S: Supported
F: Documentation/filesystems/xfs.txt
F: fs/xfs/
diff --git a/Makefile b/Makefile
index ec411ba9e40f..5f1a84735ff6 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 4
PATCHLEVEL = 10
SUBLEVEL = 0
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc3
NAME = Roaring Lionus
# *DOCUMENTATION*
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5fab553fd03a..186c4c214e0a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1502,8 +1502,7 @@ source kernel/Kconfig.preempt
config HZ_FIXED
int
- default 200 if ARCH_EBSA110 || ARCH_S3C24XX || \
- ARCH_S5PV210 || ARCH_EXYNOS4
+ default 200 if ARCH_EBSA110
default 128 if SOC_AT91RM9200
default 0
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index cccdbcb557b6..7327250f0bb6 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -501,6 +501,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += \
am3517-evm.dtb \
am3517_mt_ventoux.dtb \
logicpd-torpedo-37xx-devkit.dtb \
+ logicpd-som-lv-37xx-devkit.dtb \
omap3430-sdp.dtb \
omap3-beagle.dtb \
omap3-beagle-xm.dtb \
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index dc561d505bbe..3e32dd18fd25 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -6,8 +6,6 @@
* published by the Free Software Foundation.
*/
-#include <dt-bindings/mfd/tps65217.h>
-
/ {
cpus {
cpu@0 {
@@ -319,13 +317,13 @@
ti,pmic-shutdown-controller;
charger {
- interrupts = <TPS65217_IRQ_AC>, <TPS65217_IRQ_USB>;
- interrupts-names = "AC", "USB";
+ interrupts = <0>, <1>;
+ interrupt-names = "USB", "AC";
status = "okay";
};
pwrbutton {
- interrupts = <TPS65217_IRQ_PB>;
+ interrupts = <2>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 64c8aa9057a3..18d72a245e88 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -16,6 +16,7 @@
interrupt-parent = <&intc>;
#address-cells = <1>;
#size-cells = <1>;
+ chosen { };
aliases {
i2c0 = &i2c0;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index ac55f93fc91e..2df9e6050c2f 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -16,6 +16,7 @@
interrupt-parent = <&wakeupgen>;
#address-cells = <1>;
#size-cells = <1>;
+ chosen { };
memory@0 {
device_type = "memory";
diff --git a/arch/arm/boot/dts/am571x-idk.dts b/arch/arm/boot/dts/am571x-idk.dts
index d6e43e5184c1..ad68d1eb3bc3 100644
--- a/arch/arm/boot/dts/am571x-idk.dts
+++ b/arch/arm/boot/dts/am571x-idk.dts
@@ -62,11 +62,6 @@
linux,default-trigger = "mmc0";
};
};
-
- extcon_usb2: extcon_usb2 {
- compatible = "linux,extcon-usb-gpio";
- id-gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>;
- };
};
&mmc1 {
@@ -79,3 +74,8 @@
&omap_dwc3_2 {
extcon = <&extcon_usb2>;
};
+
+&extcon_usb2 {
+ id-gpio = <&gpio5 7 GPIO_ACTIVE_HIGH>;
+ vbus-gpio = <&gpio7 22 GPIO_ACTIVE_HIGH>;
+};
diff --git a/arch/arm/boot/dts/am572x-idk.dts b/arch/arm/boot/dts/am572x-idk.dts
index 27d9149cedba..8350b4b34b08 100644
--- a/arch/arm/boot/dts/am572x-idk.dts
+++ b/arch/arm/boot/dts/am572x-idk.dts
@@ -23,11 +23,6 @@
reg = <0x0 0x80000000 0x0 0x80000000>;
};
- extcon_usb2: extcon_usb2 {
- compatible = "linux,extcon-usb-gpio";
- id-gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>;
- };
-
status-leds {
compatible = "gpio-leds";
cpu0-led {
@@ -76,6 +71,11 @@
extcon = <&extcon_usb2>;
};
+&extcon_usb2 {
+ id-gpio = <&gpio3 16 GPIO_ACTIVE_HIGH>;
+ vbus-gpio = <&gpio3 26 GPIO_ACTIVE_HIGH>;
+};
+
&mmc1 {
status = "okay";
vmmc-supply = <&v3_3d>;
@@ -87,3 +87,7 @@
&sn65hvs882 {
load-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>;
};
+
+&pcie1 {
+ gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+};
diff --git a/arch/arm/boot/dts/am57xx-idk-common.dtsi b/arch/arm/boot/dts/am57xx-idk-common.dtsi
index 555ae21f2b9a..814a720d5c3d 100644
--- a/arch/arm/boot/dts/am57xx-idk-common.dtsi
+++ b/arch/arm/boot/dts/am57xx-idk-common.dtsi
@@ -303,6 +303,13 @@
gpio-controller;
#gpio-cells = <2>;
};
+
+ extcon_usb2: tps659038_usb {
+ compatible = "ti,palmas-usb-vid";
+ ti,enable-vbus-detection;
+ ti,enable-id-detection;
+ /* ID & VBUS GPIOs provided in board dts */
+ };
};
};
@@ -369,7 +376,7 @@
};
&usb2 {
- dr_mode = "otg";
+ dr_mode = "peripheral";
};
&mmc2 {
diff --git a/arch/arm/boot/dts/dm814x.dtsi b/arch/arm/boot/dts/dm814x.dtsi
index 1facc5f12cef..81b8cecb5820 100644
--- a/arch/arm/boot/dts/dm814x.dtsi
+++ b/arch/arm/boot/dts/dm814x.dtsi
@@ -12,6 +12,7 @@
interrupt-parent = <&intc>;
#address-cells = <1>;
#size-cells = <1>;
+ chosen { };
aliases {
i2c0 = &i2c1;
diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi
index 61dd2f6b02bc..6db652ae9bd5 100644
--- a/arch/arm/boot/dts/dm816x.dtsi
+++ b/arch/arm/boot/dts/dm816x.dtsi
@@ -12,6 +12,7 @@
interrupt-parent = <&intc>;
#address-cells = <1>;
#size-cells = <1>;
+ chosen { };
aliases {
i2c0 = &i2c1;
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index addb7530cfbe..1faf24acd521 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -18,6 +18,7 @@
compatible = "ti,dra7xx";
interrupt-parent = <&crossbar_mpu>;
+ chosen { };
aliases {
i2c0 = &i2c1;
diff --git a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
index ee6dac44edf1..e6df676886c0 100644
--- a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
+++ b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
@@ -132,3 +132,19 @@
ti,palmas-long-press-seconds = <6>;
};
};
+
+&usb2_phy1 {
+ phy-supply = <&ldo4_reg>;
+};
+
+&usb2_phy2 {
+ phy-supply = <&ldo4_reg>;
+};
+
+&dss {
+ vdda_video-supply = <&ldo5_reg>;
+};
+
+&mmc1 {
+ vmmc_aux-supply = <&ldo1_reg>;
+};
diff --git a/arch/arm/boot/dts/imx31.dtsi b/arch/arm/boot/dts/imx31.dtsi
index 685916e3d8a1..85cd8be22f71 100644
--- a/arch/arm/boot/dts/imx31.dtsi
+++ b/arch/arm/boot/dts/imx31.dtsi
@@ -31,11 +31,11 @@
};
};
- avic: avic-interrupt-controller@60000000 {
+ avic: interrupt-controller@68000000 {
compatible = "fsl,imx31-avic", "fsl,avic";
interrupt-controller;
#interrupt-cells = <1>;
- reg = <0x60000000 0x100000>;
+ reg = <0x68000000 0x100000>;
};
soc {
diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
index e476d01959ea..26d060484728 100644
--- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi
@@ -533,7 +533,6 @@
MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17071
MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17071
MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17071
- MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x000b0
>;
};
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index 53e6e63cbb02..89b834f3fa17 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -1100,6 +1100,7 @@
interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_EIM_SLOW>;
fsl,weim-cs-gpr = <&gpr>;
+ status = "disabled";
};
ocotp: ocotp@021bc000 {
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi
index 4fd6de29f07d..19cbd879c448 100644
--- a/arch/arm/boot/dts/imx6sl.dtsi
+++ b/arch/arm/boot/dts/imx6sl.dtsi
@@ -900,6 +900,7 @@
reg = <0x021b8000 0x4000>;
interrupts = <0 14 IRQ_TYPE_LEVEL_HIGH>;
fsl,weim-cs-gpr = <&gpr>;
+ status = "disabled";
};
ocotp: ocotp@021bc000 {
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 076a30f9bcae..10f333016197 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -977,6 +977,7 @@
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6SX_CLK_EIM_SLOW>;
fsl,weim-cs-gpr = <&gpr>;
+ status = "disabled";
};
ocotp: ocotp@021bc000 {
diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi
index 4f793a025a72..f1d6de8b3c19 100644
--- a/arch/arm/boot/dts/omap2.dtsi
+++ b/arch/arm/boot/dts/omap2.dtsi
@@ -17,6 +17,7 @@
interrupt-parent = <&intc>;
#address-cells = <1>;
#size-cells = <1>;
+ chosen { };
aliases {
serial0 = &uart1;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 87ca50b53002..4d448f145ed1 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -734,6 +734,8 @@
vmmc_aux-supply = <&vsim>;
bus-width = <8>;
non-removable;
+ no-sdio;
+ no-sd;
};
&mmc3 {
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index ecf5eb584c75..a3ff4933dbc1 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -17,6 +17,7 @@
interrupt-parent = <&intc>;
#address-cells = <1>;
#size-cells = <1>;
+ chosen { };
aliases {
i2c0 = &i2c1;
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 8087456b5fbe..578c53f08309 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -15,6 +15,7 @@
interrupt-parent = <&wakeupgen>;
#address-cells = <1>;
#size-cells = <1>;
+ chosen { };
aliases {
i2c0 = &i2c1;
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 968c67a49dbd..7cd92babc41a 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -17,6 +17,7 @@
compatible = "ti,omap5";
interrupt-parent = <&wakeupgen>;
+ chosen { };
aliases {
i2c0 = &i2c1;
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index 268bd470c865..407a4610f4a7 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -4,6 +4,7 @@
#include <dt-bindings/clock/qcom,gcc-msm8960.h>
#include <dt-bindings/reset/qcom,gcc-msm8960.h>
#include <dt-bindings/clock/qcom,mmcc-msm8960.h>
+#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/soc/qcom,gsbi.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -303,6 +304,9 @@
firmware {
scm {
compatible = "qcom,scm-apq8064";
+
+ clocks = <&rpmcc RPM_DAYTONA_FABRIC_CLK>;
+ clock-names = "core";
};
};
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
index 102838fcc588..15f4fd3f4695 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
@@ -81,7 +81,7 @@
#address-cells = <0>;
interrupt-controller;
reg = <0 0x2c001000 0 0x1000>,
- <0 0x2c002000 0 0x1000>,
+ <0 0x2c002000 0 0x2000>,
<0 0x2c004000 0 0x2000>,
<0 0x2c006000 0 0x2000>;
interrupts = <1 9 0xf04>;
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
index 45d08cc37b01..bd107c5a0226 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts
@@ -131,7 +131,7 @@
#address-cells = <0>;
interrupt-controller;
reg = <0 0x2c001000 0 0x1000>,
- <0 0x2c002000 0 0x1000>,
+ <0 0x2c002000 0 0x2000>,
<0 0x2c004000 0 0x2000>,
<0 0x2c006000 0 0x2000>;
interrupts = <1 9 0xf04>;
diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
index 7ea617e47fe4..958b4c42d320 100644
--- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
@@ -153,7 +153,8 @@
switch0phy1: switch1phy0@1 {
reg = <1>;
interrupt-parent = <&switch0>;
- interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; };
+ interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+ };
switch0phy2: switch1phy0@2 {
reg = <2>;
interrupt-parent = <&switch0>;
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index df42c93a93d6..f5dce9b4e617 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -31,10 +31,10 @@ static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clockfw_lock);
-static void __clk_enable(struct clk *clk)
+void davinci_clk_enable(struct clk *clk)
{
if (clk->parent)
- __clk_enable(clk->parent);
+ davinci_clk_enable(clk->parent);
if (clk->usecount++ == 0) {
if (clk->flags & CLK_PSC)
davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc,
@@ -44,7 +44,7 @@ static void __clk_enable(struct clk *clk)
}
}
-static void __clk_disable(struct clk *clk)
+void davinci_clk_disable(struct clk *clk)
{
if (WARN_ON(clk->usecount == 0))
return;
@@ -56,7 +56,7 @@ static void __clk_disable(struct clk *clk)
clk->clk_disable(clk);
}
if (clk->parent)
- __clk_disable(clk->parent);
+ davinci_clk_disable(clk->parent);
}
int davinci_clk_reset(struct clk *clk, bool reset)
@@ -103,7 +103,7 @@ int clk_enable(struct clk *clk)
return -EINVAL;
spin_lock_irqsave(&clockfw_lock, flags);
- __clk_enable(clk);
+ davinci_clk_enable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
return 0;
@@ -118,7 +118,7 @@ void clk_disable(struct clk *clk)
return;
spin_lock_irqsave(&clockfw_lock, flags);
- __clk_disable(clk);
+ davinci_clk_disable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
index e2a5437a1aee..fa2b83752e03 100644
--- a/arch/arm/mach-davinci/clock.h
+++ b/arch/arm/mach-davinci/clock.h
@@ -132,6 +132,8 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
int davinci_set_refclk_rate(unsigned long rate);
int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
int davinci_clk_reset(struct clk *clk, bool reset);
+void davinci_clk_enable(struct clk *clk);
+void davinci_clk_disable(struct clk *clk);
extern struct platform_device davinci_wdt_device;
extern void davinci_watchdog_reset(struct platform_device *);
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index e770c97ea45c..1d873d15b545 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -319,6 +319,16 @@ static struct clk emac_clk = {
.gpsc = 1,
};
+/*
+ * In order to avoid adding the emac_clk to the clock lookup table twice (and
+ * screwing up the linked list in the process) create a separate clock for
+ * mdio inheriting the rate from emac_clk.
+ */
+static struct clk mdio_clk = {
+ .name = "mdio",
+ .parent = &emac_clk,
+};
+
static struct clk mcasp_clk = {
.name = "mcasp",
.parent = &async3_clk,
@@ -367,6 +377,16 @@ static struct clk aemif_clk = {
.flags = ALWAYS_ENABLED,
};
+/*
+ * In order to avoid adding the aemif_clk to the clock lookup table twice (and
+ * screwing up the linked list in the process) create a separate clock for
+ * nand inheriting the rate from aemif_clk.
+ */
+static struct clk aemif_nand_clk = {
+ .name = "nand",
+ .parent = &aemif_clk,
+};
+
static struct clk usb11_clk = {
.name = "usb11",
.parent = &pll0_sysclk4,
@@ -529,7 +549,7 @@ static struct clk_lookup da850_clks[] = {
CLK(NULL, "arm", &arm_clk),
CLK(NULL, "rmii", &rmii_clk),
CLK("davinci_emac.1", NULL, &emac_clk),
- CLK("davinci_mdio.0", "fck", &emac_clk),
+ CLK("davinci_mdio.0", "fck", &mdio_clk),
CLK("davinci-mcasp.0", NULL, &mcasp_clk),
CLK("davinci-mcbsp.0", NULL, &mcbsp0_clk),
CLK("davinci-mcbsp.1", NULL, &mcbsp1_clk),
@@ -537,7 +557,15 @@ static struct clk_lookup da850_clks[] = {
CLK("da830-mmc.0", NULL, &mmcsd0_clk),
CLK("da830-mmc.1", NULL, &mmcsd1_clk),
CLK("ti-aemif", NULL, &aemif_clk),
- CLK(NULL, "aemif", &aemif_clk),
+ /*
+ * The only user of this clock is davinci_nand and it get's it through
+ * con_id. The nand node itself is created from within the aemif
+ * driver to guarantee that it's probed after the aemif timing
+ * parameters are configured. of_dev_auxdata is not accessible from
+ * the aemif driver and can't be passed to of_platform_populate(). For
+ * that reason we're leaving the dev_id here as NULL.
+ */
+ CLK(NULL, "aemif", &aemif_nand_clk),
CLK("ohci-da8xx", "usb11", &usb11_clk),
CLK("musb-da8xx", "usb20", &usb20_clk),
CLK("spi_davinci.0", NULL, &spi0_clk),
diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c
index c6feecf7ae24..9a6af0bd5dc3 100644
--- a/arch/arm/mach-davinci/usb-da8xx.c
+++ b/arch/arm/mach-davinci/usb-da8xx.c
@@ -22,6 +22,8 @@
#define DA8XX_USB0_BASE 0x01e00000
#define DA8XX_USB1_BASE 0x01e25000
+static struct clk *usb20_clk;
+
static struct platform_device da8xx_usb_phy = {
.name = "da8xx-usb-phy",
.id = -1,
@@ -158,26 +160,13 @@ int __init da8xx_register_usb_refclkin(int rate)
static void usb20_phy_clk_enable(struct clk *clk)
{
- struct clk *usb20_clk;
- int err;
u32 val;
u32 timeout = 500000; /* 500 msec */
val = readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
- usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
- if (IS_ERR(usb20_clk)) {
- pr_err("could not get usb20 clk: %ld\n", PTR_ERR(usb20_clk));
- return;
- }
-
/* The USB 2.O PLL requires that the USB 2.O PSC is enabled as well. */
- err = clk_prepare_enable(usb20_clk);
- if (err) {
- pr_err("failed to enable usb20 clk: %d\n", err);
- clk_put(usb20_clk);
- return;
- }
+ davinci_clk_enable(usb20_clk);
/*
* Turn on the USB 2.0 PHY, but just the PLL, and not OTG. The USB 1.1
@@ -197,8 +186,7 @@ static void usb20_phy_clk_enable(struct clk *clk)
pr_err("Timeout waiting for USB 2.0 PHY clock good\n");
done:
- clk_disable_unprepare(usb20_clk);
- clk_put(usb20_clk);
+ davinci_clk_disable(usb20_clk);
}
static void usb20_phy_clk_disable(struct clk *clk)
@@ -285,11 +273,19 @@ static struct clk_lookup usb20_phy_clk_lookup =
int __init da8xx_register_usb20_phy_clk(bool use_usb_refclkin)
{
struct clk *parent;
- int ret = 0;
+ int ret;
+
+ usb20_clk = clk_get(&da8xx_usb20_dev.dev, "usb20");
+ ret = PTR_ERR_OR_ZERO(usb20_clk);
+ if (ret)
+ return ret;
parent = clk_get(NULL, use_usb_refclkin ? "usb_refclkin" : "pll0_aux");
- if (IS_ERR(parent))
- return PTR_ERR(parent);
+ ret = PTR_ERR_OR_ZERO(parent);
+ if (ret) {
+ clk_put(usb20_clk);
+ return ret;
+ }
usb20_phy_clk.parent = parent;
ret = clk_register(&usb20_phy_clk);
diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c
index 98ffe1e62ad5..a5d68411a037 100644
--- a/arch/arm/mach-exynos/platsmp.c
+++ b/arch/arm/mach-exynos/platsmp.c
@@ -385,36 +385,6 @@ fail:
return pen_release != -1 ? ret : 0;
}
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-
-static void __init exynos_smp_init_cpus(void)
-{
- void __iomem *scu_base = scu_base_addr();
- unsigned int i, ncores;
-
- if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
- ncores = scu_base ? scu_get_core_count(scu_base) : 1;
- else
- /*
- * CPU Nodes are passed thru DT and set_cpu_possible
- * is set by "arm_dt_init_cpu_maps".
- */
- return;
-
- /* sanity check */
- if (ncores > nr_cpu_ids) {
- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
- ncores, nr_cpu_ids);
- ncores = nr_cpu_ids;
- }
-
- for (i = 0; i < ncores; i++)
- set_cpu_possible(i, true);
-}
-
static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
{
int i;
@@ -479,7 +449,6 @@ static void exynos_cpu_die(unsigned int cpu)
#endif /* CONFIG_HOTPLUG_CPU */
const struct smp_operations exynos_smp_ops __initconst = {
- .smp_init_cpus = exynos_smp_init_cpus,
.smp_prepare_cpus = exynos_smp_prepare_cpus,
.smp_secondary_init = exynos_secondary_init,
.smp_boot_secondary = exynos_boot_secondary,
diff --git a/arch/arm/mach-imx/mach-imx1.c b/arch/arm/mach-imx/mach-imx1.c
index de5ab8d88549..3a8406e45b65 100644
--- a/arch/arm/mach-imx/mach-imx1.c
+++ b/arch/arm/mach-imx/mach-imx1.c
@@ -37,7 +37,6 @@ static const char * const imx1_dt_board_compat[] __initconst = {
};
DT_MACHINE_START(IMX1_DT, "Freescale i.MX1 (Device Tree Support)")
- .map_io = debug_ll_io_init,
.init_early = imx1_init_early,
.init_irq = imx1_init_irq,
.dt_compat = imx1_dt_board_compat,
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 469894082fea..093458b62c8d 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -7,7 +7,7 @@ ccflags-y := -I$(srctree)/$(src)/include \
# Common support
obj-y := id.o io.o control.o devices.o fb.o timer.o pm.o \
- common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
+ common.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
omap_device.o omap-headsmp.o sram.o drm.o
hwmod-common = omap_hwmod.o omap_hwmod_reset.o \
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 36d9943205ca..dc9e34e670a2 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -304,7 +304,7 @@ DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
.init_late = am43xx_init_late,
.init_irq = omap_gic_of_init,
.init_machine = omap_generic_init,
- .init_time = omap4_local_timer_init,
+ .init_time = omap3_gptimer_timer_init,
.dt_compat = am43_boards_compat,
.restart = omap44xx_restart,
MACHINE_END
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
deleted file mode 100644
index 7a577145b68b..000000000000
--- a/arch/arm/mach-omap2/gpio.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * OMAP2+ specific gpio initialization
- *
- * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
- *
- * Author:
- * Charulatha V <charu@ti.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/gpio.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/of.h>
-#include <linux/platform_data/gpio-omap.h>
-
-#include "soc.h"
-#include "omap_hwmod.h"
-#include "omap_device.h"
-#include "omap-pm.h"
-
-#include "powerdomain.h"
-
-static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
-{
- struct platform_device *pdev;
- struct omap_gpio_platform_data *pdata;
- struct omap_gpio_dev_attr *dev_attr;
- char *name = "omap_gpio";
- int id;
- struct powerdomain *pwrdm;
-
- /*
- * extract the device id from name field available in the
- * hwmod database and use the same for constructing ids for
- * gpio devices.
- * CAUTION: Make sure the name in the hwmod database does
- * not change. If changed, make corresponding change here
- * or make use of static variable mechanism to handle this.
- */
- sscanf(oh->name, "gpio%d", &id);
-
- pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL);
- if (!pdata) {
- pr_err("gpio%d: Memory allocation failed\n", id);
- return -ENOMEM;
- }
-
- dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr;
- pdata->bank_width = dev_attr->bank_width;
- pdata->dbck_flag = dev_attr->dbck_flag;
- pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
- pdata->regs = kzalloc(sizeof(struct omap_gpio_reg_offs), GFP_KERNEL);
- if (!pdata->regs) {
- pr_err("gpio%d: Memory allocation failed\n", id);
- kfree(pdata);
- return -ENOMEM;
- }
-
- switch (oh->class->rev) {
- case 0:
- if (id == 1)
- /* non-wakeup GPIO pins for OMAP2 Bank1 */
- pdata->non_wakeup_gpios = 0xe203ffc0;
- else if (id == 2)
- /* non-wakeup GPIO pins for OMAP2 Bank2 */
- pdata->non_wakeup_gpios = 0x08700040;
- /* fall through */
-
- case 1:
- pdata->regs->revision = OMAP24XX_GPIO_REVISION;
- pdata->regs->direction = OMAP24XX_GPIO_OE;
- pdata->regs->datain = OMAP24XX_GPIO_DATAIN;
- pdata->regs->dataout = OMAP24XX_GPIO_DATAOUT;
- pdata->regs->set_dataout = OMAP24XX_GPIO_SETDATAOUT;
- pdata->regs->clr_dataout = OMAP24XX_GPIO_CLEARDATAOUT;
- pdata->regs->irqstatus = OMAP24XX_GPIO_IRQSTATUS1;
- pdata->regs->irqstatus2 = OMAP24XX_GPIO_IRQSTATUS2;
- pdata->regs->irqenable = OMAP24XX_GPIO_IRQENABLE1;
- pdata->regs->irqenable2 = OMAP24XX_GPIO_IRQENABLE2;
- pdata->regs->set_irqenable = OMAP24XX_GPIO_SETIRQENABLE1;
- pdata->regs->clr_irqenable = OMAP24XX_GPIO_CLEARIRQENABLE1;
- pdata->regs->debounce = OMAP24XX_GPIO_DEBOUNCE_VAL;
- pdata->regs->debounce_en = OMAP24XX_GPIO_DEBOUNCE_EN;
- pdata->regs->ctrl = OMAP24XX_GPIO_CTRL;
- pdata->regs->wkup_en = OMAP24XX_GPIO_WAKE_EN;
- pdata->regs->leveldetect0 = OMAP24XX_GPIO_LEVELDETECT0;
- pdata->regs->leveldetect1 = OMAP24XX_GPIO_LEVELDETECT1;
- pdata->regs->risingdetect = OMAP24XX_GPIO_RISINGDETECT;
- pdata->regs->fallingdetect = OMAP24XX_GPIO_FALLINGDETECT;
- break;
- case 2:
- pdata->regs->revision = OMAP4_GPIO_REVISION;
- pdata->regs->direction = OMAP4_GPIO_OE;
- pdata->regs->datain = OMAP4_GPIO_DATAIN;
- pdata->regs->dataout = OMAP4_GPIO_DATAOUT;
- pdata->regs->set_dataout = OMAP4_GPIO_SETDATAOUT;
- pdata->regs->clr_dataout = OMAP4_GPIO_CLEARDATAOUT;
- pdata->regs->irqstatus_raw0 = OMAP4_GPIO_IRQSTATUSRAW0;
- pdata->regs->irqstatus_raw1 = OMAP4_GPIO_IRQSTATUSRAW1;
- pdata->regs->irqstatus = OMAP4_GPIO_IRQSTATUS0;
- pdata->regs->irqstatus2 = OMAP4_GPIO_IRQSTATUS1;
- pdata->regs->irqenable = OMAP4_GPIO_IRQSTATUSSET0;
- pdata->regs->irqenable2 = OMAP4_GPIO_IRQSTATUSSET1;
- pdata->regs->set_irqenable = OMAP4_GPIO_IRQSTATUSSET0;
- pdata->regs->clr_irqenable = OMAP4_GPIO_IRQSTATUSCLR0;
- pdata->regs->debounce = OMAP4_GPIO_DEBOUNCINGTIME;
- pdata->regs->debounce_en = OMAP4_GPIO_DEBOUNCENABLE;
- pdata->regs->ctrl = OMAP4_GPIO_CTRL;
- pdata->regs->wkup_en = OMAP4_GPIO_IRQWAKEN0;
- pdata->regs->leveldetect0 = OMAP4_GPIO_LEVELDETECT0;
- pdata->regs->leveldetect1 = OMAP4_GPIO_LEVELDETECT1;
- pdata->regs->risingdetect = OMAP4_GPIO_RISINGDETECT;
- pdata->regs->fallingdetect = OMAP4_GPIO_FALLINGDETECT;
- break;
- default:
- WARN(1, "Invalid gpio bank_type\n");
- kfree(pdata->regs);
- kfree(pdata);
- return -EINVAL;
- }
-
- pwrdm = omap_hwmod_get_pwrdm(oh);
- pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
-
- pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata));
- kfree(pdata);
-
- if (IS_ERR(pdev)) {
- WARN(1, "Can't build omap_device for %s:%s.\n",
- name, oh->name);
- return PTR_ERR(pdev);
- }
-
- return 0;
-}
-
-/*
- * gpio_init needs to be done before
- * machine_init functions access gpio APIs.
- * Hence gpio_init is a omap_postcore_initcall.
- */
-static int __init omap2_gpio_init(void)
-{
- /* If dtb is there, the devices will be created dynamically */
- if (of_have_populated_dt())
- return -ENODEV;
-
- return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, NULL);
-}
-omap_postcore_initcall(omap2_gpio_init);
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 759e1d45ba25..e8b988714a09 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -741,14 +741,14 @@ static int _init_main_clk(struct omap_hwmod *oh)
int ret = 0;
char name[MOD_CLK_MAX_NAME_LEN];
struct clk *clk;
+ static const char modck[] = "_mod_ck";
- /* +7 magic comes from '_mod_ck' suffix */
- if (strlen(oh->name) + 7 > MOD_CLK_MAX_NAME_LEN)
+ if (strlen(oh->name) >= MOD_CLK_MAX_NAME_LEN - strlen(modck))
pr_warn("%s: warning: cropping name for %s\n", __func__,
oh->name);
- strncpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - 7);
- strcat(name, "_mod_ck");
+ strlcpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - strlen(modck));
+ strlcat(name, modck, MOD_CLK_MAX_NAME_LEN);
clk = clk_get(NULL, name);
if (!IS_ERR(clk)) {
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h
index cdfbb44ceb0c..f22e9cb39f4a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_common_data.h
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h
@@ -121,10 +121,6 @@ extern struct omap_hwmod_irq_info omap2_uart3_mpu_irqs[];
extern struct omap_hwmod_irq_info omap2_dispc_irqs[];
extern struct omap_hwmod_irq_info omap2_i2c1_mpu_irqs[];
extern struct omap_hwmod_irq_info omap2_i2c2_mpu_irqs[];
-extern struct omap_hwmod_irq_info omap2_gpio1_irqs[];
-extern struct omap_hwmod_irq_info omap2_gpio2_irqs[];
-extern struct omap_hwmod_irq_info omap2_gpio3_irqs[];
-extern struct omap_hwmod_irq_info omap2_gpio4_irqs[];
extern struct omap_hwmod_irq_info omap2_dma_system_irqs[];
extern struct omap_hwmod_irq_info omap2_mcspi1_mpu_irqs[];
extern struct omap_hwmod_irq_info omap2_mcspi2_mpu_irqs[];
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 5b2f5138d938..2b138b65129a 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -295,10 +295,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
GFP_KERNEL);
if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
- !prcm_irq_setup->priority_mask) {
- pr_err("PRCM: kzalloc failed\n");
+ !prcm_irq_setup->priority_mask)
goto err;
- }
memset(mask, 0, sizeof(mask));
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 56128da23c3a..07dd692c4737 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -510,18 +510,19 @@ void __init omap3_secure_sync32k_timer_init(void)
}
#endif /* CONFIG_ARCH_OMAP3 */
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX)
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \
+ defined(CONFIG_SOC_AM43XX)
void __init omap3_gptimer_timer_init(void)
{
__omap_sync32k_timer_init(2, "timer_sys_ck", NULL,
1, "timer_sys_ck", "ti,timer-alwon", true);
-
- clocksource_probe();
+ if (of_have_populated_dt())
+ clocksource_probe();
}
#endif
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
- defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
+ defined(CONFIG_SOC_DRA7XX)
static void __init omap4_sync32k_timer_init(void)
{
__omap_sync32k_timer_init(1, "timer_32k_ck", "ti,timer-alwon",
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index f6c3f151d0d4..b59f4f4f256f 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -345,10 +345,40 @@ static struct s3c24xx_dma_channel s3c2410_dma_channels[DMACH_MAX] = {
[DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, S3C24XX_DMA_CHANREQ(4, 3), },
};
+static const struct dma_slave_map s3c2410_dma_slave_map[] = {
+ { "s3c2410-sdi", "rx-tx", (void *)DMACH_SDI },
+ { "s3c2410-spi.0", "rx", (void *)DMACH_SPI0_RX },
+ { "s3c2410-spi.0", "tx", (void *)DMACH_SPI0_TX },
+ { "s3c2410-spi.1", "rx", (void *)DMACH_SPI1_RX },
+ { "s3c2410-spi.1", "tx", (void *)DMACH_SPI1_TX },
+ /*
+ * The DMA request source[1] (DMACH_UARTx_SRC2) are
+ * not used in the UART driver.
+ */
+ { "s3c2410-uart.0", "rx", (void *)DMACH_UART0 },
+ { "s3c2410-uart.0", "tx", (void *)DMACH_UART0 },
+ { "s3c2410-uart.1", "rx", (void *)DMACH_UART1 },
+ { "s3c2410-uart.1", "tx", (void *)DMACH_UART1 },
+ { "s3c2410-uart.2", "rx", (void *)DMACH_UART2 },
+ { "s3c2410-uart.2", "tx", (void *)DMACH_UART2 },
+ { "s3c24xx-iis", "rx", (void *)DMACH_I2S_IN },
+ { "s3c24xx-iis", "tx", (void *)DMACH_I2S_OUT },
+ { "s3c-hsudc", "rx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "tx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "rx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "tx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "rx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "tx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "rx3", (void *)DMACH_USB_EP4 },
+ { "s3c-hsudc", "tx3", (void *)DMACH_USB_EP4 }
+};
+
static struct s3c24xx_dma_platdata s3c2410_dma_platdata = {
.num_phy_channels = 4,
.channels = s3c2410_dma_channels,
.num_channels = DMACH_MAX,
+ .slave_map = s3c2410_dma_slave_map,
+ .slavecnt = ARRAY_SIZE(s3c2410_dma_slave_map),
};
struct platform_device s3c2410_device_dma = {
@@ -388,10 +418,36 @@ static struct s3c24xx_dma_channel s3c2412_dma_channels[DMACH_MAX] = {
[DMACH_USB_EP4] = { S3C24XX_DMA_APB, true, 16 },
};
+static const struct dma_slave_map s3c2412_dma_slave_map[] = {
+ { "s3c2412-sdi", "rx-tx", (void *)DMACH_SDI },
+ { "s3c2412-spi.0", "rx", (void *)DMACH_SPI0_RX },
+ { "s3c2412-spi.0", "tx", (void *)DMACH_SPI0_TX },
+ { "s3c2412-spi.1", "rx", (void *)DMACH_SPI1_RX },
+ { "s3c2412-spi.1", "tx", (void *)DMACH_SPI1_TX },
+ { "s3c2440-uart.0", "rx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.0", "tx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.1", "rx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.1", "tx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.2", "rx", (void *)DMACH_UART2 },
+ { "s3c2440-uart.2", "tx", (void *)DMACH_UART2 },
+ { "s3c2412-iis", "rx", (void *)DMACH_I2S_IN },
+ { "s3c2412-iis", "tx", (void *)DMACH_I2S_OUT },
+ { "s3c-hsudc", "rx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "tx0", (void *)DMACH_USB_EP1 },
+ { "s3c-hsudc", "rx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "tx1", (void *)DMACH_USB_EP2 },
+ { "s3c-hsudc", "rx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "tx2", (void *)DMACH_USB_EP3 },
+ { "s3c-hsudc", "rx3", (void *)DMACH_USB_EP4 },
+ { "s3c-hsudc", "tx3", (void *)DMACH_USB_EP4 }
+};
+
static struct s3c24xx_dma_platdata s3c2412_dma_platdata = {
.num_phy_channels = 4,
.channels = s3c2412_dma_channels,
.num_channels = DMACH_MAX,
+ .slave_map = s3c2412_dma_slave_map,
+ .slavecnt = ARRAY_SIZE(s3c2412_dma_slave_map),
};
struct platform_device s3c2412_device_dma = {
@@ -534,10 +590,30 @@ static struct s3c24xx_dma_channel s3c2443_dma_channels[DMACH_MAX] = {
[DMACH_MIC_IN] = { S3C24XX_DMA_APB, true, 29 },
};
+static const struct dma_slave_map s3c2443_dma_slave_map[] = {
+ { "s3c2440-sdi", "rx-tx", (void *)DMACH_SDI },
+ { "s3c2443-spi.0", "rx", (void *)DMACH_SPI0_RX },
+ { "s3c2443-spi.0", "tx", (void *)DMACH_SPI0_TX },
+ { "s3c2443-spi.1", "rx", (void *)DMACH_SPI1_RX },
+ { "s3c2443-spi.1", "tx", (void *)DMACH_SPI1_TX },
+ { "s3c2440-uart.0", "rx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.0", "tx", (void *)DMACH_UART0 },
+ { "s3c2440-uart.1", "rx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.1", "tx", (void *)DMACH_UART1 },
+ { "s3c2440-uart.2", "rx", (void *)DMACH_UART2 },
+ { "s3c2440-uart.2", "tx", (void *)DMACH_UART2 },
+ { "s3c2440-uart.3", "rx", (void *)DMACH_UART3 },
+ { "s3c2440-uart.3", "tx", (void *)DMACH_UART3 },
+ { "s3c24xx-iis", "rx", (void *)DMACH_I2S_IN },
+ { "s3c24xx-iis", "tx", (void *)DMACH_I2S_OUT },
+};
+
static struct s3c24xx_dma_platdata s3c2443_dma_platdata = {
.num_phy_channels = 6,
.channels = s3c2443_dma_channels,
.num_channels = DMACH_MAX,
+ .slave_map = s3c2443_dma_slave_map,
+ .slavecnt = ARRAY_SIZE(s3c2443_dma_slave_map),
};
struct platform_device s3c2443_device_dma = {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index fc033c0d2a0f..eada0b58ba1c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -356,5 +356,21 @@
status = "disabled";
};
};
+
+ vpu: vpu@d0100000 {
+ compatible = "amlogic,meson-gx-vpu";
+ reg = <0x0 0xd0100000 0x0 0x100000>,
+ <0x0 0xc883c000 0x0 0x1000>,
+ <0x0 0xc8838000 0x0 0x1000>;
+ reg-names = "vpu", "hhi", "dmc";
+ interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* CVBS VDAC output port */
+ cvbs_vdac_port: port@0 {
+ reg = <0>;
+ };
+ };
};
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
index 969682092e0f..4cbd626a9e88 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
@@ -142,6 +142,16 @@
clocks = <&wifi32k>;
clock-names = "ext_clock";
};
+
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
};
&uart_AO {
@@ -229,3 +239,9 @@
clocks = <&clkc CLKID_FCLK_DIV4>;
clock-names = "clkin0";
};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
index 203be28978d5..4a96e0f6f926 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
@@ -125,6 +125,16 @@
clocks = <&wifi32k>;
clock-names = "ext_clock";
};
+
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
};
/* This UART is brought out to the DB9 connector */
@@ -234,3 +244,9 @@
clocks = <&clkc CLKID_FCLK_DIV4>;
clock-names = "clkin0";
};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 51edd5b5c460..596240c38a9c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -506,3 +506,7 @@
<&clkc CLKID_FCLK_DIV2>;
clock-names = "core", "clkin0", "clkin1";
};
+
+&vpu {
+ compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
index e99101ae9664..cea4a3eded9b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-nexbox-a95x.dts
@@ -117,6 +117,16 @@
clocks = <&wifi32k>;
clock-names = "ext_clock";
};
+
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
};
&uart_AO {
@@ -203,3 +213,9 @@
clocks = <&clkc CLKID_FCLK_DIV4>;
clock-names = "clkin0";
};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index 9f89b99c4806..69216246275d 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -43,7 +43,7 @@
#include "meson-gx.dtsi"
#include <dt-bindings/clock/gxbb-clkc.h>
-#include <dt-bindings/gpio/meson-gxbb-gpio.h>
+#include <dt-bindings/gpio/meson-gxl-gpio.h>
/ {
compatible = "amlogic,meson-gxl";
@@ -299,3 +299,7 @@
<&clkc CLKID_FCLK_DIV2>;
clock-names = "core", "clkin0", "clkin1";
};
+
+&vpu {
+ compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
index f859d75db8bd..5a337d339df1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
@@ -90,6 +90,16 @@
compatible = "mmc-pwrseq-emmc";
reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
};
+
+ cvbs-connector {
+ compatible = "composite-video-connector";
+
+ port {
+ cvbs_connector_in: endpoint {
+ remote-endpoint = <&cvbs_vdac_out>;
+ };
+ };
+ };
};
/* This UART is brought out to the DB9 connector */
@@ -167,3 +177,9 @@
max-speed = <1000>;
};
};
+
+&cvbs_vdac_port {
+ cvbs_vdac_out: endpoint {
+ remote-endpoint = <&cvbs_connector_in>;
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
index c1974bbbddea..eb2f0c3e5e53 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
@@ -112,3 +112,7 @@
};
};
};
+
+&vpu {
+ compatible = "amlogic,meson-gxm-vpu", "amlogic,meson-gx-vpu";
+};
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts
index a852e28a40e1..a83ed2c6bbf7 100644
--- a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts
+++ b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts
@@ -81,7 +81,7 @@
#address-cells = <0>;
interrupt-controller;
reg = <0x0 0x2c001000 0 0x1000>,
- <0x0 0x2c002000 0 0x1000>,
+ <0x0 0x2c002000 0 0x2000>,
<0x0 0x2c004000 0 0x2000>,
<0x0 0x2c006000 0 0x2000>;
interrupts = <1 9 0xf04>;
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 9d1d7ad9b075..29ed6b61c737 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -64,6 +64,16 @@
reg = <0x0 0x86000000 0x0 0x200000>;
no-map;
};
+
+ memory@85800000 {
+ reg = <0x0 0x85800000 0x0 0x800000>;
+ no-map;
+ };
+
+ memory@86200000 {
+ reg = <0x0 0x86200000 0x0 0x2600000>;
+ no-map;
+ };
};
cpus {
diff --git a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
index 6ffb0517421a..dbea2c3d8f0c 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
+++ b/arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts
@@ -169,7 +169,7 @@
power-source = <3300>;
};
- sdhi0_pins_uhs: sd0 {
+ sdhi0_pins_uhs: sd0_uhs {
groups = "sdhi0_data4", "sdhi0_ctrl";
function = "sdhi0";
power-source = <1800>;
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 869dded0f09f..33b744d54739 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -331,6 +331,7 @@ CONFIG_DRM_VC4=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_I2C_ADV7511=m
CONFIG_DRM_HISI_KIRIN=m
+CONFIG_DRM_MESON=m
CONFIG_FB=y
CONFIG_FB_ARMCLCD=y
CONFIG_BACKLIGHT_GENERIC=m
diff --git a/arch/arm64/include/asm/asm-uaccess.h b/arch/arm64/include/asm/asm-uaccess.h
new file mode 100644
index 000000000000..df411f3e083c
--- /dev/null
+++ b/arch/arm64/include/asm/asm-uaccess.h
@@ -0,0 +1,65 @@
+#ifndef __ASM_ASM_UACCESS_H
+#define __ASM_ASM_UACCESS_H
+
+#include <asm/alternative.h>
+#include <asm/kernel-pgtable.h>
+#include <asm/sysreg.h>
+#include <asm/assembler.h>
+
+/*
+ * User access enabling/disabling macros.
+ */
+#ifdef CONFIG_ARM64_SW_TTBR0_PAN
+ .macro __uaccess_ttbr0_disable, tmp1
+ mrs \tmp1, ttbr1_el1 // swapper_pg_dir
+ add \tmp1, \tmp1, #SWAPPER_DIR_SIZE // reserved_ttbr0 at the end of swapper_pg_dir
+ msr ttbr0_el1, \tmp1 // set reserved TTBR0_EL1
+ isb
+ .endm
+
+ .macro __uaccess_ttbr0_enable, tmp1
+ get_thread_info \tmp1
+ ldr \tmp1, [\tmp1, #TSK_TI_TTBR0] // load saved TTBR0_EL1
+ msr ttbr0_el1, \tmp1 // set the non-PAN TTBR0_EL1
+ isb
+ .endm
+
+ .macro uaccess_ttbr0_disable, tmp1
+alternative_if_not ARM64_HAS_PAN
+ __uaccess_ttbr0_disable \tmp1
+alternative_else_nop_endif
+ .endm
+
+ .macro uaccess_ttbr0_enable, tmp1, tmp2
+alternative_if_not ARM64_HAS_PAN
+ save_and_disable_irq \tmp2 // avoid preemption
+ __uaccess_ttbr0_enable \tmp1
+ restore_irq \tmp2
+alternative_else_nop_endif
+ .endm
+#else
+ .macro uaccess_ttbr0_disable, tmp1
+ .endm
+
+ .macro uaccess_ttbr0_enable, tmp1, tmp2
+ .endm
+#endif
+
+/*
+ * These macros are no-ops when UAO is present.
+ */
+ .macro uaccess_disable_not_uao, tmp1
+ uaccess_ttbr0_disable \tmp1
+alternative_if ARM64_ALT_PAN_NOT_UAO
+ SET_PSTATE_PAN(1)
+alternative_else_nop_endif
+ .endm
+
+ .macro uaccess_enable_not_uao, tmp1, tmp2
+ uaccess_ttbr0_enable \tmp1, \tmp2
+alternative_if ARM64_ALT_PAN_NOT_UAO
+ SET_PSTATE_PAN(0)
+alternative_else_nop_endif
+ .endm
+
+#endif
diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h
index f2bcbe2d9889..86c404171305 100644
--- a/arch/arm64/include/asm/current.h
+++ b/arch/arm64/include/asm/current.h
@@ -9,9 +9,17 @@
struct task_struct;
+/*
+ * We don't use read_sysreg() as we want the compiler to cache the value where
+ * possible.
+ */
static __always_inline struct task_struct *get_current(void)
{
- return (struct task_struct *)read_sysreg(sp_el0);
+ unsigned long sp_el0;
+
+ asm ("mrs %0, sp_el0" : "=r" (sp_el0));
+
+ return (struct task_struct *)sp_el0;
}
#define current get_current()
diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index d26750ca6e06..46da3ea638bb 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -22,8 +22,6 @@
#include <asm/kernel-pgtable.h>
#include <asm/sysreg.h>
-#ifndef __ASSEMBLY__
-
/*
* User space memory access functions
*/
@@ -424,66 +422,4 @@ extern long strncpy_from_user(char *dest, const char __user *src, long count);
extern __must_check long strlen_user(const char __user *str);
extern __must_check long strnlen_user(const char __user *str, long n);
-#else /* __ASSEMBLY__ */
-
-#include <asm/assembler.h>
-
-/*
- * User access enabling/disabling macros.
- */
-#ifdef CONFIG_ARM64_SW_TTBR0_PAN
- .macro __uaccess_ttbr0_disable, tmp1
- mrs \tmp1, ttbr1_el1 // swapper_pg_dir
- add \tmp1, \tmp1, #SWAPPER_DIR_SIZE // reserved_ttbr0 at the end of swapper_pg_dir
- msr ttbr0_el1, \tmp1 // set reserved TTBR0_EL1
- isb
- .endm
-
- .macro __uaccess_ttbr0_enable, tmp1
- get_thread_info \tmp1
- ldr \tmp1, [\tmp1, #TSK_TI_TTBR0] // load saved TTBR0_EL1
- msr ttbr0_el1, \tmp1 // set the non-PAN TTBR0_EL1
- isb
- .endm
-
- .macro uaccess_ttbr0_disable, tmp1
-alternative_if_not ARM64_HAS_PAN
- __uaccess_ttbr0_disable \tmp1
-alternative_else_nop_endif
- .endm
-
- .macro uaccess_ttbr0_enable, tmp1, tmp2
-alternative_if_not ARM64_HAS_PAN
- save_and_disable_irq \tmp2 // avoid preemption
- __uaccess_ttbr0_enable \tmp1
- restore_irq \tmp2
-alternative_else_nop_endif
- .endm
-#else
- .macro uaccess_ttbr0_disable, tmp1
- .endm
-
- .macro uaccess_ttbr0_enable, tmp1, tmp2
- .endm
-#endif
-
-/*
- * These macros are no-ops when UAO is present.
- */
- .macro uaccess_disable_not_uao, tmp1
- uaccess_ttbr0_disable \tmp1
-alternative_if ARM64_ALT_PAN_NOT_UAO
- SET_PSTATE_PAN(1)
-alternative_else_nop_endif
- .endm
-
- .macro uaccess_enable_not_uao, tmp1, tmp2
- uaccess_ttbr0_enable \tmp1, \tmp2
-alternative_if ARM64_ALT_PAN_NOT_UAO
- SET_PSTATE_PAN(0)
-alternative_else_nop_endif
- .endm
-
-#endif /* __ASSEMBLY__ */
-
#endif /* __ASM_UACCESS_H */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index a7504f40d7ee..923841ffe4a9 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -31,7 +31,7 @@
#include <asm/memory.h>
#include <asm/ptrace.h>
#include <asm/thread_info.h>
-#include <linux/uaccess.h>
+#include <asm/asm-uaccess.h>
#include <asm/unistd.h>
/*
diff --git a/arch/arm64/lib/clear_user.S b/arch/arm64/lib/clear_user.S
index add4a1334085..e88fb99c1561 100644
--- a/arch/arm64/lib/clear_user.S
+++ b/arch/arm64/lib/clear_user.S
@@ -17,7 +17,7 @@
*/
#include <linux/linkage.h>
-#include <linux/uaccess.h>
+#include <asm/asm-uaccess.h>
.text
diff --git a/arch/arm64/lib/copy_from_user.S b/arch/arm64/lib/copy_from_user.S
index fd6cd05593f9..4b5d826895ff 100644
--- a/arch/arm64/lib/copy_from_user.S
+++ b/arch/arm64/lib/copy_from_user.S
@@ -17,7 +17,7 @@
#include <linux/linkage.h>
#include <asm/cache.h>
-#include <linux/uaccess.h>
+#include <asm/asm-uaccess.h>
/*
* Copy from user space to a kernel buffer (alignment handled by the hardware)
diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S
index d828540ded6f..47184c3a97da 100644
--- a/arch/arm64/lib/copy_in_user.S
+++ b/arch/arm64/lib/copy_in_user.S
@@ -19,7 +19,7 @@
#include <linux/linkage.h>
#include <asm/cache.h>
-#include <linux/uaccess.h>
+#include <asm/asm-uaccess.h>
/*
* Copy from user space to user space (alignment handled by the hardware)
diff --git a/arch/arm64/lib/copy_to_user.S b/arch/arm64/lib/copy_to_user.S
index 3e6ae2663b82..351f0766f7a6 100644
--- a/arch/arm64/lib/copy_to_user.S
+++ b/arch/arm64/lib/copy_to_user.S
@@ -17,7 +17,7 @@
#include <linux/linkage.h>
#include <asm/cache.h>
-#include <linux/uaccess.h>
+#include <asm/asm-uaccess.h>
/*
* Copy to user space from a kernel buffer (alignment handled by the hardware)
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index 17f422a4dc55..83c27b6e6dca 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -23,7 +23,7 @@
#include <asm/assembler.h>
#include <asm/cpufeature.h>
#include <asm/alternative.h>
-#include <linux/uaccess.h>
+#include <asm/asm-uaccess.h>
/*
* flush_icache_range(start,end)
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 290a84f3351f..e04082700bb1 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -524,7 +524,8 @@ EXPORT_SYMBOL(dummy_dma_ops);
static int __init arm64_dma_init(void)
{
- if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT))
+ if (swiotlb_force == SWIOTLB_FORCE ||
+ max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT))
swiotlb = 1;
return atomic_pool_init();
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index a78a5c401806..156169c6981b 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -88,21 +88,21 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
break;
pud = pud_offset(pgd, addr);
- printk(", *pud=%016llx", pud_val(*pud));
+ pr_cont(", *pud=%016llx", pud_val(*pud));
if (pud_none(*pud) || pud_bad(*pud))
break;
pmd = pmd_offset(pud, addr);
- printk(", *pmd=%016llx", pmd_val(*pmd));
+ pr_cont(", *pmd=%016llx", pmd_val(*pmd));
if (pmd_none(*pmd) || pmd_bad(*pmd))
break;
pte = pte_offset_map(pmd, addr);
- printk(", *pte=%016llx", pte_val(*pte));
+ pr_cont(", *pte=%016llx", pte_val(*pte));
pte_unmap(pte);
} while(0);
- printk("\n");
+ pr_cont("\n");
}
#ifdef CONFIG_ARM64_HW_AFDBM
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 212c4d1e2f26..716d1226ba69 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -401,7 +401,8 @@ static void __init free_unused_memmap(void)
*/
void __init mem_init(void)
{
- if (swiotlb_force || max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT))
+ if (swiotlb_force == SWIOTLB_FORCE ||
+ max_pfn > (arm64_dma_phys_limit >> PAGE_SHIFT))
swiotlb_init(1);
set_max_mapnr(pfn_to_page(max_pfn) - mem_map);
diff --git a/arch/arm64/xen/hypercall.S b/arch/arm64/xen/hypercall.S
index 47cf3f9d89ff..947830a459d2 100644
--- a/arch/arm64/xen/hypercall.S
+++ b/arch/arm64/xen/hypercall.S
@@ -49,7 +49,7 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <linux/uaccess.h>
+#include <asm/asm-uaccess.h>
#include <xen/interface/xen.h>
diff --git a/arch/mips/kvm/entry.c b/arch/mips/kvm/entry.c
index 6a02b3a3fa65..e92fb190e2d6 100644
--- a/arch/mips/kvm/entry.c
+++ b/arch/mips/kvm/entry.c
@@ -521,6 +521,9 @@ void *kvm_mips_build_exit(void *addr)
uasm_i_and(&p, V0, V0, AT);
uasm_i_lui(&p, AT, ST0_CU0 >> 16);
uasm_i_or(&p, V0, V0, AT);
+#ifdef CONFIG_64BIT
+ uasm_i_ori(&p, V0, V0, ST0_SX | ST0_UX);
+#endif
uasm_i_mtc0(&p, V0, C0_STATUS);
uasm_i_ehb(&p);
@@ -643,7 +646,7 @@ static void *kvm_mips_build_ret_to_guest(void *addr)
/* Setup status register for running guest in UM */
uasm_i_ori(&p, V1, V1, ST0_EXL | KSU_USER | ST0_IE);
- UASM_i_LA(&p, AT, ~(ST0_CU0 | ST0_MX));
+ UASM_i_LA(&p, AT, ~(ST0_CU0 | ST0_MX | ST0_SX | ST0_UX));
uasm_i_and(&p, V1, V1, AT);
uasm_i_mtc0(&p, V1, C0_STATUS);
uasm_i_ehb(&p);
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 06a60b19acfb..29ec9ab3fd55 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -360,8 +360,8 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
dump_handler("kvm_exit", gebase + 0x2000, vcpu->arch.vcpu_run);
/* Invalidate the icache for these ranges */
- local_flush_icache_range((unsigned long)gebase,
- (unsigned long)gebase + ALIGN(size, PAGE_SIZE));
+ flush_icache_range((unsigned long)gebase,
+ (unsigned long)gebase + ALIGN(size, PAGE_SIZE));
/*
* Allocate comm page for guest kernel, a TLB will be reserved for
diff --git a/arch/openrisc/kernel/vmlinux.lds.S b/arch/openrisc/kernel/vmlinux.lds.S
index ef31fc24344e..552544616b9d 100644
--- a/arch/openrisc/kernel/vmlinux.lds.S
+++ b/arch/openrisc/kernel/vmlinux.lds.S
@@ -44,6 +44,8 @@ SECTIONS
/* Read-only sections, merged into text segment: */
. = LOAD_BASE ;
+ _text = .;
+
/* _s_kernel_ro must be page aligned */
. = ALIGN(PAGE_SIZE);
_s_kernel_ro = .;
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index 7581330ea35b..88fe0aad4390 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -49,7 +49,6 @@ struct thread_info {
#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_32BIT 4 /* 32 bit binary */
#define TIF_MEMDIE 5 /* is terminating due to OOM killer */
-#define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
#define TIF_SINGLESTEP 9 /* single stepping? */
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index da0d9cb63403..1e22f981cd81 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -235,9 +235,26 @@ void __init time_init(void)
cr16_hz = 100 * PAGE0->mem_10msec; /* Hz */
- /* register at clocksource framework */
- clocksource_register_hz(&clocksource_cr16, cr16_hz);
-
/* register as sched_clock source */
sched_clock_register(read_cr16_sched_clock, BITS_PER_LONG, cr16_hz);
}
+
+static int __init init_cr16_clocksource(void)
+{
+ /*
+ * The cr16 interval timers are not syncronized across CPUs, so mark
+ * them unstable and lower rating on SMP systems.
+ */
+ if (num_online_cpus() > 1) {
+ clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
+ clocksource_cr16.rating = 0;
+ }
+
+ /* register at clocksource framework */
+ clocksource_register_hz(&clocksource_cr16,
+ 100 * PAGE0->mem_10msec);
+
+ return 0;
+}
+
+device_initcall(init_cr16_clocksource);
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 8ff9253930af..1a0b4f63f0e9 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -234,7 +234,7 @@ show_signal_msg(struct pt_regs *regs, unsigned long code,
tsk->comm, code, address);
print_vma_addr(KERN_CONT " in ", regs->iaoq[0]);
- pr_cont(" trap #%lu: %s%c", code, trap_name(code),
+ pr_cont("\ntrap #%lu: %s%c", code, trap_name(code),
vma ? ',':'\n');
if (vma)
diff --git a/arch/s390/include/asm/asm-prototypes.h b/arch/s390/include/asm/asm-prototypes.h
new file mode 100644
index 000000000000..2c3413b0ca52
--- /dev/null
+++ b/arch/s390/include/asm/asm-prototypes.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_S390_PROTOTYPES_H
+
+#include <linux/kvm_host.h>
+#include <linux/ftrace.h>
+#include <asm/fpu/api.h>
+#include <asm-generic/asm-prototypes.h>
+
+#endif /* _ASM_S390_PROTOTYPES_H */
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 6b246aadf311..1b5c5ee9fc1b 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -94,7 +94,7 @@ static void update_mt_scaling(void)
* Update process times based on virtual cpu times stored by entry.S
* to the lowcore fields user_timer, system_timer & steal_clock.
*/
-static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
+static int do_account_vtime(struct task_struct *tsk)
{
u64 timer, clock, user, system, steal;
u64 user_scaled, system_scaled;
@@ -138,7 +138,7 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
}
account_user_time(tsk, user);
tsk->utimescaled += user_scaled;
- account_system_time(tsk, hardirq_offset, system);
+ account_system_time(tsk, 0, system);
tsk->stimescaled += system_scaled;
steal = S390_lowcore.steal_timer;
@@ -152,7 +152,7 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset)
void vtime_task_switch(struct task_struct *prev)
{
- do_account_vtime(prev, 0);
+ do_account_vtime(prev);
prev->thread.user_timer = S390_lowcore.user_timer;
prev->thread.system_timer = S390_lowcore.system_timer;
S390_lowcore.user_timer = current->thread.user_timer;
@@ -166,7 +166,7 @@ void vtime_task_switch(struct task_struct *prev)
*/
void vtime_account_user(struct task_struct *tsk)
{
- if (do_account_vtime(tsk, HARDIRQ_OFFSET))
+ if (do_account_vtime(tsk))
virt_timer_expire();
}
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index 68557f52b961..854022772c5b 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -139,6 +139,19 @@ static __always_inline void __clear_bit(long nr, volatile unsigned long *addr)
asm volatile("btr %1,%0" : ADDR : "Ir" (nr));
}
+static __always_inline bool clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
+{
+ bool negative;
+ asm volatile(LOCK_PREFIX "andb %2,%1\n\t"
+ CC_SET(s)
+ : CC_OUT(s) (negative), ADDR
+ : "ir" ((char) ~(1 << nr)) : "memory");
+ return negative;
+}
+
+// Let everybody know we have it
+#define clear_bit_unlock_is_negative_byte clear_bit_unlock_is_negative_byte
+
/*
* __clear_bit_unlock - Clears a bit in memory
* @nr: Bit to clear
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index ffacfdcacb85..a5fd137417a2 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -1182,6 +1182,9 @@ static int threshold_create_bank(unsigned int cpu, unsigned int bank)
const char *name = get_name(bank, NULL);
int err = 0;
+ if (!dev)
+ return -ENODEV;
+
if (is_shared_bank(bank)) {
nb = node_to_amd_nb(amd_get_nb_id(cpu));
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c
index b47edb8f5256..410efb2c7b80 100644
--- a/arch/x86/kernel/pci-swiotlb.c
+++ b/arch/x86/kernel/pci-swiotlb.c
@@ -68,12 +68,10 @@ static struct dma_map_ops swiotlb_dma_ops = {
*/
int __init pci_swiotlb_detect_override(void)
{
- int use_swiotlb = swiotlb | swiotlb_force;
-
- if (swiotlb_force)
+ if (swiotlb_force == SWIOTLB_FORCE)
swiotlb = 1;
- return use_swiotlb;
+ return swiotlb;
}
IOMMU_INIT_FINISH(pci_swiotlb_detect_override,
pci_xen_swiotlb_detect,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 24db5fb6f575..a236decb81e4 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -132,12 +132,6 @@ module_param_named(preemption_timer, enable_preemption_timer, bool, S_IRUGO);
#define VMX_MISC_EMULATED_PREEMPTION_TIMER_RATE 5
-#define VMX_VPID_EXTENT_SUPPORTED_MASK \
- (VMX_VPID_EXTENT_INDIVIDUAL_ADDR_BIT | \
- VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT | \
- VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT | \
- VMX_VPID_EXTENT_SINGLE_NON_GLOBAL_BIT)
-
/*
* Hyper-V requires all of these, so mark them as supported even though
* they are just treated the same as all-context.
@@ -10473,12 +10467,12 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
!nested_guest_cr4_valid(vcpu, vmcs12->guest_cr4)) {
nested_vmx_entry_failure(vcpu, vmcs12,
EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
- goto out;
+ return 1;
}
if (vmcs12->vmcs_link_pointer != -1ull) {
nested_vmx_entry_failure(vcpu, vmcs12,
EXIT_REASON_INVALID_STATE, ENTRY_FAIL_VMCS_LINK_PTR);
- goto out;
+ return 1;
}
/*
@@ -10498,7 +10492,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
ia32e != !!(vmcs12->guest_ia32_efer & EFER_LME))) {
nested_vmx_entry_failure(vcpu, vmcs12,
EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
- goto out;
+ return 1;
}
}
@@ -10516,7 +10510,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
ia32e != !!(vmcs12->host_ia32_efer & EFER_LME)) {
nested_vmx_entry_failure(vcpu, vmcs12,
EXIT_REASON_INVALID_STATE, ENTRY_FAIL_DEFAULT);
- goto out;
+ return 1;
}
}
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 51ccfe08e32f..2f22810a7e0c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3070,6 +3070,8 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
memset(&events->reserved, 0, sizeof(events->reserved));
}
+static void kvm_set_hflags(struct kvm_vcpu *vcpu, unsigned emul_flags);
+
static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
struct kvm_vcpu_events *events)
{
@@ -3106,10 +3108,13 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
vcpu->arch.apic->sipi_vector = events->sipi_vector;
if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
+ u32 hflags = vcpu->arch.hflags;
if (events->smi.smm)
- vcpu->arch.hflags |= HF_SMM_MASK;
+ hflags |= HF_SMM_MASK;
else
- vcpu->arch.hflags &= ~HF_SMM_MASK;
+ hflags &= ~HF_SMM_MASK;
+ kvm_set_hflags(vcpu, hflags);
+
vcpu->arch.smi_pending = events->smi.pending;
if (events->smi.smm_inside_nmi)
vcpu->arch.hflags |= HF_SMM_INSIDE_NMI_MASK;
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index a9fafb5c8738..a0b36a9d5df1 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -48,7 +48,7 @@ int __init pci_xen_swiotlb_detect(void)
* activate this IOMMU. If running as PV privileged, activate it
* irregardless.
*/
- if ((xen_initial_domain() || swiotlb || swiotlb_force))
+ if (xen_initial_domain() || swiotlb || swiotlb_force == SWIOTLB_FORCE)
xen_swiotlb = 1;
/* If we are running under Xen, we MUST disable the native SWIOTLB.
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 8c394e30e5fe..f3f7b41116f7 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -713,10 +713,9 @@ static void __init xen_reserve_xen_mfnlist(void)
size = PFN_PHYS(xen_start_info->nr_p2m_frames);
}
- if (!xen_is_e820_reserved(start, size)) {
- memblock_reserve(start, size);
+ memblock_reserve(start, size);
+ if (!xen_is_e820_reserved(start, size))
return;
- }
#ifdef CONFIG_X86_32
/*
@@ -727,6 +726,7 @@ static void __init xen_reserve_xen_mfnlist(void)
BUG();
#else
xen_relocate_p2m();
+ memblock_free(start, size);
#endif
}
diff --git a/block/blk-wbt.c b/block/blk-wbt.c
index 6e82769f4042..f0a9c07b4c7a 100644
--- a/block/blk-wbt.c
+++ b/block/blk-wbt.c
@@ -544,6 +544,8 @@ static inline bool may_queue(struct rq_wb *rwb, struct rq_wait *rqw,
* the timer to kick off queuing again.
*/
static void __wbt_wait(struct rq_wb *rwb, unsigned long rw, spinlock_t *lock)
+ __releases(lock)
+ __acquires(lock)
{
struct rq_wait *rqw = get_rq_wait(rwb, current_is_kswapd());
DEFINE_WAIT(wait);
@@ -558,13 +560,12 @@ static void __wbt_wait(struct rq_wb *rwb, unsigned long rw, spinlock_t *lock)
if (may_queue(rwb, rqw, &wait, rw))
break;
- if (lock)
+ if (lock) {
spin_unlock_irq(lock);
-
- io_schedule();
-
- if (lock)
+ io_schedule();
spin_lock_irq(lock);
+ } else
+ io_schedule();
} while (1);
finish_wait(&rqw->wait, &wait);
@@ -595,7 +596,7 @@ static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio)
* in an irq held spinlock, if it holds one when calling this function.
* If we do sleep, we'll release and re-grab it.
*/
-unsigned int wbt_wait(struct rq_wb *rwb, struct bio *bio, spinlock_t *lock)
+enum wbt_flags wbt_wait(struct rq_wb *rwb, struct bio *bio, spinlock_t *lock)
{
unsigned int ret = 0;
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index f616ad74cce7..44e888b0b041 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1461,16 +1461,25 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
for (i = 0; i < ctcount; i++) {
unsigned int dlen = COMP_BUF_SIZE;
int ilen = ctemplate[i].inlen;
+ void *input_vec;
+ input_vec = kmalloc(ilen, GFP_KERNEL);
+ if (!input_vec) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(input_vec, ctemplate[i].input, ilen);
memset(output, 0, dlen);
init_completion(&result.completion);
- sg_init_one(&src, ctemplate[i].input, ilen);
+ sg_init_one(&src, input_vec, ilen);
sg_init_one(&dst, output, dlen);
req = acomp_request_alloc(tfm);
if (!req) {
pr_err("alg: acomp: request alloc failed for %s\n",
algo);
+ kfree(input_vec);
ret = -ENOMEM;
goto out;
}
@@ -1483,6 +1492,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
if (ret) {
pr_err("alg: acomp: compression failed on test %d for %s: ret=%d\n",
i + 1, algo, -ret);
+ kfree(input_vec);
acomp_request_free(req);
goto out;
}
@@ -1491,6 +1501,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
pr_err("alg: acomp: Compression test %d failed for %s: output len = %d\n",
i + 1, algo, req->dlen);
ret = -EINVAL;
+ kfree(input_vec);
acomp_request_free(req);
goto out;
}
@@ -1500,26 +1511,37 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
i + 1, algo);
hexdump(output, req->dlen);
ret = -EINVAL;
+ kfree(input_vec);
acomp_request_free(req);
goto out;
}
+ kfree(input_vec);
acomp_request_free(req);
}
for (i = 0; i < dtcount; i++) {
unsigned int dlen = COMP_BUF_SIZE;
int ilen = dtemplate[i].inlen;
+ void *input_vec;
+
+ input_vec = kmalloc(ilen, GFP_KERNEL);
+ if (!input_vec) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ memcpy(input_vec, dtemplate[i].input, ilen);
memset(output, 0, dlen);
init_completion(&result.completion);
- sg_init_one(&src, dtemplate[i].input, ilen);
+ sg_init_one(&src, input_vec, ilen);
sg_init_one(&dst, output, dlen);
req = acomp_request_alloc(tfm);
if (!req) {
pr_err("alg: acomp: request alloc failed for %s\n",
algo);
+ kfree(input_vec);
ret = -ENOMEM;
goto out;
}
@@ -1532,6 +1554,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
if (ret) {
pr_err("alg: acomp: decompression failed on test %d for %s: ret=%d\n",
i + 1, algo, -ret);
+ kfree(input_vec);
acomp_request_free(req);
goto out;
}
@@ -1540,6 +1563,7 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
pr_err("alg: acomp: Decompression test %d failed for %s: output len = %d\n",
i + 1, algo, req->dlen);
ret = -EINVAL;
+ kfree(input_vec);
acomp_request_free(req);
goto out;
}
@@ -1549,10 +1573,12 @@ static int test_acomp(struct crypto_acomp *tfm, struct comp_testvec *ctemplate,
i + 1, algo);
hexdump(output, req->dlen);
ret = -EINVAL;
+ kfree(input_vec);
acomp_request_free(req);
goto out;
}
+ kfree(input_vec);
acomp_request_free(req);
}
diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c
index 13caebd679f5..8c4e0a18460a 100644
--- a/drivers/acpi/acpi_watchdog.c
+++ b/drivers/acpi/acpi_watchdog.c
@@ -114,7 +114,7 @@ void __init acpi_watchdog_init(void)
pdev = platform_device_register_simple("wdat_wdt", PLATFORM_DEVID_NONE,
resources, nresources);
if (IS_ERR(pdev))
- pr_err("Failed to create platform device\n");
+ pr_err("Device creation failed: %ld\n", PTR_ERR(pdev));
kfree(resources);
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index f8d65647ea79..fb19e1cdb641 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -98,7 +98,15 @@ static int find_child_checks(struct acpi_device *adev, bool check_children)
if (check_children && list_empty(&adev->children))
return -ENODEV;
- return sta_present ? FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE;
+ /*
+ * If the device has a _HID (or _CID) returning a valid ACPI/PNP
+ * device ID, it is better to make it look less attractive here, so that
+ * the other device with the same _ADR value (that may not have a valid
+ * device ID) can be matched going forward. [This means a second spec
+ * violation in a row, so whatever we do here is best effort anyway.]
+ */
+ return sta_present && list_empty(&adev->pnp.ids) ?
+ FIND_CHILD_MAX_SCORE : FIND_CHILD_MIN_SCORE;
}
struct acpi_device *acpi_find_child_device(struct acpi_device *parent,
@@ -250,7 +258,6 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev)
return 0;
err:
- acpi_dma_deconfigure(dev);
ACPI_COMPANION_SET(dev, NULL);
put_device(dev);
put_device(&acpi_dev->dev);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 1b41a2739dac..0c452265c111 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -37,6 +37,7 @@ void acpi_amba_init(void);
static inline void acpi_amba_init(void) {}
#endif
int acpi_sysfs_init(void);
+void acpi_gpe_apply_masked_gpes(void);
void acpi_container_init(void);
void acpi_memory_hotplug_init(void);
#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 45dec874ea55..192691880d55 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -2074,6 +2074,7 @@ int __init acpi_scan_init(void)
}
}
+ acpi_gpe_apply_masked_gpes();
acpi_update_all_gpes();
acpi_ec_ecdt_start();
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 703c26e7022c..cf05ae973381 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -708,6 +708,62 @@ end:
return result ? result : size;
}
+/*
+ * A Quirk Mechanism for GPE Flooding Prevention:
+ *
+ * Quirks may be needed to prevent GPE flooding on a specific GPE. The
+ * flooding typically cannot be detected and automatically prevented by
+ * ACPI_GPE_DISPATCH_NONE check because there is a _Lxx/_Exx prepared in
+ * the AML tables. This normally indicates a feature gap in Linux, thus
+ * instead of providing endless quirk tables, we provide a boot parameter
+ * for those who want this quirk. For example, if the users want to prevent
+ * the GPE flooding for GPE 00, they need to specify the following boot
+ * parameter:
+ * acpi_mask_gpe=0x00
+ * The masking status can be modified by the following runtime controlling
+ * interface:
+ * echo unmask > /sys/firmware/acpi/interrupts/gpe00
+ */
+
+/*
+ * Currently, the GPE flooding prevention only supports to mask the GPEs
+ * numbered from 00 to 7f.
+ */
+#define ACPI_MASKABLE_GPE_MAX 0x80
+
+static u64 __initdata acpi_masked_gpes;
+
+static int __init acpi_gpe_set_masked_gpes(char *val)
+{
+ u8 gpe;
+
+ if (kstrtou8(val, 0, &gpe) || gpe > ACPI_MASKABLE_GPE_MAX)
+ return -EINVAL;
+ acpi_masked_gpes |= ((u64)1<<gpe);
+
+ return 1;
+}
+__setup("acpi_mask_gpe=", acpi_gpe_set_masked_gpes);
+
+void __init acpi_gpe_apply_masked_gpes(void)
+{
+ acpi_handle handle;
+ acpi_status status;
+ u8 gpe;
+
+ for (gpe = 0;
+ gpe < min_t(u8, ACPI_MASKABLE_GPE_MAX, acpi_current_gpe_count);
+ gpe++) {
+ if (acpi_masked_gpes & ((u64)1<<gpe)) {
+ status = acpi_get_gpe_device(gpe, &handle);
+ if (ACPI_SUCCESS(status)) {
+ pr_info("Masking GPE 0x%x.\n", gpe);
+ (void)acpi_mask_gpe(handle, gpe, TRUE);
+ }
+ }
+ }
+}
+
void acpi_irq_stats_init(void)
{
acpi_status status;
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index a5e1262b964b..2997026b4dfb 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -626,6 +626,7 @@ static int genpd_runtime_resume(struct device *dev)
out:
/* Measure resume latency. */
+ time_start = 0;
if (timed && runtime_pm)
time_start = ktime_get();
diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c
index 5eb05dbf59b8..fc585f370549 100644
--- a/drivers/clk/clk-stm32f4.c
+++ b/drivers/clk/clk-stm32f4.c
@@ -768,5 +768,5 @@ fail:
kfree(clks);
iounmap(base);
}
-CLK_OF_DECLARE(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init);
-CLK_OF_DECLARE(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init);
+CLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init);
+CLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init);
diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c
index 9375777776d9..b533f99550e1 100644
--- a/drivers/clk/renesas/clk-mstp.c
+++ b/drivers/clk/renesas/clk-mstp.c
@@ -37,12 +37,14 @@
* @smstpcr: module stop control register
* @mstpsr: module stop status register (optional)
* @lock: protects writes to SMSTPCR
+ * @width_8bit: registers are 8-bit, not 32-bit
*/
struct mstp_clock_group {
struct clk_onecell_data data;
void __iomem *smstpcr;
void __iomem *mstpsr;
spinlock_t lock;
+ bool width_8bit;
};
/**
@@ -59,6 +61,18 @@ struct mstp_clock {
#define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw)
+static inline u32 cpg_mstp_read(struct mstp_clock_group *group,
+ u32 __iomem *reg)
+{
+ return group->width_8bit ? readb(reg) : clk_readl(reg);
+}
+
+static inline void cpg_mstp_write(struct mstp_clock_group *group, u32 val,
+ u32 __iomem *reg)
+{
+ group->width_8bit ? writeb(val, reg) : clk_writel(val, reg);
+}
+
static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
{
struct mstp_clock *clock = to_mstp_clock(hw);
@@ -70,12 +84,12 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
spin_lock_irqsave(&group->lock, flags);
- value = clk_readl(group->smstpcr);
+ value = cpg_mstp_read(group, group->smstpcr);
if (enable)
value &= ~bitmask;
else
value |= bitmask;
- clk_writel(value, group->smstpcr);
+ cpg_mstp_write(group, value, group->smstpcr);
spin_unlock_irqrestore(&group->lock, flags);
@@ -83,7 +97,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
return 0;
for (i = 1000; i > 0; --i) {
- if (!(clk_readl(group->mstpsr) & bitmask))
+ if (!(cpg_mstp_read(group, group->mstpsr) & bitmask))
break;
cpu_relax();
}
@@ -114,9 +128,9 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
u32 value;
if (group->mstpsr)
- value = clk_readl(group->mstpsr);
+ value = cpg_mstp_read(group, group->mstpsr);
else
- value = clk_readl(group->smstpcr);
+ value = cpg_mstp_read(group, group->smstpcr);
return !(value & BIT(clock->bit_index));
}
@@ -188,6 +202,9 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
return;
}
+ if (of_device_is_compatible(np, "renesas,r7s72100-mstp-clocks"))
+ group->width_8bit = true;
+
for (i = 0; i < MSTP_MAX_CLOCKS; ++i)
clks[i] = ERR_PTR(-ENOENT);
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index bc97b6a4b1cf..7fcaf26e8f81 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -26,6 +26,8 @@ static const struct of_device_id machines[] __initconst = {
{ .compatible = "allwinner,sun8i-a83t", },
{ .compatible = "allwinner,sun8i-h3", },
+ { .compatible = "apm,xgene-shadowcat", },
+
{ .compatible = "arm,integrator-ap", },
{ .compatible = "arm,integrator-cp", },
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 6acbd4af632e..f91c25718d16 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -857,13 +857,13 @@ static struct freq_attr *hwp_cpufreq_attrs[] = {
NULL,
};
-static void intel_pstate_hwp_set(const struct cpumask *cpumask)
+static void intel_pstate_hwp_set(struct cpufreq_policy *policy)
{
int min, hw_min, max, hw_max, cpu, range, adj_range;
struct perf_limits *perf_limits = limits;
u64 value, cap;
- for_each_cpu(cpu, cpumask) {
+ for_each_cpu(cpu, policy->cpus) {
int max_perf_pct, min_perf_pct;
struct cpudata *cpu_data = all_cpu_data[cpu];
s16 epp;
@@ -949,7 +949,7 @@ skip_epp:
static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy)
{
if (hwp_active)
- intel_pstate_hwp_set(policy->cpus);
+ intel_pstate_hwp_set(policy);
return 0;
}
@@ -968,19 +968,28 @@ static int intel_pstate_hwp_save_state(struct cpufreq_policy *policy)
static int intel_pstate_resume(struct cpufreq_policy *policy)
{
+ int ret;
+
if (!hwp_active)
return 0;
+ mutex_lock(&intel_pstate_limits_lock);
+
all_cpu_data[policy->cpu]->epp_policy = 0;
- return intel_pstate_hwp_set_policy(policy);
+ ret = intel_pstate_hwp_set_policy(policy);
+
+ mutex_unlock(&intel_pstate_limits_lock);
+
+ return ret;
}
-static void intel_pstate_hwp_set_online_cpus(void)
+static void intel_pstate_update_policies(void)
{
- get_online_cpus();
- intel_pstate_hwp_set(cpu_online_mask);
- put_online_cpus();
+ int cpu;
+
+ for_each_possible_cpu(cpu)
+ cpufreq_update_policy(cpu);
}
/************************** debugfs begin ************************/
@@ -1018,10 +1027,6 @@ static void __init intel_pstate_debug_expose_params(void)
struct dentry *debugfs_parent;
int i = 0;
- if (hwp_active ||
- pstate_funcs.get_target_pstate == get_target_pstate_use_cpu_load)
- return;
-
debugfs_parent = debugfs_create_dir("pstate_snb", NULL);
if (IS_ERR_OR_NULL(debugfs_parent))
return;
@@ -1105,11 +1110,10 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b,
limits->no_turbo = clamp_t(int, input, 0, 1);
- if (hwp_active)
- intel_pstate_hwp_set_online_cpus();
-
mutex_unlock(&intel_pstate_limits_lock);
+ intel_pstate_update_policies();
+
return count;
}
@@ -1134,11 +1138,10 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b,
limits->max_perf_pct);
limits->max_perf = div_ext_fp(limits->max_perf_pct, 100);
- if (hwp_active)
- intel_pstate_hwp_set_online_cpus();
-
mutex_unlock(&intel_pstate_limits_lock);
+ intel_pstate_update_policies();
+
return count;
}
@@ -1163,11 +1166,10 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b,
limits->min_perf_pct);
limits->min_perf = div_ext_fp(limits->min_perf_pct, 100);
- if (hwp_active)
- intel_pstate_hwp_set_online_cpus();
-
mutex_unlock(&intel_pstate_limits_lock);
+ intel_pstate_update_policies();
+
return count;
}
@@ -2153,8 +2155,12 @@ static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy)
if (per_cpu_limits)
perf_limits = cpu->perf_limits;
+ mutex_lock(&intel_pstate_limits_lock);
+
intel_pstate_update_perf_limits(policy, perf_limits);
+ mutex_unlock(&intel_pstate_limits_lock);
+
return 0;
}
@@ -2487,7 +2493,10 @@ hwp_cpu_matched:
if (rc)
goto out;
- intel_pstate_debug_expose_params();
+ if (intel_pstate_driver == &intel_pstate && !hwp_active &&
+ pstate_funcs.get_target_pstate != get_target_pstate_use_cpu_load)
+ intel_pstate_debug_expose_params();
+
intel_pstate_sysfs_expose_params();
if (hwp_active)
diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h
index a768da7138a1..b7872f62f674 100644
--- a/drivers/crypto/marvell/cesa.h
+++ b/drivers/crypto/marvell/cesa.h
@@ -273,7 +273,8 @@ struct mv_cesa_op_ctx {
#define CESA_TDMA_SRC_IN_SRAM BIT(30)
#define CESA_TDMA_END_OF_REQ BIT(29)
#define CESA_TDMA_BREAK_CHAIN BIT(28)
-#define CESA_TDMA_TYPE_MSK GENMASK(27, 0)
+#define CESA_TDMA_SET_STATE BIT(27)
+#define CESA_TDMA_TYPE_MSK GENMASK(26, 0)
#define CESA_TDMA_DUMMY 0
#define CESA_TDMA_DATA 1
#define CESA_TDMA_OP 2
diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c
index 317cf029c0cf..77c0fb936f47 100644
--- a/drivers/crypto/marvell/hash.c
+++ b/drivers/crypto/marvell/hash.c
@@ -280,13 +280,32 @@ static void mv_cesa_ahash_std_prepare(struct ahash_request *req)
sreq->offset = 0;
}
+static void mv_cesa_ahash_dma_step(struct ahash_request *req)
+{
+ struct mv_cesa_ahash_req *creq = ahash_request_ctx(req);
+ struct mv_cesa_req *base = &creq->base;
+
+ /* We must explicitly set the digest state. */
+ if (base->chain.first->flags & CESA_TDMA_SET_STATE) {
+ struct mv_cesa_engine *engine = base->engine;
+ int i;
+
+ /* Set the hash state in the IVDIG regs. */
+ for (i = 0; i < ARRAY_SIZE(creq->state); i++)
+ writel_relaxed(creq->state[i], engine->regs +
+ CESA_IVDIG(i));
+ }
+
+ mv_cesa_dma_step(base);
+}
+
static void mv_cesa_ahash_step(struct crypto_async_request *req)
{
struct ahash_request *ahashreq = ahash_request_cast(req);
struct mv_cesa_ahash_req *creq = ahash_request_ctx(ahashreq);
if (mv_cesa_req_get_type(&creq->base) == CESA_DMA_REQ)
- mv_cesa_dma_step(&creq->base);
+ mv_cesa_ahash_dma_step(ahashreq);
else
mv_cesa_ahash_std_step(ahashreq);
}
@@ -584,12 +603,16 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
struct mv_cesa_ahash_dma_iter iter;
struct mv_cesa_op_ctx *op = NULL;
unsigned int frag_len;
+ bool set_state = false;
int ret;
u32 type;
basereq->chain.first = NULL;
basereq->chain.last = NULL;
+ if (!mv_cesa_mac_op_is_first_frag(&creq->op_tmpl))
+ set_state = true;
+
if (creq->src_nents) {
ret = dma_map_sg(cesa_dev->dev, req->src, creq->src_nents,
DMA_TO_DEVICE);
@@ -683,6 +706,15 @@ static int mv_cesa_ahash_dma_req_init(struct ahash_request *req)
if (type != CESA_TDMA_RESULT)
basereq->chain.last->flags |= CESA_TDMA_BREAK_CHAIN;
+ if (set_state) {
+ /*
+ * Put the CESA_TDMA_SET_STATE flag on the first tdma desc to
+ * let the step logic know that the IVDIG registers should be
+ * explicitly set before launching a TDMA chain.
+ */
+ basereq->chain.first->flags |= CESA_TDMA_SET_STATE;
+ }
+
return 0;
err_free_tdma:
diff --git a/drivers/crypto/marvell/tdma.c b/drivers/crypto/marvell/tdma.c
index 4416b88eca70..c76375ff376d 100644
--- a/drivers/crypto/marvell/tdma.c
+++ b/drivers/crypto/marvell/tdma.c
@@ -109,7 +109,14 @@ void mv_cesa_tdma_chain(struct mv_cesa_engine *engine,
last->next = dreq->chain.first;
engine->chain.last = dreq->chain.last;
- if (!(last->flags & CESA_TDMA_BREAK_CHAIN))
+ /*
+ * Break the DMA chain if the CESA_TDMA_BREAK_CHAIN is set on
+ * the last element of the current chain, or if the request
+ * being queued needs the IV regs to be set before lauching
+ * the request.
+ */
+ if (!(last->flags & CESA_TDMA_BREAK_CHAIN) &&
+ !(dreq->chain.first->flags & CESA_TDMA_SET_STATE))
last->next_dma = dreq->chain.first->cur_dma;
}
}
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index a324801d6a66..47206a21bb90 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -593,11 +593,16 @@ struct devfreq *devfreq_add_device(struct device *dev,
list_add(&devfreq->node, &devfreq_list);
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);
+ if (IS_ERR(governor)) {
+ dev_err(dev, "%s: Unable to find governor for the device\n",
+ __func__);
+ err = PTR_ERR(governor);
+ goto err_init;
+ }
+
+ devfreq->governor = governor;
+ err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START,
+ NULL);
if (err) {
dev_err(dev, "%s: Unable to start governor for the device\n",
__func__);
diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index a8ed7792ece2..9af86f46fbec 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -497,7 +497,7 @@ passive:
if (IS_ERR(bus->devfreq)) {
dev_err(dev,
"failed to add devfreq dev with passive governor\n");
- ret = -EPROBE_DEFER;
+ ret = PTR_ERR(bus->devfreq);
goto err;
}
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index 70e13230d8db..9ad0b1934be9 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -721,11 +721,17 @@ static int scpi_sensor_get_value(u16 sensor, u64 *val)
ret = scpi_send_message(CMD_SENSOR_VALUE, &id, sizeof(id),
&buf, sizeof(buf));
- if (!ret)
+ if (ret)
+ return ret;
+
+ if (scpi_info->is_legacy)
+ /* only 32-bits supported, hi_val can be junk */
+ *val = le32_to_cpu(buf.lo_val);
+ else
*val = (u64)le32_to_cpu(buf.hi_val) << 32 |
le32_to_cpu(buf.lo_val);
- return ret;
+ return 0;
}
static int scpi_device_get_power_state(u16 dev_id)
diff --git a/drivers/firmware/psci_checker.c b/drivers/firmware/psci_checker.c
index 44bdb78f837b..29d58feaf675 100644
--- a/drivers/firmware/psci_checker.c
+++ b/drivers/firmware/psci_checker.c
@@ -270,8 +270,7 @@ static int suspend_test_thread(void *arg)
struct cpuidle_device *dev;
struct cpuidle_driver *drv;
/* No need for an actual callback, we just want to wake up the CPU. */
- struct timer_list wakeup_timer =
- TIMER_INITIALIZER(dummy_callback, 0, 0);
+ struct timer_list wakeup_timer;
/* Wait for the main thread to give the start signal. */
wait_for_completion(&suspend_threads_started);
@@ -287,6 +286,7 @@ static int suspend_test_thread(void *arg)
pr_info("CPU %d entering suspend cycles, states 1 through %d\n",
cpu, drv->state_count - 1);
+ setup_timer_on_stack(&wakeup_timer, dummy_callback, 0);
for (i = 0; i < NUM_SUSPEND_CYCLE; ++i) {
int index;
/*
diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c
index db516382a4d4..711c31c8d8b4 100644
--- a/drivers/gpu/drm/i915/gvt/cfg_space.c
+++ b/drivers/gpu/drm/i915/gvt/cfg_space.c
@@ -123,6 +123,7 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu,
u8 changed = old ^ new;
int ret;
+ memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes);
if (!(changed & PCI_COMMAND_MEMORY))
return 0;
@@ -142,7 +143,6 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu,
return ret;
}
- memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes);
return 0;
}
@@ -240,7 +240,7 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
if (WARN_ON(bytes > 4))
return -EINVAL;
- if (WARN_ON(offset + bytes >= INTEL_GVT_MAX_CFG_SPACE_SZ))
+ if (WARN_ON(offset + bytes > INTEL_GVT_MAX_CFG_SPACE_SZ))
return -EINVAL;
/* First check if it's PCI_COMMAND */
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 7eaaf1c9ed2b..6c5fdf5b2ce2 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1998,6 +1998,8 @@ int intel_vgpu_init_gtt(struct intel_vgpu *vgpu)
INIT_LIST_HEAD(&gtt->oos_page_list_head);
INIT_LIST_HEAD(&gtt->post_shadow_list_head);
+ intel_vgpu_reset_ggtt(vgpu);
+
ggtt_mm = intel_vgpu_create_mm(vgpu, INTEL_GVT_MM_GGTT,
NULL, 1, 0);
if (IS_ERR(ggtt_mm)) {
@@ -2206,6 +2208,7 @@ int intel_vgpu_g2v_destroy_ppgtt_mm(struct intel_vgpu *vgpu,
int intel_gvt_init_gtt(struct intel_gvt *gvt)
{
int ret;
+ void *page_addr;
gvt_dbg_core("init gtt\n");
@@ -2218,6 +2221,23 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt)
return -ENODEV;
}
+ gvt->gtt.scratch_ggtt_page =
+ alloc_page(GFP_KERNEL | GFP_ATOMIC | __GFP_ZERO);
+ if (!gvt->gtt.scratch_ggtt_page) {
+ gvt_err("fail to allocate scratch ggtt page\n");
+ return -ENOMEM;
+ }
+
+ page_addr = page_address(gvt->gtt.scratch_ggtt_page);
+
+ gvt->gtt.scratch_ggtt_mfn =
+ intel_gvt_hypervisor_virt_to_mfn(page_addr);
+ if (gvt->gtt.scratch_ggtt_mfn == INTEL_GVT_INVALID_ADDR) {
+ gvt_err("fail to translate scratch ggtt page\n");
+ __free_page(gvt->gtt.scratch_ggtt_page);
+ return -EFAULT;
+ }
+
if (enable_out_of_sync) {
ret = setup_spt_oos(gvt);
if (ret) {
@@ -2239,6 +2259,41 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt)
*/
void intel_gvt_clean_gtt(struct intel_gvt *gvt)
{
+ __free_page(gvt->gtt.scratch_ggtt_page);
+
if (enable_out_of_sync)
clean_spt_oos(gvt);
}
+
+/**
+ * intel_vgpu_reset_ggtt - reset the GGTT entry
+ * @vgpu: a vGPU
+ *
+ * This function is called at the vGPU create stage
+ * to reset all the GGTT entries.
+ *
+ */
+void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu)
+{
+ struct intel_gvt *gvt = vgpu->gvt;
+ struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
+ u32 index;
+ u32 offset;
+ u32 num_entries;
+ struct intel_gvt_gtt_entry e;
+
+ memset(&e, 0, sizeof(struct intel_gvt_gtt_entry));
+ e.type = GTT_TYPE_GGTT_PTE;
+ ops->set_pfn(&e, gvt->gtt.scratch_ggtt_mfn);
+ e.val64 |= _PAGE_PRESENT;
+
+ index = vgpu_aperture_gmadr_base(vgpu) >> PAGE_SHIFT;
+ num_entries = vgpu_aperture_sz(vgpu) >> PAGE_SHIFT;
+ for (offset = 0; offset < num_entries; offset++)
+ ops->set_entry(NULL, &e, index + offset, false, 0, vgpu);
+
+ index = vgpu_hidden_gmadr_base(vgpu) >> PAGE_SHIFT;
+ num_entries = vgpu_hidden_sz(vgpu) >> PAGE_SHIFT;
+ for (offset = 0; offset < num_entries; offset++)
+ ops->set_entry(NULL, &e, index + offset, false, 0, vgpu);
+}
diff --git a/drivers/gpu/drm/i915/gvt/gtt.h b/drivers/gpu/drm/i915/gvt/gtt.h
index d250013bc37b..b315ab3593ec 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.h
+++ b/drivers/gpu/drm/i915/gvt/gtt.h
@@ -81,6 +81,9 @@ struct intel_gvt_gtt {
struct list_head oos_page_use_list_head;
struct list_head oos_page_free_list_head;
struct list_head mm_lru_list_head;
+
+ struct page *scratch_ggtt_page;
+ unsigned long scratch_ggtt_mfn;
};
enum {
@@ -202,6 +205,7 @@ struct intel_vgpu_gtt {
extern int intel_vgpu_init_gtt(struct intel_vgpu *vgpu);
extern void intel_vgpu_clean_gtt(struct intel_vgpu *vgpu);
+void intel_vgpu_reset_ggtt(struct intel_vgpu *vgpu);
extern int intel_gvt_init_gtt(struct intel_gvt *gvt);
extern void intel_gvt_clean_gtt(struct intel_gvt *gvt);
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index ad0e9364ee70..0af17016f33f 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -175,6 +175,7 @@ struct intel_vgpu {
struct notifier_block group_notifier;
struct kvm *kvm;
struct work_struct release_work;
+ atomic_t released;
} vdev;
#endif
};
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 4dd6722a7339..faaae07ae487 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -114,12 +114,15 @@ out:
static kvm_pfn_t gvt_cache_find(struct intel_vgpu *vgpu, gfn_t gfn)
{
struct gvt_dma *entry;
+ kvm_pfn_t pfn;
mutex_lock(&vgpu->vdev.cache_lock);
+
entry = __gvt_cache_find(vgpu, gfn);
- mutex_unlock(&vgpu->vdev.cache_lock);
+ pfn = (entry == NULL) ? 0 : entry->pfn;
- return entry == NULL ? 0 : entry->pfn;
+ mutex_unlock(&vgpu->vdev.cache_lock);
+ return pfn;
}
static void gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn, kvm_pfn_t pfn)
@@ -166,7 +169,7 @@ static void __gvt_cache_remove_entry(struct intel_vgpu *vgpu,
static void gvt_cache_remove(struct intel_vgpu *vgpu, gfn_t gfn)
{
- struct device *dev = &vgpu->vdev.mdev->dev;
+ struct device *dev = mdev_dev(vgpu->vdev.mdev);
struct gvt_dma *this;
unsigned long g1;
int rc;
@@ -195,7 +198,7 @@ static void gvt_cache_destroy(struct intel_vgpu *vgpu)
{
struct gvt_dma *dma;
struct rb_node *node = NULL;
- struct device *dev = &vgpu->vdev.mdev->dev;
+ struct device *dev = mdev_dev(vgpu->vdev.mdev);
unsigned long gfn;
mutex_lock(&vgpu->vdev.cache_lock);
@@ -396,7 +399,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
struct device *pdev;
void *gvt;
- pdev = mdev->parent->dev;
+ pdev = mdev_parent_dev(mdev);
gvt = kdev_to_i915(pdev)->gvt;
type = intel_gvt_find_vgpu_type(gvt, kobject_name(kobj));
@@ -418,7 +421,7 @@ static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *mdev)
mdev_set_drvdata(mdev, vgpu);
gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
- dev_name(&mdev->dev));
+ dev_name(mdev_dev(mdev)));
return 0;
}
@@ -482,7 +485,7 @@ static int intel_vgpu_open(struct mdev_device *mdev)
vgpu->vdev.group_notifier.notifier_call = intel_vgpu_group_notifier;
events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
- ret = vfio_register_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY, &events,
+ ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, &events,
&vgpu->vdev.iommu_notifier);
if (ret != 0) {
gvt_err("vfio_register_notifier for iommu failed: %d\n", ret);
@@ -490,17 +493,26 @@ static int intel_vgpu_open(struct mdev_device *mdev)
}
events = VFIO_GROUP_NOTIFY_SET_KVM;
- ret = vfio_register_notifier(&mdev->dev, VFIO_GROUP_NOTIFY, &events,
+ ret = vfio_register_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY, &events,
&vgpu->vdev.group_notifier);
if (ret != 0) {
gvt_err("vfio_register_notifier for group failed: %d\n", ret);
goto undo_iommu;
}
- return kvmgt_guest_init(mdev);
+ ret = kvmgt_guest_init(mdev);
+ if (ret)
+ goto undo_group;
+
+ atomic_set(&vgpu->vdev.released, 0);
+ return ret;
+
+undo_group:
+ vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
+ &vgpu->vdev.group_notifier);
undo_iommu:
- vfio_unregister_notifier(&mdev->dev, VFIO_IOMMU_NOTIFY,
+ vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
&vgpu->vdev.iommu_notifier);
out:
return ret;
@@ -509,17 +521,26 @@ out:
static void __intel_vgpu_release(struct intel_vgpu *vgpu)
{
struct kvmgt_guest_info *info;
+ int ret;
if (!handle_valid(vgpu->handle))
return;
- vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_IOMMU_NOTIFY,
+ if (atomic_cmpxchg(&vgpu->vdev.released, 0, 1))
+ return;
+
+ ret = vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_IOMMU_NOTIFY,
&vgpu->vdev.iommu_notifier);
- vfio_unregister_notifier(&vgpu->vdev.mdev->dev, VFIO_GROUP_NOTIFY,
+ WARN(ret, "vfio_unregister_notifier for iommu failed: %d\n", ret);
+
+ ret = vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_GROUP_NOTIFY,
&vgpu->vdev.group_notifier);
+ WARN(ret, "vfio_unregister_notifier for group failed: %d\n", ret);
info = (struct kvmgt_guest_info *)vgpu->handle;
kvmgt_guest_exit(info);
+
+ vgpu->vdev.kvm = NULL;
vgpu->handle = 0;
}
@@ -534,6 +555,7 @@ static void intel_vgpu_release_work(struct work_struct *work)
{
struct intel_vgpu *vgpu = container_of(work, struct intel_vgpu,
vdev.release_work);
+
__intel_vgpu_release(vgpu);
}
@@ -1089,7 +1111,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
return 0;
}
-static const struct parent_ops intel_vgpu_ops = {
+static const struct mdev_parent_ops intel_vgpu_ops = {
.supported_type_groups = intel_vgpu_type_groups,
.create = intel_vgpu_create,
.remove = intel_vgpu_remove,
@@ -1134,6 +1156,10 @@ static int kvmgt_write_protect_add(unsigned long handle, u64 gfn)
idx = srcu_read_lock(&kvm->srcu);
slot = gfn_to_memslot(kvm, gfn);
+ if (!slot) {
+ srcu_read_unlock(&kvm->srcu, idx);
+ return -EINVAL;
+ }
spin_lock(&kvm->mmu_lock);
@@ -1164,6 +1190,10 @@ static int kvmgt_write_protect_remove(unsigned long handle, u64 gfn)
idx = srcu_read_lock(&kvm->srcu);
slot = gfn_to_memslot(kvm, gfn);
+ if (!slot) {
+ srcu_read_unlock(&kvm->srcu, idx);
+ return -EINVAL;
+ }
spin_lock(&kvm->mmu_lock);
@@ -1311,18 +1341,14 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
static bool kvmgt_guest_exit(struct kvmgt_guest_info *info)
{
- struct intel_vgpu *vgpu;
-
if (!info) {
gvt_err("kvmgt_guest_info invalid\n");
return false;
}
- vgpu = info->vgpu;
-
kvm_page_track_unregister_notifier(info->kvm, &info->track_node);
kvmgt_protect_table_destroy(info);
- gvt_cache_destroy(vgpu);
+ gvt_cache_destroy(info->vgpu);
vfree(info);
return true;
@@ -1372,7 +1398,7 @@ static unsigned long kvmgt_gfn_to_pfn(unsigned long handle, unsigned long gfn)
return pfn;
pfn = INTEL_GVT_INVALID_ADDR;
- dev = &info->vgpu->vdev.mdev->dev;
+ dev = mdev_dev(info->vgpu->vdev.mdev);
rc = vfio_pin_pages(dev, &gfn, 1, IOMMU_READ | IOMMU_WRITE, &pfn);
if (rc != 1) {
gvt_err("vfio_pin_pages failed for gfn 0x%lx: %d\n", gfn, rc);
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c
index d2a0fbc896c3..81cd921770c6 100644
--- a/drivers/gpu/drm/i915/gvt/opregion.c
+++ b/drivers/gpu/drm/i915/gvt/opregion.c
@@ -65,7 +65,7 @@ static int map_vgpu_opregion(struct intel_vgpu *vgpu, bool map)
int i, ret;
for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++) {
- mfn = intel_gvt_hypervisor_virt_to_mfn(vgpu_opregion(vgpu)
+ mfn = intel_gvt_hypervisor_virt_to_mfn(vgpu_opregion(vgpu)->va
+ i * PAGE_SIZE);
if (mfn == INTEL_GVT_INVALID_ADDR) {
gvt_err("fail to get MFN from VA\n");
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4a31b7a891ec..3dd7fc662859 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -244,14 +244,16 @@ err_phys:
static void
__i915_gem_object_release_shmem(struct drm_i915_gem_object *obj,
- struct sg_table *pages)
+ struct sg_table *pages,
+ bool needs_clflush)
{
GEM_BUG_ON(obj->mm.madv == __I915_MADV_PURGED);
if (obj->mm.madv == I915_MADV_DONTNEED)
obj->mm.dirty = false;
- if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0 &&
+ if (needs_clflush &&
+ (obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0 &&
!cpu_cache_is_coherent(obj->base.dev, obj->cache_level))
drm_clflush_sg(pages);
@@ -263,7 +265,7 @@ static void
i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
struct sg_table *pages)
{
- __i915_gem_object_release_shmem(obj, pages);
+ __i915_gem_object_release_shmem(obj, pages, false);
if (obj->mm.dirty) {
struct address_space *mapping = obj->base.filp->f_mapping;
@@ -2231,7 +2233,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj,
struct sgt_iter sgt_iter;
struct page *page;
- __i915_gem_object_release_shmem(obj, pages);
+ __i915_gem_object_release_shmem(obj, pages, true);
i915_gem_gtt_finish_pages(obj, pages);
@@ -2304,15 +2306,6 @@ unlock:
mutex_unlock(&obj->mm.lock);
}
-static unsigned int swiotlb_max_size(void)
-{
-#if IS_ENABLED(CONFIG_SWIOTLB)
- return rounddown(swiotlb_nr_tbl() << IO_TLB_SHIFT, PAGE_SIZE);
-#else
- return 0;
-#endif
-}
-
static void i915_sg_trim(struct sg_table *orig_st)
{
struct sg_table new_st;
@@ -2322,7 +2315,7 @@ static void i915_sg_trim(struct sg_table *orig_st)
if (orig_st->nents == orig_st->orig_nents)
return;
- if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL))
+ if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN))
return;
new_sg = new_st.sgl;
@@ -2360,7 +2353,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
GEM_BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS);
GEM_BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS);
- max_segment = swiotlb_max_size();
+ max_segment = swiotlb_max_segment();
if (!max_segment)
max_segment = rounddown(UINT_MAX, PAGE_SIZE);
@@ -2728,6 +2721,7 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
struct drm_i915_gem_request *request;
struct i915_gem_context *incomplete_ctx;
struct intel_timeline *timeline;
+ unsigned long flags;
bool ring_hung;
if (engine->irq_seqno_barrier)
@@ -2763,13 +2757,20 @@ static void i915_gem_reset_engine(struct intel_engine_cs *engine)
if (i915_gem_context_is_default(incomplete_ctx))
return;
+ timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine);
+
+ spin_lock_irqsave(&engine->timeline->lock, flags);
+ spin_lock(&timeline->lock);
+
list_for_each_entry_continue(request, &engine->timeline->requests, link)
if (request->ctx == incomplete_ctx)
reset_request(request);
- timeline = i915_gem_context_lookup_timeline(incomplete_ctx, engine);
list_for_each_entry(request, &timeline->requests, link)
reset_request(request);
+
+ spin_unlock(&timeline->lock);
+ spin_unlock_irqrestore(&engine->timeline->lock, flags);
}
void i915_gem_reset(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_gem_request.h b/drivers/gpu/drm/i915/i915_gem_request.h
index e2b077df2da0..d229f47d1028 100644
--- a/drivers/gpu/drm/i915/i915_gem_request.h
+++ b/drivers/gpu/drm/i915/i915_gem_request.h
@@ -413,6 +413,25 @@ i915_gem_active_set(struct i915_gem_active *active,
rcu_assign_pointer(active->request, request);
}
+/**
+ * i915_gem_active_set_retire_fn - updates the retirement callback
+ * @active - the active tracker
+ * @fn - the routine called when the request is retired
+ * @mutex - struct_mutex used to guard retirements
+ *
+ * i915_gem_active_set_retire_fn() updates the function pointer that
+ * is called when the final request associated with the @active tracker
+ * is retired.
+ */
+static inline void
+i915_gem_active_set_retire_fn(struct i915_gem_active *active,
+ i915_gem_retire_fn fn,
+ struct mutex *mutex)
+{
+ lockdep_assert_held(mutex);
+ active->retire = fn ?: i915_gem_retire_noop;
+}
+
static inline struct drm_i915_gem_request *
__i915_gem_active_peek(const struct i915_gem_active *active)
{
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6daad8613760..3dc8724df400 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -16791,7 +16791,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
for_each_intel_crtc(dev, crtc) {
struct intel_crtc_state *crtc_state = crtc->config;
- int pixclk = 0;
__drm_atomic_helper_crtc_destroy_state(&crtc_state->base);
memset(crtc_state, 0, sizeof(*crtc_state));
@@ -16803,23 +16802,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
crtc->base.enabled = crtc_state->base.enable;
crtc->active = crtc_state->base.active;
- if (crtc_state->base.active) {
+ if (crtc_state->base.active)
dev_priv->active_crtcs |= 1 << crtc->pipe;
- if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
- pixclk = ilk_pipe_pixel_rate(crtc_state);
- else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
- pixclk = crtc_state->base.adjusted_mode.crtc_clock;
- else
- WARN_ON(dev_priv->display.modeset_calc_cdclk);
-
- /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
- if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled)
- pixclk = DIV_ROUND_UP(pixclk * 100, 95);
- }
-
- dev_priv->min_pixclk[crtc->pipe] = pixclk;
-
readout_plane_state(crtc);
DRM_DEBUG_KMS("[CRTC:%d:%s] hw state readout: %s\n",
@@ -16892,6 +16877,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
}
for_each_intel_crtc(dev, crtc) {
+ int pixclk = 0;
+
crtc->base.hwmode = crtc->config->base.adjusted_mode;
memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
@@ -16919,10 +16906,23 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
*/
crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
+ if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
+ pixclk = ilk_pipe_pixel_rate(crtc->config);
+ else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
+ pixclk = crtc->config->base.adjusted_mode.crtc_clock;
+ else
+ WARN_ON(dev_priv->display.modeset_calc_cdclk);
+
+ /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
+ if (IS_BROADWELL(dev_priv) && crtc->config->ips_enabled)
+ pixclk = DIV_ROUND_UP(pixclk * 100, 95);
+
drm_calc_timestamping_constants(&crtc->base, &crtc->base.hwmode);
update_scanline_offset(crtc);
}
+ dev_priv->min_pixclk[crtc->pipe] = pixclk;
+
intel_pipe_config_sanity_check(dev_priv, crtc->config);
}
}
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index d9bc19be855e..0b8e8eb85c19 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -355,7 +355,8 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
struct intel_dp *intel_dp);
static void
intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
- struct intel_dp *intel_dp);
+ struct intel_dp *intel_dp,
+ bool force_disable_vdd);
static void
intel_dp_pps_init(struct drm_device *dev, struct intel_dp *intel_dp);
@@ -516,7 +517,7 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
/* init power sequencer on this pipe and port */
intel_dp_init_panel_power_sequencer(dev, intel_dp);
- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
+ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true);
/*
* Even vdd force doesn't work until we've made
@@ -553,7 +554,7 @@ bxt_power_sequencer_idx(struct intel_dp *intel_dp)
* Only the HW needs to be reprogrammed, the SW state is fixed and
* has been setup during connector init.
*/
- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
+ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false);
return 0;
}
@@ -636,7 +637,7 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp)
port_name(port), pipe_name(intel_dp->pps_pipe));
intel_dp_init_panel_power_sequencer(dev, intel_dp);
- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
+ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false);
}
void intel_power_sequencer_reset(struct drm_i915_private *dev_priv)
@@ -2912,7 +2913,7 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp)
/* init power sequencer on this pipe and port */
intel_dp_init_panel_power_sequencer(dev, intel_dp);
- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
+ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, true);
}
static void vlv_pre_enable_dp(struct intel_encoder *encoder,
@@ -5055,7 +5056,8 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
static void
intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
- struct intel_dp *intel_dp)
+ struct intel_dp *intel_dp,
+ bool force_disable_vdd)
{
struct drm_i915_private *dev_priv = to_i915(dev);
u32 pp_on, pp_off, pp_div, port_sel = 0;
@@ -5068,6 +5070,31 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
intel_pps_get_registers(dev_priv, intel_dp, &regs);
+ /*
+ * On some VLV machines the BIOS can leave the VDD
+ * enabled even on power seqeuencers which aren't
+ * hooked up to any port. This would mess up the
+ * power domain tracking the first time we pick
+ * one of these power sequencers for use since
+ * edp_panel_vdd_on() would notice that the VDD was
+ * already on and therefore wouldn't grab the power
+ * domain reference. Disable VDD first to avoid this.
+ * This also avoids spuriously turning the VDD on as
+ * soon as the new power seqeuencer gets initialized.
+ */
+ if (force_disable_vdd) {
+ u32 pp = ironlake_get_pp_control(intel_dp);
+
+ WARN(pp & PANEL_POWER_ON, "Panel power already on\n");
+
+ if (pp & EDP_FORCE_VDD)
+ DRM_DEBUG_KMS("VDD already on, disabling first\n");
+
+ pp &= ~EDP_FORCE_VDD;
+
+ I915_WRITE(regs.pp_ctrl, pp);
+ }
+
pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) |
(seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT);
pp_off = (seq->t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) |
@@ -5122,7 +5149,7 @@ static void intel_dp_pps_init(struct drm_device *dev,
vlv_initial_power_sequencer_setup(intel_dp);
} else {
intel_dp_init_panel_power_sequencer(dev, intel_dp);
- intel_dp_init_panel_power_sequencer_registers(dev, intel_dp);
+ intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, false);
}
}
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index fd0e4dac7cc1..e589e17876dc 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -216,7 +216,8 @@ static void intel_overlay_submit_request(struct intel_overlay *overlay,
{
GEM_BUG_ON(i915_gem_active_peek(&overlay->last_flip,
&overlay->i915->drm.struct_mutex));
- overlay->last_flip.retire = retire;
+ i915_gem_active_set_retire_fn(&overlay->last_flip, retire,
+ &overlay->i915->drm.struct_mutex);
i915_gem_active_set(&overlay->last_flip, req);
i915_add_request(req);
}
@@ -839,8 +840,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
if (ret)
goto out_unpin;
- i915_gem_track_fb(overlay->vma->obj, new_bo,
- INTEL_FRONTBUFFER_OVERLAY(pipe));
+ i915_gem_track_fb(overlay->vma ? overlay->vma->obj : NULL,
+ vma->obj, INTEL_FRONTBUFFER_OVERLAY(pipe));
overlay->old_vma = overlay->vma;
overlay->vma = vma;
@@ -1430,6 +1431,8 @@ void intel_setup_overlay(struct drm_i915_private *dev_priv)
overlay->contrast = 75;
overlay->saturation = 146;
+ init_request_active(&overlay->last_flip, NULL);
+
regs = intel_overlay_map_regs(overlay);
if (!regs)
goto out_unpin_bo;
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index d40ed9fdf68d..70b12f89a193 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -64,7 +64,8 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
#define QUIRK_SKIP_INPUT_MAPPING BIT(2)
#define QUIRK_IS_MULTITOUCH BIT(3)
-#define NOTEBOOK_QUIRKS QUIRK_FIX_NOTEBOOK_REPORT
+#define KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
+ QUIRK_NO_INIT_REPORTS)
#define TOUCHPAD_QUIRKS (QUIRK_NO_INIT_REPORTS | \
QUIRK_SKIP_INPUT_MAPPING | \
QUIRK_IS_MULTITOUCH)
@@ -170,11 +171,11 @@ static int asus_raw_event(struct hid_device *hdev,
static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
{
+ struct input_dev *input = hi->input;
struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
if (drvdata->quirks & QUIRK_IS_MULTITOUCH) {
int ret;
- struct input_dev *input = hi->input;
input_set_abs_params(input, ABS_MT_POSITION_X, 0, MAX_X, 0, 0);
input_set_abs_params(input, ABS_MT_POSITION_Y, 0, MAX_Y, 0, 0);
@@ -191,10 +192,10 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
hid_err(hdev, "Asus input mt init slots failed: %d\n", ret);
return ret;
}
-
- drvdata->input = input;
}
+ drvdata->input = input;
+
return 0;
}
@@ -286,7 +287,11 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_stop_hw;
}
- drvdata->input->name = "Asus TouchPad";
+ if (drvdata->quirks & QUIRK_IS_MULTITOUCH) {
+ drvdata->input->name = "Asus TouchPad";
+ } else {
+ drvdata->input->name = "Asus Keyboard";
+ }
if (drvdata->quirks & QUIRK_IS_MULTITOUCH) {
ret = asus_start_multitouch(hdev);
@@ -315,7 +320,7 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
static const struct hid_device_id asus_devices[] = {
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
- USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD), NOTEBOOK_QUIRKS},
+ USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD), KEYBOARD_QUIRKS},
{ HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK,
USB_DEVICE_ID_ASUSTEK_TOUCHPAD), TOUCHPAD_QUIRKS },
{ }
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index ec277b96eaa1..54bd22dc1411 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -319,6 +319,7 @@
#define USB_VENDOR_ID_DRAGONRISE 0x0079
#define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800
#define USB_DEVICE_ID_DRAGONRISE_PS3 0x1801
+#define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803
#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE 0x1843
#define USB_VENDOR_ID_DWAV 0x0eef
@@ -365,6 +366,9 @@
#define USB_VENDOR_ID_FLATFROG 0x25b5
#define USB_DEVICE_ID_MULTITOUCH_3200 0x0002
+#define USB_VENDOR_ID_FUTABA 0x0547
+#define USB_DEVICE_ID_LED_DISPLAY 0x7000
+
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 5c925228847c..4ef73374a8f9 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -212,7 +212,6 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
__s32 value;
int ret = 0;
- memset(buffer, 0, buffer_size);
mutex_lock(&data->mutex);
report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
if (!report || (field_index >= report->maxfield)) {
@@ -256,6 +255,8 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
int buffer_index = 0;
int i;
+ memset(buffer, 0, buffer_size);
+
mutex_lock(&data->mutex);
report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
if (!report || (field_index >= report->maxfield) ||
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 7687c0875395..f405b07d0381 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1099,8 +1099,11 @@ struct sony_sc {
u8 led_delay_on[MAX_LEDS];
u8 led_delay_off[MAX_LEDS];
u8 led_count;
+ bool ds4_dongle_connected;
};
+static void sony_set_leds(struct sony_sc *sc);
+
static inline void sony_schedule_work(struct sony_sc *sc)
{
if (!sc->defer_initialization)
@@ -1430,6 +1433,31 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
return -EILSEQ;
}
}
+
+ /*
+ * In the case of a DS4 USB dongle, bit[2] of byte 31 indicates
+ * if a DS4 is actually connected (indicated by '0').
+ * For non-dongle, this bit is always 0 (connected).
+ */
+ if (sc->hdev->vendor == USB_VENDOR_ID_SONY &&
+ sc->hdev->product == USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) {
+ bool connected = (rd[31] & 0x04) ? false : true;
+
+ if (!sc->ds4_dongle_connected && connected) {
+ hid_info(sc->hdev, "DualShock 4 USB dongle: controller connected\n");
+ sony_set_leds(sc);
+ sc->ds4_dongle_connected = true;
+ } else if (sc->ds4_dongle_connected && !connected) {
+ hid_info(sc->hdev, "DualShock 4 USB dongle: controller disconnected\n");
+ sc->ds4_dongle_connected = false;
+ /* Return 0, so hidraw can get the report. */
+ return 0;
+ } else if (!sc->ds4_dongle_connected) {
+ /* Return 0, so hidraw can get the report. */
+ return 0;
+ }
+ }
+
dualshock4_parse_report(sc, rd, size);
}
@@ -2390,6 +2418,12 @@ static int sony_check_add(struct sony_sc *sc)
}
memcpy(sc->mac_address, &buf[1], sizeof(sc->mac_address));
+
+ snprintf(sc->hdev->uniq, sizeof(sc->hdev->uniq),
+ "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+ sc->mac_address[5], sc->mac_address[4],
+ sc->mac_address[3], sc->mac_address[2],
+ sc->mac_address[1], sc->mac_address[0]);
} else if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
(sc->quirks & NAVIGATION_CONTROLLER_USB)) {
buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL);
@@ -2548,7 +2582,7 @@ static int sony_input_configured(struct hid_device *hdev,
hid_err(sc->hdev,
"Unable to initialize multi-touch slots: %d\n",
ret);
- return ret;
+ goto err_stop;
}
sony_init_output_report(sc, dualshock4_send_output_report);
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index b3e01c82af05..e9d6cc7cdfc5 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -83,11 +83,13 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY, HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 322ed9272811..841f2428e84a 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -1036,7 +1036,7 @@ static const u8 lm90_temp_emerg_index[3] = {
};
static const u8 lm90_min_alarm_bits[3] = { 5, 3, 11 };
-static const u8 lm90_max_alarm_bits[3] = { 0, 4, 12 };
+static const u8 lm90_max_alarm_bits[3] = { 6, 4, 12 };
static const u8 lm90_crit_alarm_bits[3] = { 0, 1, 9 };
static const u8 lm90_emergency_alarm_bits[3] = { 15, 13, 14 };
static const u8 lm90_fault_bits[3] = { 0, 2, 10 };
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index c68bdb649005..ef8401ac1141 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -120,6 +120,8 @@ config HID_SENSOR_ACCEL_3D
config IIO_ST_ACCEL_3AXIS
tristate "STMicroelectronics accelerometers 3-Axis Driver"
depends on (I2C || SPI_MASTER) && SYSFS
+ depends on !SENSORS_LIS3_I2C
+ depends on !SENSORS_LIS3_SPI
select IIO_ST_SENSORS_CORE
select IIO_ST_ACCEL_I2C_3AXIS if (I2C)
select IIO_ST_ACCEL_SPI_3AXIS if (SPI_MASTER)
diff --git a/drivers/iio/accel/bmc150-accel-core.c b/drivers/iio/accel/bmc150-accel-core.c
index 59b380dbf27f..6b5d3be283c4 100644
--- a/drivers/iio/accel/bmc150-accel-core.c
+++ b/drivers/iio/accel/bmc150-accel-core.c
@@ -1638,7 +1638,8 @@ int bmc150_accel_core_probe(struct device *dev, struct regmap *regmap, int irq,
if (block_supported) {
indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
indio_dev->info = &bmc150_accel_info_fifo;
- indio_dev->buffer->attrs = bmc150_accel_fifo_attributes;
+ iio_buffer_set_attrs(indio_dev->buffer,
+ bmc150_accel_fifo_attributes);
}
}
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index ab1e238d5c75..ca5759c0c318 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -42,11 +42,13 @@ struct accel_3d_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX];
- u32 accel_val[ACCEL_3D_CHANNEL_MAX];
+ /* Reserve for 3 channels + padding + timestamp */
+ u32 accel_val[ACCEL_3D_CHANNEL_MAX + 3];
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
int value_offset;
+ int64_t timestamp;
};
static const u32 accel_3d_addresses[ACCEL_3D_CHANNEL_MAX] = {
@@ -87,6 +89,42 @@ static const struct iio_chan_spec accel_3d_channels[] = {
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
.scan_index = CHANNEL_SCAN_INDEX_Z,
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(3)
+};
+
+/* Channel definitions */
+static const struct iio_chan_spec gravity_channels[] = {
+ {
+ .type = IIO_GRAVITY,
+ .modified = 1,
+ .channel2 = IIO_MOD_X,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
+ .scan_index = CHANNEL_SCAN_INDEX_X,
+ }, {
+ .type = IIO_GRAVITY,
+ .modified = 1,
+ .channel2 = IIO_MOD_Y,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
+ .scan_index = CHANNEL_SCAN_INDEX_Y,
+ }, {
+ .type = IIO_GRAVITY,
+ .modified = 1,
+ .channel2 = IIO_MOD_Z,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
+ .scan_index = CHANNEL_SCAN_INDEX_Z,
}
};
@@ -111,6 +149,8 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
int report_id = -1;
u32 address;
int ret_type;
+ struct hid_sensor_hub_device *hsdev =
+ accel_state->common_attributes.hsdev;
*val = 0;
*val2 = 0;
@@ -122,8 +162,7 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
if (report_id >= 0)
*val = sensor_hub_input_attr_get_raw_value(
accel_state->common_attributes.hsdev,
- HID_USAGE_SENSOR_ACCEL_3D, address,
- report_id,
+ hsdev->usage, address, report_id,
SENSOR_HUB_SYNC);
else {
*val = 0;
@@ -192,11 +231,11 @@ static const struct iio_info accel_3d_info = {
};
/* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
- int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, void *data,
+ int len, int64_t timestamp)
{
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
- iio_push_to_buffers(indio_dev, data);
+ iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp);
}
/* Callback handler to send event after all samples are received and captured */
@@ -208,10 +247,17 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
struct accel_3d_state *accel_state = iio_priv(indio_dev);
dev_dbg(&indio_dev->dev, "accel_3d_proc_event\n");
- if (atomic_read(&accel_state->common_attributes.data_ready))
+ if (atomic_read(&accel_state->common_attributes.data_ready)) {
+ if (!accel_state->timestamp)
+ accel_state->timestamp = iio_get_time_ns(indio_dev);
+
hid_sensor_push_data(indio_dev,
- accel_state->accel_val,
- sizeof(accel_state->accel_val));
+ accel_state->accel_val,
+ sizeof(accel_state->accel_val),
+ accel_state->timestamp);
+
+ accel_state->timestamp = 0;
+ }
return 0;
}
@@ -236,6 +282,12 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev,
*(u32 *)raw_data;
ret = 0;
break;
+ case HID_USAGE_SENSOR_TIME_TIMESTAMP:
+ accel_state->timestamp =
+ hid_sensor_convert_timestamp(
+ &accel_state->common_attributes,
+ *(int64_t *)raw_data);
+ break;
default:
break;
}
@@ -272,7 +324,7 @@ static int accel_3d_parse_report(struct platform_device *pdev,
st->accel[2].index, st->accel[2].report_id);
st->scale_precision = hid_sensor_format_scale(
- HID_USAGE_SENSOR_ACCEL_3D,
+ hsdev->usage,
&st->accel[CHANNEL_SCAN_INDEX_X],
&st->scale_pre_decml, &st->scale_post_decml);
@@ -295,9 +347,12 @@ static int accel_3d_parse_report(struct platform_device *pdev,
static int hid_accel_3d_probe(struct platform_device *pdev)
{
int ret = 0;
- static const char *name = "accel_3d";
+ static const char *name;
struct iio_dev *indio_dev;
struct accel_3d_state *accel_state;
+ const struct iio_chan_spec *channel_spec;
+ int channel_size;
+
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
indio_dev = devm_iio_device_alloc(&pdev->dev,
@@ -311,24 +366,30 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
accel_state->common_attributes.hsdev = hsdev;
accel_state->common_attributes.pdev = pdev;
- ret = hid_sensor_parse_common_attributes(hsdev,
- HID_USAGE_SENSOR_ACCEL_3D,
+ if (hsdev->usage == HID_USAGE_SENSOR_ACCEL_3D) {
+ name = "accel_3d";
+ channel_spec = accel_3d_channels;
+ channel_size = sizeof(accel_3d_channels);
+ } else {
+ name = "gravity";
+ channel_spec = gravity_channels;
+ channel_size = sizeof(gravity_channels);
+ }
+ ret = hid_sensor_parse_common_attributes(hsdev, hsdev->usage,
&accel_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
return ret;
}
+ indio_dev->channels = kmemdup(channel_spec, channel_size, GFP_KERNEL);
- indio_dev->channels = kmemdup(accel_3d_channels,
- sizeof(accel_3d_channels), GFP_KERNEL);
if (!indio_dev->channels) {
dev_err(&pdev->dev, "failed to duplicate channels\n");
return -ENOMEM;
}
-
ret = accel_3d_parse_report(pdev, hsdev,
- (struct iio_chan_spec *)indio_dev->channels,
- HID_USAGE_SENSOR_ACCEL_3D, accel_state);
+ (struct iio_chan_spec *)indio_dev->channels,
+ hsdev->usage, accel_state);
if (ret) {
dev_err(&pdev->dev, "failed to setup attributes\n");
goto error_free_dev_mem;
@@ -363,7 +424,7 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
accel_state->callbacks.send_event = accel_3d_proc_event;
accel_state->callbacks.capture_sample = accel_3d_capture_sample;
accel_state->callbacks.pdev = pdev;
- ret = sensor_hub_register_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D,
+ ret = sensor_hub_register_callback(hsdev, hsdev->usage,
&accel_state->callbacks);
if (ret < 0) {
dev_err(&pdev->dev, "callback reg failed\n");
@@ -390,7 +451,7 @@ static int hid_accel_3d_remove(struct platform_device *pdev)
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct accel_3d_state *accel_state = iio_priv(indio_dev);
- sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_ACCEL_3D);
+ sensor_hub_remove_callback(hsdev, hsdev->usage);
iio_device_unregister(indio_dev);
hid_sensor_remove_trigger(&accel_state->common_attributes);
iio_triggered_buffer_cleanup(indio_dev);
@@ -404,6 +465,9 @@ static const struct platform_device_id hid_accel_3d_ids[] = {
/* Format: HID-SENSOR-usage_id_in_hex_lowercase */
.name = "HID-SENSOR-200073",
},
+ { /* gravity sensor */
+ .name = "HID-SENSOR-20007b",
+ },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, hid_accel_3d_ids);
diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
index f418c588af6a..eb6e3dc789b2 100644
--- a/drivers/iio/accel/mma8452.c
+++ b/drivers/iio/accel/mma8452.c
@@ -248,7 +248,7 @@ static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n,
return -EINVAL;
}
-static int mma8452_get_odr_index(struct mma8452_data *data)
+static unsigned int mma8452_get_odr_index(struct mma8452_data *data)
{
return (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >>
MMA8452_CTRL_DR_SHIFT;
@@ -260,7 +260,7 @@ static const int mma8452_samp_freq[8][2] = {
};
/* Datasheet table: step time "Relationship with the ODR" (sample frequency) */
-static const int mma8452_transient_time_step_us[4][8] = {
+static const unsigned int mma8452_transient_time_step_us[4][8] = {
{ 1250, 2500, 5000, 10000, 20000, 20000, 20000, 20000 }, /* normal */
{ 1250, 2500, 5000, 10000, 20000, 80000, 80000, 80000 }, /* l p l n */
{ 1250, 2500, 2500, 2500, 2500, 2500, 2500, 2500 }, /* high res*/
diff --git a/drivers/iio/accel/ssp_accel_sensor.c b/drivers/iio/accel/ssp_accel_sensor.c
index 31db00970fa0..dd6ece8f9239 100644
--- a/drivers/iio/accel/ssp_accel_sensor.c
+++ b/drivers/iio/accel/ssp_accel_sensor.c
@@ -15,6 +15,7 @@
#include <linux/iio/common/ssp_sensors.h>
#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -135,7 +136,7 @@ static int ssp_accel_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev);
- ret = iio_device_register(indio_dev);
+ ret = devm_iio_device_register(&pdev->dev, indio_dev);
if (ret < 0)
return ret;
@@ -145,21 +146,11 @@ static int ssp_accel_probe(struct platform_device *pdev)
return 0;
}
-static int ssp_accel_remove(struct platform_device *pdev)
-{
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
-
- iio_device_unregister(indio_dev);
-
- return 0;
-}
-
static struct platform_driver ssp_accel_driver = {
.driver = {
.name = SSP_ACCEL_NAME,
},
.probe = ssp_accel_probe,
- .remove = ssp_accel_remove,
};
module_platform_driver(ssp_accel_driver);
diff --git a/drivers/iio/accel/st_accel.h b/drivers/iio/accel/st_accel.h
index 7c231687109a..3ad44ce7ae82 100644
--- a/drivers/iio/accel/st_accel.h
+++ b/drivers/iio/accel/st_accel.h
@@ -14,6 +14,24 @@
#include <linux/types.h>
#include <linux/iio/common/st_sensors.h>
+enum st_accel_type {
+ LSM303DLH,
+ LSM303DLHC,
+ LIS3DH,
+ LSM330D,
+ LSM330DL,
+ LSM330DLC,
+ LIS331DLH,
+ LSM303DL,
+ LSM303DLM,
+ LSM330,
+ LSM303AGR,
+ LIS2DH12,
+ LIS3L02DQ,
+ LNG2DM,
+ ST_ACCEL_MAX,
+};
+
#define H3LIS331DL_DRIVER_NAME "h3lis331dl_accel"
#define LIS3LV02DL_ACCEL_DEV_NAME "lis3lv02dl_accel"
#define LSM303DLHC_ACCEL_DEV_NAME "lsm303dlhc_accel"
diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
index f6b6d42385e1..784670e2736b 100644
--- a/drivers/iio/accel/st_accel_core.c
+++ b/drivers/iio/accel/st_accel_core.c
@@ -353,12 +353,12 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
[0] = {
.num = ST_ACCEL_FS_AVL_2G,
.value = 0x00,
- .gain = IIO_G_TO_M_S_2(1024),
+ .gain = IIO_G_TO_M_S_2(1000),
},
[1] = {
.num = ST_ACCEL_FS_AVL_6G,
.value = 0x01,
- .gain = IIO_G_TO_M_S_2(340),
+ .gain = IIO_G_TO_M_S_2(3000),
},
},
},
@@ -366,6 +366,14 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.addr = 0x21,
.mask = 0x40,
},
+ /*
+ * Data Alignment Setting - needs to be set to get
+ * left-justified data like all other sensors.
+ */
+ .das = {
+ .addr = 0x21,
+ .mask = 0x01,
+ },
.drdy_irq = {
.addr = 0x21,
.mask_int1 = 0x04,
diff --git a/drivers/iio/accel/st_accel_i2c.c b/drivers/iio/accel/st_accel_i2c.c
index c0f8867aa1ea..543f0ad7fd7e 100644
--- a/drivers/iio/accel/st_accel_i2c.c
+++ b/drivers/iio/accel/st_accel_i2c.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
@@ -21,6 +22,11 @@
#ifdef CONFIG_OF
static const struct of_device_id st_accel_of_match[] = {
{
+ /* An older compatible */
+ .compatible = "st,lis3lv02d",
+ .data = LIS3LV02DL_ACCEL_DEV_NAME,
+ },
+ {
.compatible = "st,lis3lv02dl-accel",
.data = LIS3LV02DL_ACCEL_DEV_NAME,
},
@@ -95,25 +101,67 @@ MODULE_DEVICE_TABLE(of, st_accel_of_match);
#define st_accel_of_match NULL
#endif
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id st_accel_acpi_match[] = {
+ {"SMO8A90", LNG2DM},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, st_accel_acpi_match);
+#else
+#define st_accel_acpi_match NULL
+#endif
+
+static const struct i2c_device_id st_accel_id_table[] = {
+ { LSM303DLH_ACCEL_DEV_NAME, LSM303DLH },
+ { LSM303DLHC_ACCEL_DEV_NAME, LSM303DLHC },
+ { LIS3DH_ACCEL_DEV_NAME, LIS3DH },
+ { LSM330D_ACCEL_DEV_NAME, LSM330D },
+ { LSM330DL_ACCEL_DEV_NAME, LSM330DL },
+ { LSM330DLC_ACCEL_DEV_NAME, LSM330DLC },
+ { LIS331DLH_ACCEL_DEV_NAME, LIS331DLH },
+ { LSM303DL_ACCEL_DEV_NAME, LSM303DL },
+ { LSM303DLM_ACCEL_DEV_NAME, LSM303DLM },
+ { LSM330_ACCEL_DEV_NAME, LSM330 },
+ { LSM303AGR_ACCEL_DEV_NAME, LSM303AGR },
+ { LIS2DH12_ACCEL_DEV_NAME, LIS2DH12 },
+ { LIS3L02DQ_ACCEL_DEV_NAME, LIS3L02DQ },
+ { LNG2DM_ACCEL_DEV_NAME, LNG2DM },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
+
static int st_accel_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct st_sensor_data *adata;
- int err;
+ int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adata));
if (!indio_dev)
return -ENOMEM;
adata = iio_priv(indio_dev);
- st_sensors_of_i2c_probe(client, st_accel_of_match);
+
+ if (client->dev.of_node) {
+ st_sensors_of_i2c_probe(client, st_accel_of_match);
+ } else if (ACPI_HANDLE(&client->dev)) {
+ ret = st_sensors_match_acpi_device(&client->dev);
+ if ((ret < 0) || (ret >= ST_ACCEL_MAX))
+ return -ENODEV;
+
+ strncpy(client->name, st_accel_id_table[ret].name,
+ sizeof(client->name));
+ client->name[sizeof(client->name) - 1] = '\0';
+ } else if (!id)
+ return -ENODEV;
+
st_sensors_i2c_configure(indio_dev, client, adata);
- err = st_accel_common_probe(indio_dev);
- if (err < 0)
- return err;
+ ret = st_accel_common_probe(indio_dev);
+ if (ret < 0)
+ return ret;
return 0;
}
@@ -125,29 +173,11 @@ static int st_accel_i2c_remove(struct i2c_client *client)
return 0;
}
-static const struct i2c_device_id st_accel_id_table[] = {
- { LSM303DLH_ACCEL_DEV_NAME },
- { LSM303DLHC_ACCEL_DEV_NAME },
- { LIS3DH_ACCEL_DEV_NAME },
- { LSM330D_ACCEL_DEV_NAME },
- { LSM330DL_ACCEL_DEV_NAME },
- { LSM330DLC_ACCEL_DEV_NAME },
- { LIS331DLH_ACCEL_DEV_NAME },
- { LSM303DL_ACCEL_DEV_NAME },
- { LSM303DLM_ACCEL_DEV_NAME },
- { LSM330_ACCEL_DEV_NAME },
- { LSM303AGR_ACCEL_DEV_NAME },
- { LIS2DH12_ACCEL_DEV_NAME },
- { LIS3L02DQ_ACCEL_DEV_NAME },
- { LNG2DM_ACCEL_DEV_NAME },
- {},
-};
-MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
-
static struct i2c_driver st_accel_driver = {
.driver = {
.name = "st-accel-i2c",
.of_match_table = of_match_ptr(st_accel_of_match),
+ .acpi_match_table = ACPI_PTR(st_accel_acpi_match),
},
.probe = st_accel_i2c_probe,
.remove = st_accel_i2c_remove,
diff --git a/drivers/iio/accel/st_accel_spi.c b/drivers/iio/accel/st_accel_spi.c
index c25ac50d4600..29a15f27a51b 100644
--- a/drivers/iio/accel/st_accel_spi.c
+++ b/drivers/iio/accel/st_accel_spi.c
@@ -65,9 +65,18 @@ static const struct spi_device_id st_accel_id_table[] = {
};
MODULE_DEVICE_TABLE(spi, st_accel_id_table);
+#ifdef CONFIG_OF
+static const struct of_device_id lis302dl_spi_dt_ids[] = {
+ { .compatible = "st,lis302dl-spi" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, lis302dl_spi_dt_ids);
+#endif
+
static struct spi_driver st_accel_driver = {
.driver = {
.name = "st-accel-spi",
+ .of_match_table = of_match_ptr(lis302dl_spi_dt_ids),
},
.probe = st_accel_spi_probe,
.remove = st_accel_spi_remove,
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 38bc319904c4..e2a64fda99f6 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -247,6 +247,25 @@ config HI8435
This driver can also be built as a module. If so, the module will be
called hi8435.
+config HX711
+ tristate "AVIA HX711 ADC for weight cells"
+ depends on GPIOLIB
+ help
+ If you say yes here you get support for AVIA HX711 ADC which is used
+ for weigh cells
+
+ This driver uses two GPIOs, one acts as the clock and controls the
+ channel selection and gain, the other one is used for the measurement
+ data
+
+ Currently the raw value is read from the chip and delivered.
+ To get an actual weight one needs to subtract the
+ zero offset and multiply by a scale factor.
+ This should be done in userspace.
+
+ This driver can also be built as a module. If so, the module will be
+ called hx711.
+
config INA2XX_ADC
tristate "Texas Instruments INA2xx Power Monitors IIO driver"
depends on I2C && !SENSORS_INA2XX
@@ -307,6 +326,15 @@ config MAX1027
To compile this driver as a module, choose M here: the module will be
called max1027.
+config MAX11100
+ tristate "Maxim max11100 ADC driver"
+ depends on SPI_MASTER
+ help
+ Say yes here to build support for Maxim max11100 SPI ADC
+
+ To compile this driver as a module, choose M here: the module will be
+ called max11100.
+
config MAX1363
tristate "Maxim max1363 ADC driver"
depends on I2C
@@ -371,6 +399,18 @@ config MEN_Z188_ADC
This driver can also be built as a module. If so, the module will be
called men_z188_adc.
+config MESON_SARADC
+ tristate "Amlogic Meson SAR ADC driver"
+ default ARCH_MESON
+ depends on OF && COMMON_CLK && (ARCH_MESON || COMPILE_TEST)
+ select REGMAP_MMIO
+ help
+ Say yes here to build support for the SAR ADC found in Amlogic Meson
+ SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called meson_saradc.
+
config MXS_LRADC
tristate "Freescale i.MX23/i.MX28 LRADC"
depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM
@@ -430,6 +470,19 @@ config QCOM_SPMI_VADC
To compile this driver as a module, choose M here: the module will
be called qcom-spmi-vadc.
+config RCAR_GYRO_ADC
+ tristate "Renesas R-Car GyroADC driver"
+ depends on ARCH_RCAR_GEN2 || (ARM && COMPILE_TEST)
+ help
+ Say yes here to build support for the GyroADC found in Renesas
+ R-Car Gen2 SoCs. This block is a simple SPI offload engine for
+ reading data out of attached compatible ADCs in a round-robin
+ fashion. Up to 4 or 8 ADC channels are supported by this block,
+ depending on which ADCs are attached.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rcar-gyroadc.
+
config ROCKCHIP_SARADC
tristate "Rockchip SARADC driver"
depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
@@ -549,6 +602,19 @@ config TI_ADS1015
This driver can also be built as a module. If so, the module will be
called ti-ads1015.
+config TI_ADS7950
+ tristate "Texas Instruments ADS7950 ADC driver"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Texas Instruments ADS7950, ADS7951,
+ ADS7952, ADS7953, ADS7954, ADS7955, ADS7956, ADS7957, ADS7958, ADS7959.
+ ADS7960, ADS7961.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ti-ads7950.
+
config TI_ADS8688
tristate "Texas Instruments ADS8688"
depends on SPI && OF
@@ -561,7 +627,7 @@ config TI_ADS8688
config TI_AM335X_ADC
tristate "TI's AM335X ADC driver"
- depends on MFD_TI_AM335X_TSCADC
+ depends on MFD_TI_AM335X_TSCADC && HAS_DMA
select IIO_BUFFER
select IIO_KFIFO_BUF
help
@@ -571,6 +637,18 @@ config TI_AM335X_ADC
To compile this driver as a module, choose M here: the module will be
called ti_am335x_adc.
+config TI_TLC4541
+ tristate "Texas Instruments TLC4541 ADC driver"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Texas Instruments TLC4541 / TLC3541
+ ADC chips.
+
+ This driver can also be built as a module. If so, the module will be
+ called ti-tlc4541.
+
config TWL4030_MADC
tristate "TWL4030 MADC (Monitoring A/D Converter)"
depends on TWL4030_CORE
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index d36c4be8d1fc..d0012620cd1c 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -25,22 +25,26 @@ obj-$(CONFIG_ENVELOPE_DETECTOR) += envelope-detector.o
obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
obj-$(CONFIG_HI8435) += hi8435.o
+obj-$(CONFIG_HX711) += hx711.o
obj-$(CONFIG_IMX7D_ADC) += imx7d_adc.o
obj-$(CONFIG_INA2XX_ADC) += ina2xx-adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
obj-$(CONFIG_LPC18XX_ADC) += lpc18xx_adc.o
obj-$(CONFIG_LTC2485) += ltc2485.o
obj-$(CONFIG_MAX1027) += max1027.o
+obj-$(CONFIG_MAX11100) += max11100.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
+obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o
obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
+obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o
obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
obj-$(CONFIG_STX104) += stx104.o
obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
@@ -51,8 +55,10 @@ obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o
obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
+obj-$(CONFIG_TI_ADS7950) += ti-ads7950.o
obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
+obj-$(CONFIG_TI_TLC4541) += ti-tlc4541.o
obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
obj-$(CONFIG_VF610_ADC) += vf610_adc.o
diff --git a/drivers/iio/adc/axp288_adc.c b/drivers/iio/adc/axp288_adc.c
index 7fd24949c0c1..64799ad7ebad 100644
--- a/drivers/iio/adc/axp288_adc.c
+++ b/drivers/iio/adc/axp288_adc.c
@@ -28,8 +28,6 @@
#include <linux/iio/driver.h>
#define AXP288_ADC_EN_MASK 0xF1
-#define AXP288_ADC_TS_PIN_GPADC 0xF2
-#define AXP288_ADC_TS_PIN_ON 0xF3
enum axp288_adc_id {
AXP288_ADC_TS,
@@ -123,16 +121,6 @@ static int axp288_adc_read_channel(int *val, unsigned long address,
return IIO_VAL_INT;
}
-static int axp288_adc_set_ts(struct regmap *regmap, unsigned int mode,
- unsigned long address)
-{
- /* channels other than GPADC do not need to switch TS pin */
- if (address != AXP288_GP_ADC_H)
- return 0;
-
- return regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, mode);
-}
-
static int axp288_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
@@ -143,16 +131,7 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
mutex_lock(&indio_dev->mlock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
- if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_GPADC,
- chan->address)) {
- dev_err(&indio_dev->dev, "GPADC mode\n");
- ret = -EINVAL;
- break;
- }
ret = axp288_adc_read_channel(val, chan->address, info->regmap);
- if (axp288_adc_set_ts(info->regmap, AXP288_ADC_TS_PIN_ON,
- chan->address))
- dev_err(&indio_dev->dev, "TS pin restore\n");
break;
default:
ret = -EINVAL;
@@ -162,15 +141,6 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev,
return ret;
}
-static int axp288_adc_set_state(struct regmap *regmap)
-{
- /* ADC should be always enabled for internal FG to function */
- if (regmap_write(regmap, AXP288_ADC_TS_PIN_CTRL, AXP288_ADC_TS_PIN_ON))
- return -EIO;
-
- return regmap_write(regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
-}
-
static const struct iio_info axp288_adc_iio_info = {
.read_raw = &axp288_adc_read_raw,
.driver_module = THIS_MODULE,
@@ -199,7 +169,7 @@ static int axp288_adc_probe(struct platform_device *pdev)
* Set ADC to enabled state at all time, including system suspend.
* otherwise internal fuel gauge functionality may be affected.
*/
- ret = axp288_adc_set_state(axp20x->regmap);
+ ret = regmap_write(info->regmap, AXP20X_ADC_EN1, AXP288_ADC_EN_MASK);
if (ret) {
dev_err(&pdev->dev, "unable to enable ADC device\n");
return ret;
diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index c15756d7bf7f..ad1775b5f83c 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -632,7 +632,7 @@ static irqreturn_t exynos_ts_isr(int irq, void *dev_id)
input_report_key(info->input, BTN_TOUCH, 1);
input_sync(info->input);
- msleep(1);
+ usleep_range(1000, 1100);
};
writel(0, ADC_V1_CLRINTPNDNUP(info->regs));
diff --git a/drivers/iio/adc/fsl-imx25-gcq.c b/drivers/iio/adc/fsl-imx25-gcq.c
index 72b32c1ab257..ea264fa9e567 100644
--- a/drivers/iio/adc/fsl-imx25-gcq.c
+++ b/drivers/iio/adc/fsl-imx25-gcq.c
@@ -401,6 +401,7 @@ static const struct of_device_id mx25_gcq_ids[] = {
{ .compatible = "fsl,imx25-gcq", },
{ /* Sentinel */ }
};
+MODULE_DEVICE_TABLE(of, mx25_gcq_ids);
static struct platform_driver mx25_gcq_driver = {
.driver = {
diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c
new file mode 100644
index 000000000000..139639f73769
--- /dev/null
+++ b/drivers/iio/adc/hx711.c
@@ -0,0 +1,532 @@
+/*
+ * HX711: analog to digital converter for weight sensor module
+ *
+ * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
+
+/* gain to pulse and scale conversion */
+#define HX711_GAIN_MAX 3
+
+struct hx711_gain_to_scale {
+ int gain;
+ int gain_pulse;
+ int scale;
+ int channel;
+};
+
+/*
+ * .scale depends on AVDD which in turn is known as soon as the regulator
+ * is available
+ * therefore we set .scale in hx711_probe()
+ *
+ * channel A in documentation is channel 0 in source code
+ * channel B in documentation is channel 1 in source code
+ */
+static struct hx711_gain_to_scale hx711_gain_to_scale[HX711_GAIN_MAX] = {
+ { 128, 1, 0, 0 },
+ { 32, 2, 0, 1 },
+ { 64, 3, 0, 0 }
+};
+
+static int hx711_get_gain_to_pulse(int gain)
+{
+ int i;
+
+ for (i = 0; i < HX711_GAIN_MAX; i++)
+ if (hx711_gain_to_scale[i].gain == gain)
+ return hx711_gain_to_scale[i].gain_pulse;
+ return 1;
+}
+
+static int hx711_get_gain_to_scale(int gain)
+{
+ int i;
+
+ for (i = 0; i < HX711_GAIN_MAX; i++)
+ if (hx711_gain_to_scale[i].gain == gain)
+ return hx711_gain_to_scale[i].scale;
+ return 0;
+}
+
+static int hx711_get_scale_to_gain(int scale)
+{
+ int i;
+
+ for (i = 0; i < HX711_GAIN_MAX; i++)
+ if (hx711_gain_to_scale[i].scale == scale)
+ return hx711_gain_to_scale[i].gain;
+ return -EINVAL;
+}
+
+struct hx711_data {
+ struct device *dev;
+ struct gpio_desc *gpiod_pd_sck;
+ struct gpio_desc *gpiod_dout;
+ struct regulator *reg_avdd;
+ int gain_set; /* gain set on device */
+ int gain_chan_a; /* gain for channel A */
+ struct mutex lock;
+};
+
+static int hx711_cycle(struct hx711_data *hx711_data)
+{
+ int val;
+
+ /*
+ * if preempted for more then 60us while PD_SCK is high:
+ * hx711 is going in reset
+ * ==> measuring is false
+ */
+ preempt_disable();
+ gpiod_set_value(hx711_data->gpiod_pd_sck, 1);
+ val = gpiod_get_value(hx711_data->gpiod_dout);
+ /*
+ * here we are not waiting for 0.2 us as suggested by the datasheet,
+ * because the oscilloscope showed in a test scenario
+ * at least 1.15 us for PD_SCK high (T3 in datasheet)
+ * and 0.56 us for PD_SCK low on TI Sitara with 800 MHz
+ */
+ gpiod_set_value(hx711_data->gpiod_pd_sck, 0);
+ preempt_enable();
+
+ return val;
+}
+
+static int hx711_read(struct hx711_data *hx711_data)
+{
+ int i, ret;
+ int value = 0;
+ int val = gpiod_get_value(hx711_data->gpiod_dout);
+
+ /* we double check if it's really down */
+ if (val)
+ return -EIO;
+
+ for (i = 0; i < 24; i++) {
+ value <<= 1;
+ ret = hx711_cycle(hx711_data);
+ if (ret)
+ value++;
+ }
+
+ value ^= 0x800000;
+
+ for (i = 0; i < hx711_get_gain_to_pulse(hx711_data->gain_set); i++)
+ hx711_cycle(hx711_data);
+
+ return value;
+}
+
+static int hx711_wait_for_ready(struct hx711_data *hx711_data)
+{
+ int i, val;
+
+ /*
+ * a maximum reset cycle time of 56 ms was measured.
+ * we round it up to 100 ms
+ */
+ for (i = 0; i < 100; i++) {
+ val = gpiod_get_value(hx711_data->gpiod_dout);
+ if (!val)
+ break;
+ /* sleep at least 1 ms */
+ msleep(1);
+ }
+ if (val)
+ return -EIO;
+
+ return 0;
+}
+
+static int hx711_reset(struct hx711_data *hx711_data)
+{
+ int ret;
+ int val = gpiod_get_value(hx711_data->gpiod_dout);
+
+ if (val) {
+ /*
+ * an examination with the oszilloscope indicated
+ * that the first value read after the reset is not stable
+ * if we reset too short;
+ * the shorter the reset cycle
+ * the less reliable the first value after reset is;
+ * there were no problems encountered with a value
+ * of 10 ms or higher
+ */
+ gpiod_set_value(hx711_data->gpiod_pd_sck, 1);
+ msleep(10);
+ gpiod_set_value(hx711_data->gpiod_pd_sck, 0);
+
+ ret = hx711_wait_for_ready(hx711_data);
+ if (ret)
+ return ret;
+ /*
+ * after a reset the gain is 128 so we do a dummy read
+ * to set the gain for the next read
+ */
+ ret = hx711_read(hx711_data);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * after a dummy read we need to wait vor readiness
+ * for not mixing gain pulses with the clock
+ */
+ ret = hx711_wait_for_ready(hx711_data);
+ if (ret)
+ return ret;
+ }
+
+ return val;
+}
+
+static int hx711_set_gain_for_channel(struct hx711_data *hx711_data, int chan)
+{
+ int ret;
+
+ if (chan == 0) {
+ if (hx711_data->gain_set == 32) {
+ hx711_data->gain_set = hx711_data->gain_chan_a;
+
+ ret = hx711_read(hx711_data);
+ if (ret < 0)
+ return ret;
+
+ ret = hx711_wait_for_ready(hx711_data);
+ if (ret)
+ return ret;
+ }
+ } else {
+ if (hx711_data->gain_set != 32) {
+ hx711_data->gain_set = 32;
+
+ ret = hx711_read(hx711_data);
+ if (ret < 0)
+ return ret;
+
+ ret = hx711_wait_for_ready(hx711_data);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int hx711_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long mask)
+{
+ struct hx711_data *hx711_data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ mutex_lock(&hx711_data->lock);
+
+ /*
+ * hx711_reset() must be called from here
+ * because it could be calling hx711_read() by itself
+ */
+ if (hx711_reset(hx711_data)) {
+ mutex_unlock(&hx711_data->lock);
+ dev_err(hx711_data->dev, "reset failed!");
+ return -EIO;
+ }
+
+ ret = hx711_set_gain_for_channel(hx711_data, chan->channel);
+ if (ret < 0) {
+ mutex_unlock(&hx711_data->lock);
+ return ret;
+ }
+
+ *val = hx711_read(hx711_data);
+
+ mutex_unlock(&hx711_data->lock);
+
+ if (*val < 0)
+ return *val;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ mutex_lock(&hx711_data->lock);
+
+ *val2 = hx711_get_gain_to_scale(hx711_data->gain_set);
+
+ mutex_unlock(&hx711_data->lock);
+
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int hx711_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val,
+ int val2,
+ long mask)
+{
+ struct hx711_data *hx711_data = iio_priv(indio_dev);
+ int ret;
+ int gain;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ /*
+ * a scale greater than 1 mV per LSB is not possible
+ * with the HX711, therefore val must be 0
+ */
+ if (val != 0)
+ return -EINVAL;
+
+ mutex_lock(&hx711_data->lock);
+
+ gain = hx711_get_scale_to_gain(val2);
+ if (gain < 0) {
+ mutex_unlock(&hx711_data->lock);
+ return gain;
+ }
+
+ if (gain != hx711_data->gain_set) {
+ hx711_data->gain_set = gain;
+ if (gain != 32)
+ hx711_data->gain_chan_a = gain;
+
+ ret = hx711_read(hx711_data);
+ if (ret < 0) {
+ mutex_unlock(&hx711_data->lock);
+ return ret;
+ }
+ }
+
+ mutex_unlock(&hx711_data->lock);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int hx711_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ long mask)
+{
+ return IIO_VAL_INT_PLUS_NANO;
+}
+
+static ssize_t hx711_scale_available_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr);
+ int channel = iio_attr->address;
+ int i, len = 0;
+
+ for (i = 0; i < HX711_GAIN_MAX; i++)
+ if (hx711_gain_to_scale[i].channel == channel)
+ len += sprintf(buf + len, "0.%09d ",
+ hx711_gain_to_scale[i].scale);
+
+ len += sprintf(buf + len, "\n");
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(in_voltage0_scale_available, S_IRUGO,
+ hx711_scale_available_show, NULL, 0);
+
+static IIO_DEVICE_ATTR(in_voltage1_scale_available, S_IRUGO,
+ hx711_scale_available_show, NULL, 1);
+
+static struct attribute *hx711_attributes[] = {
+ &iio_dev_attr_in_voltage0_scale_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage1_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static struct attribute_group hx711_attribute_group = {
+ .attrs = hx711_attributes,
+};
+
+static const struct iio_info hx711_iio_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = hx711_read_raw,
+ .write_raw = hx711_write_raw,
+ .write_raw_get_fmt = hx711_write_raw_get_fmt,
+ .attrs = &hx711_attribute_group,
+};
+
+static const struct iio_chan_spec hx711_chan_spec[] = {
+ {
+ .type = IIO_VOLTAGE,
+ .channel = 0,
+ .indexed = 1,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ },
+ {
+ .type = IIO_VOLTAGE,
+ .channel = 1,
+ .indexed = 1,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+ },
+};
+
+static int hx711_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct hx711_data *hx711_data;
+ struct iio_dev *indio_dev;
+ int ret;
+ int i;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(struct hx711_data));
+ if (!indio_dev) {
+ dev_err(dev, "failed to allocate IIO device\n");
+ return -ENOMEM;
+ }
+
+ hx711_data = iio_priv(indio_dev);
+ hx711_data->dev = dev;
+
+ mutex_init(&hx711_data->lock);
+
+ /*
+ * PD_SCK stands for power down and serial clock input of HX711
+ * in the driver it is an output
+ */
+ hx711_data->gpiod_pd_sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW);
+ if (IS_ERR(hx711_data->gpiod_pd_sck)) {
+ dev_err(dev, "failed to get sck-gpiod: err=%ld\n",
+ PTR_ERR(hx711_data->gpiod_pd_sck));
+ return PTR_ERR(hx711_data->gpiod_pd_sck);
+ }
+
+ /*
+ * DOUT stands for serial data output of HX711
+ * for the driver it is an input
+ */
+ hx711_data->gpiod_dout = devm_gpiod_get(dev, "dout", GPIOD_IN);
+ if (IS_ERR(hx711_data->gpiod_dout)) {
+ dev_err(dev, "failed to get dout-gpiod: err=%ld\n",
+ PTR_ERR(hx711_data->gpiod_dout));
+ return PTR_ERR(hx711_data->gpiod_dout);
+ }
+
+ hx711_data->reg_avdd = devm_regulator_get(dev, "avdd");
+ if (IS_ERR(hx711_data->reg_avdd))
+ return PTR_ERR(hx711_data->reg_avdd);
+
+ ret = regulator_enable(hx711_data->reg_avdd);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * with
+ * full scale differential input range: AVDD / GAIN
+ * full scale output data: 2^24
+ * we can say:
+ * AVDD / GAIN = 2^24
+ * therefore:
+ * 1 LSB = AVDD / GAIN / 2^24
+ * AVDD is in uV, but we need 10^-9 mV
+ * approximately to fit into a 32 bit number:
+ * 1 LSB = (AVDD * 100) / GAIN / 1678 [10^-9 mV]
+ */
+ ret = regulator_get_voltage(hx711_data->reg_avdd);
+ if (ret < 0) {
+ regulator_disable(hx711_data->reg_avdd);
+ return ret;
+ }
+ /* we need 10^-9 mV */
+ ret *= 100;
+
+ for (i = 0; i < HX711_GAIN_MAX; i++)
+ hx711_gain_to_scale[i].scale =
+ ret / hx711_gain_to_scale[i].gain / 1678;
+
+ hx711_data->gain_set = 128;
+ hx711_data->gain_chan_a = 128;
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ indio_dev->name = "hx711";
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->info = &hx711_iio_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = hx711_chan_spec;
+ indio_dev->num_channels = ARRAY_SIZE(hx711_chan_spec);
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(dev, "Couldn't register the device\n");
+ regulator_disable(hx711_data->reg_avdd);
+ }
+
+ return ret;
+}
+
+static int hx711_remove(struct platform_device *pdev)
+{
+ struct hx711_data *hx711_data;
+ struct iio_dev *indio_dev;
+
+ indio_dev = platform_get_drvdata(pdev);
+ hx711_data = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+
+ regulator_disable(hx711_data->reg_avdd);
+
+ return 0;
+}
+
+static const struct of_device_id of_hx711_match[] = {
+ { .compatible = "avia,hx711", },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, of_hx711_match);
+
+static struct platform_driver hx711_driver = {
+ .probe = hx711_probe,
+ .remove = hx711_remove,
+ .driver = {
+ .name = "hx711-gpio",
+ .of_match_table = of_hx711_match,
+ },
+};
+
+module_platform_driver(hx711_driver);
+
+MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
+MODULE_DESCRIPTION("HX711 bitbanging driver - ADC for weight cells");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:hx711-gpio");
+
diff --git a/drivers/iio/adc/ina2xx-adc.c b/drivers/iio/adc/ina2xx-adc.c
index 59b7d76e1ad2..3263231276ca 100644
--- a/drivers/iio/adc/ina2xx-adc.c
+++ b/drivers/iio/adc/ina2xx-adc.c
@@ -22,6 +22,8 @@
#include <linux/delay.h>
#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/sysfs.h>
#include <linux/kthread.h>
diff --git a/drivers/iio/adc/max11100.c b/drivers/iio/adc/max11100.c
new file mode 100644
index 000000000000..a088cf99bfe1
--- /dev/null
+++ b/drivers/iio/adc/max11100.c
@@ -0,0 +1,181 @@
+/*
+ * iio/adc/max11100.c
+ * Maxim max11100 ADC Driver with IIO interface
+ *
+ * Copyright (C) 2016-17 Renesas Electronics Corporation
+ * Copyright (C) 2016-17 Jacopo Mondi
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/driver.h>
+
+/*
+ * LSB is the ADC single digital step
+ * 1 LSB = (vref_mv / 2 ^ 16)
+ *
+ * LSB is used to calculate analog voltage value
+ * from the number of ADC steps count
+ *
+ * Ain = (count * LSB)
+ */
+#define MAX11100_LSB_DIV (1 << 16)
+
+struct max11100_state {
+ struct regulator *vref_reg;
+ struct spi_device *spi;
+
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+ u8 buffer[3] ____cacheline_aligned;
+};
+
+static struct iio_chan_spec max11100_channels[] = {
+ { /* [0] */
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ },
+};
+
+static int max11100_read_single(struct iio_dev *indio_dev, int *val)
+{
+ int ret;
+ struct max11100_state *state = iio_priv(indio_dev);
+
+ ret = spi_read(state->spi, state->buffer, sizeof(state->buffer));
+ if (ret) {
+ dev_err(&indio_dev->dev, "SPI transfer failed\n");
+ return ret;
+ }
+
+ /* the first 8 bits sent out from ADC must be 0s */
+ if (state->buffer[0]) {
+ dev_err(&indio_dev->dev, "Invalid value: buffer[0] != 0\n");
+ return -EINVAL;
+ }
+
+ *val = (state->buffer[1] << 8) | state->buffer[2];
+
+ return 0;
+}
+
+static int max11100_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long info)
+{
+ int ret, vref_uv;
+ struct max11100_state *state = iio_priv(indio_dev);
+
+ switch (info) {
+ case IIO_CHAN_INFO_RAW:
+ ret = max11100_read_single(indio_dev, val);
+ if (ret)
+ return ret;
+
+ return IIO_VAL_INT;
+
+ case IIO_CHAN_INFO_SCALE:
+ vref_uv = regulator_get_voltage(state->vref_reg);
+ if (vref_uv < 0)
+ /* dummy regulator "get_voltage" returns -EINVAL */
+ return -EINVAL;
+
+ *val = vref_uv / 1000;
+ *val2 = MAX11100_LSB_DIV;
+ return IIO_VAL_FRACTIONAL;
+ }
+
+ return -EINVAL;
+}
+
+static const struct iio_info max11100_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = max11100_read_raw,
+};
+
+static int max11100_probe(struct spi_device *spi)
+{
+ int ret;
+ struct iio_dev *indio_dev;
+ struct max11100_state *state;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, indio_dev);
+
+ state = iio_priv(indio_dev);
+ state->spi = spi;
+
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->dev.of_node = spi->dev.of_node;
+ indio_dev->name = "max11100";
+ indio_dev->info = &max11100_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = max11100_channels,
+ indio_dev->num_channels = ARRAY_SIZE(max11100_channels),
+
+ state->vref_reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(state->vref_reg))
+ return PTR_ERR(state->vref_reg);
+
+ ret = regulator_enable(state->vref_reg);
+ if (ret)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto disable_regulator;
+
+ return 0;
+
+disable_regulator:
+ regulator_disable(state->vref_reg);
+
+ return ret;
+}
+
+static int max11100_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct max11100_state *state = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ regulator_disable(state->vref_reg);
+
+ return 0;
+}
+
+static const struct of_device_id max11100_ids[] = {
+ {.compatible = "maxim,max11100"},
+ { },
+};
+MODULE_DEVICE_TABLE(of, max11100_ids);
+
+static struct spi_driver max11100_driver = {
+ .driver = {
+ .name = "max11100",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(max11100_ids),
+ },
+ .probe = max11100_probe,
+ .remove = max11100_remove,
+};
+
+module_spi_driver(max11100_driver);
+
+MODULE_AUTHOR("Jacopo Mondi <jacopo@jmondi.org>");
+MODULE_DESCRIPTION("Maxim max11100 ADC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c
index 841a13c9b6ea..c6c12feb4a08 100644
--- a/drivers/iio/adc/max1363.c
+++ b/drivers/iio/adc/max1363.c
@@ -1567,6 +1567,7 @@ static const struct of_device_id max1363_of_match[] = {
MAX1363_COMPATIBLE("maxim,max11647", max11647),
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, max1363_of_match);
#endif
static int max1363_probe(struct i2c_client *client,
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
new file mode 100644
index 000000000000..89def6034f40
--- /dev/null
+++ b/drivers/iio/adc/meson_saradc.c
@@ -0,0 +1,922 @@
+/*
+ * Amlogic Meson Successive Approximation Register (SAR) A/D Converter
+ *
+ * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+
+#define MESON_SAR_ADC_REG0 0x00
+ #define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31)
+ #define MESON_SAR_ADC_REG0_BUSY_MASK GENMASK(30, 28)
+ #define MESON_SAR_ADC_REG0_DELTA_BUSY BIT(30)
+ #define MESON_SAR_ADC_REG0_AVG_BUSY BIT(29)
+ #define MESON_SAR_ADC_REG0_SAMPLE_BUSY BIT(28)
+ #define MESON_SAR_ADC_REG0_FIFO_FULL BIT(27)
+ #define MESON_SAR_ADC_REG0_FIFO_EMPTY BIT(26)
+ #define MESON_SAR_ADC_REG0_FIFO_COUNT_MASK GENMASK(25, 21)
+ #define MESON_SAR_ADC_REG0_ADC_BIAS_CTRL_MASK GENMASK(20, 19)
+ #define MESON_SAR_ADC_REG0_CURR_CHAN_ID_MASK GENMASK(18, 16)
+ #define MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL BIT(15)
+ #define MESON_SAR_ADC_REG0_SAMPLING_STOP BIT(14)
+ #define MESON_SAR_ADC_REG0_CHAN_DELTA_EN_MASK GENMASK(13, 12)
+ #define MESON_SAR_ADC_REG0_DETECT_IRQ_POL BIT(10)
+ #define MESON_SAR_ADC_REG0_DETECT_IRQ_EN BIT(9)
+ #define MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK GENMASK(8, 4)
+ #define MESON_SAR_ADC_REG0_FIFO_IRQ_EN BIT(3)
+ #define MESON_SAR_ADC_REG0_SAMPLING_START BIT(2)
+ #define MESON_SAR_ADC_REG0_CONTINUOUS_EN BIT(1)
+ #define MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE BIT(0)
+
+#define MESON_SAR_ADC_CHAN_LIST 0x04
+ #define MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK GENMASK(26, 24)
+ #define MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(_chan) \
+ (GENMASK(2, 0) << ((_chan) * 3))
+
+#define MESON_SAR_ADC_AVG_CNTL 0x08
+ #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(_chan) \
+ (16 + ((_chan) * 2))
+ #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(_chan) \
+ (GENMASK(17, 16) << ((_chan) * 2))
+ #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(_chan) \
+ (0 + ((_chan) * 2))
+ #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(_chan) \
+ (GENMASK(1, 0) << ((_chan) * 2))
+
+#define MESON_SAR_ADC_REG3 0x0c
+ #define MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY BIT(31)
+ #define MESON_SAR_ADC_REG3_CLK_EN BIT(30)
+ #define MESON_SAR_ADC_REG3_BL30_INITIALIZED BIT(28)
+ #define MESON_SAR_ADC_REG3_CTRL_CONT_RING_COUNTER_EN BIT(27)
+ #define MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE BIT(26)
+ #define MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK GENMASK(25, 23)
+ #define MESON_SAR_ADC_REG3_DETECT_EN BIT(22)
+ #define MESON_SAR_ADC_REG3_ADC_EN BIT(21)
+ #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18)
+ #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16)
+ #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10
+ #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5
+ #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8)
+ #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0)
+
+#define MESON_SAR_ADC_DELAY 0x10
+ #define MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK GENMASK(25, 24)
+ #define MESON_SAR_ADC_DELAY_BL30_BUSY BIT(15)
+ #define MESON_SAR_ADC_DELAY_KERNEL_BUSY BIT(14)
+ #define MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK GENMASK(23, 16)
+ #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK GENMASK(9, 8)
+ #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK GENMASK(7, 0)
+
+#define MESON_SAR_ADC_LAST_RD 0x14
+ #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL1_MASK GENMASK(23, 16)
+ #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL0_MASK GENMASK(9, 0)
+
+#define MESON_SAR_ADC_FIFO_RD 0x18
+ #define MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK GENMASK(14, 12)
+ #define MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK GENMASK(11, 0)
+
+#define MESON_SAR_ADC_AUX_SW 0x1c
+ #define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_MASK(_chan) \
+ (GENMASK(10, 8) << (((_chan) - 2) * 2))
+ #define MESON_SAR_ADC_AUX_SW_VREF_P_MUX BIT(6)
+ #define MESON_SAR_ADC_AUX_SW_VREF_N_MUX BIT(5)
+ #define MESON_SAR_ADC_AUX_SW_MODE_SEL BIT(4)
+ #define MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW BIT(3)
+ #define MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW BIT(2)
+ #define MESON_SAR_ADC_AUX_SW_YM_DRIVE_SW BIT(1)
+ #define MESON_SAR_ADC_AUX_SW_XM_DRIVE_SW BIT(0)
+
+#define MESON_SAR_ADC_CHAN_10_SW 0x20
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK GENMASK(25, 23)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_P_MUX BIT(22)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_N_MUX BIT(21)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MODE_SEL BIT(20)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YP_DRIVE_SW BIT(19)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XP_DRIVE_SW BIT(18)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YM_DRIVE_SW BIT(17)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XM_DRIVE_SW BIT(16)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK GENMASK(9, 7)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_P_MUX BIT(6)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_N_MUX BIT(5)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MODE_SEL BIT(4)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YP_DRIVE_SW BIT(3)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XP_DRIVE_SW BIT(2)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YM_DRIVE_SW BIT(1)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XM_DRIVE_SW BIT(0)
+
+#define MESON_SAR_ADC_DETECT_IDLE_SW 0x24
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_SW_EN BIT(26)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK GENMASK(25, 23)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_P_MUX BIT(22)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_N_MUX BIT(21)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_SEL BIT(20)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YP_DRIVE_SW BIT(19)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XP_DRIVE_SW BIT(18)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YM_DRIVE_SW BIT(17)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XM_DRIVE_SW BIT(16)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK GENMASK(9, 7)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_P_MUX BIT(6)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_N_MUX BIT(5)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_SEL BIT(4)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YP_DRIVE_SW BIT(3)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XP_DRIVE_SW BIT(2)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YM_DRIVE_SW BIT(1)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XM_DRIVE_SW BIT(0)
+
+#define MESON_SAR_ADC_DELTA_10 0x28
+ #define MESON_SAR_ADC_DELTA_10_TEMP_SEL BIT(27)
+ #define MESON_SAR_ADC_DELTA_10_TS_REVE1 BIT(26)
+ #define MESON_SAR_ADC_DELTA_10_CHAN1_DELTA_VALUE_MASK GENMASK(25, 16)
+ #define MESON_SAR_ADC_DELTA_10_TS_REVE0 BIT(15)
+ #define MESON_SAR_ADC_DELTA_10_TS_C_SHIFT 11
+ #define MESON_SAR_ADC_DELTA_10_TS_C_MASK GENMASK(14, 11)
+ #define MESON_SAR_ADC_DELTA_10_TS_VBG_EN BIT(10)
+ #define MESON_SAR_ADC_DELTA_10_CHAN0_DELTA_VALUE_MASK GENMASK(9, 0)
+
+/*
+ * NOTE: registers from here are undocumented (the vendor Linux kernel driver
+ * and u-boot source served as reference). These only seem to be relevant on
+ * GXBB and newer.
+ */
+#define MESON_SAR_ADC_REG11 0x2c
+ #define MESON_SAR_ADC_REG11_BANDGAP_EN BIT(13)
+
+#define MESON_SAR_ADC_REG13 0x34
+ #define MESON_SAR_ADC_REG13_12BIT_CALIBRATION_MASK GENMASK(13, 8)
+
+#define MESON_SAR_ADC_MAX_FIFO_SIZE 32
+
+#define MESON_SAR_ADC_CHAN(_chan) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = _chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_AVERAGE_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .datasheet_name = "SAR_ADC_CH"#_chan, \
+}
+
+/*
+ * TODO: the hardware supports IIO_TEMP for channel 6 as well which is
+ * currently not supported by this driver.
+ */
+static const struct iio_chan_spec meson_sar_adc_iio_channels[] = {
+ MESON_SAR_ADC_CHAN(0),
+ MESON_SAR_ADC_CHAN(1),
+ MESON_SAR_ADC_CHAN(2),
+ MESON_SAR_ADC_CHAN(3),
+ MESON_SAR_ADC_CHAN(4),
+ MESON_SAR_ADC_CHAN(5),
+ MESON_SAR_ADC_CHAN(6),
+ MESON_SAR_ADC_CHAN(7),
+ IIO_CHAN_SOFT_TIMESTAMP(8),
+};
+
+enum meson_sar_adc_avg_mode {
+ NO_AVERAGING = 0x0,
+ MEAN_AVERAGING = 0x1,
+ MEDIAN_AVERAGING = 0x2,
+};
+
+enum meson_sar_adc_num_samples {
+ ONE_SAMPLE = 0x0,
+ TWO_SAMPLES = 0x1,
+ FOUR_SAMPLES = 0x2,
+ EIGHT_SAMPLES = 0x3,
+};
+
+enum meson_sar_adc_chan7_mux_sel {
+ CHAN7_MUX_VSS = 0x0,
+ CHAN7_MUX_VDD_DIV4 = 0x1,
+ CHAN7_MUX_VDD_DIV2 = 0x2,
+ CHAN7_MUX_VDD_MUL3_DIV4 = 0x3,
+ CHAN7_MUX_VDD = 0x4,
+ CHAN7_MUX_CH7_INPUT = 0x7,
+};
+
+struct meson_sar_adc_data {
+ unsigned int resolution;
+ const char *name;
+};
+
+struct meson_sar_adc_priv {
+ struct regmap *regmap;
+ struct regulator *vref;
+ const struct meson_sar_adc_data *data;
+ struct clk *clkin;
+ struct clk *core_clk;
+ struct clk *sana_clk;
+ struct clk *adc_sel_clk;
+ struct clk *adc_clk;
+ struct clk_gate clk_gate;
+ struct clk *adc_div_clk;
+ struct clk_divider clk_div;
+};
+
+static const struct regmap_config meson_sar_adc_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = MESON_SAR_ADC_REG13,
+};
+
+static unsigned int meson_sar_adc_get_fifo_count(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ u32 regval;
+
+ regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval);
+
+ return FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval);
+}
+
+static int meson_sar_adc_wait_busy_clear(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int regval, timeout = 10000;
+
+ /*
+ * NOTE: we need a small delay before reading the status, otherwise
+ * the sample engine may not have started internally (which would
+ * seem to us that sampling is already finished).
+ */
+ do {
+ udelay(1);
+ regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval);
+ } while (FIELD_GET(MESON_SAR_ADC_REG0_BUSY_MASK, regval) && timeout--);
+
+ if (timeout < 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int ret, regval, fifo_chan, fifo_val, sum = 0, count = 0;
+
+ ret = meson_sar_adc_wait_busy_clear(indio_dev);
+ if (ret)
+ return ret;
+
+ while (meson_sar_adc_get_fifo_count(indio_dev) > 0 &&
+ count < MESON_SAR_ADC_MAX_FIFO_SIZE) {
+ regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &regval);
+
+ fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK,
+ regval);
+ if (fifo_chan != chan->channel)
+ continue;
+
+ fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK,
+ regval);
+ fifo_val &= (BIT(priv->data->resolution) - 1);
+
+ sum += fifo_val;
+ count++;
+ }
+
+ if (!count)
+ return -ENOENT;
+
+ *val = sum / count;
+
+ return 0;
+}
+
+static void meson_sar_adc_set_averaging(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum meson_sar_adc_avg_mode mode,
+ enum meson_sar_adc_num_samples samples)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int val, channel = chan->channel;
+
+ val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
+ MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(channel),
+ val);
+
+ val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
+ MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(channel), val);
+}
+
+static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ u32 regval;
+
+ /*
+ * the SAR ADC engine allows sampling multiple channels at the same
+ * time. to keep it simple we're only working with one *internal*
+ * channel, which starts counting at index 0 (which means: count = 1).
+ */
+ regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
+ MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval);
+
+ /* map channel index 0 to the channel which we want to read */
+ regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0),
+ chan->channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
+ MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), regval);
+
+ regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
+ chan->channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
+ MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
+ regval);
+
+ regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
+ chan->channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
+ MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
+ regval);
+
+ if (chan->channel == 6)
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10,
+ MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0);
+}
+
+static void meson_sar_adc_set_chan7_mux(struct iio_dev *indio_dev,
+ enum meson_sar_adc_chan7_mux_sel sel)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ u32 regval;
+
+ regval = FIELD_PREP(MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval);
+
+ usleep_range(10, 20);
+}
+
+static void meson_sar_adc_start_sample_engine(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE,
+ MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_SAMPLING_START,
+ MESON_SAR_ADC_REG0_SAMPLING_START);
+}
+
+static void meson_sar_adc_stop_sample_engine(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_SAMPLING_STOP,
+ MESON_SAR_ADC_REG0_SAMPLING_STOP);
+
+ /* wait until all modules are stopped */
+ meson_sar_adc_wait_busy_clear(indio_dev);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0);
+}
+
+static int meson_sar_adc_lock(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int val, timeout = 10000;
+
+ mutex_lock(&indio_dev->mlock);
+
+ /* prevent BL30 from using the SAR ADC while we are using it */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_KERNEL_BUSY,
+ MESON_SAR_ADC_DELAY_KERNEL_BUSY);
+
+ /* wait until BL30 releases it's lock (so we can use the SAR ADC) */
+ do {
+ udelay(1);
+ regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
+ } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--);
+
+ if (timeout < 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+
+ /* allow BL30 to use the SAR ADC again */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
+
+ mutex_unlock(&indio_dev->mlock);
+}
+
+static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int count;
+
+ for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) {
+ if (!meson_sar_adc_get_fifo_count(indio_dev))
+ break;
+
+ regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, 0);
+ }
+}
+
+static int meson_sar_adc_get_sample(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum meson_sar_adc_avg_mode avg_mode,
+ enum meson_sar_adc_num_samples avg_samples,
+ int *val)
+{
+ int ret;
+
+ ret = meson_sar_adc_lock(indio_dev);
+ if (ret)
+ return ret;
+
+ /* clear the FIFO to make sure we're not reading old values */
+ meson_sar_adc_clear_fifo(indio_dev);
+
+ meson_sar_adc_set_averaging(indio_dev, chan, avg_mode, avg_samples);
+
+ meson_sar_adc_enable_channel(indio_dev, chan);
+
+ meson_sar_adc_start_sample_engine(indio_dev);
+ ret = meson_sar_adc_read_raw_sample(indio_dev, chan, val);
+ meson_sar_adc_stop_sample_engine(indio_dev);
+
+ meson_sar_adc_unlock(indio_dev);
+
+ if (ret) {
+ dev_warn(indio_dev->dev.parent,
+ "failed to read sample for channel %d: %d\n",
+ chan->channel, ret);
+ return ret;
+ }
+
+ return IIO_VAL_INT;
+}
+
+static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long mask)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ return meson_sar_adc_get_sample(indio_dev, chan, NO_AVERAGING,
+ ONE_SAMPLE, val);
+ break;
+
+ case IIO_CHAN_INFO_AVERAGE_RAW:
+ return meson_sar_adc_get_sample(indio_dev, chan,
+ MEAN_AVERAGING, EIGHT_SAMPLES,
+ val);
+ break;
+
+ case IIO_CHAN_INFO_SCALE:
+ ret = regulator_get_voltage(priv->vref);
+ if (ret < 0) {
+ dev_err(indio_dev->dev.parent,
+ "failed to get vref voltage: %d\n", ret);
+ return ret;
+ }
+
+ *val = ret / 1000;
+ *val2 = priv->data->resolution;
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int meson_sar_adc_clk_init(struct iio_dev *indio_dev,
+ void __iomem *base)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ struct clk_init_data init;
+ const char *clk_parents[1];
+
+ init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_div",
+ of_node_full_name(indio_dev->dev.of_node));
+ init.flags = 0;
+ init.ops = &clk_divider_ops;
+ clk_parents[0] = __clk_get_name(priv->clkin);
+ init.parent_names = clk_parents;
+ init.num_parents = 1;
+
+ priv->clk_div.reg = base + MESON_SAR_ADC_REG3;
+ priv->clk_div.shift = MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT;
+ priv->clk_div.width = MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH;
+ priv->clk_div.hw.init = &init;
+ priv->clk_div.flags = 0;
+
+ priv->adc_div_clk = devm_clk_register(&indio_dev->dev,
+ &priv->clk_div.hw);
+ if (WARN_ON(IS_ERR(priv->adc_div_clk)))
+ return PTR_ERR(priv->adc_div_clk);
+
+ init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_en",
+ of_node_full_name(indio_dev->dev.of_node));
+ init.flags = CLK_SET_RATE_PARENT;
+ init.ops = &clk_gate_ops;
+ clk_parents[0] = __clk_get_name(priv->adc_div_clk);
+ init.parent_names = clk_parents;
+ init.num_parents = 1;
+
+ priv->clk_gate.reg = base + MESON_SAR_ADC_REG3;
+ priv->clk_gate.bit_idx = fls(MESON_SAR_ADC_REG3_CLK_EN);
+ priv->clk_gate.hw.init = &init;
+
+ priv->adc_clk = devm_clk_register(&indio_dev->dev, &priv->clk_gate.hw);
+ if (WARN_ON(IS_ERR(priv->adc_clk)))
+ return PTR_ERR(priv->adc_clk);
+
+ return 0;
+}
+
+static int meson_sar_adc_init(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int regval, ret;
+
+ /*
+ * make sure we start at CH7 input since the other muxes are only used
+ * for internal calibration.
+ */
+ meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT);
+
+ /*
+ * leave sampling delay and the input clocks as configured by BL30 to
+ * make sure BL30 gets the values it expects when reading the
+ * temperature sensor.
+ */
+ regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval);
+ if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED)
+ return 0;
+
+ meson_sar_adc_stop_sample_engine(indio_dev);
+
+ /* update the channel 6 MUX to select the temperature sensor */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL,
+ MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL);
+
+ /* disable all channels by default */
+ regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE, 0);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY,
+ MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY);
+
+ /* delay between two samples = (10+1) * 1uS */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
+ FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK,
+ 10));
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
+ FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
+ 0));
+
+ /* delay between two samples = (10+1) * 1uS */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
+ FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
+ 10));
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
+ FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
+ 1));
+
+ ret = clk_set_parent(priv->adc_sel_clk, priv->clkin);
+ if (ret) {
+ dev_err(indio_dev->dev.parent,
+ "failed to set adc parent to clkin\n");
+ return ret;
+ }
+
+ ret = clk_set_rate(priv->adc_clk, 1200000);
+ if (ret) {
+ dev_err(indio_dev->dev.parent,
+ "failed to set adc clock rate\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int ret;
+
+ ret = meson_sar_adc_lock(indio_dev);
+ if (ret)
+ goto err_lock;
+
+ ret = regulator_enable(priv->vref);
+ if (ret < 0) {
+ dev_err(indio_dev->dev.parent,
+ "failed to enable vref regulator\n");
+ goto err_vref;
+ }
+
+ ret = clk_prepare_enable(priv->core_clk);
+ if (ret) {
+ dev_err(indio_dev->dev.parent, "failed to enable core clk\n");
+ goto err_core_clk;
+ }
+
+ ret = clk_prepare_enable(priv->sana_clk);
+ if (ret) {
+ dev_err(indio_dev->dev.parent, "failed to enable sana clk\n");
+ goto err_sana_clk;
+ }
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
+ MESON_SAR_ADC_REG11_BANDGAP_EN,
+ MESON_SAR_ADC_REG11_BANDGAP_EN);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_ADC_EN,
+ MESON_SAR_ADC_REG3_ADC_EN);
+
+ udelay(5);
+
+ ret = clk_prepare_enable(priv->adc_clk);
+ if (ret) {
+ dev_err(indio_dev->dev.parent, "failed to enable adc clk\n");
+ goto err_adc_clk;
+ }
+
+ meson_sar_adc_unlock(indio_dev);
+
+ return 0;
+
+err_adc_clk:
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_ADC_EN, 0);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
+ MESON_SAR_ADC_REG11_BANDGAP_EN, 0);
+ clk_disable_unprepare(priv->sana_clk);
+err_sana_clk:
+ clk_disable_unprepare(priv->core_clk);
+err_core_clk:
+ regulator_disable(priv->vref);
+err_vref:
+ meson_sar_adc_unlock(indio_dev);
+err_lock:
+ return ret;
+}
+
+static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int ret;
+
+ ret = meson_sar_adc_lock(indio_dev);
+ if (ret)
+ return ret;
+
+ clk_disable_unprepare(priv->adc_clk);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_ADC_EN, 0);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
+ MESON_SAR_ADC_REG11_BANDGAP_EN, 0);
+
+ clk_disable_unprepare(priv->sana_clk);
+ clk_disable_unprepare(priv->core_clk);
+
+ regulator_disable(priv->vref);
+
+ meson_sar_adc_unlock(indio_dev);
+
+ return 0;
+}
+
+static const struct iio_info meson_sar_adc_iio_info = {
+ .read_raw = meson_sar_adc_iio_info_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+struct meson_sar_adc_data meson_sar_adc_gxbb_data = {
+ .resolution = 10,
+ .name = "meson-gxbb-saradc",
+};
+
+struct meson_sar_adc_data meson_sar_adc_gxl_data = {
+ .resolution = 12,
+ .name = "meson-gxl-saradc",
+};
+
+struct meson_sar_adc_data meson_sar_adc_gxm_data = {
+ .resolution = 12,
+ .name = "meson-gxm-saradc",
+};
+
+static const struct of_device_id meson_sar_adc_of_match[] = {
+ {
+ .compatible = "amlogic,meson-gxbb-saradc",
+ .data = &meson_sar_adc_gxbb_data,
+ }, {
+ .compatible = "amlogic,meson-gxl-saradc",
+ .data = &meson_sar_adc_gxl_data,
+ }, {
+ .compatible = "amlogic,meson-gxm-saradc",
+ .data = &meson_sar_adc_gxm_data,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match);
+
+static int meson_sar_adc_probe(struct platform_device *pdev)
+{
+ struct meson_sar_adc_priv *priv;
+ struct iio_dev *indio_dev;
+ struct resource *res;
+ void __iomem *base;
+ const struct of_device_id *match;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
+ if (!indio_dev) {
+ dev_err(&pdev->dev, "failed allocating iio device\n");
+ return -ENOMEM;
+ }
+
+ priv = iio_priv(indio_dev);
+
+ match = of_match_device(meson_sar_adc_of_match, &pdev->dev);
+ priv->data = match->data;
+
+ indio_dev->name = priv->data->name;
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->dev.of_node = pdev->dev.of_node;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &meson_sar_adc_iio_info;
+
+ indio_dev->channels = meson_sar_adc_iio_channels;
+ indio_dev->num_channels = ARRAY_SIZE(meson_sar_adc_iio_channels);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+ &meson_sar_adc_regmap_config);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ priv->clkin = devm_clk_get(&pdev->dev, "clkin");
+ if (IS_ERR(priv->clkin)) {
+ dev_err(&pdev->dev, "failed to get clkin\n");
+ return PTR_ERR(priv->clkin);
+ }
+
+ priv->core_clk = devm_clk_get(&pdev->dev, "core");
+ if (IS_ERR(priv->core_clk)) {
+ dev_err(&pdev->dev, "failed to get core clk\n");
+ return PTR_ERR(priv->core_clk);
+ }
+
+ priv->sana_clk = devm_clk_get(&pdev->dev, "sana");
+ if (IS_ERR(priv->sana_clk)) {
+ if (PTR_ERR(priv->sana_clk) == -ENOENT) {
+ priv->sana_clk = NULL;
+ } else {
+ dev_err(&pdev->dev, "failed to get sana clk\n");
+ return PTR_ERR(priv->sana_clk);
+ }
+ }
+
+ priv->adc_clk = devm_clk_get(&pdev->dev, "adc_clk");
+ if (IS_ERR(priv->adc_clk)) {
+ if (PTR_ERR(priv->adc_clk) == -ENOENT) {
+ priv->adc_clk = NULL;
+ } else {
+ dev_err(&pdev->dev, "failed to get adc clk\n");
+ return PTR_ERR(priv->adc_clk);
+ }
+ }
+
+ priv->adc_sel_clk = devm_clk_get(&pdev->dev, "adc_sel");
+ if (IS_ERR(priv->adc_sel_clk)) {
+ if (PTR_ERR(priv->adc_sel_clk) == -ENOENT) {
+ priv->adc_sel_clk = NULL;
+ } else {
+ dev_err(&pdev->dev, "failed to get adc_sel clk\n");
+ return PTR_ERR(priv->adc_sel_clk);
+ }
+ }
+
+ /* on pre-GXBB SoCs the SAR ADC itself provides the ADC clock: */
+ if (!priv->adc_clk) {
+ ret = meson_sar_adc_clk_init(indio_dev, base);
+ if (ret)
+ return ret;
+ }
+
+ priv->vref = devm_regulator_get(&pdev->dev, "vref");
+ if (IS_ERR(priv->vref)) {
+ dev_err(&pdev->dev, "failed to get vref regulator\n");
+ return PTR_ERR(priv->vref);
+ }
+
+ ret = meson_sar_adc_init(indio_dev);
+ if (ret)
+ goto err;
+
+ ret = meson_sar_adc_hw_enable(indio_dev);
+ if (ret)
+ goto err;
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto err_hw;
+
+ return 0;
+
+err_hw:
+ meson_sar_adc_hw_disable(indio_dev);
+err:
+ return ret;
+}
+
+static int meson_sar_adc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+
+ iio_device_unregister(indio_dev);
+
+ return meson_sar_adc_hw_disable(indio_dev);
+}
+
+static int __maybe_unused meson_sar_adc_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
+ return meson_sar_adc_hw_disable(indio_dev);
+}
+
+static int __maybe_unused meson_sar_adc_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
+ return meson_sar_adc_hw_enable(indio_dev);
+}
+
+static SIMPLE_DEV_PM_OPS(meson_sar_adc_pm_ops,
+ meson_sar_adc_suspend, meson_sar_adc_resume);
+
+static struct platform_driver meson_sar_adc_driver = {
+ .probe = meson_sar_adc_probe,
+ .remove = meson_sar_adc_remove,
+ .driver = {
+ .name = "meson-saradc",
+ .of_match_table = meson_sar_adc_of_match,
+ .pm = &meson_sar_adc_pm_ops,
+ },
+};
+
+module_platform_driver(meson_sar_adc_driver);
+
+MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
+MODULE_DESCRIPTION("Amlogic Meson SAR ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c
index c2babe50a0d8..0a19761d656c 100644
--- a/drivers/iio/adc/qcom-spmi-vadc.c
+++ b/drivers/iio/adc/qcom-spmi-vadc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -84,7 +84,7 @@
#define VADC_MAX_ADC_CODE 0xa800
#define VADC_ABSOLUTE_RANGE_UV 625000
-#define VADC_RATIOMETRIC_RANGE_UV 1800000
+#define VADC_RATIOMETRIC_RANGE 1800
#define VADC_DEF_PRESCALING 0 /* 1:1 */
#define VADC_DEF_DECIMATION 0 /* 512 */
@@ -100,9 +100,23 @@
#define KELVINMIL_CELSIUSMIL 273150
+#define PMI_CHG_SCALE_1 -138890
+#define PMI_CHG_SCALE_2 391750000000LL
+
#define VADC_CHAN_MIN VADC_USBIN
#define VADC_CHAN_MAX VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM
+/**
+ * struct vadc_map_pt - Map the graph representation for ADC channel
+ * @x: Represent the ADC digitized code.
+ * @y: Represent the physical data which can be temperature, voltage,
+ * resistance.
+ */
+struct vadc_map_pt {
+ s32 x;
+ s32 y;
+};
+
/*
* VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels.
* VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for
@@ -148,6 +162,9 @@ struct vadc_prescale_ratio {
* start of conversion.
* @avg_samples: ability to provide single result from the ADC
* that is an average of multiple measurements.
+ * @scale_fn: Represents the scaling function to convert voltage
+ * physical units desired by the client for the channel.
+ * Referenced from enum vadc_scale_fn_type.
*/
struct vadc_channel_prop {
unsigned int channel;
@@ -156,6 +173,7 @@ struct vadc_channel_prop {
unsigned int prescale;
unsigned int hw_settle_time;
unsigned int avg_samples;
+ unsigned int scale_fn;
};
/**
@@ -186,6 +204,35 @@ struct vadc_priv {
struct mutex lock;
};
+/**
+ * struct vadc_scale_fn - Scaling function prototype
+ * @scale: Function pointer to one of the scaling functions
+ * which takes the adc properties, channel properties,
+ * and returns the physical result.
+ */
+struct vadc_scale_fn {
+ int (*scale)(struct vadc_priv *, const struct vadc_channel_prop *,
+ u16, int *);
+};
+
+/**
+ * enum vadc_scale_fn_type - Scaling function to convert ADC code to
+ * physical scaled units for the channel.
+ * SCALE_DEFAULT: Default scaling to convert raw adc code to voltage (uV).
+ * SCALE_THERM_100K_PULLUP: Returns temperature in millidegC.
+ * Uses a mapping table with 100K pullup.
+ * SCALE_PMIC_THERM: Returns result in milli degree's Centigrade.
+ * SCALE_XOTHERM: Returns XO thermistor voltage in millidegC.
+ * SCALE_PMI_CHG_TEMP: Conversion for PMI CHG temp
+ */
+enum vadc_scale_fn_type {
+ SCALE_DEFAULT = 0,
+ SCALE_THERM_100K_PULLUP,
+ SCALE_PMIC_THERM,
+ SCALE_XOTHERM,
+ SCALE_PMI_CHG_TEMP,
+};
+
static const struct vadc_prescale_ratio vadc_prescale_ratios[] = {
{.num = 1, .den = 1},
{.num = 1, .den = 3},
@@ -197,6 +244,44 @@ static const struct vadc_prescale_ratio vadc_prescale_ratios[] = {
{.num = 1, .den = 10}
};
+/* Voltage to temperature */
+static const struct vadc_map_pt adcmap_100k_104ef_104fb[] = {
+ {1758, -40},
+ {1742, -35},
+ {1719, -30},
+ {1691, -25},
+ {1654, -20},
+ {1608, -15},
+ {1551, -10},
+ {1483, -5},
+ {1404, 0},
+ {1315, 5},
+ {1218, 10},
+ {1114, 15},
+ {1007, 20},
+ {900, 25},
+ {795, 30},
+ {696, 35},
+ {605, 40},
+ {522, 45},
+ {448, 50},
+ {383, 55},
+ {327, 60},
+ {278, 65},
+ {237, 70},
+ {202, 75},
+ {172, 80},
+ {146, 85},
+ {125, 90},
+ {107, 95},
+ {92, 100},
+ {79, 105},
+ {68, 110},
+ {59, 115},
+ {51, 120},
+ {44, 125}
+};
+
static int vadc_read(struct vadc_priv *vadc, u16 offset, u8 *data)
{
return regmap_bulk_read(vadc->regmap, vadc->base + offset, data, 1);
@@ -418,7 +503,7 @@ static int vadc_measure_ref_points(struct vadc_priv *vadc)
u16 read_1, read_2;
int ret;
- vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE_UV;
+ vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE;
vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV;
prop = vadc_get_channel(vadc, VADC_REF_1250MV);
@@ -468,27 +553,148 @@ err:
return ret;
}
-static s32 vadc_calibrate(struct vadc_priv *vadc,
- const struct vadc_channel_prop *prop, u16 adc_code)
+static int vadc_map_voltage_temp(const struct vadc_map_pt *pts,
+ u32 tablesize, s32 input, s64 *output)
+{
+ bool descending = 1;
+ u32 i = 0;
+
+ if (!pts)
+ return -EINVAL;
+
+ /* Check if table is descending or ascending */
+ if (tablesize > 1) {
+ if (pts[0].x < pts[1].x)
+ descending = 0;
+ }
+
+ while (i < tablesize) {
+ if ((descending) && (pts[i].x < input)) {
+ /* table entry is less than measured*/
+ /* value and table is descending, stop */
+ break;
+ } else if ((!descending) &&
+ (pts[i].x > input)) {
+ /* table entry is greater than measured*/
+ /*value and table is ascending, stop */
+ break;
+ }
+ i++;
+ }
+
+ if (i == 0) {
+ *output = pts[0].y;
+ } else if (i == tablesize) {
+ *output = pts[tablesize - 1].y;
+ } else {
+ /* result is between search_index and search_index-1 */
+ /* interpolate linearly */
+ *output = (((s32)((pts[i].y - pts[i - 1].y) *
+ (input - pts[i - 1].x)) /
+ (pts[i].x - pts[i - 1].x)) +
+ pts[i - 1].y);
+ }
+
+ return 0;
+}
+
+static void vadc_scale_calib(struct vadc_priv *vadc, u16 adc_code,
+ const struct vadc_channel_prop *prop,
+ s64 *scale_voltage)
+{
+ *scale_voltage = (adc_code -
+ vadc->graph[prop->calibration].gnd);
+ *scale_voltage *= vadc->graph[prop->calibration].dx;
+ *scale_voltage = div64_s64(*scale_voltage,
+ vadc->graph[prop->calibration].dy);
+ if (prop->calibration == VADC_CALIB_ABSOLUTE)
+ *scale_voltage +=
+ vadc->graph[prop->calibration].dx;
+
+ if (*scale_voltage < 0)
+ *scale_voltage = 0;
+}
+
+static int vadc_scale_volt(struct vadc_priv *vadc,
+ const struct vadc_channel_prop *prop, u16 adc_code,
+ int *result_uv)
{
const struct vadc_prescale_ratio *prescale;
- s64 voltage;
+ s64 voltage = 0, result = 0;
- voltage = adc_code - vadc->graph[prop->calibration].gnd;
- voltage *= vadc->graph[prop->calibration].dx;
- voltage = div64_s64(voltage, vadc->graph[prop->calibration].dy);
+ vadc_scale_calib(vadc, adc_code, prop, &voltage);
+
+ prescale = &vadc_prescale_ratios[prop->prescale];
+ voltage = voltage * prescale->den;
+ result = div64_s64(voltage, prescale->num);
+ *result_uv = result;
+
+ return 0;
+}
+
+static int vadc_scale_therm(struct vadc_priv *vadc,
+ const struct vadc_channel_prop *prop, u16 adc_code,
+ int *result_mdec)
+{
+ s64 voltage = 0, result = 0;
+
+ vadc_scale_calib(vadc, adc_code, prop, &voltage);
if (prop->calibration == VADC_CALIB_ABSOLUTE)
- voltage += vadc->graph[prop->calibration].dx;
+ voltage = div64_s64(voltage, 1000);
+
+ vadc_map_voltage_temp(adcmap_100k_104ef_104fb,
+ ARRAY_SIZE(adcmap_100k_104ef_104fb),
+ voltage, &result);
+ result *= 1000;
+ *result_mdec = result;
- if (voltage < 0)
+ return 0;
+}
+
+static int vadc_scale_die_temp(struct vadc_priv *vadc,
+ const struct vadc_channel_prop *prop,
+ u16 adc_code, int *result_mdec)
+{
+ const struct vadc_prescale_ratio *prescale;
+ s64 voltage = 0;
+ u64 temp; /* Temporary variable for do_div */
+
+ vadc_scale_calib(vadc, adc_code, prop, &voltage);
+
+ if (voltage > 0) {
+ prescale = &vadc_prescale_ratios[prop->prescale];
+ temp = voltage * prescale->den;
+ do_div(temp, prescale->num * 2);
+ voltage = temp;
+ } else {
voltage = 0;
+ }
- prescale = &vadc_prescale_ratios[prop->prescale];
+ voltage -= KELVINMIL_CELSIUSMIL;
+ *result_mdec = voltage;
+
+ return 0;
+}
+
+static int vadc_scale_chg_temp(struct vadc_priv *vadc,
+ const struct vadc_channel_prop *prop,
+ u16 adc_code, int *result_mdec)
+{
+ const struct vadc_prescale_ratio *prescale;
+ s64 voltage = 0, result = 0;
+ vadc_scale_calib(vadc, adc_code, prop, &voltage);
+
+ prescale = &vadc_prescale_ratios[prop->prescale];
voltage = voltage * prescale->den;
+ voltage = div64_s64(voltage, prescale->num);
+ voltage = ((PMI_CHG_SCALE_1) * (voltage * 2));
+ voltage = (voltage + PMI_CHG_SCALE_2);
+ result = div64_s64(voltage, 1000000);
+ *result_mdec = result;
- return div64_s64(voltage, prescale->num);
+ return 0;
}
static int vadc_decimation_from_dt(u32 value)
@@ -536,6 +742,14 @@ static int vadc_avg_samples_from_dt(u32 value)
return __ffs64(value);
}
+static struct vadc_scale_fn scale_fn[] = {
+ [SCALE_DEFAULT] = {vadc_scale_volt},
+ [SCALE_THERM_100K_PULLUP] = {vadc_scale_therm},
+ [SCALE_PMIC_THERM] = {vadc_scale_die_temp},
+ [SCALE_XOTHERM] = {vadc_scale_therm},
+ [SCALE_PMI_CHG_TEMP] = {vadc_scale_chg_temp},
+};
+
static int vadc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2,
long mask)
@@ -552,11 +766,8 @@ static int vadc_read_raw(struct iio_dev *indio_dev,
if (ret)
break;
- *val = vadc_calibrate(vadc, prop, adc_code);
+ scale_fn[prop->scale_fn].scale(vadc, prop, adc_code, val);
- /* 2mV/K, return milli Celsius */
- *val /= 2;
- *val -= KELVINMIL_CELSIUSMIL;
return IIO_VAL_INT;
case IIO_CHAN_INFO_RAW:
prop = &vadc->chan_props[chan->address];
@@ -564,12 +775,8 @@ static int vadc_read_raw(struct iio_dev *indio_dev,
if (ret)
break;
- *val = vadc_calibrate(vadc, prop, adc_code);
+ *val = (int)adc_code;
return IIO_VAL_INT;
- case IIO_CHAN_INFO_SCALE:
- *val = 0;
- *val2 = 1000;
- return IIO_VAL_INT_PLUS_MICRO;
default:
ret = -EINVAL;
break;
@@ -602,22 +809,39 @@ struct vadc_channels {
unsigned int prescale_index;
enum iio_chan_type type;
long info_mask;
+ unsigned int scale_fn;
};
-#define VADC_CHAN(_dname, _type, _mask, _pre) \
+#define VADC_CHAN(_dname, _type, _mask, _pre, _scale) \
[VADC_##_dname] = { \
.datasheet_name = __stringify(_dname), \
.prescale_index = _pre, \
.type = _type, \
- .info_mask = _mask \
+ .info_mask = _mask, \
+ .scale_fn = _scale \
}, \
-#define VADC_CHAN_TEMP(_dname, _pre) \
- VADC_CHAN(_dname, IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED), _pre) \
+#define VADC_NO_CHAN(_dname, _type, _mask, _pre) \
+ [VADC_##_dname] = { \
+ .datasheet_name = __stringify(_dname), \
+ .prescale_index = _pre, \
+ .type = _type, \
+ .info_mask = _mask \
+ },
-#define VADC_CHAN_VOLT(_dname, _pre) \
+#define VADC_CHAN_TEMP(_dname, _pre, _scale) \
+ VADC_CHAN(_dname, IIO_TEMP, \
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED), \
+ _pre, _scale) \
+
+#define VADC_CHAN_VOLT(_dname, _pre, _scale) \
VADC_CHAN(_dname, IIO_VOLTAGE, \
- BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_PROCESSED),\
+ _pre, _scale) \
+
+#define VADC_CHAN_NO_SCALE(_dname, _pre) \
+ VADC_NO_CHAN(_dname, IIO_VOLTAGE, \
+ BIT(IIO_CHAN_INFO_RAW), \
_pre) \
/*
@@ -626,106 +850,106 @@ struct vadc_channels {
* gaps in the array should be treated as reserved channels.
*/
static const struct vadc_channels vadc_chans[] = {
- VADC_CHAN_VOLT(USBIN, 4)
- VADC_CHAN_VOLT(DCIN, 4)
- VADC_CHAN_VOLT(VCHG_SNS, 3)
- VADC_CHAN_VOLT(SPARE1_03, 1)
- VADC_CHAN_VOLT(USB_ID_MV, 1)
- VADC_CHAN_VOLT(VCOIN, 1)
- VADC_CHAN_VOLT(VBAT_SNS, 1)
- VADC_CHAN_VOLT(VSYS, 1)
- VADC_CHAN_TEMP(DIE_TEMP, 0)
- VADC_CHAN_VOLT(REF_625MV, 0)
- VADC_CHAN_VOLT(REF_1250MV, 0)
- VADC_CHAN_VOLT(CHG_TEMP, 0)
- VADC_CHAN_VOLT(SPARE1, 0)
- VADC_CHAN_VOLT(SPARE2, 0)
- VADC_CHAN_VOLT(GND_REF, 0)
- VADC_CHAN_VOLT(VDD_VADC, 0)
-
- VADC_CHAN_VOLT(P_MUX1_1_1, 0)
- VADC_CHAN_VOLT(P_MUX2_1_1, 0)
- VADC_CHAN_VOLT(P_MUX3_1_1, 0)
- VADC_CHAN_VOLT(P_MUX4_1_1, 0)
- VADC_CHAN_VOLT(P_MUX5_1_1, 0)
- VADC_CHAN_VOLT(P_MUX6_1_1, 0)
- VADC_CHAN_VOLT(P_MUX7_1_1, 0)
- VADC_CHAN_VOLT(P_MUX8_1_1, 0)
- VADC_CHAN_VOLT(P_MUX9_1_1, 0)
- VADC_CHAN_VOLT(P_MUX10_1_1, 0)
- VADC_CHAN_VOLT(P_MUX11_1_1, 0)
- VADC_CHAN_VOLT(P_MUX12_1_1, 0)
- VADC_CHAN_VOLT(P_MUX13_1_1, 0)
- VADC_CHAN_VOLT(P_MUX14_1_1, 0)
- VADC_CHAN_VOLT(P_MUX15_1_1, 0)
- VADC_CHAN_VOLT(P_MUX16_1_1, 0)
-
- VADC_CHAN_VOLT(P_MUX1_1_3, 1)
- VADC_CHAN_VOLT(P_MUX2_1_3, 1)
- VADC_CHAN_VOLT(P_MUX3_1_3, 1)
- VADC_CHAN_VOLT(P_MUX4_1_3, 1)
- VADC_CHAN_VOLT(P_MUX5_1_3, 1)
- VADC_CHAN_VOLT(P_MUX6_1_3, 1)
- VADC_CHAN_VOLT(P_MUX7_1_3, 1)
- VADC_CHAN_VOLT(P_MUX8_1_3, 1)
- VADC_CHAN_VOLT(P_MUX9_1_3, 1)
- VADC_CHAN_VOLT(P_MUX10_1_3, 1)
- VADC_CHAN_VOLT(P_MUX11_1_3, 1)
- VADC_CHAN_VOLT(P_MUX12_1_3, 1)
- VADC_CHAN_VOLT(P_MUX13_1_3, 1)
- VADC_CHAN_VOLT(P_MUX14_1_3, 1)
- VADC_CHAN_VOLT(P_MUX15_1_3, 1)
- VADC_CHAN_VOLT(P_MUX16_1_3, 1)
-
- VADC_CHAN_VOLT(LR_MUX1_BAT_THERM, 0)
- VADC_CHAN_VOLT(LR_MUX2_BAT_ID, 0)
- VADC_CHAN_VOLT(LR_MUX3_XO_THERM, 0)
- VADC_CHAN_VOLT(LR_MUX4_AMUX_THM1, 0)
- VADC_CHAN_VOLT(LR_MUX5_AMUX_THM2, 0)
- VADC_CHAN_VOLT(LR_MUX6_AMUX_THM3, 0)
- VADC_CHAN_VOLT(LR_MUX7_HW_ID, 0)
- VADC_CHAN_VOLT(LR_MUX8_AMUX_THM4, 0)
- VADC_CHAN_VOLT(LR_MUX9_AMUX_THM5, 0)
- VADC_CHAN_VOLT(LR_MUX10_USB_ID, 0)
- VADC_CHAN_VOLT(AMUX_PU1, 0)
- VADC_CHAN_VOLT(AMUX_PU2, 0)
- VADC_CHAN_VOLT(LR_MUX3_BUF_XO_THERM, 0)
-
- VADC_CHAN_VOLT(LR_MUX1_PU1_BAT_THERM, 0)
- VADC_CHAN_VOLT(LR_MUX2_PU1_BAT_ID, 0)
- VADC_CHAN_VOLT(LR_MUX3_PU1_XO_THERM, 0)
- VADC_CHAN_VOLT(LR_MUX4_PU1_AMUX_THM1, 0)
- VADC_CHAN_VOLT(LR_MUX5_PU1_AMUX_THM2, 0)
- VADC_CHAN_VOLT(LR_MUX6_PU1_AMUX_THM3, 0)
- VADC_CHAN_VOLT(LR_MUX7_PU1_AMUX_HW_ID, 0)
- VADC_CHAN_VOLT(LR_MUX8_PU1_AMUX_THM4, 0)
- VADC_CHAN_VOLT(LR_MUX9_PU1_AMUX_THM5, 0)
- VADC_CHAN_VOLT(LR_MUX10_PU1_AMUX_USB_ID, 0)
- VADC_CHAN_VOLT(LR_MUX3_BUF_PU1_XO_THERM, 0)
-
- VADC_CHAN_VOLT(LR_MUX1_PU2_BAT_THERM, 0)
- VADC_CHAN_VOLT(LR_MUX2_PU2_BAT_ID, 0)
- VADC_CHAN_VOLT(LR_MUX3_PU2_XO_THERM, 0)
- VADC_CHAN_VOLT(LR_MUX4_PU2_AMUX_THM1, 0)
- VADC_CHAN_VOLT(LR_MUX5_PU2_AMUX_THM2, 0)
- VADC_CHAN_VOLT(LR_MUX6_PU2_AMUX_THM3, 0)
- VADC_CHAN_VOLT(LR_MUX7_PU2_AMUX_HW_ID, 0)
- VADC_CHAN_VOLT(LR_MUX8_PU2_AMUX_THM4, 0)
- VADC_CHAN_VOLT(LR_MUX9_PU2_AMUX_THM5, 0)
- VADC_CHAN_VOLT(LR_MUX10_PU2_AMUX_USB_ID, 0)
- VADC_CHAN_VOLT(LR_MUX3_BUF_PU2_XO_THERM, 0)
-
- VADC_CHAN_VOLT(LR_MUX1_PU1_PU2_BAT_THERM, 0)
- VADC_CHAN_VOLT(LR_MUX2_PU1_PU2_BAT_ID, 0)
- VADC_CHAN_VOLT(LR_MUX3_PU1_PU2_XO_THERM, 0)
- VADC_CHAN_VOLT(LR_MUX4_PU1_PU2_AMUX_THM1, 0)
- VADC_CHAN_VOLT(LR_MUX5_PU1_PU2_AMUX_THM2, 0)
- VADC_CHAN_VOLT(LR_MUX6_PU1_PU2_AMUX_THM3, 0)
- VADC_CHAN_VOLT(LR_MUX7_PU1_PU2_AMUX_HW_ID, 0)
- VADC_CHAN_VOLT(LR_MUX8_PU1_PU2_AMUX_THM4, 0)
- VADC_CHAN_VOLT(LR_MUX9_PU1_PU2_AMUX_THM5, 0)
- VADC_CHAN_VOLT(LR_MUX10_PU1_PU2_AMUX_USB_ID, 0)
- VADC_CHAN_VOLT(LR_MUX3_BUF_PU1_PU2_XO_THERM, 0)
+ VADC_CHAN_VOLT(USBIN, 4, SCALE_DEFAULT)
+ VADC_CHAN_VOLT(DCIN, 4, SCALE_DEFAULT)
+ VADC_CHAN_NO_SCALE(VCHG_SNS, 3)
+ VADC_CHAN_NO_SCALE(SPARE1_03, 1)
+ VADC_CHAN_NO_SCALE(USB_ID_MV, 1)
+ VADC_CHAN_VOLT(VCOIN, 1, SCALE_DEFAULT)
+ VADC_CHAN_NO_SCALE(VBAT_SNS, 1)
+ VADC_CHAN_VOLT(VSYS, 1, SCALE_DEFAULT)
+ VADC_CHAN_TEMP(DIE_TEMP, 0, SCALE_PMIC_THERM)
+ VADC_CHAN_VOLT(REF_625MV, 0, SCALE_DEFAULT)
+ VADC_CHAN_VOLT(REF_1250MV, 0, SCALE_DEFAULT)
+ VADC_CHAN_NO_SCALE(CHG_TEMP, 0)
+ VADC_CHAN_NO_SCALE(SPARE1, 0)
+ VADC_CHAN_TEMP(SPARE2, 0, SCALE_PMI_CHG_TEMP)
+ VADC_CHAN_VOLT(GND_REF, 0, SCALE_DEFAULT)
+ VADC_CHAN_VOLT(VDD_VADC, 0, SCALE_DEFAULT)
+
+ VADC_CHAN_NO_SCALE(P_MUX1_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX2_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX3_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX4_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX5_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX6_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX7_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX8_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX9_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX10_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX11_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX12_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX13_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX14_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX15_1_1, 0)
+ VADC_CHAN_NO_SCALE(P_MUX16_1_1, 0)
+
+ VADC_CHAN_NO_SCALE(P_MUX1_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX2_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX3_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX4_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX5_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX6_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX7_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX8_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX9_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX10_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX11_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX12_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX13_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX14_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX15_1_3, 1)
+ VADC_CHAN_NO_SCALE(P_MUX16_1_3, 1)
+
+ VADC_CHAN_NO_SCALE(LR_MUX1_BAT_THERM, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX2_BAT_ID, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX3_XO_THERM, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX4_AMUX_THM1, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX5_AMUX_THM2, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX6_AMUX_THM3, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX7_HW_ID, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX8_AMUX_THM4, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX9_AMUX_THM5, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX10_USB_ID, 0)
+ VADC_CHAN_NO_SCALE(AMUX_PU1, 0)
+ VADC_CHAN_NO_SCALE(AMUX_PU2, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX3_BUF_XO_THERM, 0)
+
+ VADC_CHAN_NO_SCALE(LR_MUX1_PU1_BAT_THERM, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX2_PU1_BAT_ID, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX3_PU1_XO_THERM, 0)
+ VADC_CHAN_TEMP(LR_MUX4_PU1_AMUX_THM1, 0, SCALE_THERM_100K_PULLUP)
+ VADC_CHAN_TEMP(LR_MUX5_PU1_AMUX_THM2, 0, SCALE_THERM_100K_PULLUP)
+ VADC_CHAN_TEMP(LR_MUX6_PU1_AMUX_THM3, 0, SCALE_THERM_100K_PULLUP)
+ VADC_CHAN_NO_SCALE(LR_MUX7_PU1_AMUX_HW_ID, 0)
+ VADC_CHAN_TEMP(LR_MUX8_PU1_AMUX_THM4, 0, SCALE_THERM_100K_PULLUP)
+ VADC_CHAN_TEMP(LR_MUX9_PU1_AMUX_THM5, 0, SCALE_THERM_100K_PULLUP)
+ VADC_CHAN_NO_SCALE(LR_MUX10_PU1_AMUX_USB_ID, 0)
+ VADC_CHAN_TEMP(LR_MUX3_BUF_PU1_XO_THERM, 0, SCALE_XOTHERM)
+
+ VADC_CHAN_NO_SCALE(LR_MUX1_PU2_BAT_THERM, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX2_PU2_BAT_ID, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX3_PU2_XO_THERM, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX4_PU2_AMUX_THM1, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX5_PU2_AMUX_THM2, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX6_PU2_AMUX_THM3, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX7_PU2_AMUX_HW_ID, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX8_PU2_AMUX_THM4, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX9_PU2_AMUX_THM5, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX10_PU2_AMUX_USB_ID, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX3_BUF_PU2_XO_THERM, 0)
+
+ VADC_CHAN_NO_SCALE(LR_MUX1_PU1_PU2_BAT_THERM, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX2_PU1_PU2_BAT_ID, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX3_PU1_PU2_XO_THERM, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX4_PU1_PU2_AMUX_THM1, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX5_PU1_PU2_AMUX_THM2, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX6_PU1_PU2_AMUX_THM3, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX7_PU1_PU2_AMUX_HW_ID, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX8_PU1_PU2_AMUX_THM4, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX9_PU1_PU2_AMUX_THM5, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX10_PU1_PU2_AMUX_USB_ID, 0)
+ VADC_CHAN_NO_SCALE(LR_MUX3_BUF_PU1_PU2_XO_THERM, 0)
};
static int vadc_get_dt_channel_data(struct device *dev,
@@ -844,6 +1068,7 @@ static int vadc_get_dt_data(struct vadc_priv *vadc, struct device_node *node)
return ret;
}
+ prop.scale_fn = vadc_chans[prop.channel].scale_fn;
vadc->chan_props[index] = prop;
vadc_chan = &vadc_chans[prop.channel];
diff --git a/drivers/iio/adc/rcar-gyroadc.c b/drivers/iio/adc/rcar-gyroadc.c
new file mode 100644
index 000000000000..0c44f72c32a8
--- /dev/null
+++ b/drivers/iio/adc/rcar-gyroadc.c
@@ -0,0 +1,631 @@
+/*
+ * Renesas R-Car GyroADC driver
+ *
+ * Copyright 2016 Marek Vasut <marek.vasut@gmail.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.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_platform.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+
+#define DRIVER_NAME "rcar-gyroadc"
+
+/* GyroADC registers. */
+#define RCAR_GYROADC_MODE_SELECT 0x00
+#define RCAR_GYROADC_MODE_SELECT_1_MB88101A 0x0
+#define RCAR_GYROADC_MODE_SELECT_2_ADCS7476 0x1
+#define RCAR_GYROADC_MODE_SELECT_3_MAX1162 0x3
+
+#define RCAR_GYROADC_START_STOP 0x04
+#define RCAR_GYROADC_START_STOP_START BIT(0)
+
+#define RCAR_GYROADC_CLOCK_LENGTH 0x08
+#define RCAR_GYROADC_1_25MS_LENGTH 0x0c
+
+#define RCAR_GYROADC_REALTIME_DATA(ch) (0x10 + ((ch) * 4))
+#define RCAR_GYROADC_100MS_ADDED_DATA(ch) (0x30 + ((ch) * 4))
+#define RCAR_GYROADC_10MS_AVG_DATA(ch) (0x50 + ((ch) * 4))
+
+#define RCAR_GYROADC_FIFO_STATUS 0x70
+#define RCAR_GYROADC_FIFO_STATUS_EMPTY(ch) BIT(0 + (4 * (ch)))
+#define RCAR_GYROADC_FIFO_STATUS_FULL(ch) BIT(1 + (4 * (ch)))
+#define RCAR_GYROADC_FIFO_STATUS_ERROR(ch) BIT(2 + (4 * (ch)))
+
+#define RCAR_GYROADC_INTR 0x74
+#define RCAR_GYROADC_INTR_INT BIT(0)
+
+#define RCAR_GYROADC_INTENR 0x78
+#define RCAR_GYROADC_INTENR_INTEN BIT(0)
+
+#define RCAR_GYROADC_SAMPLE_RATE 800 /* Hz */
+
+#define RCAR_GYROADC_RUNTIME_PM_DELAY_MS 2000
+
+enum rcar_gyroadc_model {
+ RCAR_GYROADC_MODEL_DEFAULT,
+ RCAR_GYROADC_MODEL_R8A7792,
+};
+
+struct rcar_gyroadc {
+ struct device *dev;
+ void __iomem *regs;
+ struct clk *iclk;
+ struct regulator *vref[8];
+ unsigned int num_channels;
+ enum rcar_gyroadc_model model;
+ unsigned int mode;
+ unsigned int sample_width;
+};
+
+static void rcar_gyroadc_hw_init(struct rcar_gyroadc *priv)
+{
+ const unsigned long clk_mhz = clk_get_rate(priv->iclk) / 1000000;
+ const unsigned long clk_mul =
+ (priv->mode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) ? 10 : 5;
+ unsigned long clk_len = clk_mhz * clk_mul;
+
+ /*
+ * According to the R-Car Gen2 datasheet Rev. 1.01, Sept 08 2014,
+ * page 77-7, clock length must be even number. If it's odd number,
+ * add one.
+ */
+ if (clk_len & 1)
+ clk_len++;
+
+ /* Stop the GyroADC. */
+ writel(0, priv->regs + RCAR_GYROADC_START_STOP);
+
+ /* Disable IRQ on V2H. */
+ if (priv->model == RCAR_GYROADC_MODEL_R8A7792)
+ writel(0, priv->regs + RCAR_GYROADC_INTENR);
+
+ /* Set mode and timing. */
+ writel(priv->mode, priv->regs + RCAR_GYROADC_MODE_SELECT);
+ writel(clk_len, priv->regs + RCAR_GYROADC_CLOCK_LENGTH);
+ writel(clk_mhz * 1250, priv->regs + RCAR_GYROADC_1_25MS_LENGTH);
+}
+
+static void rcar_gyroadc_hw_start(struct rcar_gyroadc *priv)
+{
+ /* Start sampling. */
+ writel(RCAR_GYROADC_START_STOP_START,
+ priv->regs + RCAR_GYROADC_START_STOP);
+
+ /*
+ * Wait for the first conversion to complete. This is longer than
+ * the 1.25 mS in the datasheet because 1.25 mS is not enough for
+ * the hardware to deliver the first sample and the hardware does
+ * then return zeroes instead of valid data.
+ */
+ mdelay(3);
+}
+
+static void rcar_gyroadc_hw_stop(struct rcar_gyroadc *priv)
+{
+ /* Stop the GyroADC. */
+ writel(0, priv->regs + RCAR_GYROADC_START_STOP);
+}
+
+#define RCAR_GYROADC_CHAN(_idx) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = (_idx), \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+}
+
+static const struct iio_chan_spec rcar_gyroadc_iio_channels_1[] = {
+ RCAR_GYROADC_CHAN(0),
+ RCAR_GYROADC_CHAN(1),
+ RCAR_GYROADC_CHAN(2),
+ RCAR_GYROADC_CHAN(3),
+};
+
+static const struct iio_chan_spec rcar_gyroadc_iio_channels_2[] = {
+ RCAR_GYROADC_CHAN(0),
+ RCAR_GYROADC_CHAN(1),
+ RCAR_GYROADC_CHAN(2),
+ RCAR_GYROADC_CHAN(3),
+ RCAR_GYROADC_CHAN(4),
+ RCAR_GYROADC_CHAN(5),
+ RCAR_GYROADC_CHAN(6),
+ RCAR_GYROADC_CHAN(7),
+};
+
+static const struct iio_chan_spec rcar_gyroadc_iio_channels_3[] = {
+ RCAR_GYROADC_CHAN(0),
+ RCAR_GYROADC_CHAN(1),
+ RCAR_GYROADC_CHAN(2),
+ RCAR_GYROADC_CHAN(3),
+ RCAR_GYROADC_CHAN(4),
+ RCAR_GYROADC_CHAN(5),
+ RCAR_GYROADC_CHAN(6),
+ RCAR_GYROADC_CHAN(7),
+};
+
+static int rcar_gyroadc_set_power(struct rcar_gyroadc *priv, bool on)
+{
+ struct device *dev = priv->dev;
+ int ret;
+
+ if (on) {
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ pm_runtime_put_noidle(dev);
+ } else {
+ pm_runtime_mark_last_busy(dev);
+ ret = pm_runtime_put_autosuspend(dev);
+ }
+
+ return ret;
+}
+
+static int rcar_gyroadc_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct rcar_gyroadc *priv = iio_priv(indio_dev);
+ struct regulator *consumer;
+ unsigned int datareg = RCAR_GYROADC_REALTIME_DATA(chan->channel);
+ unsigned int vref;
+ int ret;
+
+ /*
+ * MB88101 is special in that it has only single regulator for
+ * all four channels.
+ */
+ if (priv->mode == RCAR_GYROADC_MODE_SELECT_1_MB88101A)
+ consumer = priv->vref[0];
+ else
+ consumer = priv->vref[chan->channel];
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (chan->type != IIO_VOLTAGE)
+ return -EINVAL;
+
+ /* Channel not connected. */
+ if (!consumer)
+ return -EINVAL;
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+
+ ret = rcar_gyroadc_set_power(priv, true);
+ if (ret < 0) {
+ iio_device_release_direct_mode(indio_dev);
+ return ret;
+ }
+
+ *val = readl(priv->regs + datareg);
+ *val &= BIT(priv->sample_width) - 1;
+
+ ret = rcar_gyroadc_set_power(priv, false);
+ iio_device_release_direct_mode(indio_dev);
+ if (ret < 0)
+ return ret;
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ /* Channel not connected. */
+ if (!consumer)
+ return -EINVAL;
+
+ vref = regulator_get_voltage(consumer);
+ *val = vref / 1000;
+ *val2 = 1 << priv->sample_width;
+
+ return IIO_VAL_FRACTIONAL;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = RCAR_GYROADC_SAMPLE_RATE;
+
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int rcar_gyroadc_reg_access(struct iio_dev *indio_dev,
+ unsigned int reg, unsigned int writeval,
+ unsigned int *readval)
+{
+ struct rcar_gyroadc *priv = iio_priv(indio_dev);
+ unsigned int maxreg = RCAR_GYROADC_FIFO_STATUS;
+
+ if (readval == NULL)
+ return -EINVAL;
+
+ if (reg % 4)
+ return -EINVAL;
+
+ /* Handle the V2H case with extra interrupt block. */
+ if (priv->model == RCAR_GYROADC_MODEL_R8A7792)
+ maxreg = RCAR_GYROADC_INTENR;
+
+ if (reg > maxreg)
+ return -EINVAL;
+
+ *readval = readl(priv->regs + reg);
+
+ return 0;
+}
+
+static const struct iio_info rcar_gyroadc_iio_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = rcar_gyroadc_read_raw,
+ .debugfs_reg_access = rcar_gyroadc_reg_access,
+};
+
+static const struct of_device_id rcar_gyroadc_match[] = {
+ {
+ /* R-Car compatible GyroADC */
+ .compatible = "renesas,rcar-gyroadc",
+ .data = (void *)RCAR_GYROADC_MODEL_DEFAULT,
+ }, {
+ /* R-Car V2H specialty with interrupt registers. */
+ .compatible = "renesas,r8a7792-gyroadc",
+ .data = (void *)RCAR_GYROADC_MODEL_R8A7792,
+ }, {
+ /* sentinel */
+ }
+};
+
+MODULE_DEVICE_TABLE(of, rcar_gyroadc_match);
+
+static const struct of_device_id rcar_gyroadc_child_match[] = {
+ /* Mode 1 ADCs */
+ {
+ .compatible = "fujitsu,mb88101a",
+ .data = (void *)RCAR_GYROADC_MODE_SELECT_1_MB88101A,
+ },
+ /* Mode 2 ADCs */
+ {
+ .compatible = "ti,adcs7476",
+ .data = (void *)RCAR_GYROADC_MODE_SELECT_2_ADCS7476,
+ }, {
+ .compatible = "ti,adc121",
+ .data = (void *)RCAR_GYROADC_MODE_SELECT_2_ADCS7476,
+ }, {
+ .compatible = "adi,ad7476",
+ .data = (void *)RCAR_GYROADC_MODE_SELECT_2_ADCS7476,
+ },
+ /* Mode 3 ADCs */
+ {
+ .compatible = "maxim,max1162",
+ .data = (void *)RCAR_GYROADC_MODE_SELECT_3_MAX1162,
+ }, {
+ .compatible = "maxim,max11100",
+ .data = (void *)RCAR_GYROADC_MODE_SELECT_3_MAX1162,
+ },
+ { /* sentinel */ }
+};
+
+static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev)
+{
+ const struct of_device_id *of_id;
+ const struct iio_chan_spec *channels;
+ struct rcar_gyroadc *priv = iio_priv(indio_dev);
+ struct device *dev = priv->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *child;
+ struct regulator *vref;
+ unsigned int reg;
+ unsigned int adcmode, childmode;
+ unsigned int sample_width;
+ unsigned int num_channels;
+ int ret, first = 1;
+
+ for_each_child_of_node(np, child) {
+ of_id = of_match_node(rcar_gyroadc_child_match, child);
+ if (!of_id) {
+ dev_err(dev, "Ignoring unsupported ADC \"%s\".",
+ child->name);
+ continue;
+ }
+
+ childmode = (unsigned int)of_id->data;
+ switch (childmode) {
+ case RCAR_GYROADC_MODE_SELECT_1_MB88101A:
+ sample_width = 12;
+ channels = rcar_gyroadc_iio_channels_1;
+ num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_1);
+ break;
+ case RCAR_GYROADC_MODE_SELECT_2_ADCS7476:
+ sample_width = 15;
+ channels = rcar_gyroadc_iio_channels_2;
+ num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_2);
+ break;
+ case RCAR_GYROADC_MODE_SELECT_3_MAX1162:
+ sample_width = 16;
+ channels = rcar_gyroadc_iio_channels_3;
+ num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_3);
+ break;
+ }
+
+ /*
+ * MB88101 is special in that it's only a single chip taking
+ * up all the CHS lines. Thus, the DT binding is also special
+ * and has no reg property. If we run into such ADC, handle
+ * it here.
+ */
+ if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) {
+ reg = 0;
+ } else {
+ ret = of_property_read_u32(child, "reg", &reg);
+ if (ret) {
+ dev_err(dev,
+ "Failed to get child reg property of ADC \"%s\".\n",
+ child->name);
+ return ret;
+ }
+
+ /* Channel number is too high. */
+ if (reg >= num_channels) {
+ dev_err(dev,
+ "Only %i channels supported with %s, but reg = <%i>.\n",
+ num_channels, child->name, reg);
+ return ret;
+ }
+ }
+
+ /* Child node selected different mode than the rest. */
+ if (!first && (adcmode != childmode)) {
+ dev_err(dev,
+ "Channel %i uses different ADC mode than the rest.\n",
+ reg);
+ return ret;
+ }
+
+ /* Channel is valid, grab the regulator. */
+ dev->of_node = child;
+ vref = devm_regulator_get(dev, "vref");
+ dev->of_node = np;
+ if (IS_ERR(vref)) {
+ dev_dbg(dev, "Channel %i 'vref' supply not connected.\n",
+ reg);
+ return PTR_ERR(vref);
+ }
+
+ priv->vref[reg] = vref;
+
+ if (!first)
+ continue;
+
+ /* First child node which passed sanity tests. */
+ adcmode = childmode;
+ first = 0;
+
+ priv->num_channels = num_channels;
+ priv->mode = childmode;
+ priv->sample_width = sample_width;
+
+ indio_dev->channels = channels;
+ indio_dev->num_channels = num_channels;
+
+ /*
+ * MB88101 is special and we only have one such device
+ * attached to the GyroADC at a time, so if we found it,
+ * we can stop parsing here.
+ */
+ if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A)
+ break;
+ }
+
+ if (first) {
+ dev_err(dev, "No valid ADC channels found, aborting.\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void rcar_gyroadc_deinit_supplies(struct iio_dev *indio_dev)
+{
+ struct rcar_gyroadc *priv = iio_priv(indio_dev);
+ unsigned int i;
+
+ for (i = 0; i < priv->num_channels; i++) {
+ if (!priv->vref[i])
+ continue;
+
+ regulator_disable(priv->vref[i]);
+ }
+}
+
+static int rcar_gyroadc_init_supplies(struct iio_dev *indio_dev)
+{
+ struct rcar_gyroadc *priv = iio_priv(indio_dev);
+ struct device *dev = priv->dev;
+ unsigned int i;
+ int ret;
+
+ for (i = 0; i < priv->num_channels; i++) {
+ if (!priv->vref[i])
+ continue;
+
+ ret = regulator_enable(priv->vref[i]);
+ if (ret) {
+ dev_err(dev, "Failed to enable regulator %i (ret=%i)\n",
+ i, ret);
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ rcar_gyroadc_deinit_supplies(indio_dev);
+ return ret;
+}
+
+static int rcar_gyroadc_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *of_id =
+ of_match_device(rcar_gyroadc_match, &pdev->dev);
+ struct device *dev = &pdev->dev;
+ struct rcar_gyroadc *priv;
+ struct iio_dev *indio_dev;
+ struct resource *mem;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
+ if (!indio_dev) {
+ dev_err(dev, "Failed to allocate IIO device.\n");
+ return -ENOMEM;
+ }
+
+ priv = iio_priv(indio_dev);
+ priv->dev = dev;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->regs = devm_ioremap_resource(dev, mem);
+ if (IS_ERR(priv->regs))
+ return PTR_ERR(priv->regs);
+
+ priv->iclk = devm_clk_get(dev, "if");
+ if (IS_ERR(priv->iclk)) {
+ ret = PTR_ERR(priv->iclk);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to get IF clock (ret=%i)\n", ret);
+ return ret;
+ }
+
+ ret = rcar_gyroadc_parse_subdevs(indio_dev);
+ if (ret)
+ return ret;
+
+ ret = rcar_gyroadc_init_supplies(indio_dev);
+ if (ret)
+ return ret;
+
+ priv->model = (enum rcar_gyroadc_model)of_id->data;
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ indio_dev->name = DRIVER_NAME;
+ indio_dev->dev.parent = dev;
+ indio_dev->dev.of_node = pdev->dev.of_node;
+ indio_dev->info = &rcar_gyroadc_iio_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = clk_prepare_enable(priv->iclk);
+ if (ret) {
+ dev_err(dev, "Could not prepare or enable the IF clock.\n");
+ goto err_clk_if_enable;
+ }
+
+ pm_runtime_set_autosuspend_delay(dev, RCAR_GYROADC_RUNTIME_PM_DELAY_MS);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_enable(dev);
+
+ pm_runtime_get_sync(dev);
+ rcar_gyroadc_hw_init(priv);
+ rcar_gyroadc_hw_start(priv);
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(dev, "Couldn't register IIO device.\n");
+ goto err_iio_device_register;
+ }
+
+ pm_runtime_put_sync(dev);
+
+ return 0;
+
+err_iio_device_register:
+ rcar_gyroadc_hw_stop(priv);
+ pm_runtime_put_sync(dev);
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ clk_disable_unprepare(priv->iclk);
+err_clk_if_enable:
+ rcar_gyroadc_deinit_supplies(indio_dev);
+
+ return ret;
+}
+
+static int rcar_gyroadc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct rcar_gyroadc *priv = iio_priv(indio_dev);
+ struct device *dev = priv->dev;
+
+ iio_device_unregister(indio_dev);
+ pm_runtime_get_sync(dev);
+ rcar_gyroadc_hw_stop(priv);
+ pm_runtime_put_sync(dev);
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ clk_disable_unprepare(priv->iclk);
+ rcar_gyroadc_deinit_supplies(indio_dev);
+
+ return 0;
+}
+
+#if defined(CONFIG_PM)
+static int rcar_gyroadc_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct rcar_gyroadc *priv = iio_priv(indio_dev);
+
+ rcar_gyroadc_hw_stop(priv);
+
+ return 0;
+}
+
+static int rcar_gyroadc_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct rcar_gyroadc *priv = iio_priv(indio_dev);
+
+ rcar_gyroadc_hw_start(priv);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops rcar_gyroadc_pm_ops = {
+ SET_RUNTIME_PM_OPS(rcar_gyroadc_suspend, rcar_gyroadc_resume, NULL)
+};
+
+static struct platform_driver rcar_gyroadc_driver = {
+ .probe = rcar_gyroadc_probe,
+ .remove = rcar_gyroadc_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .of_match_table = rcar_gyroadc_match,
+ .pm = &rcar_gyroadc_pm_ops,
+ },
+};
+
+module_platform_driver(rcar_gyroadc_driver);
+
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("Renesas R-Car GyroADC driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/adc/stx104.c b/drivers/iio/adc/stx104.c
index 7e3645749eaf..c56ff286695d 100644
--- a/drivers/iio/adc/stx104.c
+++ b/drivers/iio/adc/stx104.c
@@ -339,30 +339,13 @@ static int stx104_probe(struct device *dev, unsigned int id)
stx104dev->chip = &stx104gpio->chip;
dev_set_drvdata(dev, stx104dev);
- err = gpiochip_add_data(&stx104gpio->chip, stx104gpio);
+ err = devm_gpiochip_add_data(dev, &stx104gpio->chip, stx104gpio);
if (err) {
dev_err(dev, "GPIO registering failed (%d)\n", err);
return err;
}
- err = iio_device_register(indio_dev);
- if (err) {
- dev_err(dev, "IIO device registering failed (%d)\n", err);
- gpiochip_remove(&stx104gpio->chip);
- return err;
- }
-
- return 0;
-}
-
-static int stx104_remove(struct device *dev, unsigned int id)
-{
- struct stx104_dev *const stx104dev = dev_get_drvdata(dev);
-
- iio_device_unregister(stx104dev->indio_dev);
- gpiochip_remove(stx104dev->chip);
-
- return 0;
+ return devm_iio_device_register(dev, indio_dev);
}
static struct isa_driver stx104_driver = {
@@ -370,7 +353,6 @@ static struct isa_driver stx104_driver = {
.driver = {
.name = "stx104"
},
- .remove = stx104_remove
};
module_isa_driver(stx104_driver, num_stx104);
diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c
index cde6f130a99a..422b314f5a3f 100644
--- a/drivers/iio/adc/ti-ads1015.c
+++ b/drivers/iio/adc/ti-ads1015.c
@@ -472,14 +472,14 @@ static const struct attribute_group ads1115_attribute_group = {
.attrs = ads1115_attributes,
};
-static struct iio_info ads1015_info = {
+static const struct iio_info ads1015_info = {
.driver_module = THIS_MODULE,
.read_raw = ads1015_read_raw,
.write_raw = ads1015_write_raw,
.attrs = &ads1015_attribute_group,
};
-static struct iio_info ads1115_info = {
+static const struct iio_info ads1115_info = {
.driver_module = THIS_MODULE,
.read_raw = ads1015_read_raw,
.write_raw = ads1015_write_raw,
diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c
new file mode 100644
index 000000000000..16a06633332c
--- /dev/null
+++ b/drivers/iio/adc/ti-ads7950.c
@@ -0,0 +1,490 @@
+/*
+ * Texas Instruments ADS7950 SPI ADC driver
+ *
+ * Copyright 2016 David Lechner <david@lechnology.com>
+ *
+ * Based on iio/ad7923.c:
+ * Copyright 2011 Analog Devices Inc
+ * Copyright 2012 CS Systemes d'Information
+ *
+ * And also on hwmon/ads79xx.c
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define TI_ADS7950_CR_MANUAL BIT(12)
+#define TI_ADS7950_CR_WRITE BIT(11)
+#define TI_ADS7950_CR_CHAN(ch) ((ch) << 7)
+#define TI_ADS7950_CR_RANGE_5V BIT(6)
+
+#define TI_ADS7950_MAX_CHAN 16
+
+#define TI_ADS7950_TIMESTAMP_SIZE (sizeof(int64_t) / sizeof(__be16))
+
+/* val = value, dec = left shift, bits = number of bits of the mask */
+#define TI_ADS7950_EXTRACT(val, dec, bits) \
+ (((val) >> (dec)) & ((1 << (bits)) - 1))
+
+struct ti_ads7950_state {
+ struct spi_device *spi;
+ struct spi_transfer ring_xfer[TI_ADS7950_MAX_CHAN + 2];
+ struct spi_transfer scan_single_xfer[3];
+ struct spi_message ring_msg;
+ struct spi_message scan_single_msg;
+
+ struct regulator *reg;
+
+ unsigned int settings;
+
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+ __be16 rx_buf[TI_ADS7950_MAX_CHAN + TI_ADS7950_TIMESTAMP_SIZE]
+ ____cacheline_aligned;
+ __be16 tx_buf[TI_ADS7950_MAX_CHAN];
+};
+
+struct ti_ads7950_chip_info {
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
+};
+
+enum ti_ads7950_id {
+ TI_ADS7950,
+ TI_ADS7951,
+ TI_ADS7952,
+ TI_ADS7953,
+ TI_ADS7954,
+ TI_ADS7955,
+ TI_ADS7956,
+ TI_ADS7957,
+ TI_ADS7958,
+ TI_ADS7959,
+ TI_ADS7960,
+ TI_ADS7961,
+};
+
+#define TI_ADS7950_V_CHAN(index, bits) \
+{ \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = index, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .address = index, \
+ .datasheet_name = "CH##index", \
+ .scan_index = index, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = bits, \
+ .storagebits = 16, \
+ .shift = 12 - (bits), \
+ .endianness = IIO_BE, \
+ }, \
+}
+
+#define DECLARE_TI_ADS7950_4_CHANNELS(name, bits) \
+const struct iio_chan_spec name ## _channels[] = { \
+ TI_ADS7950_V_CHAN(0, bits), \
+ TI_ADS7950_V_CHAN(1, bits), \
+ TI_ADS7950_V_CHAN(2, bits), \
+ TI_ADS7950_V_CHAN(3, bits), \
+ IIO_CHAN_SOFT_TIMESTAMP(4), \
+}
+
+#define DECLARE_TI_ADS7950_8_CHANNELS(name, bits) \
+const struct iio_chan_spec name ## _channels[] = { \
+ TI_ADS7950_V_CHAN(0, bits), \
+ TI_ADS7950_V_CHAN(1, bits), \
+ TI_ADS7950_V_CHAN(2, bits), \
+ TI_ADS7950_V_CHAN(3, bits), \
+ TI_ADS7950_V_CHAN(4, bits), \
+ TI_ADS7950_V_CHAN(5, bits), \
+ TI_ADS7950_V_CHAN(6, bits), \
+ TI_ADS7950_V_CHAN(7, bits), \
+ IIO_CHAN_SOFT_TIMESTAMP(8), \
+}
+
+#define DECLARE_TI_ADS7950_12_CHANNELS(name, bits) \
+const struct iio_chan_spec name ## _channels[] = { \
+ TI_ADS7950_V_CHAN(0, bits), \
+ TI_ADS7950_V_CHAN(1, bits), \
+ TI_ADS7950_V_CHAN(2, bits), \
+ TI_ADS7950_V_CHAN(3, bits), \
+ TI_ADS7950_V_CHAN(4, bits), \
+ TI_ADS7950_V_CHAN(5, bits), \
+ TI_ADS7950_V_CHAN(6, bits), \
+ TI_ADS7950_V_CHAN(7, bits), \
+ TI_ADS7950_V_CHAN(8, bits), \
+ TI_ADS7950_V_CHAN(9, bits), \
+ TI_ADS7950_V_CHAN(10, bits), \
+ TI_ADS7950_V_CHAN(11, bits), \
+ IIO_CHAN_SOFT_TIMESTAMP(12), \
+}
+
+#define DECLARE_TI_ADS7950_16_CHANNELS(name, bits) \
+const struct iio_chan_spec name ## _channels[] = { \
+ TI_ADS7950_V_CHAN(0, bits), \
+ TI_ADS7950_V_CHAN(1, bits), \
+ TI_ADS7950_V_CHAN(2, bits), \
+ TI_ADS7950_V_CHAN(3, bits), \
+ TI_ADS7950_V_CHAN(4, bits), \
+ TI_ADS7950_V_CHAN(5, bits), \
+ TI_ADS7950_V_CHAN(6, bits), \
+ TI_ADS7950_V_CHAN(7, bits), \
+ TI_ADS7950_V_CHAN(8, bits), \
+ TI_ADS7950_V_CHAN(9, bits), \
+ TI_ADS7950_V_CHAN(10, bits), \
+ TI_ADS7950_V_CHAN(11, bits), \
+ TI_ADS7950_V_CHAN(12, bits), \
+ TI_ADS7950_V_CHAN(13, bits), \
+ TI_ADS7950_V_CHAN(14, bits), \
+ TI_ADS7950_V_CHAN(15, bits), \
+ IIO_CHAN_SOFT_TIMESTAMP(16), \
+}
+
+static DECLARE_TI_ADS7950_4_CHANNELS(ti_ads7950, 12);
+static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7951, 12);
+static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7952, 12);
+static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7953, 12);
+static DECLARE_TI_ADS7950_4_CHANNELS(ti_ads7954, 10);
+static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7955, 10);
+static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7956, 10);
+static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7957, 10);
+static DECLARE_TI_ADS7950_4_CHANNELS(ti_ads7958, 8);
+static DECLARE_TI_ADS7950_8_CHANNELS(ti_ads7959, 8);
+static DECLARE_TI_ADS7950_12_CHANNELS(ti_ads7960, 8);
+static DECLARE_TI_ADS7950_16_CHANNELS(ti_ads7961, 8);
+
+static const struct ti_ads7950_chip_info ti_ads7950_chip_info[] = {
+ [TI_ADS7950] = {
+ .channels = ti_ads7950_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7950_channels),
+ },
+ [TI_ADS7951] = {
+ .channels = ti_ads7951_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7951_channels),
+ },
+ [TI_ADS7952] = {
+ .channels = ti_ads7952_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7952_channels),
+ },
+ [TI_ADS7953] = {
+ .channels = ti_ads7953_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7953_channels),
+ },
+ [TI_ADS7954] = {
+ .channels = ti_ads7954_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7954_channels),
+ },
+ [TI_ADS7955] = {
+ .channels = ti_ads7955_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7955_channels),
+ },
+ [TI_ADS7956] = {
+ .channels = ti_ads7956_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7956_channels),
+ },
+ [TI_ADS7957] = {
+ .channels = ti_ads7957_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7957_channels),
+ },
+ [TI_ADS7958] = {
+ .channels = ti_ads7958_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7958_channels),
+ },
+ [TI_ADS7959] = {
+ .channels = ti_ads7959_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7959_channels),
+ },
+ [TI_ADS7960] = {
+ .channels = ti_ads7960_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7960_channels),
+ },
+ [TI_ADS7961] = {
+ .channels = ti_ads7961_channels,
+ .num_channels = ARRAY_SIZE(ti_ads7961_channels),
+ },
+};
+
+/*
+ * ti_ads7950_update_scan_mode() setup the spi transfer buffer for the new
+ * scan mask
+ */
+static int ti_ads7950_update_scan_mode(struct iio_dev *indio_dev,
+ const unsigned long *active_scan_mask)
+{
+ struct ti_ads7950_state *st = iio_priv(indio_dev);
+ int i, cmd, len;
+
+ len = 0;
+ for_each_set_bit(i, active_scan_mask, indio_dev->num_channels) {
+ cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(i) | st->settings;
+ st->tx_buf[len++] = cpu_to_be16(cmd);
+ }
+
+ /* Data for the 1st channel is not returned until the 3rd transfer */
+ len += 2;
+ for (i = 0; i < len; i++) {
+ if ((i + 2) < len)
+ st->ring_xfer[i].tx_buf = &st->tx_buf[i];
+ if (i >= 2)
+ st->ring_xfer[i].rx_buf = &st->rx_buf[i - 2];
+ st->ring_xfer[i].len = 2;
+ st->ring_xfer[i].cs_change = 1;
+ }
+ /* make sure last transfer's cs_change is not set */
+ st->ring_xfer[len - 1].cs_change = 0;
+
+ spi_message_init_with_transfers(&st->ring_msg, st->ring_xfer, len);
+
+ return 0;
+}
+
+static irqreturn_t ti_ads7950_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct ti_ads7950_state *st = iio_priv(indio_dev);
+ int ret;
+
+ ret = spi_sync(st->spi, &st->ring_msg);
+ if (ret < 0)
+ goto out;
+
+ iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+ iio_get_time_ns(indio_dev));
+
+out:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+}
+
+static int ti_ads7950_scan_direct(struct ti_ads7950_state *st, unsigned int ch)
+{
+ int ret, cmd;
+
+ cmd = TI_ADS7950_CR_WRITE | TI_ADS7950_CR_CHAN(ch) | st->settings;
+ st->tx_buf[0] = cpu_to_be16(cmd);
+
+ ret = spi_sync(st->spi, &st->scan_single_msg);
+ if (ret)
+ return ret;
+
+ return be16_to_cpu(st->rx_buf[0]);
+}
+
+static int ti_ads7950_get_range(struct ti_ads7950_state *st)
+{
+ int vref;
+
+ vref = regulator_get_voltage(st->reg);
+ if (vref < 0)
+ return vref;
+
+ vref /= 1000;
+
+ if (st->settings & TI_ADS7950_CR_RANGE_5V)
+ vref *= 2;
+
+ return vref;
+}
+
+static int ti_ads7950_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long m)
+{
+ struct ti_ads7950_state *st = iio_priv(indio_dev);
+ int ret;
+
+ switch (m) {
+ case IIO_CHAN_INFO_RAW:
+
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret < 0)
+ return ret;
+
+ ret = ti_ads7950_scan_direct(st, chan->address);
+ iio_device_release_direct_mode(indio_dev);
+ if (ret < 0)
+ return ret;
+
+ if (chan->address != TI_ADS7950_EXTRACT(ret, 12, 4))
+ return -EIO;
+
+ *val = TI_ADS7950_EXTRACT(ret, chan->scan_type.shift,
+ chan->scan_type.realbits);
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ ret = ti_ads7950_get_range(st);
+ if (ret < 0)
+ return ret;
+
+ *val = ret;
+ *val2 = (1 << chan->scan_type.realbits) - 1;
+
+ return IIO_VAL_FRACTIONAL;
+ }
+
+ return -EINVAL;
+}
+
+static const struct iio_info ti_ads7950_info = {
+ .read_raw = &ti_ads7950_read_raw,
+ .update_scan_mode = ti_ads7950_update_scan_mode,
+ .driver_module = THIS_MODULE,
+};
+
+static int ti_ads7950_probe(struct spi_device *spi)
+{
+ struct ti_ads7950_state *st;
+ struct iio_dev *indio_dev;
+ const struct ti_ads7950_chip_info *info;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+
+ spi_set_drvdata(spi, indio_dev);
+
+ st->spi = spi;
+ st->settings = TI_ADS7950_CR_MANUAL | TI_ADS7950_CR_RANGE_5V;
+
+ info = &ti_ads7950_chip_info[spi_get_device_id(spi)->driver_data];
+
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = info->channels;
+ indio_dev->num_channels = info->num_channels;
+ indio_dev->info = &ti_ads7950_info;
+
+ /*
+ * Setup default message. The sample is read at the end of the first
+ * transfer, then it takes one full cycle to convert the sample and one
+ * more cycle to send the value. The conversion process is driven by
+ * the SPI clock, which is why we have 3 transfers. The middle one is
+ * just dummy data sent while the chip is converting the sample that
+ * was read at the end of the first transfer.
+ */
+
+ st->scan_single_xfer[0].tx_buf = &st->tx_buf[0];
+ st->scan_single_xfer[0].len = 2;
+ st->scan_single_xfer[0].cs_change = 1;
+ st->scan_single_xfer[1].tx_buf = &st->tx_buf[0];
+ st->scan_single_xfer[1].len = 2;
+ st->scan_single_xfer[1].cs_change = 1;
+ st->scan_single_xfer[2].rx_buf = &st->rx_buf[0];
+ st->scan_single_xfer[2].len = 2;
+
+ spi_message_init_with_transfers(&st->scan_single_msg,
+ st->scan_single_xfer, 3);
+
+ st->reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(st->reg)) {
+ dev_err(&spi->dev, "Failed get get regulator \"vref\"\n");
+ return PTR_ERR(st->reg);
+ }
+
+ ret = regulator_enable(st->reg);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to enable regulator \"vref\"\n");
+ return ret;
+ }
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ &ti_ads7950_trigger_handler, NULL);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to setup triggered buffer\n");
+ goto error_disable_reg;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret) {
+ dev_err(&spi->dev, "Failed to register iio device\n");
+ goto error_cleanup_ring;
+ }
+
+ return 0;
+
+error_cleanup_ring:
+ iio_triggered_buffer_cleanup(indio_dev);
+error_disable_reg:
+ regulator_disable(st->reg);
+
+ return ret;
+}
+
+static int ti_ads7950_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct ti_ads7950_state *st = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ regulator_disable(st->reg);
+
+ return 0;
+}
+
+static const struct spi_device_id ti_ads7950_id[] = {
+ { "ads7950", TI_ADS7950 },
+ { "ads7951", TI_ADS7951 },
+ { "ads7952", TI_ADS7952 },
+ { "ads7953", TI_ADS7953 },
+ { "ads7954", TI_ADS7954 },
+ { "ads7955", TI_ADS7955 },
+ { "ads7956", TI_ADS7956 },
+ { "ads7957", TI_ADS7957 },
+ { "ads7958", TI_ADS7958 },
+ { "ads7959", TI_ADS7959 },
+ { "ads7960", TI_ADS7960 },
+ { "ads7961", TI_ADS7961 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, ti_ads7950_id);
+
+static struct spi_driver ti_ads7950_driver = {
+ .driver = {
+ .name = "ads7950",
+ },
+ .probe = ti_ads7950_probe,
+ .remove = ti_ads7950_remove,
+ .id_table = ti_ads7950_id,
+};
+module_spi_driver(ti_ads7950_driver);
+
+MODULE_AUTHOR("David Lechner <david@lechnology.com>");
+MODULE_DESCRIPTION("TI TI_ADS7950 ADC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c
new file mode 100644
index 000000000000..78d91a069ea4
--- /dev/null
+++ b/drivers/iio/adc/ti-tlc4541.c
@@ -0,0 +1,271 @@
+/*
+ * TI tlc4541 ADC Driver
+ *
+ * Copyright (C) 2017 Phil Reid
+ *
+ * Datasheets can be found here:
+ * http://www.ti.com/lit/gpn/tlc3541
+ * http://www.ti.com/lit/gpn/tlc4541
+ *
+ * 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.
+ *
+ * The tlc4541 requires 24 clock cycles to start a transfer.
+ * Conversion then takes 2.94us to complete before data is ready
+ * Data is returned MSB first.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+
+struct tlc4541_state {
+ struct spi_device *spi;
+ struct regulator *reg;
+ struct spi_transfer scan_single_xfer[3];
+ struct spi_message scan_single_msg;
+
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ * 2 bytes data + 6 bytes padding + 8 bytes timestamp when
+ * call iio_push_to_buffers_with_timestamp.
+ */
+ __be16 rx_buf[8] ____cacheline_aligned;
+};
+
+struct tlc4541_chip_info {
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
+};
+
+enum tlc4541_id {
+ TLC3541,
+ TLC4541,
+};
+
+#define TLC4541_V_CHAN(bits, bitshift) { \
+ .type = IIO_VOLTAGE, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = (bits), \
+ .storagebits = 16, \
+ .shift = (bitshift), \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+#define DECLARE_TLC4541_CHANNELS(name, bits, bitshift) \
+const struct iio_chan_spec name ## _channels[] = { \
+ TLC4541_V_CHAN(bits, bitshift), \
+ IIO_CHAN_SOFT_TIMESTAMP(1), \
+}
+
+static DECLARE_TLC4541_CHANNELS(tlc3541, 14, 2);
+static DECLARE_TLC4541_CHANNELS(tlc4541, 16, 0);
+
+static const struct tlc4541_chip_info tlc4541_chip_info[] = {
+ [TLC3541] = {
+ .channels = tlc3541_channels,
+ .num_channels = ARRAY_SIZE(tlc3541_channels),
+ },
+ [TLC4541] = {
+ .channels = tlc4541_channels,
+ .num_channels = ARRAY_SIZE(tlc4541_channels),
+ },
+};
+
+static irqreturn_t tlc4541_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct tlc4541_state *st = iio_priv(indio_dev);
+ int ret;
+
+ ret = spi_sync(st->spi, &st->scan_single_msg);
+ if (ret < 0)
+ goto done;
+
+ iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+ iio_get_time_ns(indio_dev));
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+ return IRQ_HANDLED;
+}
+
+static int tlc4541_get_range(struct tlc4541_state *st)
+{
+ int vref;
+
+ vref = regulator_get_voltage(st->reg);
+ if (vref < 0)
+ return vref;
+
+ vref /= 1000;
+
+ return vref;
+}
+
+static int tlc4541_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long m)
+{
+ int ret = 0;
+ struct tlc4541_state *st = iio_priv(indio_dev);
+
+ switch (m) {
+ case IIO_CHAN_INFO_RAW:
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+ ret = spi_sync(st->spi, &st->scan_single_msg);
+ iio_device_release_direct_mode(indio_dev);
+ if (ret < 0)
+ return ret;
+ *val = be16_to_cpu(st->rx_buf[0]);
+ *val = *val >> chan->scan_type.shift;
+ *val &= GENMASK(chan->scan_type.realbits - 1, 0);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ ret = tlc4541_get_range(st);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+ *val2 = chan->scan_type.realbits;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ }
+ return -EINVAL;
+}
+
+static const struct iio_info tlc4541_info = {
+ .read_raw = &tlc4541_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int tlc4541_probe(struct spi_device *spi)
+{
+ struct tlc4541_state *st;
+ struct iio_dev *indio_dev;
+ const struct tlc4541_chip_info *info;
+ int ret;
+ int8_t device_init = 0;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+
+ spi_set_drvdata(spi, indio_dev);
+
+ st->spi = spi;
+
+ info = &tlc4541_chip_info[spi_get_device_id(spi)->driver_data];
+
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = info->channels;
+ indio_dev->num_channels = info->num_channels;
+ indio_dev->info = &tlc4541_info;
+
+ /* perform reset */
+ spi_write(spi, &device_init, 1);
+
+ /* Setup default message */
+ st->scan_single_xfer[0].rx_buf = &st->rx_buf[0];
+ st->scan_single_xfer[0].len = 3;
+ st->scan_single_xfer[1].delay_usecs = 3;
+ st->scan_single_xfer[2].rx_buf = &st->rx_buf[0];
+ st->scan_single_xfer[2].len = 2;
+
+ spi_message_init_with_transfers(&st->scan_single_msg,
+ st->scan_single_xfer, 3);
+
+ st->reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
+
+ ret = regulator_enable(st->reg);
+ if (ret)
+ return ret;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ &tlc4541_trigger_handler, NULL);
+ if (ret)
+ goto error_disable_reg;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto error_cleanup_buffer;
+
+ return 0;
+
+error_cleanup_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+error_disable_reg:
+ regulator_disable(st->reg);
+
+ return ret;
+}
+
+static int tlc4541_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct tlc4541_state *st = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ regulator_disable(st->reg);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id tlc4541_dt_ids[] = {
+ { .compatible = "ti,tlc3541", },
+ { .compatible = "ti,tlc4541", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, tlc4541_dt_ids);
+#endif
+
+static const struct spi_device_id tlc4541_id[] = {
+ {"tlc3541", TLC3541},
+ {"tlc4541", TLC4541},
+ {}
+};
+MODULE_DEVICE_TABLE(spi, tlc4541_id);
+
+static struct spi_driver tlc4541_driver = {
+ .driver = {
+ .name = "tlc4541",
+ .of_match_table = of_match_ptr(tlc4541_dt_ids),
+ },
+ .probe = tlc4541_probe,
+ .remove = tlc4541_remove,
+ .id_table = tlc4541_id,
+};
+module_spi_driver(tlc4541_driver);
+
+MODULE_AUTHOR("Phil Reid <preid@electromag.com.au>");
+MODULE_DESCRIPTION("Texas Instruments TLC4541 ADC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c
index b8f550e47d3d..4847534700e7 100644
--- a/drivers/iio/buffer/industrialio-buffer-cb.c
+++ b/drivers/iio/buffer/industrialio-buffer-cb.c
@@ -10,7 +10,8 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/export.h>
-#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer_impl.h>
#include <linux/iio/consumer.h>
struct iio_cb_buffer {
diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c
index c5b999f0c519..047fe757ab97 100644
--- a/drivers/iio/buffer/kfifo_buf.c
+++ b/drivers/iio/buffer/kfifo_buf.c
@@ -5,7 +5,10 @@
#include <linux/workqueue.h>
#include <linux/kfifo.h>
#include <linux/mutex.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/buffer_impl.h>
#include <linux/sched.h>
#include <linux/poll.h>
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
index 7ef94a90ecf7..7afdac42ed42 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
@@ -58,6 +58,10 @@ static struct {
{HID_USAGE_SENSOR_PRESSURE, 0, 100, 0},
{HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000000},
+
+ {HID_USAGE_SENSOR_TIME_TIMESTAMP, 0, 1000000000, 0},
+ {HID_USAGE_SENSOR_TIME_TIMESTAMP, HID_USAGE_SENSOR_UNITS_MILLISECOND,
+ 1000000, 0},
};
static int pow_10(unsigned power)
@@ -346,6 +350,13 @@ int hid_sensor_format_scale(u32 usage_id,
}
EXPORT_SYMBOL(hid_sensor_format_scale);
+int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st,
+ int64_t raw_value)
+{
+ return st->timestamp_ns_scale * raw_value;
+}
+EXPORT_SYMBOL(hid_sensor_convert_timestamp);
+
static
int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev,
u32 usage_id,
@@ -367,6 +378,7 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
struct hid_sensor_common *st)
{
+ struct hid_sensor_hub_attribute_info timestamp;
hid_sensor_get_reporting_interval(hsdev, usage_id, st);
@@ -385,11 +397,25 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS,
&st->sensitivity);
- hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x\n",
- st->poll.index, st->poll.report_id,
- st->report_state.index, st->report_state.report_id,
- st->power_state.index, st->power_state.report_id,
- st->sensitivity.index, st->sensitivity.report_id);
+ sensor_hub_input_get_attribute_info(hsdev,
+ HID_INPUT_REPORT, usage_id,
+ HID_USAGE_SENSOR_TIME_TIMESTAMP,
+ &timestamp);
+ if (timestamp.index >= 0 && timestamp.report_id) {
+ int val0, val1;
+
+ hid_sensor_format_scale(HID_USAGE_SENSOR_TIME_TIMESTAMP,
+ &timestamp, &val0, &val1);
+ st->timestamp_ns_scale = val0;
+ } else
+ st->timestamp_ns_scale = 1000000000;
+
+ hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x %x:%x\n",
+ st->poll.index, st->poll.report_id,
+ st->report_state.index, st->report_state.report_id,
+ st->power_state.index, st->power_state.report_id,
+ st->sensitivity.index, st->sensitivity.report_id,
+ timestamp.index, timestamp.report_id);
return 0;
}
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio.c b/drivers/iio/common/ssp_sensors/ssp_iio.c
index a3ae165f8d9f..645f2e3975db 100644
--- a/drivers/iio/common/ssp_sensors/ssp_iio.c
+++ b/drivers/iio/common/ssp_sensors/ssp_iio.c
@@ -14,6 +14,7 @@
*/
#include <linux/iio/common/ssp_sensors.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/module.h>
#include <linux/slab.h>
diff --git a/drivers/iio/common/st_sensors/st_sensors_buffer.c b/drivers/iio/common/st_sensors/st_sensors_buffer.c
index fe7775bb3740..df4045203a07 100644
--- a/drivers/iio/common/st_sensors/st_sensors_buffer.c
+++ b/drivers/iio/common/st_sensors/st_sensors_buffer.c
@@ -30,7 +30,9 @@ static int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf)
for_each_set_bit(i, indio_dev->active_scan_mask, num_data_channels) {
const struct iio_chan_spec *channel = &indio_dev->channels[i];
- unsigned int bytes_to_read = channel->scan_type.realbits >> 3;
+ unsigned int bytes_to_read =
+ DIV_ROUND_UP(channel->scan_type.realbits +
+ channel->scan_type.shift, 8);
unsigned int storage_bytes =
channel->scan_type.storagebits >> 3;
diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
index 975a1f19f747..79c8c7cd70d5 100644
--- a/drivers/iio/common/st_sensors/st_sensors_core.c
+++ b/drivers/iio/common/st_sensors/st_sensors_core.c
@@ -401,6 +401,15 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
return err;
}
+ /* set DAS */
+ if (sdata->sensor_settings->das.addr) {
+ err = st_sensors_write_data_with_mask(indio_dev,
+ sdata->sensor_settings->das.addr,
+ sdata->sensor_settings->das.mask, 1);
+ if (err < 0)
+ return err;
+ }
+
if (sdata->int_pin_open_drain) {
dev_info(&indio_dev->dev,
"set interrupt line to open drain mode\n");
@@ -483,8 +492,10 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
int err;
u8 *outdata;
struct st_sensor_data *sdata = iio_priv(indio_dev);
- unsigned int byte_for_channel = ch->scan_type.realbits >> 3;
+ unsigned int byte_for_channel;
+ byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
+ ch->scan_type.shift, 8);
outdata = kmalloc(byte_for_channel, GFP_KERNEL);
if (!outdata)
return -ENOMEM;
diff --git a/drivers/iio/common/st_sensors/st_sensors_i2c.c b/drivers/iio/common/st_sensors/st_sensors_i2c.c
index b43aa36031f8..c83df4dbfcd7 100644
--- a/drivers/iio/common/st_sensors/st_sensors_i2c.c
+++ b/drivers/iio/common/st_sensors/st_sensors_i2c.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/iio/iio.h>
#include <linux/of_device.h>
+#include <linux/acpi.h>
#include <linux/iio/common/st_sensors_i2c.h>
@@ -107,6 +108,25 @@ void st_sensors_of_i2c_probe(struct i2c_client *client,
EXPORT_SYMBOL(st_sensors_of_i2c_probe);
#endif
+#ifdef CONFIG_ACPI
+int st_sensors_match_acpi_device(struct device *dev)
+{
+ const struct acpi_device_id *acpi_id;
+ kernel_ulong_t driver_data = 0;
+
+ if (ACPI_HANDLE(dev)) {
+ acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev);
+ if (!acpi_id) {
+ dev_err(dev, "No driver data\n");
+ return -EINVAL;
+ }
+ driver_data = acpi_id->driver_data;
+ }
+ return driver_data;
+}
+EXPORT_SYMBOL(st_sensors_match_acpi_device);
+#endif
+
MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
MODULE_DESCRIPTION("STMicroelectronics ST-sensors i2c driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/counter/104-quad-8.c b/drivers/iio/counter/104-quad-8.c
index 2d2ee353dde7..a5913e97945e 100644
--- a/drivers/iio/counter/104-quad-8.c
+++ b/drivers/iio/counter/104-quad-8.c
@@ -153,7 +153,7 @@ static int quad8_write_raw(struct iio_dev *indio_dev,
ior_cfg = val | priv->preset_enable[chan->channel] << 1;
/* Load I/O control configuration */
- outb(0x40 | ior_cfg, base_offset);
+ outb(0x40 | ior_cfg, base_offset + 1);
return 0;
case IIO_CHAN_INFO_SCALE:
@@ -233,7 +233,7 @@ static ssize_t quad8_read_set_to_preset_on_index(struct iio_dev *indio_dev,
const struct quad8_iio *const priv = iio_priv(indio_dev);
return snprintf(buf, PAGE_SIZE, "%u\n",
- priv->preset_enable[chan->channel]);
+ !priv->preset_enable[chan->channel]);
}
static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev,
@@ -241,7 +241,7 @@ static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev,
size_t len)
{
struct quad8_iio *const priv = iio_priv(indio_dev);
- const int base_offset = priv->base + 2 * chan->channel;
+ const int base_offset = priv->base + 2 * chan->channel + 1;
bool preset_enable;
int ret;
unsigned int ior_cfg;
@@ -250,6 +250,9 @@ static ssize_t quad8_write_set_to_preset_on_index(struct iio_dev *indio_dev,
if (ret)
return ret;
+ /* Preset enable is active low in Input/Output Control register */
+ preset_enable = !preset_enable;
+
priv->preset_enable[chan->channel] = preset_enable;
ior_cfg = priv->ab_enable[chan->channel] |
@@ -362,7 +365,7 @@ static int quad8_set_synchronous_mode(struct iio_dev *indio_dev,
priv->synchronous_mode[chan->channel] = synchronous_mode;
/* Load Index Control configuration to Index Control Register */
- outb(0x40 | idr_cfg, base_offset);
+ outb(0x60 | idr_cfg, base_offset);
return 0;
}
@@ -444,7 +447,7 @@ static int quad8_set_index_polarity(struct iio_dev *indio_dev,
priv->index_polarity[chan->channel] = index_polarity;
/* Load Index Control configuration to Index Control Register */
- outb(0x40 | idr_cfg, base_offset);
+ outb(0x60 | idr_cfg, base_offset);
return 0;
}
diff --git a/drivers/iio/dac/ad5592r.c b/drivers/iio/dac/ad5592r.c
index 6eed5b7729be..6a12a3c9d94f 100644
--- a/drivers/iio/dac/ad5592r.c
+++ b/drivers/iio/dac/ad5592r.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/spi/spi.h>
+#include <linux/acpi.h>
#define AD5592R_GPIO_READBACK_EN BIT(10)
#define AD5592R_LDAC_READBACK_EN BIT(6)
@@ -148,10 +149,17 @@ static const struct of_device_id ad5592r_of_match[] = {
};
MODULE_DEVICE_TABLE(of, ad5592r_of_match);
+static const struct acpi_device_id ad5592r_acpi_match[] = {
+ {"ADS5592", },
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, ad5592r_acpi_match);
+
static struct spi_driver ad5592r_spi_driver = {
.driver = {
.name = "ad5592r",
.of_match_table = of_match_ptr(ad5592r_of_match),
+ .acpi_match_table = ACPI_PTR(ad5592r_acpi_match),
},
.probe = ad5592r_spi_probe,
.remove = ad5592r_spi_remove,
diff --git a/drivers/iio/dac/ad5593r.c b/drivers/iio/dac/ad5593r.c
index dca158a88f47..fc11ea098f98 100644
--- a/drivers/iio/dac/ad5593r.c
+++ b/drivers/iio/dac/ad5593r.c
@@ -13,6 +13,7 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/acpi.h>
#define AD5593R_MODE_CONF (0 << 4)
#define AD5593R_MODE_DAC_WRITE (1 << 4)
@@ -115,10 +116,17 @@ static const struct of_device_id ad5593r_of_match[] = {
};
MODULE_DEVICE_TABLE(of, ad5593r_of_match);
+static const struct acpi_device_id ad5593r_acpi_match[] = {
+ {"ADS5593", },
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, ad5593r_acpi_match);
+
static struct i2c_driver ad5593r_driver = {
.driver = {
.name = "ad5593r",
.of_match_table = of_match_ptr(ad5593r_of_match),
+ .acpi_match_table = ACPI_PTR(ad5593r_acpi_match),
},
.probe = ad5593r_i2c_probe,
.remove = ad5593r_i2c_remove,
diff --git a/drivers/iio/dummy/iio_simple_dummy.h b/drivers/iio/dummy/iio_simple_dummy.h
index b9069a180672..f7005c3f5df3 100644
--- a/drivers/iio/dummy/iio_simple_dummy.h
+++ b/drivers/iio/dummy/iio_simple_dummy.h
@@ -88,11 +88,11 @@ static inline int
iio_simple_dummy_events_register(struct iio_dev *indio_dev)
{
return 0;
-};
+}
static inline void
iio_simple_dummy_events_unregister(struct iio_dev *indio_dev)
-{ };
+{}
#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS*/
@@ -119,11 +119,11 @@ void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev);
static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
{
return 0;
-};
+}
static inline
void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
-{};
+{}
#endif /* CONFIG_IIO_SIMPLE_DUMMY_BUFFER */
#endif /* _IIO_SIMPLE_DUMMY_H_ */
diff --git a/drivers/iio/dummy/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c
index b383892a5193..744ca92c3c99 100644
--- a/drivers/iio/dummy/iio_simple_dummy_buffer.c
+++ b/drivers/iio/dummy/iio_simple_dummy_buffer.c
@@ -20,6 +20,7 @@
#include <linux/iio/iio.h>
#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
#include "iio_simple_dummy.h"
@@ -131,9 +132,6 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
iio_device_attach_buffer(indio_dev, buffer);
- /* Enable timestamps by default */
- buffer->scan_timestamp = true;
-
/*
* Tell the core what device type specific functions should
* be run on either side of buffer capture enable / disable.
diff --git a/drivers/iio/gyro/ssp_gyro_sensor.c b/drivers/iio/gyro/ssp_gyro_sensor.c
index 1f25f406c545..2dacd8e01045 100644
--- a/drivers/iio/gyro/ssp_gyro_sensor.c
+++ b/drivers/iio/gyro/ssp_gyro_sensor.c
@@ -15,6 +15,7 @@
#include <linux/iio/common/ssp_sensors.h>
#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -134,7 +135,7 @@ static int ssp_gyro_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev);
- ret = iio_device_register(indio_dev);
+ ret = devm_iio_device_register(&pdev->dev, indio_dev);
if (ret < 0)
return ret;
@@ -144,21 +145,11 @@ static int ssp_gyro_probe(struct platform_device *pdev)
return 0;
}
-static int ssp_gyro_remove(struct platform_device *pdev)
-{
- struct iio_dev *indio_dev = platform_get_drvdata(pdev);
-
- iio_device_unregister(indio_dev);
-
- return 0;
-}
-
static struct platform_driver ssp_gyro_driver = {
.driver = {
.name = SSP_GYROSCOPE_NAME,
},
.probe = ssp_gyro_probe,
- .remove = ssp_gyro_remove,
};
module_platform_driver(ssp_gyro_driver);
diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c
index 90ab8a2d2846..9648c69ea1a2 100644
--- a/drivers/iio/health/max30100.c
+++ b/drivers/iio/health/max30100.c
@@ -378,7 +378,7 @@ static int max30100_get_temp(struct max30100_data *data, int *val)
if (ret)
return ret;
- usleep_range(35000, 50000);
+ msleep(35);
return max30100_read_temp(data, val);
}
diff --git a/drivers/iio/humidity/hts221_i2c.c b/drivers/iio/humidity/hts221_i2c.c
index 367ecd509f31..8333c0296c0e 100644
--- a/drivers/iio/humidity/hts221_i2c.c
+++ b/drivers/iio/humidity/hts221_i2c.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include "hts221.h"
@@ -83,6 +84,12 @@ static int hts221_i2c_probe(struct i2c_client *client,
return hts221_probe(iio_dev);
}
+static const struct acpi_device_id hts221_acpi_match[] = {
+ {"SMO9100", 0},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, hts221_acpi_match);
+
static const struct of_device_id hts221_i2c_of_match[] = {
{ .compatible = "st,hts221", },
{},
@@ -99,6 +106,7 @@ static struct i2c_driver hts221_driver = {
.driver = {
.name = "hts221_i2c",
.of_match_table = of_match_ptr(hts221_i2c_of_match),
+ .acpi_match_table = ACPI_PTR(hts221_acpi_match),
},
.probe = hts221_i2c_probe,
.id_table = hts221_i2c_id_table,
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 1f1ad41ef881..156630a21696 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -39,6 +39,7 @@ config KMX61
be called kmx61.
source "drivers/iio/imu/inv_mpu6050/Kconfig"
+source "drivers/iio/imu/st_lsm6dsx/Kconfig"
endmenu
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index c71bcd30dc38..8b563c3323b5 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -17,3 +17,5 @@ obj-y += bmi160/
obj-y += inv_mpu6050/
obj-$(CONFIG_KMX61) += kmx61.o
+
+obj-y += st_lsm6dsx/
diff --git a/drivers/iio/imu/bmi160/bmi160_core.c b/drivers/iio/imu/bmi160/bmi160_core.c
index 5355507f8fa1..cfd225ed1c8d 100644
--- a/drivers/iio/imu/bmi160/bmi160_core.c
+++ b/drivers/iio/imu/bmi160/bmi160_core.c
@@ -66,10 +66,8 @@
#define BMI160_REG_DUMMY 0x7F
-#define BMI160_ACCEL_PMU_MIN_USLEEP 3200
-#define BMI160_ACCEL_PMU_MAX_USLEEP 3800
-#define BMI160_GYRO_PMU_MIN_USLEEP 55000
-#define BMI160_GYRO_PMU_MAX_USLEEP 80000
+#define BMI160_ACCEL_PMU_MIN_USLEEP 3800
+#define BMI160_GYRO_PMU_MIN_USLEEP 80000
#define BMI160_SOFTRESET_USLEEP 1000
#define BMI160_CHANNEL(_type, _axis, _index) { \
@@ -151,20 +149,9 @@ static struct bmi160_regs bmi160_regs[] = {
},
};
-struct bmi160_pmu_time {
- unsigned long min;
- unsigned long max;
-};
-
-static struct bmi160_pmu_time bmi160_pmu_time[] = {
- [BMI160_ACCEL] = {
- .min = BMI160_ACCEL_PMU_MIN_USLEEP,
- .max = BMI160_ACCEL_PMU_MAX_USLEEP
- },
- [BMI160_GYRO] = {
- .min = BMI160_GYRO_PMU_MIN_USLEEP,
- .max = BMI160_GYRO_PMU_MIN_USLEEP,
- },
+static unsigned long bmi160_pmu_time[] = {
+ [BMI160_ACCEL] = BMI160_ACCEL_PMU_MIN_USLEEP,
+ [BMI160_GYRO] = BMI160_GYRO_PMU_MIN_USLEEP,
};
struct bmi160_scale {
@@ -289,7 +276,7 @@ int bmi160_set_mode(struct bmi160_data *data, enum bmi160_sensor_type t,
if (ret < 0)
return ret;
- usleep_range(bmi160_pmu_time[t].min, bmi160_pmu_time[t].max);
+ usleep_range(bmi160_pmu_time[t], bmi160_pmu_time[t] + 1000);
return 0;
}
@@ -338,9 +325,9 @@ static int bmi160_get_data(struct bmi160_data *data, int chan_type,
__le16 sample;
enum bmi160_sensor_type t = bmi160_to_sensor(chan_type);
- reg = bmi160_regs[t].data + (axis - IIO_MOD_X) * sizeof(__le16);
+ reg = bmi160_regs[t].data + (axis - IIO_MOD_X) * sizeof(sample);
- ret = regmap_bulk_read(data->regmap, reg, &sample, sizeof(__le16));
+ ret = regmap_bulk_read(data->regmap, reg, &sample, sizeof(sample));
if (ret < 0)
return ret;
@@ -405,8 +392,8 @@ static irqreturn_t bmi160_trigger_handler(int irq, void *p)
for_each_set_bit(i, indio_dev->active_scan_mask,
indio_dev->masklength) {
- ret = regmap_bulk_read(data->regmap, base + i * sizeof(__le16),
- &sample, sizeof(__le16));
+ ret = regmap_bulk_read(data->regmap, base + i * sizeof(sample),
+ &sample, sizeof(sample));
if (ret < 0)
goto done;
buf[j++] = sample;
diff --git a/drivers/iio/imu/bmi160/bmi160_i2c.c b/drivers/iio/imu/bmi160/bmi160_i2c.c
index 07a179d8fb48..155a31f72445 100644
--- a/drivers/iio/imu/bmi160/bmi160_i2c.c
+++ b/drivers/iio/imu/bmi160/bmi160_i2c.c
@@ -11,10 +11,11 @@
* - 0x68 if SDO is pulled to GND
* - 0x69 if SDO is pulled to VDDIO
*/
-#include <linux/module.h>
+#include <linux/acpi.h>
#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of.h>
#include <linux/regmap.h>
-#include <linux/acpi.h>
#include "bmi160.h"
@@ -56,10 +57,19 @@ static const struct acpi_device_id bmi160_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match);
+#ifdef CONFIG_OF
+static const struct of_device_id bmi160_of_match[] = {
+ { .compatible = "bosch,bmi160" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, bmi160_of_match);
+#endif
+
static struct i2c_driver bmi160_i2c_driver = {
.driver = {
.name = "bmi160_i2c",
.acpi_match_table = ACPI_PTR(bmi160_acpi_match),
+ .of_match_table = of_match_ptr(bmi160_of_match),
},
.probe = bmi160_i2c_probe,
.remove = bmi160_i2c_remove,
diff --git a/drivers/iio/imu/bmi160/bmi160_spi.c b/drivers/iio/imu/bmi160/bmi160_spi.c
index 1ec8b12bd984..d34dfdfd1a7d 100644
--- a/drivers/iio/imu/bmi160/bmi160_spi.c
+++ b/drivers/iio/imu/bmi160/bmi160_spi.c
@@ -7,10 +7,11 @@
* the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
*/
+#include <linux/acpi.h>
#include <linux/module.h>
-#include <linux/spi/spi.h>
+#include <linux/of.h>
#include <linux/regmap.h>
-#include <linux/acpi.h>
+#include <linux/spi/spi.h>
#include "bmi160.h"
@@ -47,13 +48,22 @@ static const struct acpi_device_id bmi160_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, bmi160_acpi_match);
+#ifdef CONFIG_OF
+static const struct of_device_id bmi160_of_match[] = {
+ { .compatible = "bosch,bmi160" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, bmi160_of_match);
+#endif
+
static struct spi_driver bmi160_spi_driver = {
.probe = bmi160_spi_probe,
.remove = bmi160_spi_remove,
.id_table = bmi160_spi_id,
.driver = {
- .acpi_match_table = ACPI_PTR(bmi160_acpi_match),
- .name = "bmi160_spi",
+ .acpi_match_table = ACPI_PTR(bmi160_acpi_match),
+ .of_match_table = of_match_ptr(bmi160_of_match),
+ .name = "bmi160_spi",
},
};
module_spi_driver(bmi160_spi_driver);
diff --git a/drivers/iio/imu/st_lsm6dsx/Kconfig b/drivers/iio/imu/st_lsm6dsx/Kconfig
new file mode 100644
index 000000000000..935d4cd071a3
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/Kconfig
@@ -0,0 +1,22 @@
+
+config IIO_ST_LSM6DSX
+ tristate "ST_LSM6DSx driver for STM 6-axis IMU MEMS sensors"
+ depends on (I2C || SPI)
+ select IIO_BUFFER
+ select IIO_KFIFO_BUF
+ select IIO_ST_LSM6DSX_I2C if (I2C)
+ select IIO_ST_LSM6DSX_SPI if (SPI_MASTER)
+ help
+ Say yes here to build support for STMicroelectronics LSM6DSx imu
+ sensor. Supported devices: lsm6ds3, lsm6dsm
+
+ To compile this driver as a module, choose M here: the module
+ will be called st_lsm6dsx.
+
+config IIO_ST_LSM6DSX_I2C
+ tristate
+ depends on IIO_ST_LSM6DSX
+
+config IIO_ST_LSM6DSX_SPI
+ tristate
+ depends on IIO_ST_LSM6DSX
diff --git a/drivers/iio/imu/st_lsm6dsx/Makefile b/drivers/iio/imu/st_lsm6dsx/Makefile
new file mode 100644
index 000000000000..35919febea2a
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/Makefile
@@ -0,0 +1,5 @@
+st_lsm6dsx-y := st_lsm6dsx_core.o st_lsm6dsx_buffer.o
+
+obj-$(CONFIG_IIO_ST_LSM6DSX) += st_lsm6dsx.o
+obj-$(CONFIG_IIO_ST_LSM6DSX_I2C) += st_lsm6dsx_i2c.o
+obj-$(CONFIG_IIO_ST_LSM6DSX_SPI) += st_lsm6dsx_spi.o
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
new file mode 100644
index 000000000000..69deafe1c10d
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
@@ -0,0 +1,141 @@
+/*
+ * STMicroelectronics st_lsm6dsx sensor driver
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef ST_LSM6DSX_H
+#define ST_LSM6DSX_H
+
+#include <linux/device.h>
+
+#define ST_LSM6DS3_DEV_NAME "lsm6ds3"
+#define ST_LSM6DSM_DEV_NAME "lsm6dsm"
+
+enum st_lsm6dsx_hw_id {
+ ST_LSM6DS3_ID,
+ ST_LSM6DSM_ID,
+};
+
+#define ST_LSM6DSX_CHAN_SIZE 2
+#define ST_LSM6DSX_SAMPLE_SIZE 6
+#define ST_LSM6DSX_SAMPLE_DEPTH (ST_LSM6DSX_SAMPLE_SIZE / \
+ ST_LSM6DSX_CHAN_SIZE)
+
+#if defined(CONFIG_SPI_MASTER)
+#define ST_LSM6DSX_RX_MAX_LENGTH 256
+#define ST_LSM6DSX_TX_MAX_LENGTH 8
+
+struct st_lsm6dsx_transfer_buffer {
+ u8 rx_buf[ST_LSM6DSX_RX_MAX_LENGTH];
+ u8 tx_buf[ST_LSM6DSX_TX_MAX_LENGTH] ____cacheline_aligned;
+};
+#endif /* CONFIG_SPI_MASTER */
+
+struct st_lsm6dsx_transfer_function {
+ int (*read)(struct device *dev, u8 addr, int len, u8 *data);
+ int (*write)(struct device *dev, u8 addr, int len, u8 *data);
+};
+
+struct st_lsm6dsx_reg {
+ u8 addr;
+ u8 mask;
+};
+
+struct st_lsm6dsx_settings {
+ u8 wai;
+ u16 max_fifo_size;
+ enum st_lsm6dsx_hw_id id;
+};
+
+enum st_lsm6dsx_sensor_id {
+ ST_LSM6DSX_ID_ACC,
+ ST_LSM6DSX_ID_GYRO,
+ ST_LSM6DSX_ID_MAX,
+};
+
+enum st_lsm6dsx_fifo_mode {
+ ST_LSM6DSX_FIFO_BYPASS = 0x0,
+ ST_LSM6DSX_FIFO_CONT = 0x6,
+};
+
+/**
+ * struct st_lsm6dsx_sensor - ST IMU sensor instance
+ * @id: Sensor identifier.
+ * @hw: Pointer to instance of struct st_lsm6dsx_hw.
+ * @gain: Configured sensor sensitivity.
+ * @odr: Output data rate of the sensor [Hz].
+ * @watermark: Sensor watermark level.
+ * @sip: Number of samples in a given pattern.
+ * @decimator: FIFO decimation factor.
+ * @decimator_mask: Sensor mask for decimation register.
+ * @delta_ts: Delta time between two consecutive interrupts.
+ * @ts: Latest timestamp from the interrupt handler.
+ */
+struct st_lsm6dsx_sensor {
+ enum st_lsm6dsx_sensor_id id;
+ struct st_lsm6dsx_hw *hw;
+
+ u32 gain;
+ u16 odr;
+
+ u16 watermark;
+ u8 sip;
+ u8 decimator;
+ u8 decimator_mask;
+
+ s64 delta_ts;
+ s64 ts;
+};
+
+/**
+ * struct st_lsm6dsx_hw - ST IMU MEMS hw instance
+ * @dev: Pointer to instance of struct device (I2C or SPI).
+ * @irq: Device interrupt line (I2C or SPI).
+ * @lock: Mutex to protect read and write operations.
+ * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
+ * @fifo_mode: FIFO operating mode supported by the device.
+ * @enable_mask: Enabled sensor bitmask.
+ * @sip: Total number of samples (acc/gyro) in a given pattern.
+ * @iio_devs: Pointers to acc/gyro iio_dev instances.
+ * @settings: Pointer to the specific sensor settings in use.
+ * @tf: Transfer function structure used by I/O operations.
+ * @tb: Transfer buffers used by SPI I/O operations.
+ */
+struct st_lsm6dsx_hw {
+ struct device *dev;
+ int irq;
+
+ struct mutex lock;
+ struct mutex fifo_lock;
+
+ enum st_lsm6dsx_fifo_mode fifo_mode;
+ u8 enable_mask;
+ u8 sip;
+
+ struct iio_dev *iio_devs[ST_LSM6DSX_ID_MAX];
+
+ const struct st_lsm6dsx_settings *settings;
+
+ const struct st_lsm6dsx_transfer_function *tf;
+#if defined(CONFIG_SPI_MASTER)
+ struct st_lsm6dsx_transfer_buffer tb;
+#endif /* CONFIG_SPI_MASTER */
+};
+
+int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
+ const struct st_lsm6dsx_transfer_function *tf_ops);
+int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor);
+int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor);
+int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw);
+int st_lsm6dsx_write_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, u8 mask,
+ u8 val);
+int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
+ u16 watermark);
+
+#endif /* ST_LSM6DSX_H */
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
new file mode 100644
index 000000000000..78532ce07449
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
@@ -0,0 +1,454 @@
+/*
+ * STMicroelectronics st_lsm6dsx FIFO buffer library driver
+ *
+ * LSM6DS3/LSM6DSM: The FIFO buffer can be configured to store data
+ * from gyroscope and accelerometer. Samples are queued without any tag
+ * according to a specific pattern based on 'FIFO data sets' (6 bytes each):
+ * - 1st data set is reserved for gyroscope data
+ * - 2nd data set is reserved for accelerometer data
+ * The FIFO pattern changes depending on the ODRs and decimation factors
+ * assigned to the FIFO data sets. The first sequence of data stored in FIFO
+ * buffer contains the data of all the enabled FIFO data sets
+ * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated depending on the
+ * value of the decimation factor and ODR set for each FIFO data set.
+ * FIFO supported modes:
+ * - BYPASS: FIFO disabled
+ * - CONTINUOUS: FIFO enabled. When the buffer is full, the FIFO index
+ * restarts from the beginning and the oldest sample is overwritten
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+
+#include "st_lsm6dsx.h"
+
+#define ST_LSM6DSX_REG_FIFO_THL_ADDR 0x06
+#define ST_LSM6DSX_REG_FIFO_THH_ADDR 0x07
+#define ST_LSM6DSX_FIFO_TH_MASK GENMASK(11, 0)
+#define ST_LSM6DSX_REG_FIFO_DEC_GXL_ADDR 0x08
+#define ST_LSM6DSX_REG_FIFO_MODE_ADDR 0x0a
+#define ST_LSM6DSX_FIFO_MODE_MASK GENMASK(2, 0)
+#define ST_LSM6DSX_FIFO_ODR_MASK GENMASK(6, 3)
+#define ST_LSM6DSX_REG_FIFO_DIFFL_ADDR 0x3a
+#define ST_LSM6DSX_FIFO_DIFF_MASK GENMASK(11, 0)
+#define ST_LSM6DSX_FIFO_EMPTY_MASK BIT(12)
+#define ST_LSM6DSX_REG_FIFO_OUTL_ADDR 0x3e
+
+#define ST_LSM6DSX_MAX_FIFO_ODR_VAL 0x08
+
+struct st_lsm6dsx_decimator_entry {
+ u8 decimator;
+ u8 val;
+};
+
+static const
+struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = {
+ { 0, 0x0 },
+ { 1, 0x1 },
+ { 2, 0x2 },
+ { 3, 0x3 },
+ { 4, 0x4 },
+ { 8, 0x5 },
+ { 16, 0x6 },
+ { 32, 0x7 },
+};
+
+static int st_lsm6dsx_get_decimator_val(u8 val)
+{
+ const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table);
+ int i;
+
+ for (i = 0; i < max_size; i++)
+ if (st_lsm6dsx_decimator_table[i].decimator == val)
+ break;
+
+ return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val;
+}
+
+static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw,
+ u16 *max_odr, u16 *min_odr)
+{
+ struct st_lsm6dsx_sensor *sensor;
+ int i;
+
+ *max_odr = 0, *min_odr = ~0;
+ for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+ sensor = iio_priv(hw->iio_devs[i]);
+
+ if (!(hw->enable_mask & BIT(sensor->id)))
+ continue;
+
+ *max_odr = max_t(u16, *max_odr, sensor->odr);
+ *min_odr = min_t(u16, *min_odr, sensor->odr);
+ }
+}
+
+static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw)
+{
+ struct st_lsm6dsx_sensor *sensor;
+ u16 max_odr, min_odr, sip = 0;
+ int err, i;
+ u8 data;
+
+ st_lsm6dsx_get_max_min_odr(hw, &max_odr, &min_odr);
+
+ for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+ sensor = iio_priv(hw->iio_devs[i]);
+
+ /* update fifo decimators and sample in pattern */
+ if (hw->enable_mask & BIT(sensor->id)) {
+ sensor->sip = sensor->odr / min_odr;
+ sensor->decimator = max_odr / sensor->odr;
+ data = st_lsm6dsx_get_decimator_val(sensor->decimator);
+ } else {
+ sensor->sip = 0;
+ sensor->decimator = 0;
+ data = 0;
+ }
+
+ err = st_lsm6dsx_write_with_mask(hw,
+ ST_LSM6DSX_REG_FIFO_DEC_GXL_ADDR,
+ sensor->decimator_mask, data);
+ if (err < 0)
+ return err;
+
+ sip += sensor->sip;
+ }
+ hw->sip = sip;
+
+ return 0;
+}
+
+static int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
+ enum st_lsm6dsx_fifo_mode fifo_mode)
+{
+ u8 data;
+ int err;
+
+ switch (fifo_mode) {
+ case ST_LSM6DSX_FIFO_BYPASS:
+ data = fifo_mode;
+ break;
+ case ST_LSM6DSX_FIFO_CONT:
+ data = (ST_LSM6DSX_MAX_FIFO_ODR_VAL <<
+ __ffs(ST_LSM6DSX_FIFO_ODR_MASK)) | fifo_mode;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_FIFO_MODE_ADDR,
+ sizeof(data), &data);
+ if (err < 0)
+ return err;
+
+ hw->fifo_mode = fifo_mode;
+
+ return 0;
+}
+
+int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor, u16 watermark)
+{
+ u16 fifo_watermark = ~0, cur_watermark, sip = 0;
+ struct st_lsm6dsx_hw *hw = sensor->hw;
+ struct st_lsm6dsx_sensor *cur_sensor;
+ __le16 wdata;
+ int i, err;
+ u8 data;
+
+ for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+ cur_sensor = iio_priv(hw->iio_devs[i]);
+
+ if (!(hw->enable_mask & BIT(cur_sensor->id)))
+ continue;
+
+ cur_watermark = (cur_sensor == sensor) ? watermark
+ : cur_sensor->watermark;
+
+ fifo_watermark = min_t(u16, fifo_watermark, cur_watermark);
+ sip += cur_sensor->sip;
+ }
+
+ if (!sip)
+ return 0;
+
+ fifo_watermark = max_t(u16, fifo_watermark, sip);
+ fifo_watermark = (fifo_watermark / sip) * sip;
+ fifo_watermark = fifo_watermark * ST_LSM6DSX_SAMPLE_DEPTH;
+
+ mutex_lock(&hw->lock);
+
+ err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_THH_ADDR,
+ sizeof(data), &data);
+ if (err < 0)
+ goto out;
+
+ fifo_watermark = ((data & ~ST_LSM6DSX_FIFO_TH_MASK) << 8) |
+ (fifo_watermark & ST_LSM6DSX_FIFO_TH_MASK);
+
+ wdata = cpu_to_le16(fifo_watermark);
+ err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_FIFO_THL_ADDR,
+ sizeof(wdata), (u8 *)&wdata);
+out:
+ mutex_unlock(&hw->lock);
+
+ return err < 0 ? err : 0;
+}
+
+/**
+ * st_lsm6dsx_read_fifo() - LSM6DS3-LSM6DSM read FIFO routine
+ * @hw: Pointer to instance of struct st_lsm6dsx_hw.
+ *
+ * Read samples from the hw FIFO and push them to IIO buffers.
+ *
+ * Return: Number of bytes read from the FIFO
+ */
+static int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
+{
+ u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
+ int err, acc_sip, gyro_sip, read_len, samples, offset;
+ struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor;
+ s64 acc_ts, acc_delta_ts, gyro_ts, gyro_delta_ts;
+ u8 iio_buff[ALIGN(ST_LSM6DSX_SAMPLE_SIZE, sizeof(s64)) + sizeof(s64)];
+ u8 buff[pattern_len];
+ __le16 fifo_status;
+
+ err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_DIFFL_ADDR,
+ sizeof(fifo_status), (u8 *)&fifo_status);
+ if (err < 0)
+ return err;
+
+ if (fifo_status & cpu_to_le16(ST_LSM6DSX_FIFO_EMPTY_MASK))
+ return 0;
+
+ fifo_len = (le16_to_cpu(fifo_status) & ST_LSM6DSX_FIFO_DIFF_MASK) *
+ ST_LSM6DSX_CHAN_SIZE;
+ samples = fifo_len / ST_LSM6DSX_SAMPLE_SIZE;
+ fifo_len = (fifo_len / pattern_len) * pattern_len;
+
+ /*
+ * compute delta timestamp between two consecutive samples
+ * in order to estimate queueing time of data generated
+ * by the sensor
+ */
+ acc_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
+ acc_ts = acc_sensor->ts - acc_sensor->delta_ts;
+ acc_delta_ts = div_s64(acc_sensor->delta_ts * acc_sensor->decimator,
+ samples);
+
+ gyro_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_GYRO]);
+ gyro_ts = gyro_sensor->ts - gyro_sensor->delta_ts;
+ gyro_delta_ts = div_s64(gyro_sensor->delta_ts * gyro_sensor->decimator,
+ samples);
+
+ for (read_len = 0; read_len < fifo_len; read_len += pattern_len) {
+ err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_FIFO_OUTL_ADDR,
+ sizeof(buff), buff);
+ if (err < 0)
+ return err;
+
+ /*
+ * Data are written to the FIFO with a specific pattern
+ * depending on the configured ODRs. The first sequence of data
+ * stored in FIFO contains the data of all enabled sensors
+ * (e.g. Gx, Gy, Gz, Ax, Ay, Az), then data are repeated
+ * depending on the value of the decimation factor set for each
+ * sensor.
+ *
+ * Supposing the FIFO is storing data from gyroscope and
+ * accelerometer at different ODRs:
+ * - gyroscope ODR = 208Hz, accelerometer ODR = 104Hz
+ * Since the gyroscope ODR is twice the accelerometer one, the
+ * following pattern is repeated every 9 samples:
+ * - Gx, Gy, Gz, Ax, Ay, Az, Gx, Gy, Gz
+ */
+ gyro_sip = gyro_sensor->sip;
+ acc_sip = acc_sensor->sip;
+ offset = 0;
+
+ while (acc_sip > 0 || gyro_sip > 0) {
+ if (gyro_sip-- > 0) {
+ memcpy(iio_buff, &buff[offset],
+ ST_LSM6DSX_SAMPLE_SIZE);
+ iio_push_to_buffers_with_timestamp(
+ hw->iio_devs[ST_LSM6DSX_ID_GYRO],
+ iio_buff, gyro_ts);
+ offset += ST_LSM6DSX_SAMPLE_SIZE;
+ gyro_ts += gyro_delta_ts;
+ }
+
+ if (acc_sip-- > 0) {
+ memcpy(iio_buff, &buff[offset],
+ ST_LSM6DSX_SAMPLE_SIZE);
+ iio_push_to_buffers_with_timestamp(
+ hw->iio_devs[ST_LSM6DSX_ID_ACC],
+ iio_buff, acc_ts);
+ offset += ST_LSM6DSX_SAMPLE_SIZE;
+ acc_ts += acc_delta_ts;
+ }
+ }
+ }
+
+ return read_len;
+}
+
+static int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw)
+{
+ int err;
+
+ mutex_lock(&hw->fifo_lock);
+
+ st_lsm6dsx_read_fifo(hw);
+ err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_BYPASS);
+
+ mutex_unlock(&hw->fifo_lock);
+
+ return err;
+}
+
+static int st_lsm6dsx_update_fifo(struct iio_dev *iio_dev, bool enable)
+{
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+ struct st_lsm6dsx_hw *hw = sensor->hw;
+ int err;
+
+ if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) {
+ err = st_lsm6dsx_flush_fifo(hw);
+ if (err < 0)
+ return err;
+ }
+
+ if (enable) {
+ err = st_lsm6dsx_sensor_enable(sensor);
+ if (err < 0)
+ return err;
+ } else {
+ err = st_lsm6dsx_sensor_disable(sensor);
+ if (err < 0)
+ return err;
+ }
+
+ err = st_lsm6dsx_update_decimators(hw);
+ if (err < 0)
+ return err;
+
+ err = st_lsm6dsx_update_watermark(sensor, sensor->watermark);
+ if (err < 0)
+ return err;
+
+ if (hw->enable_mask) {
+ err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
+ if (err < 0)
+ return err;
+
+ /*
+ * store enable buffer timestamp as reference to compute
+ * first delta timestamp
+ */
+ sensor->ts = iio_get_time_ns(iio_dev);
+ }
+
+ return 0;
+}
+
+static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private)
+{
+ struct st_lsm6dsx_hw *hw = (struct st_lsm6dsx_hw *)private;
+ struct st_lsm6dsx_sensor *sensor;
+ int i;
+
+ if (!hw->sip)
+ return IRQ_NONE;
+
+ for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+ sensor = iio_priv(hw->iio_devs[i]);
+
+ if (sensor->sip > 0) {
+ s64 timestamp;
+
+ timestamp = iio_get_time_ns(hw->iio_devs[i]);
+ sensor->delta_ts = timestamp - sensor->ts;
+ sensor->ts = timestamp;
+ }
+ }
+
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
+{
+ struct st_lsm6dsx_hw *hw = (struct st_lsm6dsx_hw *)private;
+ int count;
+
+ mutex_lock(&hw->fifo_lock);
+ count = st_lsm6dsx_read_fifo(hw);
+ mutex_unlock(&hw->fifo_lock);
+
+ return !count ? IRQ_NONE : IRQ_HANDLED;
+}
+
+static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev)
+{
+ return st_lsm6dsx_update_fifo(iio_dev, true);
+}
+
+static int st_lsm6dsx_buffer_postdisable(struct iio_dev *iio_dev)
+{
+ return st_lsm6dsx_update_fifo(iio_dev, false);
+}
+
+static const struct iio_buffer_setup_ops st_lsm6dsx_buffer_ops = {
+ .preenable = st_lsm6dsx_buffer_preenable,
+ .postdisable = st_lsm6dsx_buffer_postdisable,
+};
+
+int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw)
+{
+ struct iio_buffer *buffer;
+ unsigned long irq_type;
+ int i, err;
+
+ irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
+
+ switch (irq_type) {
+ case IRQF_TRIGGER_HIGH:
+ case IRQF_TRIGGER_RISING:
+ break;
+ default:
+ dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
+ return -EINVAL;
+ }
+
+ err = devm_request_threaded_irq(hw->dev, hw->irq,
+ st_lsm6dsx_handler_irq,
+ st_lsm6dsx_handler_thread,
+ irq_type | IRQF_ONESHOT,
+ "lsm6dsx", hw);
+ if (err) {
+ dev_err(hw->dev, "failed to request trigger irq %d\n",
+ hw->irq);
+ return err;
+ }
+
+ for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+ buffer = devm_iio_kfifo_allocate(hw->dev);
+ if (!buffer)
+ return -ENOMEM;
+
+ iio_device_attach_buffer(hw->iio_devs[i], buffer);
+ hw->iio_devs[i]->modes |= INDIO_BUFFER_SOFTWARE;
+ hw->iio_devs[i]->setup_ops = &st_lsm6dsx_buffer_ops;
+ }
+
+ return 0;
+}
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
new file mode 100644
index 000000000000..c92ddcc190e2
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -0,0 +1,720 @@
+/*
+ * STMicroelectronics st_lsm6dsx sensor driver
+ *
+ * The ST LSM6DSx IMU MEMS series consists of 3D digital accelerometer
+ * and 3D digital gyroscope system-in-package with a digital I2C/SPI serial
+ * interface standard output.
+ * LSM6DSx IMU MEMS series has a dynamic user-selectable full-scale
+ * acceleration range of +-2/+-4/+-8/+-16 g and an angular rate range of
+ * +-125/+-245/+-500/+-1000/+-2000 dps
+ * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
+ * allowing dynamic batching of sensor data.
+ *
+ * Supported sensors:
+ * - LSM6DS3:
+ * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
+ * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
+ * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
+ * - FIFO size: 8KB
+ *
+ * - LSM6DSM:
+ * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
+ * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
+ * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
+ * - FIFO size: 4KB
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#include <linux/platform_data/st_sensors_pdata.h>
+
+#include "st_lsm6dsx.h"
+
+#define ST_LSM6DSX_REG_ACC_DEC_MASK GENMASK(2, 0)
+#define ST_LSM6DSX_REG_GYRO_DEC_MASK GENMASK(5, 3)
+#define ST_LSM6DSX_REG_INT1_ADDR 0x0d
+#define ST_LSM6DSX_REG_INT2_ADDR 0x0e
+#define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3)
+#define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f
+#define ST_LSM6DSX_REG_RESET_ADDR 0x12
+#define ST_LSM6DSX_REG_RESET_MASK BIT(0)
+#define ST_LSM6DSX_REG_BDU_ADDR 0x12
+#define ST_LSM6DSX_REG_BDU_MASK BIT(6)
+#define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13
+#define ST_LSM6DSX_REG_INT2_ON_INT1_MASK BIT(5)
+#define ST_LSM6DSX_REG_ROUNDING_ADDR 0x16
+#define ST_LSM6DSX_REG_ROUNDING_MASK BIT(2)
+#define ST_LSM6DSX_REG_LIR_ADDR 0x58
+#define ST_LSM6DSX_REG_LIR_MASK BIT(0)
+
+#define ST_LSM6DSX_REG_ACC_ODR_ADDR 0x10
+#define ST_LSM6DSX_REG_ACC_ODR_MASK GENMASK(7, 4)
+#define ST_LSM6DSX_REG_ACC_FS_ADDR 0x10
+#define ST_LSM6DSX_REG_ACC_FS_MASK GENMASK(3, 2)
+#define ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR 0x28
+#define ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR 0x2a
+#define ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR 0x2c
+
+#define ST_LSM6DSX_REG_GYRO_ODR_ADDR 0x11
+#define ST_LSM6DSX_REG_GYRO_ODR_MASK GENMASK(7, 4)
+#define ST_LSM6DSX_REG_GYRO_FS_ADDR 0x11
+#define ST_LSM6DSX_REG_GYRO_FS_MASK GENMASK(3, 2)
+#define ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR 0x22
+#define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR 0x24
+#define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR 0x26
+
+#define ST_LSM6DS3_WHOAMI 0x69
+#define ST_LSM6DSM_WHOAMI 0x6a
+
+#define ST_LSM6DS3_MAX_FIFO_SIZE 8192
+#define ST_LSM6DSM_MAX_FIFO_SIZE 4096
+
+#define ST_LSM6DSX_ACC_FS_2G_GAIN IIO_G_TO_M_S_2(61)
+#define ST_LSM6DSX_ACC_FS_4G_GAIN IIO_G_TO_M_S_2(122)
+#define ST_LSM6DSX_ACC_FS_8G_GAIN IIO_G_TO_M_S_2(244)
+#define ST_LSM6DSX_ACC_FS_16G_GAIN IIO_G_TO_M_S_2(488)
+
+#define ST_LSM6DSX_GYRO_FS_245_GAIN IIO_DEGREE_TO_RAD(8750)
+#define ST_LSM6DSX_GYRO_FS_500_GAIN IIO_DEGREE_TO_RAD(17500)
+#define ST_LSM6DSX_GYRO_FS_1000_GAIN IIO_DEGREE_TO_RAD(35000)
+#define ST_LSM6DSX_GYRO_FS_2000_GAIN IIO_DEGREE_TO_RAD(70000)
+
+struct st_lsm6dsx_odr {
+ u16 hz;
+ u8 val;
+};
+
+#define ST_LSM6DSX_ODR_LIST_SIZE 6
+struct st_lsm6dsx_odr_table_entry {
+ struct st_lsm6dsx_reg reg;
+ struct st_lsm6dsx_odr odr_avl[ST_LSM6DSX_ODR_LIST_SIZE];
+};
+
+static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = ST_LSM6DSX_REG_ACC_ODR_ADDR,
+ .mask = ST_LSM6DSX_REG_ACC_ODR_MASK,
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = ST_LSM6DSX_REG_GYRO_ODR_ADDR,
+ .mask = ST_LSM6DSX_REG_GYRO_ODR_MASK,
+ },
+ .odr_avl[0] = { 13, 0x01 },
+ .odr_avl[1] = { 26, 0x02 },
+ .odr_avl[2] = { 52, 0x03 },
+ .odr_avl[3] = { 104, 0x04 },
+ .odr_avl[4] = { 208, 0x05 },
+ .odr_avl[5] = { 416, 0x06 },
+ }
+};
+
+struct st_lsm6dsx_fs {
+ u32 gain;
+ u8 val;
+};
+
+#define ST_LSM6DSX_FS_LIST_SIZE 4
+struct st_lsm6dsx_fs_table_entry {
+ struct st_lsm6dsx_reg reg;
+ struct st_lsm6dsx_fs fs_avl[ST_LSM6DSX_FS_LIST_SIZE];
+};
+
+static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = {
+ [ST_LSM6DSX_ID_ACC] = {
+ .reg = {
+ .addr = ST_LSM6DSX_REG_ACC_FS_ADDR,
+ .mask = ST_LSM6DSX_REG_ACC_FS_MASK,
+ },
+ .fs_avl[0] = { ST_LSM6DSX_ACC_FS_2G_GAIN, 0x0 },
+ .fs_avl[1] = { ST_LSM6DSX_ACC_FS_4G_GAIN, 0x2 },
+ .fs_avl[2] = { ST_LSM6DSX_ACC_FS_8G_GAIN, 0x3 },
+ .fs_avl[3] = { ST_LSM6DSX_ACC_FS_16G_GAIN, 0x1 },
+ },
+ [ST_LSM6DSX_ID_GYRO] = {
+ .reg = {
+ .addr = ST_LSM6DSX_REG_GYRO_FS_ADDR,
+ .mask = ST_LSM6DSX_REG_GYRO_FS_MASK,
+ },
+ .fs_avl[0] = { ST_LSM6DSX_GYRO_FS_245_GAIN, 0x0 },
+ .fs_avl[1] = { ST_LSM6DSX_GYRO_FS_500_GAIN, 0x1 },
+ .fs_avl[2] = { ST_LSM6DSX_GYRO_FS_1000_GAIN, 0x2 },
+ .fs_avl[3] = { ST_LSM6DSX_GYRO_FS_2000_GAIN, 0x3 },
+ }
+};
+
+static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
+ {
+ .wai = ST_LSM6DS3_WHOAMI,
+ .max_fifo_size = ST_LSM6DS3_MAX_FIFO_SIZE,
+ .id = ST_LSM6DS3_ID,
+ },
+ {
+ .wai = ST_LSM6DSM_WHOAMI,
+ .max_fifo_size = ST_LSM6DSM_MAX_FIFO_SIZE,
+ .id = ST_LSM6DSM_ID,
+ },
+};
+
+#define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx) \
+{ \
+ .type = chan_type, \
+ .address = addr, \
+ .modified = 1, \
+ .channel2 = mod, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+ .scan_index = scan_idx, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = 16, \
+ .storagebits = 16, \
+ .endianness = IIO_LE, \
+ }, \
+}
+
+static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR,
+ IIO_MOD_X, 0),
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR,
+ IIO_MOD_Y, 1),
+ ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR,
+ IIO_MOD_Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR,
+ IIO_MOD_X, 0),
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR,
+ IIO_MOD_Y, 1),
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR,
+ IIO_MOD_Z, 2),
+ IIO_CHAN_SOFT_TIMESTAMP(3),
+};
+
+int st_lsm6dsx_write_with_mask(struct st_lsm6dsx_hw *hw, u8 addr, u8 mask,
+ u8 val)
+{
+ u8 data;
+ int err;
+
+ mutex_lock(&hw->lock);
+
+ err = hw->tf->read(hw->dev, addr, sizeof(data), &data);
+ if (err < 0) {
+ dev_err(hw->dev, "failed to read %02x register\n", addr);
+ goto out;
+ }
+
+ data = (data & ~mask) | ((val << __ffs(mask)) & mask);
+
+ err = hw->tf->write(hw->dev, addr, sizeof(data), &data);
+ if (err < 0)
+ dev_err(hw->dev, "failed to write %02x register\n", addr);
+
+out:
+ mutex_unlock(&hw->lock);
+
+ return err;
+}
+
+static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id)
+{
+ int err, i;
+ u8 data;
+
+ for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
+ if (id == st_lsm6dsx_sensor_settings[i].id)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
+ dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
+ return -ENODEV;
+ }
+
+ err = hw->tf->read(hw->dev, ST_LSM6DSX_REG_WHOAMI_ADDR, sizeof(data),
+ &data);
+ if (err < 0) {
+ dev_err(hw->dev, "failed to read whoami register\n");
+ return err;
+ }
+
+ if (data != st_lsm6dsx_sensor_settings[i].wai) {
+ dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
+ return -ENODEV;
+ }
+
+ hw->settings = &st_lsm6dsx_sensor_settings[i];
+
+ return 0;
+}
+
+static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
+ u32 gain)
+{
+ enum st_lsm6dsx_sensor_id id = sensor->id;
+ int i, err;
+ u8 val;
+
+ for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
+ if (st_lsm6dsx_fs_table[id].fs_avl[i].gain == gain)
+ break;
+
+ if (i == ST_LSM6DSX_FS_LIST_SIZE)
+ return -EINVAL;
+
+ val = st_lsm6dsx_fs_table[id].fs_avl[i].val;
+ err = st_lsm6dsx_write_with_mask(sensor->hw,
+ st_lsm6dsx_fs_table[id].reg.addr,
+ st_lsm6dsx_fs_table[id].reg.mask,
+ val);
+ if (err < 0)
+ return err;
+
+ sensor->gain = gain;
+
+ return 0;
+}
+
+static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr)
+{
+ enum st_lsm6dsx_sensor_id id = sensor->id;
+ int i, err;
+ u8 val;
+
+ for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
+ if (st_lsm6dsx_odr_table[id].odr_avl[i].hz == odr)
+ break;
+
+ if (i == ST_LSM6DSX_ODR_LIST_SIZE)
+ return -EINVAL;
+
+ val = st_lsm6dsx_odr_table[id].odr_avl[i].val;
+ err = st_lsm6dsx_write_with_mask(sensor->hw,
+ st_lsm6dsx_odr_table[id].reg.addr,
+ st_lsm6dsx_odr_table[id].reg.mask,
+ val);
+ if (err < 0)
+ return err;
+
+ sensor->odr = odr;
+
+ return 0;
+}
+
+int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor)
+{
+ int err;
+
+ err = st_lsm6dsx_set_odr(sensor, sensor->odr);
+ if (err < 0)
+ return err;
+
+ sensor->hw->enable_mask |= BIT(sensor->id);
+
+ return 0;
+}
+
+int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor)
+{
+ enum st_lsm6dsx_sensor_id id = sensor->id;
+ int err;
+
+ err = st_lsm6dsx_write_with_mask(sensor->hw,
+ st_lsm6dsx_odr_table[id].reg.addr,
+ st_lsm6dsx_odr_table[id].reg.mask, 0);
+ if (err < 0)
+ return err;
+
+ sensor->hw->enable_mask &= ~BIT(id);
+
+ return 0;
+}
+
+static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
+ u8 addr, int *val)
+{
+ int err, delay;
+ __le16 data;
+
+ err = st_lsm6dsx_sensor_enable(sensor);
+ if (err < 0)
+ return err;
+
+ delay = 1000000 / sensor->odr;
+ usleep_range(delay, 2 * delay);
+
+ err = sensor->hw->tf->read(sensor->hw->dev, addr, sizeof(data),
+ (u8 *)&data);
+ if (err < 0)
+ return err;
+
+ st_lsm6dsx_sensor_disable(sensor);
+
+ *val = (s16)data;
+
+ return IIO_VAL_INT;
+}
+
+static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
+ struct iio_chan_spec const *ch,
+ int *val, int *val2, long mask)
+{
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = iio_device_claim_direct_mode(iio_dev);
+ if (ret)
+ break;
+
+ ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
+ iio_device_release_direct_mode(iio_dev);
+ break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ *val = sensor->odr;
+ ret = IIO_VAL_INT;
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = sensor->gain;
+ ret = IIO_VAL_INT_PLUS_MICRO;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+ int err;
+
+ err = iio_device_claim_direct_mode(iio_dev);
+ if (err)
+ return err;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ err = st_lsm6dsx_set_full_scale(sensor, val2);
+ break;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ err = st_lsm6dsx_set_odr(sensor, val);
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ iio_device_release_direct_mode(iio_dev);
+
+ return err;
+}
+
+static int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
+{
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
+ struct st_lsm6dsx_hw *hw = sensor->hw;
+ int err, max_fifo_len;
+
+ max_fifo_len = hw->settings->max_fifo_size / ST_LSM6DSX_SAMPLE_SIZE;
+ if (val < 1 || val > max_fifo_len)
+ return -EINVAL;
+
+ err = st_lsm6dsx_update_watermark(sensor, val);
+ if (err < 0)
+ return err;
+
+ sensor->watermark = val;
+
+ return 0;
+}
+
+static ssize_t
+st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
+ enum st_lsm6dsx_sensor_id id = sensor->id;
+ int i, len = 0;
+
+ for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
+ st_lsm6dsx_odr_table[id].odr_avl[i].hz);
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
+ enum st_lsm6dsx_sensor_id id = sensor->id;
+ int i, len = 0;
+
+ for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
+ st_lsm6dsx_fs_table[id].fs_avl[i].gain);
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
+static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
+ st_lsm6dsx_sysfs_scale_avail, NULL, 0);
+static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
+ st_lsm6dsx_sysfs_scale_avail, NULL, 0);
+
+static struct attribute *st_lsm6dsx_acc_attributes[] = {
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
+ .attrs = st_lsm6dsx_acc_attributes,
+};
+
+static const struct iio_info st_lsm6dsx_acc_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &st_lsm6dsx_acc_attribute_group,
+ .read_raw = st_lsm6dsx_read_raw,
+ .write_raw = st_lsm6dsx_write_raw,
+ .hwfifo_set_watermark = st_lsm6dsx_set_watermark,
+};
+
+static struct attribute *st_lsm6dsx_gyro_attributes[] = {
+ &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+ &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
+ .attrs = st_lsm6dsx_gyro_attributes,
+};
+
+static const struct iio_info st_lsm6dsx_gyro_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &st_lsm6dsx_gyro_attribute_group,
+ .read_raw = st_lsm6dsx_read_raw,
+ .write_raw = st_lsm6dsx_write_raw,
+ .hwfifo_set_watermark = st_lsm6dsx_set_watermark,
+};
+
+static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0};
+
+static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
+{
+ struct device_node *np = hw->dev->of_node;
+ int err;
+
+ if (!np)
+ return -EINVAL;
+
+ err = of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
+ if (err == -ENODATA) {
+ /* if the property has not been specified use default value */
+ *drdy_pin = 1;
+ err = 0;
+ }
+
+ return err;
+}
+
+static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
+{
+ int err = 0, drdy_pin;
+
+ if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) {
+ struct st_sensors_platform_data *pdata;
+ struct device *dev = hw->dev;
+
+ pdata = (struct st_sensors_platform_data *)dev->platform_data;
+ drdy_pin = pdata ? pdata->drdy_int_pin : 1;
+ }
+
+ switch (drdy_pin) {
+ case 1:
+ *drdy_reg = ST_LSM6DSX_REG_INT1_ADDR;
+ break;
+ case 2:
+ *drdy_reg = ST_LSM6DSX_REG_INT2_ADDR;
+ break;
+ default:
+ dev_err(hw->dev, "unsupported data ready pin\n");
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
+{
+ u8 data, drdy_int_reg;
+ int err;
+
+ data = ST_LSM6DSX_REG_RESET_MASK;
+ err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_RESET_ADDR, sizeof(data),
+ &data);
+ if (err < 0)
+ return err;
+
+ msleep(200);
+
+ /* latch interrupts */
+ err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_LIR_ADDR,
+ ST_LSM6DSX_REG_LIR_MASK, 1);
+ if (err < 0)
+ return err;
+
+ /* enable Block Data Update */
+ err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_BDU_ADDR,
+ ST_LSM6DSX_REG_BDU_MASK, 1);
+ if (err < 0)
+ return err;
+
+ err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_ROUNDING_ADDR,
+ ST_LSM6DSX_REG_ROUNDING_MASK, 1);
+ if (err < 0)
+ return err;
+
+ /* enable FIFO watermak interrupt */
+ err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg);
+ if (err < 0)
+ return err;
+
+ return st_lsm6dsx_write_with_mask(hw, drdy_int_reg,
+ ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 1);
+}
+
+static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
+ enum st_lsm6dsx_sensor_id id)
+{
+ struct st_lsm6dsx_sensor *sensor;
+ struct iio_dev *iio_dev;
+
+ iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
+ if (!iio_dev)
+ return NULL;
+
+ iio_dev->modes = INDIO_DIRECT_MODE;
+ iio_dev->dev.parent = hw->dev;
+ iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
+
+ sensor = iio_priv(iio_dev);
+ sensor->id = id;
+ sensor->hw = hw;
+ sensor->odr = st_lsm6dsx_odr_table[id].odr_avl[0].hz;
+ sensor->gain = st_lsm6dsx_fs_table[id].fs_avl[0].gain;
+ sensor->watermark = 1;
+
+ switch (id) {
+ case ST_LSM6DSX_ID_ACC:
+ iio_dev->channels = st_lsm6dsx_acc_channels;
+ iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_acc_channels);
+ iio_dev->name = "lsm6dsx_accel";
+ iio_dev->info = &st_lsm6dsx_acc_info;
+
+ sensor->decimator_mask = ST_LSM6DSX_REG_ACC_DEC_MASK;
+ break;
+ case ST_LSM6DSX_ID_GYRO:
+ iio_dev->channels = st_lsm6dsx_gyro_channels;
+ iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_gyro_channels);
+ iio_dev->name = "lsm6dsx_gyro";
+ iio_dev->info = &st_lsm6dsx_gyro_info;
+
+ sensor->decimator_mask = ST_LSM6DSX_REG_GYRO_DEC_MASK;
+ break;
+ default:
+ return NULL;
+ }
+
+ return iio_dev;
+}
+
+int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
+ const struct st_lsm6dsx_transfer_function *tf_ops)
+{
+ struct st_lsm6dsx_hw *hw;
+ int i, err;
+
+ hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
+ if (!hw)
+ return -ENOMEM;
+
+ dev_set_drvdata(dev, (void *)hw);
+
+ mutex_init(&hw->lock);
+ mutex_init(&hw->fifo_lock);
+
+ hw->dev = dev;
+ hw->irq = irq;
+ hw->tf = tf_ops;
+
+ err = st_lsm6dsx_check_whoami(hw, hw_id);
+ if (err < 0)
+ return err;
+
+ for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+ hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i);
+ if (!hw->iio_devs[i])
+ return -ENOMEM;
+ }
+
+ err = st_lsm6dsx_init_device(hw);
+ if (err < 0)
+ return err;
+
+ if (hw->irq > 0) {
+ err = st_lsm6dsx_fifo_setup(hw);
+ if (err < 0)
+ return err;
+ }
+
+ for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
+ err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(st_lsm6dsx_probe);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
new file mode 100644
index 000000000000..ea3041186e1e
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_i2c.c
@@ -0,0 +1,101 @@
+/*
+ * STMicroelectronics st_lsm6dsx i2c driver
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "st_lsm6dsx.h"
+
+static int st_lsm6dsx_i2c_read(struct device *dev, u8 addr, int len, u8 *data)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_msg msg[2];
+
+ msg[0].addr = client->addr;
+ msg[0].flags = client->flags;
+ msg[0].len = 1;
+ msg[0].buf = &addr;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = client->flags | I2C_M_RD;
+ msg[1].len = len;
+ msg[1].buf = data;
+
+ return i2c_transfer(client->adapter, msg, 2);
+}
+
+static int st_lsm6dsx_i2c_write(struct device *dev, u8 addr, int len, u8 *data)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct i2c_msg msg;
+ u8 send[len + 1];
+
+ send[0] = addr;
+ memcpy(&send[1], data, len * sizeof(u8));
+
+ msg.addr = client->addr;
+ msg.flags = client->flags;
+ msg.len = len + 1;
+ msg.buf = send;
+
+ return i2c_transfer(client->adapter, &msg, 1);
+}
+
+static const struct st_lsm6dsx_transfer_function st_lsm6dsx_transfer_fn = {
+ .read = st_lsm6dsx_i2c_read,
+ .write = st_lsm6dsx_i2c_write,
+};
+
+static int st_lsm6dsx_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ return st_lsm6dsx_probe(&client->dev, client->irq,
+ (int)id->driver_data,
+ &st_lsm6dsx_transfer_fn);
+}
+
+static const struct of_device_id st_lsm6dsx_i2c_of_match[] = {
+ {
+ .compatible = "st,lsm6ds3",
+ .data = (void *)ST_LSM6DS3_ID,
+ },
+ {
+ .compatible = "st,lsm6dsm",
+ .data = (void *)ST_LSM6DSM_ID,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_lsm6dsx_i2c_of_match);
+
+static const struct i2c_device_id st_lsm6dsx_i2c_id_table[] = {
+ { ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID },
+ { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, st_lsm6dsx_i2c_id_table);
+
+static struct i2c_driver st_lsm6dsx_driver = {
+ .driver = {
+ .name = "st_lsm6dsx_i2c",
+ .of_match_table = of_match_ptr(st_lsm6dsx_i2c_of_match),
+ },
+ .probe = st_lsm6dsx_i2c_probe,
+ .id_table = st_lsm6dsx_i2c_id_table,
+};
+module_i2c_driver(st_lsm6dsx_driver);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx i2c driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
new file mode 100644
index 000000000000..fbe72470ed1e
--- /dev/null
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_spi.c
@@ -0,0 +1,118 @@
+/*
+ * STMicroelectronics st_lsm6dsx spi driver
+ *
+ * Copyright 2016 STMicroelectronics Inc.
+ *
+ * Lorenzo Bianconi <lorenzo.bianconi@st.com>
+ * Denis Ciocca <denis.ciocca@st.com>
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "st_lsm6dsx.h"
+
+#define SENSORS_SPI_READ BIT(7)
+
+static int st_lsm6dsx_spi_read(struct device *dev, u8 addr, int len,
+ u8 *data)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct st_lsm6dsx_hw *hw = spi_get_drvdata(spi);
+ int err;
+
+ struct spi_transfer xfers[] = {
+ {
+ .tx_buf = hw->tb.tx_buf,
+ .bits_per_word = 8,
+ .len = 1,
+ },
+ {
+ .rx_buf = hw->tb.rx_buf,
+ .bits_per_word = 8,
+ .len = len,
+ }
+ };
+
+ hw->tb.tx_buf[0] = addr | SENSORS_SPI_READ;
+
+ err = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers));
+ if (err < 0)
+ return err;
+
+ memcpy(data, hw->tb.rx_buf, len * sizeof(u8));
+
+ return len;
+}
+
+static int st_lsm6dsx_spi_write(struct device *dev, u8 addr, int len,
+ u8 *data)
+{
+ struct st_lsm6dsx_hw *hw;
+ struct spi_device *spi;
+
+ if (len >= ST_LSM6DSX_TX_MAX_LENGTH)
+ return -ENOMEM;
+
+ spi = to_spi_device(dev);
+ hw = spi_get_drvdata(spi);
+
+ hw->tb.tx_buf[0] = addr;
+ memcpy(&hw->tb.tx_buf[1], data, len);
+
+ return spi_write(spi, hw->tb.tx_buf, len + 1);
+}
+
+static const struct st_lsm6dsx_transfer_function st_lsm6dsx_transfer_fn = {
+ .read = st_lsm6dsx_spi_read,
+ .write = st_lsm6dsx_spi_write,
+};
+
+static int st_lsm6dsx_spi_probe(struct spi_device *spi)
+{
+ const struct spi_device_id *id = spi_get_device_id(spi);
+
+ return st_lsm6dsx_probe(&spi->dev, spi->irq,
+ (int)id->driver_data,
+ &st_lsm6dsx_transfer_fn);
+}
+
+static const struct of_device_id st_lsm6dsx_spi_of_match[] = {
+ {
+ .compatible = "st,lsm6ds3",
+ .data = (void *)ST_LSM6DS3_ID,
+ },
+ {
+ .compatible = "st,lsm6dsm",
+ .data = (void *)ST_LSM6DSM_ID,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, st_lsm6dsx_spi_of_match);
+
+static const struct spi_device_id st_lsm6dsx_spi_id_table[] = {
+ { ST_LSM6DS3_DEV_NAME, ST_LSM6DS3_ID },
+ { ST_LSM6DSM_DEV_NAME, ST_LSM6DSM_ID },
+ {},
+};
+MODULE_DEVICE_TABLE(spi, st_lsm6dsx_spi_id_table);
+
+static struct spi_driver st_lsm6dsx_driver = {
+ .driver = {
+ .name = "st_lsm6dsx_spi",
+ .of_match_table = of_match_ptr(st_lsm6dsx_spi_of_match),
+ },
+ .probe = st_lsm6dsx_spi_probe,
+ .id_table = st_lsm6dsx_spi_id_table,
+};
+module_spi_driver(st_lsm6dsx_driver);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
+MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx spi driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index b12830b09c7d..4972986f6455 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -26,6 +26,7 @@
#include "iio_core.h"
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/buffer_impl.h>
static const char * const iio_endian_prefix[] = {
[IIO_BE] = "be",
@@ -209,6 +210,18 @@ void iio_buffer_init(struct iio_buffer *buffer)
}
EXPORT_SYMBOL(iio_buffer_init);
+/**
+ * iio_buffer_set_attrs - Set buffer specific attributes
+ * @buffer: The buffer for which we are setting attributes
+ * @attrs: Pointer to a null terminated list of pointers to attributes
+ */
+void iio_buffer_set_attrs(struct iio_buffer *buffer,
+ const struct attribute **attrs)
+{
+ buffer->attrs = attrs;
+}
+EXPORT_SYMBOL_GPL(iio_buffer_set_attrs);
+
static ssize_t iio_show_scan_index(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -346,6 +359,19 @@ static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit)
return 0;
}
+static int iio_scan_mask_query(struct iio_dev *indio_dev,
+ struct iio_buffer *buffer, int bit)
+{
+ if (bit > indio_dev->masklength)
+ return -EINVAL;
+
+ if (!buffer->scan_mask)
+ return 0;
+
+ /* Ensure return value is 0 or 1. */
+ return !!test_bit(bit, buffer->scan_mask);
+};
+
static ssize_t iio_scan_el_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
@@ -751,6 +777,135 @@ static int iio_verify_update(struct iio_dev *indio_dev,
return 0;
}
+/**
+ * struct iio_demux_table - table describing demux memcpy ops
+ * @from: index to copy from
+ * @to: index to copy to
+ * @length: how many bytes to copy
+ * @l: list head used for management
+ */
+struct iio_demux_table {
+ unsigned from;
+ unsigned to;
+ unsigned length;
+ struct list_head l;
+};
+
+static void iio_buffer_demux_free(struct iio_buffer *buffer)
+{
+ struct iio_demux_table *p, *q;
+ list_for_each_entry_safe(p, q, &buffer->demux_list, l) {
+ list_del(&p->l);
+ kfree(p);
+ }
+}
+
+static int iio_buffer_add_demux(struct iio_buffer *buffer,
+ struct iio_demux_table **p, unsigned int in_loc, unsigned int out_loc,
+ unsigned int length)
+{
+
+ if (*p && (*p)->from + (*p)->length == in_loc &&
+ (*p)->to + (*p)->length == out_loc) {
+ (*p)->length += length;
+ } else {
+ *p = kmalloc(sizeof(**p), GFP_KERNEL);
+ if (*p == NULL)
+ return -ENOMEM;
+ (*p)->from = in_loc;
+ (*p)->to = out_loc;
+ (*p)->length = length;
+ list_add_tail(&(*p)->l, &buffer->demux_list);
+ }
+
+ return 0;
+}
+
+static int iio_buffer_update_demux(struct iio_dev *indio_dev,
+ struct iio_buffer *buffer)
+{
+ int ret, in_ind = -1, out_ind, length;
+ unsigned in_loc = 0, out_loc = 0;
+ struct iio_demux_table *p = NULL;
+
+ /* Clear out any old demux */
+ iio_buffer_demux_free(buffer);
+ kfree(buffer->demux_bounce);
+ buffer->demux_bounce = NULL;
+
+ /* First work out which scan mode we will actually have */
+ if (bitmap_equal(indio_dev->active_scan_mask,
+ buffer->scan_mask,
+ indio_dev->masklength))
+ return 0;
+
+ /* Now we have the two masks, work from least sig and build up sizes */
+ for_each_set_bit(out_ind,
+ buffer->scan_mask,
+ indio_dev->masklength) {
+ in_ind = find_next_bit(indio_dev->active_scan_mask,
+ indio_dev->masklength,
+ in_ind + 1);
+ while (in_ind != out_ind) {
+ in_ind = find_next_bit(indio_dev->active_scan_mask,
+ indio_dev->masklength,
+ in_ind + 1);
+ length = iio_storage_bytes_for_si(indio_dev, in_ind);
+ /* Make sure we are aligned */
+ in_loc = roundup(in_loc, length) + length;
+ }
+ length = iio_storage_bytes_for_si(indio_dev, in_ind);
+ out_loc = roundup(out_loc, length);
+ in_loc = roundup(in_loc, length);
+ ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length);
+ if (ret)
+ goto error_clear_mux_table;
+ out_loc += length;
+ in_loc += length;
+ }
+ /* Relies on scan_timestamp being last */
+ if (buffer->scan_timestamp) {
+ length = iio_storage_bytes_for_timestamp(indio_dev);
+ out_loc = roundup(out_loc, length);
+ in_loc = roundup(in_loc, length);
+ ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length);
+ if (ret)
+ goto error_clear_mux_table;
+ out_loc += length;
+ in_loc += length;
+ }
+ buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL);
+ if (buffer->demux_bounce == NULL) {
+ ret = -ENOMEM;
+ goto error_clear_mux_table;
+ }
+ return 0;
+
+error_clear_mux_table:
+ iio_buffer_demux_free(buffer);
+
+ return ret;
+}
+
+static 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;
+}
+
static int iio_enable_buffers(struct iio_dev *indio_dev,
struct iio_device_config *config)
{
@@ -1199,34 +1354,6 @@ bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
}
EXPORT_SYMBOL_GPL(iio_validate_scan_mask_onehot);
-int iio_scan_mask_query(struct iio_dev *indio_dev,
- struct iio_buffer *buffer, int bit)
-{
- if (bit > indio_dev->masklength)
- return -EINVAL;
-
- if (!buffer->scan_mask)
- return 0;
-
- /* Ensure return value is 0 or 1. */
- return !!test_bit(bit, buffer->scan_mask);
-};
-EXPORT_SYMBOL_GPL(iio_scan_mask_query);
-
-/**
- * struct iio_demux_table - table describing demux memcpy ops
- * @from: index to copy from
- * @to: index to copy to
- * @length: how many bytes to copy
- * @l: list head used for management
- */
-struct iio_demux_table {
- unsigned from;
- unsigned to;
- unsigned length;
- struct list_head l;
-};
-
static const void *iio_demux(struct iio_buffer *buffer,
const void *datain)
{
@@ -1258,16 +1385,11 @@ static int iio_push_to_buffer(struct iio_buffer *buffer, const void *data)
return 0;
}
-static void iio_buffer_demux_free(struct iio_buffer *buffer)
-{
- struct iio_demux_table *p, *q;
- list_for_each_entry_safe(p, q, &buffer->demux_list, l) {
- list_del(&p->l);
- kfree(p);
- }
-}
-
-
+/**
+ * iio_push_to_buffers() - push to a registered buffer.
+ * @indio_dev: iio_dev structure for device.
+ * @data: Full scan.
+ */
int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data)
{
int ret;
@@ -1283,113 +1405,6 @@ int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data)
}
EXPORT_SYMBOL_GPL(iio_push_to_buffers);
-static int iio_buffer_add_demux(struct iio_buffer *buffer,
- struct iio_demux_table **p, unsigned int in_loc, unsigned int out_loc,
- unsigned int length)
-{
-
- if (*p && (*p)->from + (*p)->length == in_loc &&
- (*p)->to + (*p)->length == out_loc) {
- (*p)->length += length;
- } else {
- *p = kmalloc(sizeof(**p), GFP_KERNEL);
- if (*p == NULL)
- return -ENOMEM;
- (*p)->from = in_loc;
- (*p)->to = out_loc;
- (*p)->length = length;
- list_add_tail(&(*p)->l, &buffer->demux_list);
- }
-
- return 0;
-}
-
-static int iio_buffer_update_demux(struct iio_dev *indio_dev,
- struct iio_buffer *buffer)
-{
- int ret, in_ind = -1, out_ind, length;
- unsigned in_loc = 0, out_loc = 0;
- struct iio_demux_table *p = NULL;
-
- /* Clear out any old demux */
- iio_buffer_demux_free(buffer);
- kfree(buffer->demux_bounce);
- buffer->demux_bounce = NULL;
-
- /* First work out which scan mode we will actually have */
- if (bitmap_equal(indio_dev->active_scan_mask,
- buffer->scan_mask,
- indio_dev->masklength))
- return 0;
-
- /* Now we have the two masks, work from least sig and build up sizes */
- for_each_set_bit(out_ind,
- buffer->scan_mask,
- indio_dev->masklength) {
- in_ind = find_next_bit(indio_dev->active_scan_mask,
- indio_dev->masklength,
- in_ind + 1);
- while (in_ind != out_ind) {
- in_ind = find_next_bit(indio_dev->active_scan_mask,
- indio_dev->masklength,
- in_ind + 1);
- length = iio_storage_bytes_for_si(indio_dev, in_ind);
- /* Make sure we are aligned */
- in_loc = roundup(in_loc, length) + length;
- }
- length = iio_storage_bytes_for_si(indio_dev, in_ind);
- out_loc = roundup(out_loc, length);
- in_loc = roundup(in_loc, length);
- ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length);
- if (ret)
- goto error_clear_mux_table;
- out_loc += length;
- in_loc += length;
- }
- /* Relies on scan_timestamp being last */
- if (buffer->scan_timestamp) {
- length = iio_storage_bytes_for_timestamp(indio_dev);
- out_loc = roundup(out_loc, length);
- in_loc = roundup(in_loc, length);
- ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length);
- if (ret)
- goto error_clear_mux_table;
- out_loc += length;
- in_loc += length;
- }
- buffer->demux_bounce = kzalloc(out_loc, GFP_KERNEL);
- if (buffer->demux_bounce == NULL) {
- ret = -ENOMEM;
- goto error_clear_mux_table;
- }
- return 0;
-
-error_clear_mux_table:
- iio_buffer_demux_free(buffer);
-
- 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);
-
/**
* iio_buffer_release() - Free a buffer's resources
* @ref: Pointer to the kref embedded in the iio_buffer struct
@@ -1431,3 +1446,19 @@ void iio_buffer_put(struct iio_buffer *buffer)
kref_put(&buffer->ref, iio_buffer_release);
}
EXPORT_SYMBOL_GPL(iio_buffer_put);
+
+/**
+ * iio_device_attach_buffer - Attach a buffer to a IIO device
+ * @indio_dev: The device the buffer should be attached to
+ * @buffer: The buffer to attach to the device
+ *
+ * This function attaches a buffer to a IIO device. The buffer stays attached to
+ * the device until the device is freed. The function should only be called at
+ * most once per device.
+ */
+void iio_device_attach_buffer(struct iio_dev *indio_dev,
+ struct iio_buffer *buffer)
+{
+ indio_dev->buffer = iio_buffer_get(buffer);
+}
+EXPORT_SYMBOL_GPL(iio_device_attach_buffer);
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index aaca42862389..d18ded45bedd 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -32,6 +32,7 @@
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/buffer_impl.h>
/* IDA to assign each registered device a unique id */
static DEFINE_IDA(iio_ida);
@@ -83,6 +84,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_ELECTRICALCONDUCTIVITY] = "electricalconductivity",
[IIO_COUNT] = "count",
[IIO_INDEX] = "index",
+ [IIO_GRAVITY] = "gravity",
};
static const char * const iio_modifier_names[] = {
diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
index 978729f6d7c4..978e1592c2a3 100644
--- a/drivers/iio/industrialio-trigger.c
+++ b/drivers/iio/industrialio-trigger.c
@@ -147,8 +147,7 @@ static struct iio_trigger *__iio_trigger_find_by_name(const char *name)
return NULL;
}
-static struct iio_trigger *iio_trigger_find_by_name(const char *name,
- size_t len)
+static struct iio_trigger *iio_trigger_acquire_by_name(const char *name)
{
struct iio_trigger *trig = NULL, *iter;
@@ -156,6 +155,7 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name,
list_for_each_entry(iter, &iio_trigger_list, list)
if (sysfs_streq(iter->name, name)) {
trig = iter;
+ iio_trigger_get(trig);
break;
}
mutex_unlock(&iio_trigger_list_lock);
@@ -416,20 +416,22 @@ static ssize_t iio_trigger_write_current(struct device *dev,
}
mutex_unlock(&indio_dev->mlock);
- trig = iio_trigger_find_by_name(buf, len);
- if (oldtrig == trig)
- return len;
+ trig = iio_trigger_acquire_by_name(buf);
+ if (oldtrig == trig) {
+ ret = len;
+ goto out_trigger_put;
+ }
if (trig && indio_dev->info->validate_trigger) {
ret = indio_dev->info->validate_trigger(indio_dev, trig);
if (ret)
- return ret;
+ goto out_trigger_put;
}
if (trig && trig->ops->validate_device) {
ret = trig->ops->validate_device(trig, indio_dev);
if (ret)
- return ret;
+ goto out_trigger_put;
}
indio_dev->trig = trig;
@@ -441,13 +443,16 @@ static ssize_t iio_trigger_write_current(struct device *dev,
iio_trigger_put(oldtrig);
}
if (indio_dev->trig) {
- iio_trigger_get(indio_dev->trig);
if (indio_dev->modes & INDIO_EVENT_TRIGGERED)
iio_trigger_attach_poll_func(indio_dev->trig,
indio_dev->pollfunc_event);
}
return len;
+
+out_trigger_put:
+ iio_trigger_put(trig);
+ return ret;
}
static DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR,
@@ -487,7 +492,7 @@ static void iio_trig_release(struct device *device)
kfree(trig);
}
-static struct device_type iio_trig_type = {
+static const struct device_type iio_trig_type = {
.release = iio_trig_release,
.groups = iio_trig_dev_groups,
};
@@ -513,46 +518,45 @@ static void iio_trig_subirqunmask(struct irq_data *d)
static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs)
{
struct iio_trigger *trig;
+ int i;
+
trig = kzalloc(sizeof *trig, GFP_KERNEL);
- if (trig) {
- int i;
- trig->dev.type = &iio_trig_type;
- trig->dev.bus = &iio_bus_type;
- device_initialize(&trig->dev);
-
- mutex_init(&trig->pool_lock);
- trig->subirq_base
- = irq_alloc_descs(-1, 0,
- CONFIG_IIO_CONSUMERS_PER_TRIGGER,
- 0);
- if (trig->subirq_base < 0) {
- kfree(trig);
- return NULL;
- }
+ if (!trig)
+ return NULL;
- trig->name = kvasprintf(GFP_KERNEL, fmt, vargs);
- if (trig->name == NULL) {
- irq_free_descs(trig->subirq_base,
- CONFIG_IIO_CONSUMERS_PER_TRIGGER);
- kfree(trig);
- return NULL;
- }
- trig->subirq_chip.name = trig->name;
- trig->subirq_chip.irq_mask = &iio_trig_subirqmask;
- trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask;
- for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
- irq_set_chip(trig->subirq_base + i,
- &trig->subirq_chip);
- irq_set_handler(trig->subirq_base + i,
- &handle_simple_irq);
- irq_modify_status(trig->subirq_base + i,
- IRQ_NOREQUEST | IRQ_NOAUTOEN,
- IRQ_NOPROBE);
- }
- get_device(&trig->dev);
+ trig->dev.type = &iio_trig_type;
+ trig->dev.bus = &iio_bus_type;
+ device_initialize(&trig->dev);
+
+ mutex_init(&trig->pool_lock);
+ trig->subirq_base = irq_alloc_descs(-1, 0,
+ CONFIG_IIO_CONSUMERS_PER_TRIGGER,
+ 0);
+ if (trig->subirq_base < 0)
+ goto free_trig;
+
+ trig->name = kvasprintf(GFP_KERNEL, fmt, vargs);
+ if (trig->name == NULL)
+ goto free_descs;
+
+ trig->subirq_chip.name = trig->name;
+ trig->subirq_chip.irq_mask = &iio_trig_subirqmask;
+ trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask;
+ for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
+ irq_set_chip(trig->subirq_base + i, &trig->subirq_chip);
+ irq_set_handler(trig->subirq_base + i, &handle_simple_irq);
+ irq_modify_status(trig->subirq_base + i,
+ IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
}
+ get_device(&trig->dev);
return trig;
+
+free_descs:
+ irq_free_descs(trig->subirq_base, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+free_trig:
+ kfree(trig);
+ return NULL;
}
struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index b0f4630a163f..7a13535dc3e9 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -601,8 +601,14 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
IIO_CHAN_INFO_SCALE);
- if (scale_type < 0)
- return scale_type;
+ if (scale_type < 0) {
+ /*
+ * Just pass raw values as processed if no scaling is
+ * available.
+ */
+ *processed = raw;
+ return 0;
+ }
switch (scale_type) {
case IIO_VAL_INT:
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 298ea5081a96..5f731ead9d46 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -115,6 +115,16 @@ config CM3323
To compile this driver as a module, choose M here: the module will
be called cm3323.
+config CM3605
+ tristate "Capella CM3605 ambient light and proximity sensor"
+ depends on OF
+ help
+ Say Y here if you want to build a driver for Capella CM3605
+ ambient light and short range proximity sensor.
+
+ To compile this driver as a module, choose M here: the module will
+ be called cm3605.
+
config CM36651
depends on I2C
tristate "CM36651 driver"
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 4de520036e6e..c13a2399e6df 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_BH1780) += bh1780.o
obj-$(CONFIG_CM32181) += cm32181.o
obj-$(CONFIG_CM3232) += cm3232.o
obj-$(CONFIG_CM3323) += cm3323.o
+obj-$(CONFIG_CM3605) += cm3605.o
obj-$(CONFIG_CM36651) += cm36651.o
obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c
index fe89b6823217..263e97235ea0 100644
--- a/drivers/iio/light/cm3232.c
+++ b/drivers/iio/light/cm3232.c
@@ -119,7 +119,7 @@ static int cm3232_reg_init(struct cm3232_chip *chip)
if (ret < 0)
dev_err(&chip->client->dev, "Error writing reg_cmd\n");
- return 0;
+ return ret;
}
/**
diff --git a/drivers/iio/light/cm3605.c b/drivers/iio/light/cm3605.c
new file mode 100644
index 000000000000..980624e9ffb5
--- /dev/null
+++ b/drivers/iio/light/cm3605.c
@@ -0,0 +1,330 @@
+/*
+ * CM3605 Ambient Light and Proximity Sensor
+ *
+ * Copyright (C) 2016 Linaro Ltd.
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ *
+ * This hardware was found in the very first Nexus One handset from Google/HTC
+ * and an early endavour into mobile light and proximity sensors.
+ */
+
+#include <linux/module.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+#include <linux/iio/consumer.h> /* To get our ADC channel */
+#include <linux/iio/types.h> /* To deal with our ADC channel */
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/math64.h>
+#include <linux/pm.h>
+
+#define CM3605_PROX_CHANNEL 0
+#define CM3605_ALS_CHANNEL 1
+#define CM3605_AOUT_TYP_MAX_MV 1550
+/* It should not go above 1.650V according to the data sheet */
+#define CM3605_AOUT_MAX_MV 1650
+
+/**
+ * struct cm3605 - CM3605 state
+ * @dev: pointer to parent device
+ * @vdd: regulator controlling VDD
+ * @aset: sleep enable GPIO, high = sleep
+ * @aout: IIO ADC channel to convert the AOUT signal
+ * @als_max: maximum LUX detection (depends on RSET)
+ * @dir: proximity direction: start as FALLING
+ * @led: trigger for the infrared LED used by the proximity sensor
+ */
+struct cm3605 {
+ struct device *dev;
+ struct regulator *vdd;
+ struct gpio_desc *aset;
+ struct iio_channel *aout;
+ s32 als_max;
+ enum iio_event_direction dir;
+ struct led_trigger *led;
+};
+
+static irqreturn_t cm3605_prox_irq(int irq, void *d)
+{
+ struct iio_dev *indio_dev = d;
+ struct cm3605 *cm3605 = iio_priv(indio_dev);
+ u64 ev;
+
+ ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, CM3605_PROX_CHANNEL,
+ IIO_EV_TYPE_THRESH, cm3605->dir);
+ iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev));
+
+ /* Invert the edge for each event */
+ if (cm3605->dir == IIO_EV_DIR_RISING)
+ cm3605->dir = IIO_EV_DIR_FALLING;
+ else
+ cm3605->dir = IIO_EV_DIR_RISING;
+
+ return IRQ_HANDLED;
+}
+
+static int cm3605_get_lux(struct cm3605 *cm3605)
+{
+ int ret, res;
+ s64 lux;
+
+ ret = iio_read_channel_processed(cm3605->aout, &res);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(cm3605->dev, "read %d mV from ADC\n", res);
+
+ /*
+ * AOUT has an offset of ~30mV then linear at dark
+ * then goes from 2.54 up to 650 LUX yielding 1.55V
+ * (1550 mV) so scale the returned value to this interval
+ * using simple linear interpolation.
+ */
+ if (res < 30)
+ return 0;
+ if (res > CM3605_AOUT_MAX_MV)
+ dev_err(cm3605->dev, "device out of range\n");
+
+ /* Remove bias */
+ lux = res - 30;
+
+ /* Linear interpolation between 0 and ALS typ max */
+ lux *= cm3605->als_max;
+ lux = div64_s64(lux, CM3605_AOUT_TYP_MAX_MV);
+
+ return lux;
+}
+
+static int cm3605_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct cm3605 *cm3605 = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ switch (chan->type) {
+ case IIO_LIGHT:
+ ret = cm3605_get_lux(cm3605);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+ return IIO_VAL_INT;
+ default:
+ return -EINVAL;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info cm3605_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = cm3605_read_raw,
+};
+
+static const struct iio_event_spec cm3605_events[] = {
+ {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_EITHER,
+ .mask_separate = BIT(IIO_EV_INFO_ENABLE),
+ },
+};
+
+static const struct iio_chan_spec cm3605_channels[] = {
+ {
+ .type = IIO_PROXIMITY,
+ .event_spec = cm3605_events,
+ .num_event_specs = ARRAY_SIZE(cm3605_events),
+ },
+ {
+ .type = IIO_LIGHT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .channel = CM3605_ALS_CHANNEL,
+ },
+};
+
+static int cm3605_probe(struct platform_device *pdev)
+{
+ struct cm3605 *cm3605;
+ struct iio_dev *indio_dev;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ enum iio_chan_type ch_type;
+ u32 rset;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*cm3605));
+ if (!indio_dev)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, indio_dev);
+
+ cm3605 = iio_priv(indio_dev);
+ cm3605->dev = dev;
+ cm3605->dir = IIO_EV_DIR_FALLING;
+
+ ret = of_property_read_u32(np, "capella,aset-resistance-ohms", &rset);
+ if (ret) {
+ dev_info(dev, "no RSET specified, assuming 100K\n");
+ rset = 100000;
+ }
+ switch (rset) {
+ case 50000:
+ cm3605->als_max = 650;
+ break;
+ case 100000:
+ cm3605->als_max = 300;
+ break;
+ case 300000:
+ cm3605->als_max = 100;
+ break;
+ case 600000:
+ cm3605->als_max = 50;
+ break;
+ default:
+ dev_info(dev, "non-standard resistance\n");
+ return -EINVAL;
+ }
+
+ cm3605->aout = devm_iio_channel_get(dev, "aout");
+ if (IS_ERR(cm3605->aout)) {
+ if (PTR_ERR(cm3605->aout) == -ENODEV) {
+ dev_err(dev, "no ADC, deferring...\n");
+ return -EPROBE_DEFER;
+ }
+ dev_err(dev, "failed to get AOUT ADC channel\n");
+ return PTR_ERR(cm3605->aout);
+ }
+ ret = iio_get_channel_type(cm3605->aout, &ch_type);
+ if (ret < 0)
+ return ret;
+ if (ch_type != IIO_VOLTAGE) {
+ dev_err(dev, "wrong type of IIO channel specified for AOUT\n");
+ return -EINVAL;
+ }
+
+ cm3605->vdd = devm_regulator_get(dev, "vdd");
+ if (IS_ERR(cm3605->vdd)) {
+ dev_err(dev, "failed to get VDD regulator\n");
+ return PTR_ERR(cm3605->vdd);
+ }
+ ret = regulator_enable(cm3605->vdd);
+ if (ret) {
+ dev_err(dev, "failed to enable VDD regulator\n");
+ return ret;
+ }
+
+ cm3605->aset = devm_gpiod_get(dev, "aset", GPIOD_OUT_HIGH);
+ if (IS_ERR(cm3605->aset)) {
+ dev_err(dev, "no ASET GPIO\n");
+ ret = PTR_ERR(cm3605->aset);
+ goto out_disable_vdd;
+ }
+
+ ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0),
+ cm3605_prox_irq, NULL, 0, "cm3605", indio_dev);
+ if (ret) {
+ dev_err(dev, "unable to request IRQ\n");
+ goto out_disable_aset;
+ }
+
+ /* Just name the trigger the same as the driver */
+ led_trigger_register_simple("cm3605", &cm3605->led);
+ led_trigger_event(cm3605->led, LED_FULL);
+
+ indio_dev->dev.parent = dev;
+ indio_dev->info = &cm3605_info;
+ indio_dev->name = "cm3605";
+ indio_dev->channels = cm3605_channels;
+ indio_dev->num_channels = ARRAY_SIZE(cm3605_channels);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto out_remove_trigger;
+ dev_info(dev, "Capella Microsystems CM3605 enabled range 0..%d LUX\n",
+ cm3605->als_max);
+
+ return 0;
+
+out_remove_trigger:
+ led_trigger_event(cm3605->led, LED_OFF);
+ led_trigger_unregister_simple(cm3605->led);
+out_disable_aset:
+ gpiod_set_value_cansleep(cm3605->aset, 0);
+out_disable_vdd:
+ regulator_disable(cm3605->vdd);
+ return ret;
+}
+
+static int cm3605_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+ struct cm3605 *cm3605 = iio_priv(indio_dev);
+
+ led_trigger_event(cm3605->led, LED_OFF);
+ led_trigger_unregister_simple(cm3605->led);
+ gpiod_set_value_cansleep(cm3605->aset, 0);
+ iio_device_unregister(indio_dev);
+ regulator_disable(cm3605->vdd);
+
+ return 0;
+}
+
+static int __maybe_unused cm3605_pm_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct cm3605 *cm3605 = iio_priv(indio_dev);
+
+ led_trigger_event(cm3605->led, LED_OFF);
+ regulator_disable(cm3605->vdd);
+
+ return 0;
+}
+
+static int __maybe_unused cm3605_pm_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ struct cm3605 *cm3605 = iio_priv(indio_dev);
+ int ret;
+
+ ret = regulator_enable(cm3605->vdd);
+ if (ret)
+ dev_err(dev, "failed to enable regulator in resume path\n");
+ led_trigger_event(cm3605->led, LED_FULL);
+
+ return 0;
+}
+
+static const struct dev_pm_ops cm3605_dev_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(cm3605_pm_suspend,
+ cm3605_pm_resume)
+};
+
+static const struct of_device_id cm3605_of_match[] = {
+ {.compatible = "capella,cm3605"},
+ { },
+};
+MODULE_DEVICE_TABLE(of, cm3605_of_match);
+
+static struct platform_driver cm3605_driver = {
+ .driver = {
+ .name = "cm3605",
+ .of_match_table = cm3605_of_match,
+ .pm = &cm3605_dev_pm_ops,
+ },
+ .probe = cm3605_probe,
+ .remove = cm3605_remove,
+};
+module_platform_driver(cm3605_driver);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
+MODULE_DESCRIPTION("CM3605 ambient light and proximity sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index 8bb1f90ecd51..059d964772c7 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -31,13 +31,17 @@
#include <linux/iio/triggered_buffer.h>
#include "../common/hid-sensors/hid-sensor-trigger.h"
-#define CHANNEL_SCAN_INDEX_ILLUM 0
+enum {
+ CHANNEL_SCAN_INDEX_INTENSITY = 0,
+ CHANNEL_SCAN_INDEX_ILLUM = 1,
+ CHANNEL_SCAN_INDEX_MAX
+};
struct als_state {
struct hid_sensor_hub_callbacks callbacks;
struct hid_sensor_common common_attributes;
struct hid_sensor_hub_attribute_info als_illum;
- u32 illum;
+ u32 illum[CHANNEL_SCAN_INDEX_MAX];
int scale_pre_decml;
int scale_post_decml;
int scale_precision;
@@ -55,6 +59,15 @@ static const struct iio_chan_spec als_channels[] = {
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_HYSTERESIS),
+ .scan_index = CHANNEL_SCAN_INDEX_INTENSITY,
+ },
+ {
+ .type = IIO_LIGHT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_HYSTERESIS),
.scan_index = CHANNEL_SCAN_INDEX_ILLUM,
}
};
@@ -86,6 +99,7 @@ static int als_read_raw(struct iio_dev *indio_dev,
switch (mask) {
case 0:
switch (chan->scan_index) {
+ case CHANNEL_SCAN_INDEX_INTENSITY:
case CHANNEL_SCAN_INDEX_ILLUM:
report_id = als_state->als_illum.report_id;
address =
@@ -202,10 +216,12 @@ static int als_capture_sample(struct hid_sensor_hub_device *hsdev,
struct iio_dev *indio_dev = platform_get_drvdata(priv);
struct als_state *als_state = iio_priv(indio_dev);
int ret = -EINVAL;
+ u32 sample_data = *(u32 *)raw_data;
switch (usage_id) {
case HID_USAGE_SENSOR_LIGHT_ILLUM:
- als_state->illum = *(u32 *)raw_data;
+ als_state->illum[CHANNEL_SCAN_INDEX_INTENSITY] = sample_data;
+ als_state->illum[CHANNEL_SCAN_INDEX_ILLUM] = sample_data;
ret = 0;
break;
default:
@@ -230,6 +246,8 @@ static int als_parse_report(struct platform_device *pdev,
&st->als_illum);
if (ret < 0)
return ret;
+ als_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_INTENSITY,
+ st->als_illum.size);
als_adjust_channel_bit_mask(channels, CHANNEL_SCAN_INDEX_ILLUM,
st->als_illum.size);
diff --git a/drivers/iio/light/max44000.c b/drivers/iio/light/max44000.c
index a144ca3461fc..81bd8e8da4a6 100644
--- a/drivers/iio/light/max44000.c
+++ b/drivers/iio/light/max44000.c
@@ -113,7 +113,7 @@ static const char max44000_int_time_avail_str[] =
"0.100 "
"0.025 "
"0.00625 "
- "0.001625";
+ "0.0015625";
/* Available scales (internal to ulux) with pretty manual alignment: */
static const int max44000_scale_avail_ulux_array[] = {
diff --git a/drivers/iio/light/opt3001.c b/drivers/iio/light/opt3001.c
index 78c9b3a6453a..b91ebc3483ce 100644
--- a/drivers/iio/light/opt3001.c
+++ b/drivers/iio/light/opt3001.c
@@ -840,6 +840,7 @@ static const struct of_device_id opt3001_of_match[] = {
{ .compatible = "ti,opt3001" },
{ }
};
+MODULE_DEVICE_TABLE(of, opt3001_of_match);
static struct i2c_driver opt3001_driver = {
.probe = opt3001_probe,
diff --git a/drivers/iio/magnetometer/ak8974.c b/drivers/iio/magnetometer/ak8974.c
index ce09d771c1fb..6dd8cbd7ce95 100644
--- a/drivers/iio/magnetometer/ak8974.c
+++ b/drivers/iio/magnetometer/ak8974.c
@@ -278,13 +278,9 @@ static int ak8974_await_drdy(struct ak8974 *ak8974)
if (val & AK8974_STATUS_DRDY)
return 0;
} while (--timeout);
- if (!timeout) {
- dev_err(&ak8974->i2c->dev,
- "timeout waiting for DRDY\n");
- return -ETIMEDOUT;
- }
- return 0;
+ dev_err(&ak8974->i2c->dev, "timeout waiting for DRDY\n");
+ return -ETIMEDOUT;
}
static int ak8974_getresult(struct ak8974 *ak8974, __le16 *result)
diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c
index f2b3bd7bf862..b4f643fb3b1e 100644
--- a/drivers/iio/magnetometer/mag3110.c
+++ b/drivers/iio/magnetometer/mag3110.c
@@ -222,29 +222,39 @@ static int mag3110_write_raw(struct iio_dev *indio_dev,
int val, int val2, long mask)
{
struct mag3110_data *data = iio_priv(indio_dev);
- int rate;
+ int rate, ret;
- if (iio_buffer_enabled(indio_dev))
- return -EBUSY;
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
rate = mag3110_get_samp_freq_index(data, val, val2);
- if (rate < 0)
- return -EINVAL;
+ if (rate < 0) {
+ ret = -EINVAL;
+ break;
+ }
data->ctrl_reg1 &= ~MAG3110_CTRL_DR_MASK;
data->ctrl_reg1 |= rate << MAG3110_CTRL_DR_SHIFT;
- return i2c_smbus_write_byte_data(data->client,
+ ret = i2c_smbus_write_byte_data(data->client,
MAG3110_CTRL_REG1, data->ctrl_reg1);
+ break;
case IIO_CHAN_INFO_CALIBBIAS:
- if (val < -10000 || val > 10000)
- return -EINVAL;
- return i2c_smbus_write_word_swapped(data->client,
+ if (val < -10000 || val > 10000) {
+ ret = -EINVAL;
+ break;
+ }
+ ret = i2c_smbus_write_word_swapped(data->client,
MAG3110_OFF_X + 2 * chan->scan_index, val << 1);
+ break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ break;
}
+ iio_device_release_direct_mode(indio_dev);
+ return ret;
}
static irqreturn_t mag3110_trigger_handler(int irq, void *p)
diff --git a/drivers/iio/potentiometer/Kconfig b/drivers/iio/potentiometer/Kconfig
index 2e9da1cf3297..8bf282510be6 100644
--- a/drivers/iio/potentiometer/Kconfig
+++ b/drivers/iio/potentiometer/Kconfig
@@ -15,6 +15,17 @@ config DS1803
To compile this driver as a module, choose M here: the
module will be called ds1803.
+config MAX5481
+ tristate "Maxim MAX5481-MAX5484 Digital Potentiometer driver"
+ depends on SPI
+ help
+ Say yes here to build support for the Maxim
+ MAX5481, MAX5482, MAX5483, MAX5484 digital potentiometer
+ chips.
+
+ To compile this driver as a module, choose M here: the
+ module will be called max5481.
+
config MAX5487
tristate "Maxim MAX5487/MAX5488/MAX5489 Digital Potentiometer driver"
depends on SPI
diff --git a/drivers/iio/potentiometer/Makefile b/drivers/iio/potentiometer/Makefile
index 8adb58f38c0b..2260d40e0936 100644
--- a/drivers/iio/potentiometer/Makefile
+++ b/drivers/iio/potentiometer/Makefile
@@ -4,6 +4,7 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_DS1803) += ds1803.o
+obj-$(CONFIG_MAX5481) += max5481.o
obj-$(CONFIG_MAX5487) += max5487.o
obj-$(CONFIG_MCP4131) += mcp4131.o
obj-$(CONFIG_MCP4531) += mcp4531.o
diff --git a/drivers/iio/potentiometer/max5481.c b/drivers/iio/potentiometer/max5481.c
new file mode 100644
index 000000000000..926554991244
--- /dev/null
+++ b/drivers/iio/potentiometer/max5481.c
@@ -0,0 +1,223 @@
+/*
+ * Maxim Integrated MAX5481-MAX5484 digital potentiometer driver
+ * Copyright 2016 Rockwell Collins
+ *
+ * Datasheet:
+ * http://datasheets.maximintegrated.com/en/ds/MAX5481-MAX5484.pdf
+ *
+ * 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/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/spi/spi.h>
+
+/* write wiper reg */
+#define MAX5481_WRITE_WIPER (0 << 4)
+/* copy wiper reg to NV reg */
+#define MAX5481_COPY_AB_TO_NV (2 << 4)
+/* copy NV reg to wiper reg */
+#define MAX5481_COPY_NV_TO_AB (3 << 4)
+
+#define MAX5481_MAX_POS 1023
+
+enum max5481_variant {
+ max5481,
+ max5482,
+ max5483,
+ max5484,
+};
+
+struct max5481_cfg {
+ int kohms;
+};
+
+static const struct max5481_cfg max5481_cfg[] = {
+ [max5481] = { .kohms = 10, },
+ [max5482] = { .kohms = 50, },
+ [max5483] = { .kohms = 10, },
+ [max5484] = { .kohms = 50, },
+};
+
+struct max5481_data {
+ struct spi_device *spi;
+ const struct max5481_cfg *cfg;
+ u8 msg[3] ____cacheline_aligned;
+};
+
+#define MAX5481_CHANNEL { \
+ .type = IIO_RESISTANCE, \
+ .indexed = 1, \
+ .output = 1, \
+ .channel = 0, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+}
+
+static const struct iio_chan_spec max5481_channels[] = {
+ MAX5481_CHANNEL,
+};
+
+static int max5481_write_cmd(struct max5481_data *data, u8 cmd, u16 val)
+{
+ struct spi_device *spi = data->spi;
+
+ data->msg[0] = cmd;
+
+ switch (cmd) {
+ case MAX5481_WRITE_WIPER:
+ data->msg[1] = val >> 2;
+ data->msg[2] = (val & 0x3) << 6;
+ return spi_write(spi, data->msg, 3);
+
+ case MAX5481_COPY_AB_TO_NV:
+ case MAX5481_COPY_NV_TO_AB:
+ return spi_write(spi, data->msg, 1);
+
+ default:
+ return -EIO;
+ }
+}
+
+static int max5481_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct max5481_data *data = iio_priv(indio_dev);
+
+ if (mask != IIO_CHAN_INFO_SCALE)
+ return -EINVAL;
+
+ *val = 1000 * data->cfg->kohms;
+ *val2 = MAX5481_MAX_POS;
+
+ return IIO_VAL_FRACTIONAL;
+}
+
+static int max5481_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct max5481_data *data = iio_priv(indio_dev);
+
+ if (mask != IIO_CHAN_INFO_RAW)
+ return -EINVAL;
+
+ if (val < 0 || val > MAX5481_MAX_POS)
+ return -EINVAL;
+
+ return max5481_write_cmd(data, MAX5481_WRITE_WIPER, val);
+}
+
+static const struct iio_info max5481_info = {
+ .read_raw = max5481_read_raw,
+ .write_raw = max5481_write_raw,
+ .driver_module = THIS_MODULE,
+};
+
+#if defined(CONFIG_OF)
+static const struct of_device_id max5481_match[] = {
+ { .compatible = "maxim,max5481", .data = &max5481_cfg[max5481] },
+ { .compatible = "maxim,max5482", .data = &max5481_cfg[max5482] },
+ { .compatible = "maxim,max5483", .data = &max5481_cfg[max5483] },
+ { .compatible = "maxim,max5484", .data = &max5481_cfg[max5484] },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max5481_match);
+#endif
+
+static int max5481_probe(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev;
+ struct max5481_data *data;
+ const struct spi_device_id *id = spi_get_device_id(spi);
+ const struct of_device_id *match;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ dev_set_drvdata(&spi->dev, indio_dev);
+ data = iio_priv(indio_dev);
+
+ data->spi = spi;
+
+ match = of_match_device(of_match_ptr(max5481_match), &spi->dev);
+ if (match)
+ data->cfg = of_device_get_match_data(&spi->dev);
+ else
+ data->cfg = &max5481_cfg[id->driver_data];
+
+ indio_dev->name = id->name;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+
+ /* variant specific configuration */
+ indio_dev->info = &max5481_info;
+ indio_dev->channels = max5481_channels;
+ indio_dev->num_channels = ARRAY_SIZE(max5481_channels);
+
+ /* restore wiper from NV */
+ ret = max5481_write_cmd(data, MAX5481_COPY_NV_TO_AB, 0);
+ if (ret < 0)
+ return ret;
+
+ return iio_device_register(indio_dev);
+}
+
+static int max5481_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
+ struct max5481_data *data = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+
+ /* save wiper reg to NV reg */
+ return max5481_write_cmd(data, MAX5481_COPY_AB_TO_NV, 0);
+}
+
+static const struct spi_device_id max5481_id_table[] = {
+ { "max5481", max5481 },
+ { "max5482", max5482 },
+ { "max5483", max5483 },
+ { "max5484", max5484 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, max5481_id_table);
+
+#if defined(CONFIG_ACPI)
+static const struct acpi_device_id max5481_acpi_match[] = {
+ { "max5481", max5481 },
+ { "max5482", max5482 },
+ { "max5483", max5483 },
+ { "max5484", max5484 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, max5481_acpi_match);
+#endif
+
+static struct spi_driver max5481_driver = {
+ .driver = {
+ .name = "max5481",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(max5481_match),
+ .acpi_match_table = ACPI_PTR(max5481_acpi_match),
+ },
+ .probe = max5481_probe,
+ .remove = max5481_remove,
+ .id_table = max5481_id_table,
+};
+
+module_spi_driver(max5481_driver);
+
+MODULE_AUTHOR("Maury Anderson <maury.anderson@rockwellcollins.com>");
+MODULE_DESCRIPTION("max5481 SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/potentiometer/mcp4531.c b/drivers/iio/potentiometer/mcp4531.c
index 0d1bcf89ae17..314353d7ab59 100644
--- a/drivers/iio/potentiometer/mcp4531.c
+++ b/drivers/iio/potentiometer/mcp4531.c
@@ -284,6 +284,7 @@ static const struct of_device_id mcp4531_of_match[] = {
MCP4531_COMPATIBLE("microchip,mcp4662-104", MCP466x_104),
{ /* sentinel */ }
};
+MODULE_DEVICE_TABLE(of, mcp4531_of_match);
#endif
static int mcp4531_probe(struct i2c_client *client,
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index bd8d96b96771..5d16b252ab6b 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -42,6 +42,16 @@ config BMP280_SPI
depends on SPI_MASTER
select REGMAP
+config IIO_CROS_EC_BARO
+ tristate "ChromeOS EC Barometer Sensor"
+ depends on IIO_CROS_EC_SENSORS_CORE
+ help
+ Say yes here to build support for the Barometer sensor when
+ presented by the ChromeOS EC Sensor hub.
+
+ To compile this driver as a module, choose M here: the module
+ will be called cros_ec_baro.
+
config HID_SENSOR_PRESS
depends on HID_SENSOR_HUB
select IIO_BUFFER
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index de3dbc81dc5a..838642789389 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_BMP280) += bmp280.o
bmp280-objs := bmp280-core.o bmp280-regmap.o
obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o
obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o
+obj-$(CONFIG_IIO_CROS_EC_BARO) += cros_ec_baro.o
obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o
obj-$(CONFIG_HP03) += hp03.o
obj-$(CONFIG_MPL115) += mpl115.o
diff --git a/drivers/iio/pressure/bmp280-core.c b/drivers/iio/pressure/bmp280-core.c
index e5a533cbd53f..4d18826ac63c 100644
--- a/drivers/iio/pressure/bmp280-core.c
+++ b/drivers/iio/pressure/bmp280-core.c
@@ -65,7 +65,7 @@ struct bmp280_data {
struct bmp180_calib calib;
struct regulator *vddd;
struct regulator *vdda;
- unsigned int start_up_time; /* in milliseconds */
+ unsigned int start_up_time; /* in microseconds */
/* log of base 2 of oversampling rate */
u8 oversampling_press;
@@ -935,14 +935,14 @@ int bmp280_common_probe(struct device *dev,
data->chip_info = &bmp180_chip_info;
data->oversampling_press = ilog2(8);
data->oversampling_temp = ilog2(1);
- data->start_up_time = 10;
+ data->start_up_time = 10000;
break;
case BMP280_CHIP_ID:
indio_dev->num_channels = 2;
data->chip_info = &bmp280_chip_info;
data->oversampling_press = ilog2(16);
data->oversampling_temp = ilog2(2);
- data->start_up_time = 2;
+ data->start_up_time = 2000;
break;
case BME280_CHIP_ID:
indio_dev->num_channels = 3;
@@ -950,7 +950,7 @@ int bmp280_common_probe(struct device *dev,
data->oversampling_press = ilog2(16);
data->oversampling_humid = ilog2(16);
data->oversampling_temp = ilog2(2);
- data->start_up_time = 2;
+ data->start_up_time = 2000;
break;
default:
return -EINVAL;
@@ -979,7 +979,7 @@ int bmp280_common_probe(struct device *dev,
goto out_disable_vddd;
}
/* Wait to make sure we started up properly */
- mdelay(data->start_up_time);
+ usleep_range(data->start_up_time, data->start_up_time + 100);
/* Bring chip out of reset if there is an assigned GPIO line */
gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
@@ -1038,7 +1038,7 @@ int bmp280_common_probe(struct device *dev,
* Set autosuspend to two orders of magnitude larger than the
* start-up time.
*/
- pm_runtime_set_autosuspend_delay(dev, data->start_up_time *100);
+ pm_runtime_set_autosuspend_delay(dev, data->start_up_time / 10);
pm_runtime_use_autosuspend(dev);
pm_runtime_put(dev);
@@ -1101,7 +1101,7 @@ static int bmp280_runtime_resume(struct device *dev)
ret = regulator_enable(data->vdda);
if (ret)
return ret;
- msleep(data->start_up_time);
+ usleep_range(data->start_up_time, data->start_up_time + 100);
return data->chip_info->chip_config(data);
}
#endif /* CONFIG_PM */
diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c
new file mode 100644
index 000000000000..48b2a30f57ae
--- /dev/null
+++ b/drivers/iio/pressure/cros_ec_baro.c
@@ -0,0 +1,220 @@
+/*
+ * cros_ec_baro - Driver for barometer sensor behind CrosEC.
+ *
+ * Copyright (C) 2017 Google, Inc
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/kernel.h>
+#include <linux/mfd/cros_ec.h>
+#include <linux/mfd/cros_ec_commands.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "../common/cros_ec_sensors/cros_ec_sensors_core.h"
+
+/*
+ * One channel for pressure, the other for timestamp.
+ */
+#define CROS_EC_BARO_MAX_CHANNELS (1 + 1)
+
+/* State data for ec_sensors iio driver. */
+struct cros_ec_baro_state {
+ /* Shared by all sensors */
+ struct cros_ec_sensors_core_state core;
+
+ struct iio_chan_spec channels[CROS_EC_BARO_MAX_CHANNELS];
+};
+
+static int cros_ec_baro_read(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct cros_ec_baro_state *st = iio_priv(indio_dev);
+ u16 data = 0;
+ int ret = IIO_VAL_INT;
+ int idx = chan->scan_index;
+
+ mutex_lock(&st->core.cmd_lock);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ if (cros_ec_sensors_read_cmd(indio_dev, 1 << idx,
+ (s16 *)&data) < 0)
+ ret = -EIO;
+ *val = data;
+ break;
+ case IIO_CHAN_INFO_SCALE:
+ st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
+ st->core.param.sensor_range.data = EC_MOTION_SENSE_NO_VALUE;
+
+ if (cros_ec_motion_send_host_cmd(&st->core, 0)) {
+ ret = -EIO;
+ break;
+ }
+ *val = st->core.resp->sensor_range.ret;
+
+ /* scale * in_pressure_raw --> kPa */
+ *val2 = 10 << CROS_EC_SENSOR_BITS;
+ ret = IIO_VAL_FRACTIONAL;
+ break;
+ default:
+ ret = cros_ec_sensors_core_read(&st->core, chan, val, val2,
+ mask);
+ break;
+ }
+
+ mutex_unlock(&st->core.cmd_lock);
+
+ return ret;
+}
+
+static int cros_ec_baro_write(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int val, int val2, long mask)
+{
+ struct cros_ec_baro_state *st = iio_priv(indio_dev);
+ int ret = 0;
+
+ mutex_lock(&st->core.cmd_lock);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
+ st->core.param.sensor_range.data = val;
+
+ /* Always roundup, so caller gets at least what it asks for. */
+ st->core.param.sensor_range.roundup = 1;
+
+ if (cros_ec_motion_send_host_cmd(&st->core, 0))
+ ret = -EIO;
+ break;
+ default:
+ ret = cros_ec_sensors_core_write(&st->core, chan, val, val2,
+ mask);
+ break;
+ }
+
+ mutex_unlock(&st->core.cmd_lock);
+
+ return ret;
+}
+
+static const struct iio_info cros_ec_baro_info = {
+ .read_raw = &cros_ec_baro_read,
+ .write_raw = &cros_ec_baro_write,
+ .driver_module = THIS_MODULE,
+};
+
+static int cros_ec_baro_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);
+ struct cros_ec_device *ec_device;
+ struct iio_dev *indio_dev;
+ struct cros_ec_baro_state *state;
+ struct iio_chan_spec *channel;
+ int ret;
+
+ if (!ec_dev || !ec_dev->ec_dev) {
+ dev_warn(dev, "No CROS EC device found.\n");
+ return -EINVAL;
+ }
+ ec_device = ec_dev->ec_dev;
+
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
+ if (ret)
+ return ret;
+
+ indio_dev->info = &cros_ec_baro_info;
+ state = iio_priv(indio_dev);
+ state->core.type = state->core.resp->info.type;
+ state->core.loc = state->core.resp->info.location;
+ channel = state->channels;
+ /* Common part */
+ channel->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
+ channel->info_mask_shared_by_all =
+ BIT(IIO_CHAN_INFO_SCALE) |
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+ BIT(IIO_CHAN_INFO_FREQUENCY);
+ channel->scan_type.realbits = CROS_EC_SENSOR_BITS;
+ channel->scan_type.storagebits = CROS_EC_SENSOR_BITS;
+ channel->scan_type.shift = 0;
+ channel->scan_index = 0;
+ channel->ext_info = cros_ec_sensors_ext_info;
+ channel->scan_type.sign = 'u';
+
+ state->core.calib[0] = 0;
+
+ /* Sensor specific */
+ switch (state->core.type) {
+ case MOTIONSENSE_TYPE_BARO:
+ channel->type = IIO_PRESSURE;
+ break;
+ default:
+ dev_warn(dev, "Unknown motion sensor\n");
+ return -EINVAL;
+ }
+
+ /* Timestamp */
+ channel++;
+ channel->type = IIO_TIMESTAMP;
+ channel->channel = -1;
+ channel->scan_index = 1;
+ channel->scan_type.sign = 's';
+ channel->scan_type.realbits = 64;
+ channel->scan_type.storagebits = 64;
+
+ indio_dev->channels = state->channels;
+ indio_dev->num_channels = CROS_EC_BARO_MAX_CHANNELS;
+
+ state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
+
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
+ cros_ec_sensors_capture, NULL);
+ if (ret)
+ return ret;
+
+ return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct platform_device_id cros_ec_baro_ids[] = {
+ {
+ .name = "cros-ec-baro",
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, cros_ec_baro_ids);
+
+static struct platform_driver cros_ec_baro_platform_driver = {
+ .driver = {
+ .name = "cros-ec-baro",
+ },
+ .probe = cros_ec_baro_probe,
+ .id_table = cros_ec_baro_ids,
+};
+module_platform_driver(cros_ec_baro_platform_driver);
+
+MODULE_DESCRIPTION("ChromeOS EC barometer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c
index 6bd53e702667..2a77a2f15752 100644
--- a/drivers/iio/pressure/ms5611_core.c
+++ b/drivers/iio/pressure/ms5611_core.c
@@ -308,6 +308,7 @@ static int ms5611_write_raw(struct iio_dev *indio_dev,
{
struct ms5611_state *st = iio_priv(indio_dev);
const struct ms5611_osr *osr = NULL;
+ int ret;
if (mask != IIO_CHAN_INFO_OVERSAMPLING_RATIO)
return -EINVAL;
@@ -321,12 +322,11 @@ static int ms5611_write_raw(struct iio_dev *indio_dev,
if (!osr)
return -EINVAL;
- mutex_lock(&st->lock);
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
- if (iio_buffer_enabled(indio_dev)) {
- mutex_unlock(&st->lock);
- return -EBUSY;
- }
+ mutex_lock(&st->lock);
if (chan->type == IIO_TEMP)
st->temp_osr = osr;
@@ -334,6 +334,8 @@ static int ms5611_write_raw(struct iio_dev *indio_dev,
st->pressure_osr = osr;
mutex_unlock(&st->lock);
+ iio_device_release_direct_mode(indio_dev);
+
return 0;
}
diff --git a/drivers/iio/pressure/st_pressure.h b/drivers/iio/pressure/st_pressure.h
index 903a21e46874..7d995937adba 100644
--- a/drivers/iio/pressure/st_pressure.h
+++ b/drivers/iio/pressure/st_pressure.h
@@ -14,6 +14,14 @@
#include <linux/types.h>
#include <linux/iio/common/st_sensors.h>
+enum st_press_type {
+ LPS001WP,
+ LPS25H,
+ LPS331AP,
+ LPS22HB,
+ ST_PRESS_MAX,
+};
+
#define LPS001WP_PRESS_DEV_NAME "lps001wp"
#define LPS25H_PRESS_DEV_NAME "lps25h"
#define LPS331AP_PRESS_DEV_NAME "lps331ap"
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
index e19e0787864c..5f2680855552 100644
--- a/drivers/iio/pressure/st_pressure_core.c
+++ b/drivers/iio/pressure/st_pressure_core.c
@@ -136,20 +136,21 @@ static const struct iio_chan_spec st_press_1_channels[] = {
.address = ST_PRESS_1_OUT_XL_ADDR,
.scan_index = 0,
.scan_type = {
- .sign = 'u',
+ .sign = 's',
.realbits = 24,
.storagebits = 32,
.endianness = IIO_LE,
},
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
{
.type = IIO_TEMP,
.address = ST_TEMP_1_OUT_L_ADDR,
.scan_index = 1,
.scan_type = {
- .sign = 'u',
+ .sign = 's',
.realbits = 16,
.storagebits = 16,
.endianness = IIO_LE,
@@ -158,6 +159,7 @@ static const struct iio_chan_spec st_press_1_channels[] = {
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_OFFSET),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
},
IIO_CHAN_SOFT_TIMESTAMP(2)
};
@@ -168,7 +170,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = {
.address = ST_PRESS_LPS001WP_OUT_L_ADDR,
.scan_index = 0,
.scan_type = {
- .sign = 'u',
+ .sign = 's',
.realbits = 16,
.storagebits = 16,
.endianness = IIO_LE,
@@ -182,7 +184,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = {
.address = ST_TEMP_LPS001WP_OUT_L_ADDR,
.scan_index = 1,
.scan_type = {
- .sign = 'u',
+ .sign = 's',
.realbits = 16,
.storagebits = 16,
.endianness = IIO_LE,
@@ -200,7 +202,7 @@ static const struct iio_chan_spec st_press_lps22hb_channels[] = {
.address = ST_PRESS_1_OUT_XL_ADDR,
.scan_index = 0,
.scan_type = {
- .sign = 'u',
+ .sign = 's',
.realbits = 24,
.storagebits = 32,
.endianness = IIO_LE,
diff --git a/drivers/iio/pressure/st_pressure_i2c.c b/drivers/iio/pressure/st_pressure_i2c.c
index ed18701c68c9..17417a4d5a5f 100644
--- a/drivers/iio/pressure/st_pressure_i2c.c
+++ b/drivers/iio/pressure/st_pressure_i2c.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
@@ -43,25 +44,56 @@ MODULE_DEVICE_TABLE(of, st_press_of_match);
#define st_press_of_match NULL
#endif
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id st_press_acpi_match[] = {
+ {"SNO9210", LPS22HB},
+ { },
+};
+MODULE_DEVICE_TABLE(acpi, st_press_acpi_match);
+#else
+#define st_press_acpi_match NULL
+#endif
+
+static const struct i2c_device_id st_press_id_table[] = {
+ { LPS001WP_PRESS_DEV_NAME, LPS001WP },
+ { LPS25H_PRESS_DEV_NAME, LPS25H },
+ { LPS331AP_PRESS_DEV_NAME, LPS331AP },
+ { LPS22HB_PRESS_DEV_NAME, LPS22HB },
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, st_press_id_table);
+
static int st_press_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct st_sensor_data *press_data;
- int err;
+ int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*press_data));
if (!indio_dev)
return -ENOMEM;
press_data = iio_priv(indio_dev);
- st_sensors_of_i2c_probe(client, st_press_of_match);
+
+ if (client->dev.of_node) {
+ st_sensors_of_i2c_probe(client, st_press_of_match);
+ } else if (ACPI_HANDLE(&client->dev)) {
+ ret = st_sensors_match_acpi_device(&client->dev);
+ if ((ret < 0) || (ret >= ST_PRESS_MAX))
+ return -ENODEV;
+
+ strncpy(client->name, st_press_id_table[ret].name,
+ sizeof(client->name));
+ client->name[sizeof(client->name) - 1] = '\0';
+ } else if (!id)
+ return -ENODEV;
st_sensors_i2c_configure(indio_dev, client, press_data);
- err = st_press_common_probe(indio_dev);
- if (err < 0)
- return err;
+ ret = st_press_common_probe(indio_dev);
+ if (ret < 0)
+ return ret;
return 0;
}
@@ -73,18 +105,11 @@ static int st_press_i2c_remove(struct i2c_client *client)
return 0;
}
-static const struct i2c_device_id st_press_id_table[] = {
- { LPS001WP_PRESS_DEV_NAME },
- { LPS25H_PRESS_DEV_NAME },
- { LPS331AP_PRESS_DEV_NAME },
- {},
-};
-MODULE_DEVICE_TABLE(i2c, st_press_id_table);
-
static struct i2c_driver st_press_driver = {
.driver = {
.name = "st-press-i2c",
.of_match_table = of_match_ptr(st_press_of_match),
+ .acpi_match_table = ACPI_PTR(st_press_acpi_match),
},
.probe = st_press_i2c_probe,
.remove = st_press_i2c_remove,
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
index ef4c73db5b53..ab96cb7a0054 100644
--- a/drivers/iio/proximity/Kconfig
+++ b/drivers/iio/proximity/Kconfig
@@ -18,7 +18,7 @@ config AS3935
endmenu
-menu "Proximity sensors"
+menu "Proximity and distance sensors"
config LIDAR_LITE_V2
tristate "PulsedLight LIDAR sensor"
@@ -45,4 +45,15 @@ config SX9500
To compile this driver as a module, choose M here: the
module will be called sx9500.
+config SRF08
+ tristate "Devantech SRF08 ultrasonic ranger sensor"
+ depends on I2C
+ help
+ Say Y here to build a driver for Devantech SRF08 ultrasonic
+ ranger sensor. This driver can be used to measure the distance
+ of objects.
+
+ To compile this driver as a module, choose M here: the
+ module will be called srf08.
+
endmenu
diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile
index 9aadd9a8ee99..e914c2a5dd49 100644
--- a/drivers/iio/proximity/Makefile
+++ b/drivers/iio/proximity/Makefile
@@ -5,4 +5,5 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AS3935) += as3935.o
obj-$(CONFIG_LIDAR_LITE_V2) += pulsedlight-lidar-lite-v2.o
+obj-$(CONFIG_SRF08) += srf08.o
obj-$(CONFIG_SX9500) += sx9500.o
diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
index 1fa9eefa0982..20c16a08c9d9 100644
--- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
+++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c
@@ -326,12 +326,14 @@ static int lidar_remove(struct i2c_client *client)
static const struct i2c_device_id lidar_id[] = {
{"lidar-lite-v2", 0},
+ {"lidar-lite-v3", 0},
{ },
};
MODULE_DEVICE_TABLE(i2c, lidar_id);
static const struct of_device_id lidar_dt_ids[] = {
{ .compatible = "pulsedlight,lidar-lite-v2" },
+ { .compatible = "grmn,lidar-lite-v3" },
{ }
};
MODULE_DEVICE_TABLE(of, lidar_dt_ids);
diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c
new file mode 100644
index 000000000000..49316cbf7c60
--- /dev/null
+++ b/drivers/iio/proximity/srf08.c
@@ -0,0 +1,398 @@
+/*
+ * srf08.c - Support for Devantech SRF08 ultrasonic ranger
+ *
+ * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * For details about the device see:
+ * http://www.robot-electronics.co.uk/htm/srf08tech.html
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/bitops.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+/* registers of SRF08 device */
+#define SRF08_WRITE_COMMAND 0x00 /* Command Register */
+#define SRF08_WRITE_MAX_GAIN 0x01 /* Max Gain Register: 0 .. 31 */
+#define SRF08_WRITE_RANGE 0x02 /* Range Register: 0 .. 255 */
+#define SRF08_READ_SW_REVISION 0x00 /* Software Revision */
+#define SRF08_READ_LIGHT 0x01 /* Light Sensor during last echo */
+#define SRF08_READ_ECHO_1_HIGH 0x02 /* Range of first echo received */
+#define SRF08_READ_ECHO_1_LOW 0x03 /* Range of first echo received */
+
+#define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */
+
+#define SRF08_DEFAULT_GAIN 1025 /* default analogue value of Gain */
+#define SRF08_DEFAULT_RANGE 6020 /* default value of Range in mm */
+
+struct srf08_data {
+ struct i2c_client *client;
+ int sensitivity; /* Gain */
+ int range_mm; /* max. Range in mm */
+ struct mutex lock;
+};
+
+/*
+ * in the documentation one can read about the "Gain" of the device
+ * which is used here for amplifying the signal and filtering out unwanted
+ * ones.
+ * But with ADC's this term is already used differently and that's why it
+ * is called "Sensitivity" here.
+ */
+static const int srf08_sensitivity[] = {
+ 94, 97, 100, 103, 107, 110, 114, 118,
+ 123, 128, 133, 139, 145, 152, 159, 168,
+ 177, 187, 199, 212, 227, 245, 265, 288,
+ 317, 352, 395, 450, 524, 626, 777, 1025 };
+
+static int srf08_read_ranging(struct srf08_data *data)
+{
+ struct i2c_client *client = data->client;
+ int ret, i;
+ int waittime;
+
+ mutex_lock(&data->lock);
+
+ ret = i2c_smbus_write_byte_data(data->client,
+ SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM);
+ if (ret < 0) {
+ dev_err(&client->dev, "write command - err: %d\n", ret);
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ /*
+ * we read here until a correct version number shows up as
+ * suggested by the documentation
+ *
+ * with an ultrasonic speed of 343 m/s and a roundtrip of it
+ * sleep the expected duration and try to read from the device
+ * if nothing useful is read try it in a shorter grid
+ *
+ * polling for not more than 20 ms should be enough
+ */
+ waittime = 1 + data->range_mm / 172;
+ msleep(waittime);
+ for (i = 0; i < 4; i++) {
+ ret = i2c_smbus_read_byte_data(data->client,
+ SRF08_READ_SW_REVISION);
+
+ /* check if a valid version number is read */
+ if (ret < 255 && ret > 0)
+ break;
+ msleep(5);
+ }
+
+ if (ret >= 255 || ret <= 0) {
+ dev_err(&client->dev, "device not ready\n");
+ mutex_unlock(&data->lock);
+ return -EIO;
+ }
+
+ ret = i2c_smbus_read_word_swapped(data->client,
+ SRF08_READ_ECHO_1_HIGH);
+ if (ret < 0) {
+ dev_err(&client->dev, "cannot read distance: ret=%d\n", ret);
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ mutex_unlock(&data->lock);
+
+ return ret;
+}
+
+static int srf08_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *channel, int *val,
+ int *val2, long mask)
+{
+ struct srf08_data *data = iio_priv(indio_dev);
+ int ret;
+
+ if (channel->type != IIO_DISTANCE)
+ return -EINVAL;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = srf08_read_ranging(data);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ /* 1 LSB is 1 cm */
+ *val = 0;
+ *val2 = 10000;
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static ssize_t srf08_show_range_mm_available(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "[0.043 0.043 11.008]\n");
+}
+
+static IIO_DEVICE_ATTR(sensor_max_range_available, S_IRUGO,
+ srf08_show_range_mm_available, NULL, 0);
+
+static ssize_t srf08_show_range_mm(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct srf08_data *data = iio_priv(indio_dev);
+
+ return sprintf(buf, "%d.%03d\n", data->range_mm / 1000,
+ data->range_mm % 1000);
+}
+
+/*
+ * set the range of the sensor to an even multiple of 43 mm
+ * which corresponds to 1 LSB in the register
+ *
+ * register value corresponding range
+ * 0x00 43 mm
+ * 0x01 86 mm
+ * 0x02 129 mm
+ * ...
+ * 0xFF 11008 mm
+ */
+static ssize_t srf08_write_range_mm(struct srf08_data *data, unsigned int val)
+{
+ int ret;
+ struct i2c_client *client = data->client;
+ unsigned int mod;
+ u8 regval;
+
+ ret = val / 43 - 1;
+ mod = val % 43;
+
+ if (mod || (ret < 0) || (ret > 255))
+ return -EINVAL;
+
+ regval = ret;
+
+ mutex_lock(&data->lock);
+
+ ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_RANGE, regval);
+ if (ret < 0) {
+ dev_err(&client->dev, "write_range - err: %d\n", ret);
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ data->range_mm = val;
+
+ mutex_unlock(&data->lock);
+
+ return 0;
+}
+
+static ssize_t srf08_store_range_mm(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct srf08_data *data = iio_priv(indio_dev);
+ int ret;
+ int integer, fract;
+
+ ret = iio_str_to_fixpoint(buf, 100, &integer, &fract);
+ if (ret)
+ return ret;
+
+ ret = srf08_write_range_mm(data, integer * 1000 + fract);
+ if (ret < 0)
+ return ret;
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(sensor_max_range, S_IRUGO | S_IWUSR,
+ srf08_show_range_mm, srf08_store_range_mm, 0);
+
+static ssize_t srf08_show_sensitivity_available(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int i, len = 0;
+
+ for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++)
+ len += sprintf(buf + len, "%d ", srf08_sensitivity[i]);
+
+ len += sprintf(buf + len, "\n");
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(sensor_sensitivity_available, S_IRUGO,
+ srf08_show_sensitivity_available, NULL, 0);
+
+static ssize_t srf08_show_sensitivity(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct srf08_data *data = iio_priv(indio_dev);
+ int len;
+
+ len = sprintf(buf, "%d\n", data->sensitivity);
+
+ return len;
+}
+
+static ssize_t srf08_write_sensitivity(struct srf08_data *data,
+ unsigned int val)
+{
+ struct i2c_client *client = data->client;
+ int ret, i;
+ u8 regval;
+
+ for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++)
+ if (val == srf08_sensitivity[i]) {
+ regval = i;
+ break;
+ }
+
+ if (i >= ARRAY_SIZE(srf08_sensitivity))
+ return -EINVAL;
+
+ mutex_lock(&data->lock);
+
+ ret = i2c_smbus_write_byte_data(client,
+ SRF08_WRITE_MAX_GAIN, regval);
+ if (ret < 0) {
+ dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
+ mutex_unlock(&data->lock);
+ return ret;
+ }
+
+ data->sensitivity = val;
+
+ mutex_unlock(&data->lock);
+
+ return 0;
+}
+
+static ssize_t srf08_store_sensitivity(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+ struct srf08_data *data = iio_priv(indio_dev);
+ int ret;
+ unsigned int val;
+
+ ret = kstrtouint(buf, 10, &val);
+ if (ret)
+ return ret;
+
+ ret = srf08_write_sensitivity(data, val);
+ if (ret < 0)
+ return ret;
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
+ srf08_show_sensitivity, srf08_store_sensitivity, 0);
+
+static struct attribute *srf08_attributes[] = {
+ &iio_dev_attr_sensor_max_range.dev_attr.attr,
+ &iio_dev_attr_sensor_max_range_available.dev_attr.attr,
+ &iio_dev_attr_sensor_sensitivity.dev_attr.attr,
+ &iio_dev_attr_sensor_sensitivity_available.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group srf08_attribute_group = {
+ .attrs = srf08_attributes,
+};
+
+static const struct iio_chan_spec srf08_channels[] = {
+ {
+ .type = IIO_DISTANCE,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ },
+};
+
+static const struct iio_info srf08_info = {
+ .read_raw = srf08_read_raw,
+ .attrs = &srf08_attribute_group,
+ .driver_module = THIS_MODULE,
+};
+
+static int srf08_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct iio_dev *indio_dev;
+ struct srf08_data *data;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_BYTE_DATA |
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
+ I2C_FUNC_SMBUS_READ_WORD_DATA))
+ return -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ indio_dev->name = "srf08";
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &srf08_info;
+ indio_dev->channels = srf08_channels;
+ indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
+
+ mutex_init(&data->lock);
+
+ /*
+ * set default values of device here
+ * these register values cannot be read from the hardware
+ * therefore set driver specific default values
+ */
+ ret = srf08_write_range_mm(data, SRF08_DEFAULT_RANGE);
+ if (ret < 0)
+ return ret;
+
+ ret = srf08_write_sensitivity(data, SRF08_DEFAULT_GAIN);
+ if (ret < 0)
+ return ret;
+
+ return devm_iio_device_register(&client->dev, indio_dev);
+}
+
+static const struct i2c_device_id srf08_id[] = {
+ { "srf08", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, srf08_id);
+
+static struct i2c_driver srf08_driver = {
+ .driver = {
+ .name = "srf08",
+ },
+ .probe = srf08_probe,
+ .id_table = srf08_id,
+};
+module_i2c_driver(srf08_driver);
+
+MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
+MODULE_DESCRIPTION("Devantech SRF08 ultrasonic ranger driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c
index 1f06282ec793..9ea147f1a50d 100644
--- a/drivers/iio/proximity/sx9500.c
+++ b/drivers/iio/proximity/sx9500.c
@@ -387,14 +387,18 @@ static int sx9500_read_raw(struct iio_dev *indio_dev,
int *val, int *val2, long mask)
{
struct sx9500_data *data = iio_priv(indio_dev);
+ int ret;
switch (chan->type) {
case IIO_PROXIMITY:
switch (mask) {
case IIO_CHAN_INFO_RAW:
- if (iio_buffer_enabled(indio_dev))
- return -EBUSY;
- return sx9500_read_proximity(data, chan, val);
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+ ret = sx9500_read_proximity(data, chan, val);
+ iio_device_release_direct_mode(indio_dev);
+ return ret;
case IIO_CHAN_INFO_SAMP_FREQ:
return sx9500_read_samp_freq(data, val, val2);
default:
diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig
index 5ea77a7e261d..3089e8d0a32d 100644
--- a/drivers/iio/temperature/Kconfig
+++ b/drivers/iio/temperature/Kconfig
@@ -39,6 +39,16 @@ config TMP006
This driver can also be built as a module. If so, the module will
be called tmp006.
+config TMP007
+ tristate "TMP007 infrared thermopile sensor with Integrated Math Engine"
+ depends on I2C
+ help
+ If you say yes here you get support for the Texas Instruments
+ TMP007 infrared thermopile sensor with Integrated Math Engine.
+
+ This driver can also be built as a module. If so, the module will
+ be called tmp007.
+
config TSYS01
tristate "Measurement Specialties TSYS01 temperature sensor using I2C bus connection"
depends on I2C
diff --git a/drivers/iio/temperature/Makefile b/drivers/iio/temperature/Makefile
index 78c3de0dc3f0..4c4377480726 100644
--- a/drivers/iio/temperature/Makefile
+++ b/drivers/iio/temperature/Makefile
@@ -5,5 +5,6 @@
obj-$(CONFIG_MAXIM_THERMOCOUPLE) += maxim_thermocouple.o
obj-$(CONFIG_MLX90614) += mlx90614.o
obj-$(CONFIG_TMP006) += tmp006.o
+obj-$(CONFIG_TMP007) += tmp007.o
obj-$(CONFIG_TSYS01) += tsys01.o
obj-$(CONFIG_TSYS02D) += tsys02d.o
diff --git a/drivers/iio/temperature/tmp007.c b/drivers/iio/temperature/tmp007.c
new file mode 100644
index 000000000000..24c6c16d169d
--- /dev/null
+++ b/drivers/iio/temperature/tmp007.c
@@ -0,0 +1,345 @@
+/*
+ * tmp007.c - Support for TI TMP007 IR thermopile sensor with integrated math engine
+ *
+ * Copyright (c) 2017 Manivannan Sadhasivam <manivannanece23@gmail.com>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * Driver for the Texas Instruments I2C 16-bit IR thermopile sensor
+ *
+ * (7-bit I2C slave address (0x40 - 0x47), changeable via ADR pins)
+ *
+ * Note: This driver assumes that the sensor has been calibrated beforehand
+ *
+ * TODO: ALERT irq, limit threshold events
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/bitops.h>
+#include <linux/of.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define TMP007_TDIE 0x01
+#define TMP007_CONFIG 0x02
+#define TMP007_TOBJECT 0x03
+#define TMP007_STATUS 0x04
+#define TMP007_STATUS_MASK 0x05
+#define TMP007_MANUFACTURER_ID 0x1e
+#define TMP007_DEVICE_ID 0x1f
+
+#define TMP007_CONFIG_CONV_EN BIT(12)
+#define TMP007_CONFIG_COMP_EN BIT(5)
+#define TMP007_CONFIG_TC_EN BIT(6)
+#define TMP007_CONFIG_CR_MASK GENMASK(11, 9)
+#define TMP007_CONFIG_CR_SHIFT 9
+
+#define TMP007_STATUS_CONV_READY BIT(14)
+#define TMP007_STATUS_DATA_VALID BIT(9)
+
+#define TMP007_MANUFACTURER_MAGIC 0x5449
+#define TMP007_DEVICE_MAGIC 0x0078
+
+#define TMP007_TEMP_SHIFT 2
+
+struct tmp007_data {
+ struct i2c_client *client;
+ u16 config;
+};
+
+static const int tmp007_avgs[5][2] = { {4, 0}, {2, 0}, {1, 0},
+ {0, 500000}, {0, 250000} };
+
+static int tmp007_read_temperature(struct tmp007_data *data, u8 reg)
+{
+ s32 ret;
+ int tries = 50;
+
+ while (tries-- > 0) {
+ ret = i2c_smbus_read_word_swapped(data->client,
+ TMP007_STATUS);
+ if (ret < 0)
+ return ret;
+ if ((ret & TMP007_STATUS_CONV_READY) &&
+ !(ret & TMP007_STATUS_DATA_VALID))
+ break;
+ msleep(100);
+ }
+
+ if (tries < 0)
+ return -EIO;
+
+ return i2c_smbus_read_word_swapped(data->client, reg);
+}
+
+static int tmp007_powerdown(struct tmp007_data *data)
+{
+ return i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG,
+ data->config & ~TMP007_CONFIG_CONV_EN);
+}
+
+static int tmp007_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *channel, int *val,
+ int *val2, long mask)
+{
+ struct tmp007_data *data = iio_priv(indio_dev);
+ s32 ret;
+ int conv_rate;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ switch (channel->channel2) {
+ case IIO_MOD_TEMP_AMBIENT: /* LSB: 0.03125 degree Celsius */
+ ret = i2c_smbus_read_word_swapped(data->client, TMP007_TDIE);
+ if (ret < 0)
+ return ret;
+ break;
+ case IIO_MOD_TEMP_OBJECT:
+ ret = tmp007_read_temperature(data, TMP007_TOBJECT);
+ if (ret < 0)
+ return ret;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *val = sign_extend32(ret, 15) >> TMP007_TEMP_SHIFT;
+
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 31;
+ *val2 = 250000;
+
+ return IIO_VAL_INT_PLUS_MICRO;
+ case IIO_CHAN_INFO_SAMP_FREQ:
+ conv_rate = (data->config & TMP007_CONFIG_CR_MASK)
+ >> TMP007_CONFIG_CR_SHIFT;
+ *val = tmp007_avgs[conv_rate][0];
+ *val2 = tmp007_avgs[conv_rate][1];
+
+ return IIO_VAL_INT_PLUS_MICRO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int tmp007_write_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *channel, int val,
+ int val2, long mask)
+{
+ struct tmp007_data *data = iio_priv(indio_dev);
+ int i;
+ u16 tmp;
+
+ if (mask == IIO_CHAN_INFO_SAMP_FREQ) {
+ for (i = 0; i < ARRAY_SIZE(tmp007_avgs); i++) {
+ if ((val == tmp007_avgs[i][0]) &&
+ (val2 == tmp007_avgs[i][1])) {
+ tmp = data->config & ~TMP007_CONFIG_CR_MASK;
+ tmp |= (i << TMP007_CONFIG_CR_SHIFT);
+
+ return i2c_smbus_write_word_swapped(data->client,
+ TMP007_CONFIG,
+ data->config = tmp);
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");
+
+static struct attribute *tmp007_attributes[] = {
+ &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group tmp007_attribute_group = {
+ .attrs = tmp007_attributes,
+};
+
+static const struct iio_chan_spec tmp007_channels[] = {
+ {
+ .type = IIO_TEMP,
+ .modified = 1,
+ .channel2 = IIO_MOD_TEMP_AMBIENT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ },
+ {
+ .type = IIO_TEMP,
+ .modified = 1,
+ .channel2 = IIO_MOD_TEMP_OBJECT,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
+ }
+};
+
+static const struct iio_info tmp007_info = {
+ .read_raw = tmp007_read_raw,
+ .write_raw = tmp007_write_raw,
+ .attrs = &tmp007_attribute_group,
+ .driver_module = THIS_MODULE,
+};
+
+static bool tmp007_identify(struct i2c_client *client)
+{
+ int manf_id, dev_id;
+
+ manf_id = i2c_smbus_read_word_swapped(client, TMP007_MANUFACTURER_ID);
+ if (manf_id < 0)
+ return false;
+
+ dev_id = i2c_smbus_read_word_swapped(client, TMP007_DEVICE_ID);
+ if (dev_id < 0)
+ return false;
+
+ return (manf_id == TMP007_MANUFACTURER_MAGIC && dev_id == TMP007_DEVICE_MAGIC);
+}
+
+static int tmp007_probe(struct i2c_client *client,
+ const struct i2c_device_id *tmp007_id)
+{
+ struct tmp007_data *data;
+ struct iio_dev *indio_dev;
+ int ret;
+ u16 status;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
+ return -EOPNOTSUPP;
+
+ if (!tmp007_identify(client)) {
+ dev_err(&client->dev, "TMP007 not found\n");
+ return -ENODEV;
+ }
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ i2c_set_clientdata(client, indio_dev);
+ data->client = client;
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->name = dev_name(&client->dev);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &tmp007_info;
+
+ indio_dev->channels = tmp007_channels;
+ indio_dev->num_channels = ARRAY_SIZE(tmp007_channels);
+
+ /*
+ * Set Configuration register:
+ * 1. Conversion ON
+ * 2. Comparator mode
+ * 3. Transient correction enable
+ */
+
+ ret = i2c_smbus_read_word_swapped(data->client, TMP007_CONFIG);
+ if (ret < 0)
+ return ret;
+
+ data->config = ret;
+ data->config |= (TMP007_CONFIG_CONV_EN | TMP007_CONFIG_COMP_EN | TMP007_CONFIG_TC_EN);
+
+ ret = i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG,
+ data->config);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Set Status Mask register:
+ * 1. Conversion ready enable
+ * 2. Data valid enable
+ */
+
+ ret = i2c_smbus_read_word_swapped(data->client, TMP007_STATUS_MASK);
+ if (ret < 0)
+ goto error_powerdown;
+
+ status = ret;
+ status |= (TMP007_STATUS_CONV_READY | TMP007_STATUS_DATA_VALID);
+
+ ret = i2c_smbus_write_word_swapped(data->client, TMP007_STATUS_MASK, status);
+ if (ret < 0)
+ goto error_powerdown;
+
+ return iio_device_register(indio_dev);
+
+error_powerdown:
+ tmp007_powerdown(data);
+
+ return ret;
+}
+
+static int tmp007_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct tmp007_data *data = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ tmp007_powerdown(data);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tmp007_suspend(struct device *dev)
+{
+ struct tmp007_data *data = iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev)));
+
+ return tmp007_powerdown(data);
+}
+
+static int tmp007_resume(struct device *dev)
+{
+ struct tmp007_data *data = iio_priv(i2c_get_clientdata(
+ to_i2c_client(dev)));
+
+ return i2c_smbus_write_word_swapped(data->client, TMP007_CONFIG,
+ data->config | TMP007_CONFIG_CONV_EN);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tmp007_pm_ops, tmp007_suspend, tmp007_resume);
+
+static const struct of_device_id tmp007_of_match[] = {
+ { .compatible = "ti,tmp007", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, tmp007_of_match);
+
+static const struct i2c_device_id tmp007_id[] = {
+ { "tmp007", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tmp007_id);
+
+static struct i2c_driver tmp007_driver = {
+ .driver = {
+ .name = "tmp007",
+ .of_match_table = of_match_ptr(tmp007_of_match),
+ .pm = &tmp007_pm_ops,
+ },
+ .probe = tmp007_probe,
+ .remove = tmp007_remove,
+ .id_table = tmp007_id,
+};
+module_i2c_driver(tmp007_driver);
+
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannanece23@gmail.com>");
+MODULE_DESCRIPTION("TI TMP007 IR thermopile sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/trigger/iio-trig-interrupt.c b/drivers/iio/trigger/iio-trig-interrupt.c
index 572bc6f02ca8..e18f12b74610 100644
--- a/drivers/iio/trigger/iio-trig-interrupt.c
+++ b/drivers/iio/trigger/iio-trig-interrupt.c
@@ -58,7 +58,7 @@ static int iio_interrupt_trigger_probe(struct platform_device *pdev)
trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
if (!trig_info) {
ret = -ENOMEM;
- goto error_put_trigger;
+ goto error_free_trigger;
}
iio_trigger_set_drvdata(trig, trig_info);
trig_info->irq = irq;
@@ -83,8 +83,8 @@ error_release_irq:
free_irq(irq, trig);
error_free_trig_info:
kfree(trig_info);
-error_put_trigger:
- iio_trigger_put(trig);
+error_free_trigger:
+ iio_trigger_free(trig);
error_ret:
return ret;
}
@@ -99,7 +99,7 @@ static int iio_interrupt_trigger_remove(struct platform_device *pdev)
iio_trigger_unregister(trig);
free_irq(trig_info->irq, trig);
kfree(trig_info);
- iio_trigger_put(trig);
+ iio_trigger_free(trig);
return 0;
}
diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c
index 3dfab2bc6d69..202e8b89caf2 100644
--- a/drivers/iio/trigger/iio-trig-sysfs.c
+++ b/drivers/iio/trigger/iio-trig-sysfs.c
@@ -174,7 +174,7 @@ static int iio_sysfs_trigger_probe(int id)
return 0;
out2:
- iio_trigger_put(t->trig);
+ iio_trigger_free(t->trig);
free_t:
kfree(t);
out1:
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index c8413fc120e6..7031a8dd4d14 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -1682,9 +1682,19 @@ static int __mlx4_ib_create_flow(struct ib_qp *qp, struct ib_flow_attr *flow_att
size += ret;
}
+ if (mlx4_is_master(mdev->dev) && flow_type == MLX4_FS_REGULAR &&
+ flow_attr->num_of_specs == 1) {
+ struct _rule_hw *rule_header = (struct _rule_hw *)(ctrl + 1);
+ enum ib_flow_spec_type header_spec =
+ ((union ib_flow_spec *)(flow_attr + 1))->type;
+
+ if (header_spec == IB_FLOW_SPEC_ETH)
+ mlx4_handle_eth_header_mcast_prio(ctrl, rule_header);
+ }
+
ret = mlx4_cmd_imm(mdev->dev, mailbox->dma, reg_id, size >> 2, 0,
MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
- MLX4_CMD_WRAPPED);
+ MLX4_CMD_NATIVE);
if (ret == -ENOMEM)
pr_err("mcg table is full. Fail to register network rule.\n");
else if (ret == -ENXIO)
@@ -1701,7 +1711,7 @@ static int __mlx4_ib_destroy_flow(struct mlx4_dev *dev, u64 reg_id)
int err;
err = mlx4_cmd(dev, reg_id, 0, 0,
MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
- MLX4_CMD_WRAPPED);
+ MLX4_CMD_NATIVE);
if (err)
pr_err("Fail to detach network rule. registration id = 0x%llx\n",
reg_id);
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 019e02707cd5..3ef0f42984f2 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1023,7 +1023,7 @@ again:
next_tail = (tail + sizeof(*cmd)) % CMD_BUFFER_SIZE;
left = (head - next_tail) % CMD_BUFFER_SIZE;
- if (left <= 2) {
+ if (left <= 0x20) {
struct iommu_cmd sync_cmd;
int ret;
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index a88576d50740..8ccbd7023194 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -903,8 +903,10 @@ int __init detect_intel_iommu(void)
x86_init.iommu.iommu_init = intel_iommu_init;
#endif
- acpi_put_table(dmar_tbl);
- dmar_tbl = NULL;
+ if (dmar_tbl) {
+ acpi_put_table(dmar_tbl);
+ dmar_tbl = NULL;
+ }
up_write(&dmar_global_lock);
return ret ? 1 : -ENODEV;
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index c66c273dfd8a..8a185250ae5a 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2037,6 +2037,25 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
if (context_present(context))
goto out_unlock;
+ /*
+ * For kdump cases, old valid entries may be cached due to the
+ * in-flight DMA and copied pgtable, but there is no unmapping
+ * behaviour for them, thus we need an explicit cache flush for
+ * the newly-mapped device. For kdump, at this point, the device
+ * is supposed to finish reset at its driver probe stage, so no
+ * in-flight DMA will exist, and we don't need to worry anymore
+ * hereafter.
+ */
+ if (context_copied(context)) {
+ u16 did_old = context_domain_id(context);
+
+ if (did_old >= 0 && did_old < cap_ndoms(iommu->cap))
+ iommu->flush.flush_context(iommu, did_old,
+ (((u16)bus) << 8) | devfn,
+ DMA_CCMD_MASK_NOBIT,
+ DMA_CCMD_DEVICE_INVL);
+ }
+
pgd = domain->pgd;
context_clear_entry(context);
@@ -5185,6 +5204,25 @@ static void intel_iommu_remove_device(struct device *dev)
}
#ifdef CONFIG_INTEL_IOMMU_SVM
+#define MAX_NR_PASID_BITS (20)
+static inline unsigned long intel_iommu_get_pts(struct intel_iommu *iommu)
+{
+ /*
+ * Convert ecap_pss to extend context entry pts encoding, also
+ * respect the soft pasid_max value set by the iommu.
+ * - number of PASID bits = ecap_pss + 1
+ * - number of PASID table entries = 2^(pts + 5)
+ * Therefore, pts = ecap_pss - 4
+ * e.g. KBL ecap_pss = 0x13, PASID has 20 bits, pts = 15
+ */
+ if (ecap_pss(iommu->ecap) < 5)
+ return 0;
+
+ /* pasid_max is encoded as actual number of entries not the bits */
+ return find_first_bit((unsigned long *)&iommu->pasid_max,
+ MAX_NR_PASID_BITS) - 5;
+}
+
int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
{
struct device_domain_info *info;
@@ -5217,7 +5255,9 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd
if (!(ctx_lo & CONTEXT_PASIDE)) {
context[1].hi = (u64)virt_to_phys(iommu->pasid_state_table);
- context[1].lo = (u64)virt_to_phys(iommu->pasid_table) | ecap_pss(iommu->ecap);
+ context[1].lo = (u64)virt_to_phys(iommu->pasid_table) |
+ intel_iommu_get_pts(iommu);
+
wmb();
/* CONTEXT_TT_MULTI_LEVEL and CONTEXT_TT_DEV_IOTLB are both
* extended to permit requests-with-PASID if the PASIDE bit
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 0037153c80a6..2d9c5dd06e42 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -450,7 +450,7 @@ bool mei_cldev_enabled(struct mei_cl_device *cldev)
EXPORT_SYMBOL_GPL(mei_cldev_enabled);
/**
- * mei_cldev_enable_device - enable me client device
+ * mei_cldev_enable - enable me client device
* create connection with me client
*
* @cldev: me client device
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 391936c1aa04..b0395601c6ae 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -1541,7 +1541,7 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
rets = first_chunk ? mei_cl_tx_flow_ctrl_creds(cl) : 1;
if (rets < 0)
- return rets;
+ goto err;
if (rets == 0) {
cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
@@ -1575,11 +1575,8 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
cb->buf.size, cb->buf_idx);
rets = mei_write_message(dev, &mei_hdr, buf->data + cb->buf_idx);
- if (rets) {
- cl->status = rets;
- list_move_tail(&cb->list, &cmpl_list->list);
- return rets;
- }
+ if (rets)
+ goto err;
cl->status = 0;
cl->writing_state = MEI_WRITING;
@@ -1587,14 +1584,21 @@ int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
cb->completed = mei_hdr.msg_complete == 1;
if (first_chunk) {
- if (mei_cl_tx_flow_ctrl_creds_reduce(cl))
- return -EIO;
+ if (mei_cl_tx_flow_ctrl_creds_reduce(cl)) {
+ rets = -EIO;
+ goto err;
+ }
}
if (mei_hdr.msg_complete)
list_move_tail(&cb->list, &dev->write_waiting_list.list);
return 0;
+
+err:
+ cl->status = rets;
+ list_move_tail(&cb->list, &cmpl_list->list);
+ return rets;
}
/**
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
index 25d1eb4933d0..7e8cf213fd81 100644
--- a/drivers/net/ethernet/broadcom/bcmsysport.c
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -1012,15 +1012,6 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
goto out;
}
- /* Insert TSB and checksum infos */
- if (priv->tsb_en) {
- skb = bcm_sysport_insert_tsb(skb, dev);
- if (!skb) {
- ret = NETDEV_TX_OK;
- goto out;
- }
- }
-
/* The Ethernet switch we are interfaced with needs packets to be at
* least 64 bytes (including FCS) otherwise they will be discarded when
* they enter the switch port logic. When Broadcom tags are enabled, we
@@ -1028,13 +1019,21 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
* (including FCS and tag) because the length verification is done after
* the Broadcom tag is stripped off the ingress packet.
*/
- if (skb_padto(skb, ETH_ZLEN + ENET_BRCM_TAG_LEN)) {
+ if (skb_put_padto(skb, ETH_ZLEN + ENET_BRCM_TAG_LEN)) {
ret = NETDEV_TX_OK;
goto out;
}
- skb_len = skb->len < ETH_ZLEN + ENET_BRCM_TAG_LEN ?
- ETH_ZLEN + ENET_BRCM_TAG_LEN : skb->len;
+ /* Insert TSB and checksum infos */
+ if (priv->tsb_en) {
+ skb = bcm_sysport_insert_tsb(skb, dev);
+ if (!skb) {
+ ret = NETDEV_TX_OK;
+ goto out;
+ }
+ }
+
+ skb_len = skb->len;
mapping = dma_map_single(kdev, skb->data, skb_len, DMA_TO_DEVICE);
if (dma_mapping_error(kdev, mapping)) {
diff --git a/drivers/net/ethernet/cadence/macb_pci.c b/drivers/net/ethernet/cadence/macb_pci.c
index 92be2cd8f817..9906fda76087 100644
--- a/drivers/net/ethernet/cadence/macb_pci.c
+++ b/drivers/net/ethernet/cadence/macb_pci.c
@@ -1,5 +1,5 @@
/**
- * macb_pci.c - Cadence GEM PCI wrapper.
+ * Cadence GEM PCI wrapper.
*
* Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
*
@@ -45,32 +45,27 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct macb_platform_data plat_data;
struct resource res[2];
- /* sanity check */
- if (!id)
- return -EINVAL;
-
/* enable pci device */
- err = pci_enable_device(pdev);
+ err = pcim_enable_device(pdev);
if (err < 0) {
- dev_err(&pdev->dev, "Enabling PCI device has failed: 0x%04X",
- err);
- return -EACCES;
+ dev_err(&pdev->dev, "Enabling PCI device has failed: %d", err);
+ return err;
}
pci_set_master(pdev);
/* set up resources */
memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
- res[0].start = pdev->resource[0].start;
- res[0].end = pdev->resource[0].end;
+ res[0].start = pci_resource_start(pdev, 0);
+ res[0].end = pci_resource_end(pdev, 0);
res[0].name = PCI_DRIVER_NAME;
res[0].flags = IORESOURCE_MEM;
- res[1].start = pdev->irq;
+ res[1].start = pci_irq_vector(pdev, 0);
res[1].name = PCI_DRIVER_NAME;
res[1].flags = IORESOURCE_IRQ;
- dev_info(&pdev->dev, "EMAC physical base addr = 0x%p\n",
- (void *)(uintptr_t)pci_resource_start(pdev, 0));
+ dev_info(&pdev->dev, "EMAC physical base addr: %pa\n",
+ &res[0].start);
/* set up macb platform data */
memset(&plat_data, 0, sizeof(plat_data));
@@ -100,7 +95,7 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
plat_info.num_res = ARRAY_SIZE(res);
plat_info.data = &plat_data;
plat_info.size_data = sizeof(plat_data);
- plat_info.dma_mask = DMA_BIT_MASK(32);
+ plat_info.dma_mask = pdev->dma_mask;
/* register platform device */
plat_dev = platform_device_register_full(&plat_info);
@@ -120,7 +115,6 @@ err_hclk_register:
clk_unregister(plat_data.pclk);
err_pclk_register:
- pci_disable_device(pdev);
return err;
}
@@ -130,7 +124,6 @@ static void macb_remove(struct pci_dev *pdev)
struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev);
platform_device_unregister(plat_dev);
- pci_disable_device(pdev);
clk_unregister(plat_data->pclk);
clk_unregister(plat_data->hclk);
}
diff --git a/drivers/net/ethernet/cavium/Kconfig b/drivers/net/ethernet/cavium/Kconfig
index bbc8bd16cb97..dcbce6cac63e 100644
--- a/drivers/net/ethernet/cavium/Kconfig
+++ b/drivers/net/ethernet/cavium/Kconfig
@@ -77,7 +77,7 @@ config OCTEON_MGMT_ETHERNET
config LIQUIDIO_VF
tristate "Cavium LiquidIO VF support"
depends on 64BIT && PCI_MSI
- select PTP_1588_CLOCK
+ imply PTP_1588_CLOCK
---help---
This driver supports Cavium LiquidIO Intelligent Server Adapter
based on CN23XX chips.
diff --git a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c
index 0f0de5b63622..d04a6c163445 100644
--- a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c
+++ b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c
@@ -133,17 +133,15 @@ cxgb_find_route6(struct cxgb4_lld_info *lldi,
if (ipv6_addr_type(&fl6.daddr) & IPV6_ADDR_LINKLOCAL)
fl6.flowi6_oif = sin6_scope_id;
dst = ip6_route_output(&init_net, NULL, &fl6);
- if (!dst)
- goto out;
- if (!cxgb_our_interface(lldi, get_real_dev,
- ip6_dst_idev(dst)->dev) &&
- !(ip6_dst_idev(dst)->dev->flags & IFF_LOOPBACK)) {
+ if (dst->error ||
+ (!cxgb_our_interface(lldi, get_real_dev,
+ ip6_dst_idev(dst)->dev) &&
+ !(ip6_dst_idev(dst)->dev->flags & IFF_LOOPBACK))) {
dst_release(dst);
- dst = NULL;
+ return NULL;
}
}
-out:
return dst;
}
EXPORT_SYMBOL(cxgb_find_route6);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 7e1633bf5a22..225e9a4877d7 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -5155,7 +5155,9 @@ static netdev_features_t be_features_check(struct sk_buff *skb,
skb->inner_protocol_type != ENCAP_TYPE_ETHER ||
skb->inner_protocol != htons(ETH_P_TEB) ||
skb_inner_mac_header(skb) - skb_transport_header(skb) !=
- sizeof(struct udphdr) + sizeof(struct vxlanhdr))
+ sizeof(struct udphdr) + sizeof(struct vxlanhdr) ||
+ !adapter->vxlan_port ||
+ udp_hdr(skb)->dest != adapter->vxlan_port)
return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
return features;
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
index 624ba9058dc4..c9b7ad65e563 100644
--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -733,6 +733,7 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)
priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
/* Enable Congestion State Change Notifications and CS taildrop */
+ memset(&initcgr, 0, sizeof(initcgr));
initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES);
initcgr.cgr.cscn_en = QM_CGR_EN;
@@ -2291,7 +2292,8 @@ static int dpaa_open(struct net_device *net_dev)
net_dev->phydev = mac_dev->init_phy(net_dev, priv->mac_dev);
if (!net_dev->phydev) {
netif_err(priv, ifup, net_dev, "init_phy() failed\n");
- return -ENODEV;
+ err = -ENODEV;
+ goto phy_init_failed;
}
for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
@@ -2314,6 +2316,7 @@ mac_start_failed:
for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++)
fman_port_disable(mac_dev->port[i]);
+phy_init_failed:
dpaa_eth_napi_disable(priv);
return err;
@@ -2420,6 +2423,7 @@ static int dpaa_ingress_cgr_init(struct dpaa_priv *priv)
}
/* Enable CS TD, but disable Congestion State Change Notifications. */
+ memset(&initcgr, 0, sizeof(initcgr));
initcgr.we_mask = cpu_to_be16(QM_CGR_WE_CS_THRES);
initcgr.cgr.cscn_en = QM_CGR_EN;
cs_th = DPAA_INGRESS_CS_THRESHOLD;
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index cbeea915f026..8037426ec50f 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -900,10 +900,10 @@ static void korina_restart_task(struct work_struct *work)
DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR,
&lp->rx_dma_regs->dmasm);
- korina_free_ring(dev);
-
napi_disable(&lp->napi);
+ korina_free_ring(dev);
+
if (korina_init(dev) < 0) {
printk(KERN_ERR "%s: cannot restart device\n", dev->name);
return;
@@ -1064,12 +1064,12 @@ static int korina_close(struct net_device *dev)
tmp = tmp | DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR;
writel(tmp, &lp->rx_dma_regs->dmasm);
- korina_free_ring(dev);
-
napi_disable(&lp->napi);
cancel_work_sync(&lp->restart_task);
+ korina_free_ring(dev);
+
free_irq(lp->rx_irq, dev);
free_irq(lp->tx_irq, dev);
free_irq(lp->ovr_irq, dev);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
index 015198c14fa8..504461a464c5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
@@ -245,13 +245,9 @@ static u32 freq_to_shift(u16 freq)
{
u32 freq_khz = freq * 1000;
u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC;
- u64 tmp_rounded =
- roundup_pow_of_two(max_val_cycles) > max_val_cycles ?
- roundup_pow_of_two(max_val_cycles) - 1 : UINT_MAX;
- u64 max_val_cycles_rounded = is_power_of_2(max_val_cycles + 1) ?
- max_val_cycles : tmp_rounded;
+ u64 max_val_cycles_rounded = 1ULL << fls64(max_val_cycles - 1);
/* calculate max possible multiplier in order to fit in 64bit */
- u64 max_mul = div_u64(0xffffffffffffffffULL, max_val_cycles_rounded);
+ u64 max_mul = div64_u64(ULLONG_MAX, max_val_cycles_rounded);
/* This comes from the reverse of clocksource_khz2mult */
return ilog2(div_u64(max_mul * freq_khz, 1000000));
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index bcd955339058..edbe200ac2fa 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1638,7 +1638,8 @@ int mlx4_en_start_port(struct net_device *dev)
/* Configure tx cq's and rings */
for (t = 0 ; t < MLX4_EN_NUM_TX_TYPES; t++) {
- u8 num_tx_rings_p_up = t == TX ? priv->num_tx_rings_p_up : 1;
+ u8 num_tx_rings_p_up = t == TX ?
+ priv->num_tx_rings_p_up : priv->tx_ring_num[t];
for (i = 0; i < priv->tx_ring_num[t]; i++) {
/* Configure cq */
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index 3c37e216bbf3..eac527e25ec9 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -445,8 +445,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
ring->cqn = priv->rx_cq[ring_ind]->mcq.cqn;
ring->stride = stride;
- if (ring->stride <= TXBB_SIZE)
+ if (ring->stride <= TXBB_SIZE) {
+ /* Stamp first unused send wqe */
+ __be32 *ptr = (__be32 *)ring->buf;
+ __be32 stamp = cpu_to_be32(1 << STAMP_SHIFT);
+ *ptr = stamp;
+ /* Move pointer to start of rx section */
ring->buf += TXBB_SIZE;
+ }
ring->log_stride = ffs(ring->stride) - 1;
ring->buf_size = ring->size * ring->stride;
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c
index 2a9dd460a95f..e1f9e7cebf8f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/icm.c
+++ b/drivers/net/ethernet/mellanox/mlx4/icm.c
@@ -118,8 +118,13 @@ static int mlx4_alloc_icm_coherent(struct device *dev, struct scatterlist *mem,
if (!buf)
return -ENOMEM;
+ if (offset_in_page(buf)) {
+ dma_free_coherent(dev, PAGE_SIZE << order,
+ buf, sg_dma_address(mem));
+ return -ENOMEM;
+ }
+
sg_set_buf(mem, buf, PAGE_SIZE << order);
- BUG_ON(mem->offset);
sg_dma_len(mem) = PAGE_SIZE << order;
return 0;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 5e7840a7a33b..bffa6f345f2f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -42,6 +42,7 @@
#include <linux/io-mapping.h>
#include <linux/delay.h>
#include <linux/kmod.h>
+#include <linux/etherdevice.h>
#include <net/devlink.h>
#include <linux/mlx4/device.h>
@@ -782,6 +783,23 @@ int mlx4_is_slave_active(struct mlx4_dev *dev, int slave)
}
EXPORT_SYMBOL(mlx4_is_slave_active);
+void mlx4_handle_eth_header_mcast_prio(struct mlx4_net_trans_rule_hw_ctrl *ctrl,
+ struct _rule_hw *eth_header)
+{
+ if (is_multicast_ether_addr(eth_header->eth.dst_mac) ||
+ is_broadcast_ether_addr(eth_header->eth.dst_mac)) {
+ struct mlx4_net_trans_rule_hw_eth *eth =
+ (struct mlx4_net_trans_rule_hw_eth *)eth_header;
+ struct _rule_hw *next_rule = (struct _rule_hw *)(eth + 1);
+ bool last_rule = next_rule->size == 0 && next_rule->id == 0 &&
+ next_rule->rsvd == 0;
+
+ if (last_rule)
+ ctrl->prio = cpu_to_be16(MLX4_DOMAIN_NIC);
+ }
+}
+EXPORT_SYMBOL(mlx4_handle_eth_header_mcast_prio);
+
static void slave_adjust_steering_mode(struct mlx4_dev *dev,
struct mlx4_dev_cap *dev_cap,
struct mlx4_init_hca_param *hca_param)
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index c548beaaf910..56185a0b827d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -4164,22 +4164,6 @@ static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header,
return 0;
}
-static void handle_eth_header_mcast_prio(struct mlx4_net_trans_rule_hw_ctrl *ctrl,
- struct _rule_hw *eth_header)
-{
- if (is_multicast_ether_addr(eth_header->eth.dst_mac) ||
- is_broadcast_ether_addr(eth_header->eth.dst_mac)) {
- struct mlx4_net_trans_rule_hw_eth *eth =
- (struct mlx4_net_trans_rule_hw_eth *)eth_header;
- struct _rule_hw *next_rule = (struct _rule_hw *)(eth + 1);
- bool last_rule = next_rule->size == 0 && next_rule->id == 0 &&
- next_rule->rsvd == 0;
-
- if (last_rule)
- ctrl->prio = cpu_to_be16(MLX4_DOMAIN_NIC);
- }
-}
-
/*
* In case of missing eth header, append eth header with a MAC address
* assigned to the VF.
@@ -4363,10 +4347,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id));
if (header_id == MLX4_NET_TRANS_RULE_ID_ETH)
- handle_eth_header_mcast_prio(ctrl, rule_header);
-
- if (slave == dev->caps.function)
- goto execute;
+ mlx4_handle_eth_header_mcast_prio(ctrl, rule_header);
switch (header_id) {
case MLX4_NET_TRANS_RULE_ID_ETH:
@@ -4394,7 +4375,6 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
goto err_put_qp;
}
-execute:
err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param,
vhcr->in_modifier, 0,
MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A,
@@ -4473,6 +4453,7 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
struct res_qp *rqp;
struct res_fs_rule *rrule;
u64 mirr_reg_id;
+ int qpn;
if (dev->caps.steering_mode !=
MLX4_STEERING_MODE_DEVICE_MANAGED)
@@ -4489,10 +4470,11 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
}
mirr_reg_id = rrule->mirr_rule_id;
kfree(rrule->mirr_mbox);
+ qpn = rrule->qpn;
/* Release the rule form busy state before removal */
put_res(dev, slave, vhcr->in_param, RES_FS_RULE);
- err = get_res(dev, slave, rrule->qpn, RES_QP, &rqp);
+ err = get_res(dev, slave, qpn, RES_QP, &rqp);
if (err)
return err;
@@ -4517,7 +4499,7 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
if (!err)
atomic_dec(&rqp->ref_count);
out:
- put_res(dev, slave, rrule->qpn, RES_QP);
+ put_res(dev, slave, qpn, RES_QP);
return err;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
index 7f6c225666c1..f0b460f47f29 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
@@ -723,6 +723,9 @@ static void mlx5e_ets_init(struct mlx5e_priv *priv)
int i;
struct ieee_ets ets;
+ if (!MLX5_CAP_GEN(priv->mdev, ets))
+ return;
+
memset(&ets, 0, sizeof(ets));
ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
for (i = 0; i < ets.ets_cap; i++) {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 352462af8d51..33a399a8b5d5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -171,7 +171,6 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
return NUM_SW_COUNTERS +
MLX5E_NUM_Q_CNTRS(priv) +
NUM_VPORT_COUNTERS + NUM_PPORT_COUNTERS +
- NUM_PCIE_COUNTERS +
MLX5E_NUM_RQ_STATS(priv) +
MLX5E_NUM_SQ_STATS(priv) +
MLX5E_NUM_PFC_COUNTERS(priv) +
@@ -219,14 +218,6 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
strcpy(data + (idx++) * ETH_GSTRING_LEN,
pport_2819_stats_desc[i].format);
- for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++)
- strcpy(data + (idx++) * ETH_GSTRING_LEN,
- pcie_perf_stats_desc[i].format);
-
- for (i = 0; i < NUM_PCIE_TAS_COUNTERS; i++)
- strcpy(data + (idx++) * ETH_GSTRING_LEN,
- pcie_tas_stats_desc[i].format);
-
for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
sprintf(data + (idx++) * ETH_GSTRING_LEN,
@@ -339,14 +330,6 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2819_counters,
pport_2819_stats_desc, i);
- for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++)
- data[idx++] = MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_perf_counters,
- pcie_perf_stats_desc, i);
-
- for (i = 0; i < NUM_PCIE_TAS_COUNTERS; i++)
- data[idx++] = MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_tas_counters,
- pcie_tas_stats_desc, i);
-
for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
index 3691451c728c..d088effd7160 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
@@ -247,6 +247,7 @@ static int set_flow_attrs(u32 *match_c, u32 *match_v,
}
if (fs->flow_type & FLOW_MAC_EXT &&
!is_zero_ether_addr(fs->m_ext.h_dest)) {
+ mask_spec(fs->m_ext.h_dest, fs->h_ext.h_dest, ETH_ALEN);
ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4,
outer_headers_c, dmac_47_16),
fs->m_ext.h_dest);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index cbfa38fc72c0..1236b27b1493 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -291,36 +291,12 @@ static void mlx5e_update_q_counter(struct mlx5e_priv *priv)
&qcnt->rx_out_of_buffer);
}
-static void mlx5e_update_pcie_counters(struct mlx5e_priv *priv)
-{
- struct mlx5e_pcie_stats *pcie_stats = &priv->stats.pcie;
- struct mlx5_core_dev *mdev = priv->mdev;
- int sz = MLX5_ST_SZ_BYTES(mpcnt_reg);
- void *out;
- u32 *in;
-
- in = mlx5_vzalloc(sz);
- if (!in)
- return;
-
- out = pcie_stats->pcie_perf_counters;
- MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP);
- mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0);
-
- out = pcie_stats->pcie_tas_counters;
- MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_TIMERS_AND_STATES_COUNTERS_GROUP);
- mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0);
-
- kvfree(in);
-}
-
void mlx5e_update_stats(struct mlx5e_priv *priv)
{
mlx5e_update_q_counter(priv);
mlx5e_update_vport_counters(priv);
mlx5e_update_pport_counters(priv);
mlx5e_update_sw_counters(priv);
- mlx5e_update_pcie_counters(priv);
}
void mlx5e_update_stats_work(struct work_struct *work)
@@ -3805,14 +3781,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
mlx5_lag_add(mdev, netdev);
- if (mlx5e_vxlan_allowed(mdev)) {
- rtnl_lock();
- udp_tunnel_get_rx_info(netdev);
- rtnl_unlock();
- }
-
mlx5e_enable_async_events(priv);
- queue_work(priv->wq, &priv->set_rx_mode_work);
if (MLX5_CAP_GEN(mdev, vport_group_manager)) {
mlx5_query_nic_vport_mac_address(mdev, 0, rep.hw_id);
@@ -3822,6 +3791,18 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
rep.netdev = netdev;
mlx5_eswitch_register_vport_rep(esw, 0, &rep);
}
+
+ if (netdev->reg_state != NETREG_REGISTERED)
+ return;
+
+ /* Device already registered: sync netdev system state */
+ if (mlx5e_vxlan_allowed(mdev)) {
+ rtnl_lock();
+ udp_tunnel_get_rx_info(netdev);
+ rtnl_unlock();
+ }
+
+ queue_work(priv->wq, &priv->set_rx_mode_work);
}
static void mlx5e_nic_disable(struct mlx5e_priv *priv)
@@ -3966,10 +3947,6 @@ void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev)
const struct mlx5e_profile *profile = priv->profile;
set_bit(MLX5E_STATE_DESTROYING, &priv->state);
- if (profile->disable)
- profile->disable(priv);
-
- flush_workqueue(priv->wq);
rtnl_lock();
if (netif_running(netdev))
@@ -3977,6 +3954,10 @@ void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev)
netif_device_detach(netdev);
rtnl_unlock();
+ if (profile->disable)
+ profile->disable(priv);
+ flush_workqueue(priv->wq);
+
mlx5e_destroy_q_counter(priv);
profile->cleanup_rx(priv);
mlx5e_close_drop_rq(priv);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
index f202f872f57f..ba5db1dd23a9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
@@ -39,7 +39,7 @@
#define MLX5E_READ_CTR32_CPU(ptr, dsc, i) \
(*(u32 *)((char *)ptr + dsc[i].offset))
#define MLX5E_READ_CTR32_BE(ptr, dsc, i) \
- be32_to_cpu(*(__be32 *)((char *)ptr + dsc[i].offset))
+ be64_to_cpu(*(__be32 *)((char *)ptr + dsc[i].offset))
#define MLX5E_DECLARE_STAT(type, fld) #fld, offsetof(type, fld)
#define MLX5E_DECLARE_RX_STAT(type, fld) "rx%d_"#fld, offsetof(type, fld)
@@ -276,32 +276,6 @@ static const struct counter_desc pport_per_prio_pfc_stats_desc[] = {
{ "rx_%s_pause_transition", PPORT_PER_PRIO_OFF(rx_pause_transition) },
};
-#define PCIE_PERF_OFF(c) \
- MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_perf_cntrs_grp_data_layout.c)
-#define PCIE_PERF_GET(pcie_stats, c) \
- MLX5_GET(mpcnt_reg, pcie_stats->pcie_perf_counters, \
- counter_set.pcie_perf_cntrs_grp_data_layout.c)
-#define PCIE_TAS_OFF(c) \
- MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_tas_cntrs_grp_data_layout.c)
-#define PCIE_TAS_GET(pcie_stats, c) \
- MLX5_GET(mpcnt_reg, pcie_stats->pcie_tas_counters, \
- counter_set.pcie_tas_cntrs_grp_data_layout.c)
-
-struct mlx5e_pcie_stats {
- __be64 pcie_perf_counters[MLX5_ST_SZ_QW(mpcnt_reg)];
- __be64 pcie_tas_counters[MLX5_ST_SZ_QW(mpcnt_reg)];
-};
-
-static const struct counter_desc pcie_perf_stats_desc[] = {
- { "rx_pci_signal_integrity", PCIE_PERF_OFF(rx_errors) },
- { "tx_pci_signal_integrity", PCIE_PERF_OFF(tx_errors) },
-};
-
-static const struct counter_desc pcie_tas_stats_desc[] = {
- { "tx_pci_transport_nonfatal_msg", PCIE_TAS_OFF(non_fatal_err_msg_sent) },
- { "tx_pci_transport_fatal_msg", PCIE_TAS_OFF(fatal_err_msg_sent) },
-};
-
struct mlx5e_rq_stats {
u64 packets;
u64 bytes;
@@ -386,8 +360,6 @@ static const struct counter_desc sq_stats_desc[] = {
#define NUM_PPORT_802_3_COUNTERS ARRAY_SIZE(pport_802_3_stats_desc)
#define NUM_PPORT_2863_COUNTERS ARRAY_SIZE(pport_2863_stats_desc)
#define NUM_PPORT_2819_COUNTERS ARRAY_SIZE(pport_2819_stats_desc)
-#define NUM_PCIE_PERF_COUNTERS ARRAY_SIZE(pcie_perf_stats_desc)
-#define NUM_PCIE_TAS_COUNTERS ARRAY_SIZE(pcie_tas_stats_desc)
#define NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS \
ARRAY_SIZE(pport_per_prio_traffic_stats_desc)
#define NUM_PPORT_PER_PRIO_PFC_COUNTERS \
@@ -397,7 +369,6 @@ static const struct counter_desc sq_stats_desc[] = {
NUM_PPORT_2819_COUNTERS + \
NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS * \
NUM_PPORT_PRIO)
-#define NUM_PCIE_COUNTERS (NUM_PCIE_PERF_COUNTERS + NUM_PCIE_TAS_COUNTERS)
#define NUM_RQ_STATS ARRAY_SIZE(rq_stats_desc)
#define NUM_SQ_STATS ARRAY_SIZE(sq_stats_desc)
@@ -406,7 +377,6 @@ struct mlx5e_stats {
struct mlx5e_qcounter_stats qcnt;
struct mlx5e_vport_stats vport;
struct mlx5e_pport_stats pport;
- struct mlx5e_pcie_stats pcie;
struct rtnl_link_stats64 vf_vport;
};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index d6807c3cc461..f14d9c9ba773 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1860,7 +1860,7 @@ int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
if (!ESW_ALLOWED(esw))
return -EPERM;
- if (!LEGAL_VPORT(esw, vport))
+ if (!LEGAL_VPORT(esw, vport) || is_multicast_ether_addr(mac))
return -EINVAL;
mutex_lock(&esw->state_lock);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 466e161010f7..03293ed1cc22 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -695,6 +695,12 @@ int esw_offloads_init(struct mlx5_eswitch *esw, int nvports)
if (err)
goto err_reps;
}
+
+ /* disable PF RoCE so missed packets don't go through RoCE steering */
+ mlx5_dev_list_lock();
+ mlx5_remove_dev_by_protocol(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
+ mlx5_dev_list_unlock();
+
return 0;
err_reps:
@@ -718,6 +724,11 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw)
{
int err, err1, num_vfs = esw->dev->priv.sriov.num_vfs;
+ /* enable back PF RoCE */
+ mlx5_dev_list_lock();
+ mlx5_add_dev_by_protocol(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
+ mlx5_dev_list_unlock();
+
mlx5_eswitch_disable_sriov(esw);
err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY);
if (err) {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index a263d8904a4c..0ac7a2fc916c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -1263,6 +1263,7 @@ static struct mlx5_flow_handle *add_rule_fg(struct mlx5_flow_group *fg,
nested_lock_ref_node(&fte->node, FS_MUTEX_CHILD);
handle = add_rule_fte(fte, fg, dest, dest_num, false);
if (IS_ERR(handle)) {
+ unlock_ref_node(&fte->node);
kfree(fte);
goto unlock_fg;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 54e5a786f191..6547f22e6b9b 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -503,6 +503,13 @@ static int handle_hca_cap(struct mlx5_core_dev *dev)
MLX5_SET(cmd_hca_cap, set_hca_cap, pkey_table_size,
to_fw_pkey_sz(dev, 128));
+ /* Check log_max_qp from HCA caps to set in current profile */
+ if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < profile[prof_sel].log_max_qp) {
+ mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n",
+ profile[prof_sel].log_max_qp,
+ MLX5_CAP_GEN_MAX(dev, log_max_qp));
+ profile[prof_sel].log_max_qp = MLX5_CAP_GEN_MAX(dev, log_max_qp);
+ }
if (prof->mask & MLX5_PROF_MASK_QP_SIZE)
MLX5_SET(cmd_hca_cap, set_hca_cap, log_max_qp,
prof->log_max_qp);
@@ -575,7 +582,6 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
struct mlx5_priv *priv = &mdev->priv;
struct msix_entry *msix = priv->msix_arr;
int irq = msix[i + MLX5_EQ_VEC_COMP_BASE].vector;
- int numa_node = priv->numa_node;
int err;
if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) {
@@ -583,7 +589,7 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
return -ENOMEM;
}
- cpumask_set_cpu(cpumask_local_spread(i, numa_node),
+ cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
priv->irq_info[i].mask);
err = irq_set_affinity_hint(irq, priv->irq_info[i].mask);
@@ -1189,6 +1195,8 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
{
int err = 0;
+ mlx5_drain_health_wq(dev);
+
mutex_lock(&dev->intf_state_mutex);
if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n",
@@ -1351,10 +1359,9 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,
mlx5_enter_error_state(dev);
mlx5_unload_one(dev, priv, false);
- /* In case of kernel call save the pci state and drain health wq */
+ /* In case of kernel call save the pci state */
if (state) {
pci_save_state(pdev);
- mlx5_drain_health_wq(dev);
mlx5_pci_disable_device(dev);
}
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index f9b97f5946f8..44389c90056a 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -326,6 +326,7 @@ enum cfg_version {
static const struct pci_device_id rtl8169_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8129), 0, 0, RTL_CFG_0 },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8136), 0, 0, RTL_CFG_2 },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8161), 0, 0, RTL_CFG_1 },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), 0, 0, RTL_CFG_0 },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 },
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index f341c1bc7001..00fafabab1d0 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -819,6 +819,7 @@ static struct sh_eth_cpu_data sh7734_data = {
.tsu = 1,
.hw_crc = 1,
.select_mii = 1,
+ .shift_rd0 = 1,
};
/* SH7763 */
@@ -1656,7 +1657,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
else
goto out;
- if (!likely(mdp->irq_enabled)) {
+ if (unlikely(!mdp->irq_enabled)) {
sh_eth_write(ndev, 0, EESIPR);
goto out;
}
diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
index de2947ccc5ad..5eb0e684fd76 100644
--- a/drivers/net/ethernet/sfc/ef10.c
+++ b/drivers/net/ethernet/sfc/ef10.c
@@ -1323,7 +1323,8 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
}
/* don't fail init if RSS setup doesn't work */
- efx->type->rx_push_rss_config(efx, false, efx->rx_indir_table);
+ rc = efx->type->rx_push_rss_config(efx, false, efx->rx_indir_table);
+ efx->rss_active = (rc == 0);
return 0;
}
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
index 87bdc56b4e3a..18ebaea44e82 100644
--- a/drivers/net/ethernet/sfc/ethtool.c
+++ b/drivers/net/ethernet/sfc/ethtool.c
@@ -975,6 +975,8 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev,
case ETHTOOL_GRXFH: {
info->data = 0;
+ if (!efx->rss_active) /* No RSS */
+ return 0;
switch (info->flow_type) {
case UDP_V4_FLOW:
if (efx->rx_hash_udp_4tuple)
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 1a635ced62d0..1c62c1a00fca 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -860,6 +860,7 @@ struct vfdi_status;
* @rx_hash_key: Toeplitz hash key for RSS
* @rx_indir_table: Indirection table for RSS
* @rx_scatter: Scatter mode enabled for receives
+ * @rss_active: RSS enabled on hardware
* @rx_hash_udp_4tuple: UDP 4-tuple hashing enabled
* @int_error_count: Number of internal errors seen recently
* @int_error_expire: Time at which error count will be expired
@@ -998,6 +999,7 @@ struct efx_nic {
u8 rx_hash_key[40];
u32 rx_indir_table[128];
bool rx_scatter;
+ bool rss_active;
bool rx_hash_udp_4tuple;
unsigned int_error_count;
diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c
index a3901bc96586..4e54e5dc9fcb 100644
--- a/drivers/net/ethernet/sfc/siena.c
+++ b/drivers/net/ethernet/sfc/siena.c
@@ -403,6 +403,7 @@ static int siena_init_nic(struct efx_nic *efx)
efx_writeo(efx, &temp, FR_AZ_RX_CFG);
siena_rx_push_rss_config(efx, false, efx->rx_indir_table);
+ efx->rss_active = true;
/* Enable event logging */
rc = efx_mcdi_log_ctrl(efx, true, false, 0);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
index c35597586121..3dc7d279f805 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
@@ -60,8 +60,9 @@ struct oxnas_dwmac {
struct regmap *regmap;
};
-static int oxnas_dwmac_init(struct oxnas_dwmac *dwmac)
+static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
{
+ struct oxnas_dwmac *dwmac = priv;
unsigned int value;
int ret;
@@ -105,20 +106,20 @@ static int oxnas_dwmac_init(struct oxnas_dwmac *dwmac)
return 0;
}
+static void oxnas_dwmac_exit(struct platform_device *pdev, void *priv)
+{
+ struct oxnas_dwmac *dwmac = priv;
+
+ clk_disable_unprepare(dwmac->clk);
+}
+
static int oxnas_dwmac_probe(struct platform_device *pdev)
{
struct plat_stmmacenet_data *plat_dat;
struct stmmac_resources stmmac_res;
- struct device_node *sysctrl;
struct oxnas_dwmac *dwmac;
int ret;
- sysctrl = of_parse_phandle(pdev->dev.of_node, "oxsemi,sys-ctrl", 0);
- if (!sysctrl) {
- dev_err(&pdev->dev, "failed to get sys-ctrl node\n");
- return -EINVAL;
- }
-
ret = stmmac_get_platform_resources(pdev, &stmmac_res);
if (ret)
return ret;
@@ -128,72 +129,48 @@ static int oxnas_dwmac_probe(struct platform_device *pdev)
return PTR_ERR(plat_dat);
dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL);
- if (!dwmac)
- return -ENOMEM;
+ if (!dwmac) {
+ ret = -ENOMEM;
+ goto err_remove_config_dt;
+ }
dwmac->dev = &pdev->dev;
plat_dat->bsp_priv = dwmac;
+ plat_dat->init = oxnas_dwmac_init;
+ plat_dat->exit = oxnas_dwmac_exit;
- dwmac->regmap = syscon_node_to_regmap(sysctrl);
+ dwmac->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+ "oxsemi,sys-ctrl");
if (IS_ERR(dwmac->regmap)) {
dev_err(&pdev->dev, "failed to have sysctrl regmap\n");
- return PTR_ERR(dwmac->regmap);
+ ret = PTR_ERR(dwmac->regmap);
+ goto err_remove_config_dt;
}
dwmac->clk = devm_clk_get(&pdev->dev, "gmac");
- if (IS_ERR(dwmac->clk))
- return PTR_ERR(dwmac->clk);
+ if (IS_ERR(dwmac->clk)) {
+ ret = PTR_ERR(dwmac->clk);
+ goto err_remove_config_dt;
+ }
- ret = oxnas_dwmac_init(dwmac);
+ ret = oxnas_dwmac_init(pdev, plat_dat->bsp_priv);
if (ret)
- return ret;
+ goto err_remove_config_dt;
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
- clk_disable_unprepare(dwmac->clk);
+ goto err_dwmac_exit;
- return ret;
-}
-static int oxnas_dwmac_remove(struct platform_device *pdev)
-{
- struct oxnas_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev);
- int ret = stmmac_dvr_remove(&pdev->dev);
-
- clk_disable_unprepare(dwmac->clk);
-
- return ret;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int oxnas_dwmac_suspend(struct device *dev)
-{
- struct oxnas_dwmac *dwmac = get_stmmac_bsp_priv(dev);
- int ret;
-
- ret = stmmac_suspend(dev);
- clk_disable_unprepare(dwmac->clk);
-
- return ret;
-}
-
-static int oxnas_dwmac_resume(struct device *dev)
-{
- struct oxnas_dwmac *dwmac = get_stmmac_bsp_priv(dev);
- int ret;
-
- ret = oxnas_dwmac_init(dwmac);
- if (ret)
- return ret;
+ return 0;
- ret = stmmac_resume(dev);
+err_dwmac_exit:
+ oxnas_dwmac_exit(pdev, plat_dat->bsp_priv);
+err_remove_config_dt:
+ stmmac_remove_config_dt(pdev, plat_dat);
return ret;
}
-#endif /* CONFIG_PM_SLEEP */
-
-static SIMPLE_DEV_PM_OPS(oxnas_dwmac_pm_ops,
- oxnas_dwmac_suspend, oxnas_dwmac_resume);
static const struct of_device_id oxnas_dwmac_match[] = {
{ .compatible = "oxsemi,ox820-dwmac" },
@@ -203,10 +180,10 @@ MODULE_DEVICE_TABLE(of, oxnas_dwmac_match);
static struct platform_driver oxnas_dwmac_driver = {
.probe = oxnas_dwmac_probe,
- .remove = oxnas_dwmac_remove,
+ .remove = stmmac_pltfr_remove,
.driver = {
.name = "oxnas-dwmac",
- .pm = &oxnas_dwmac_pm_ops,
+ .pm = &stmmac_pltfr_pm_ops,
.of_match_table = oxnas_dwmac_match,
},
};
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index bb40382e205d..39eb7a65bb9f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3339,13 +3339,6 @@ int stmmac_dvr_probe(struct device *device,
spin_lock_init(&priv->lock);
- ret = register_netdev(ndev);
- if (ret) {
- netdev_err(priv->dev, "%s: ERROR %i registering the device\n",
- __func__, ret);
- goto error_netdev_register;
- }
-
/* If a specific clk_csr value is passed from the platform
* this means that the CSR Clock Range selection cannot be
* changed at run-time and it is fixed. Viceversa the driver'll try to
@@ -3372,11 +3365,21 @@ int stmmac_dvr_probe(struct device *device,
}
}
- return 0;
+ ret = register_netdev(ndev);
+ if (ret) {
+ netdev_err(priv->dev, "%s: ERROR %i registering the device\n",
+ __func__, ret);
+ goto error_netdev_register;
+ }
+
+ return ret;
-error_mdio_register:
- unregister_netdev(ndev);
error_netdev_register:
+ if (priv->hw->pcs != STMMAC_PCS_RGMII &&
+ priv->hw->pcs != STMMAC_PCS_TBI &&
+ priv->hw->pcs != STMMAC_PCS_RTBI)
+ stmmac_mdio_unregister(ndev);
+error_mdio_register:
netif_napi_del(&priv->napi);
error_hw_init:
clk_disable_unprepare(priv->pclk);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index fda01f770eff..b0344c213752 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -116,7 +116,7 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
- u32 value = MII_WRITE | MII_BUSY;
+ u32 value = MII_BUSY;
value |= (phyaddr << priv->hw->mii.addr_shift)
& priv->hw->mii.addr_mask;
@@ -126,6 +126,8 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
& priv->hw->mii.clk_csr_mask;
if (priv->plat->has_gmac4)
value |= MII_GMAC4_WRITE;
+ else
+ value |= MII_WRITE;
/* Wait until any existing MII operation is complete */
if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index 031093e1c25f..dbfbb33ac66c 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -99,6 +99,11 @@ struct ipvl_port {
int count;
};
+struct ipvl_skb_cb {
+ bool tx_pkt;
+};
+#define IPVL_SKB_CB(_skb) ((struct ipvl_skb_cb *)&((_skb)->cb[0]))
+
static inline struct ipvl_port *ipvlan_port_get_rcu(const struct net_device *d)
{
return rcu_dereference(d->rx_handler_data);
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index b4e990743e1d..83ce74acf82d 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -198,7 +198,7 @@ void ipvlan_process_multicast(struct work_struct *work)
unsigned int mac_hash;
int ret;
u8 pkt_type;
- bool hlocal, dlocal;
+ bool tx_pkt;
__skb_queue_head_init(&list);
@@ -207,8 +207,11 @@ void ipvlan_process_multicast(struct work_struct *work)
spin_unlock_bh(&port->backlog.lock);
while ((skb = __skb_dequeue(&list)) != NULL) {
+ struct net_device *dev = skb->dev;
+ bool consumed = false;
+
ethh = eth_hdr(skb);
- hlocal = ether_addr_equal(ethh->h_source, port->dev->dev_addr);
+ tx_pkt = IPVL_SKB_CB(skb)->tx_pkt;
mac_hash = ipvlan_mac_hash(ethh->h_dest);
if (ether_addr_equal(ethh->h_dest, port->dev->broadcast))
@@ -216,41 +219,45 @@ void ipvlan_process_multicast(struct work_struct *work)
else
pkt_type = PACKET_MULTICAST;
- dlocal = false;
rcu_read_lock();
list_for_each_entry_rcu(ipvlan, &port->ipvlans, pnode) {
- if (hlocal && (ipvlan->dev == skb->dev)) {
- dlocal = true;
+ if (tx_pkt && (ipvlan->dev == skb->dev))
continue;
- }
if (!test_bit(mac_hash, ipvlan->mac_filters))
continue;
-
+ if (!(ipvlan->dev->flags & IFF_UP))
+ continue;
ret = NET_RX_DROP;
len = skb->len + ETH_HLEN;
nskb = skb_clone(skb, GFP_ATOMIC);
- if (!nskb)
- goto acct;
-
- nskb->pkt_type = pkt_type;
- nskb->dev = ipvlan->dev;
- if (hlocal)
- ret = dev_forward_skb(ipvlan->dev, nskb);
- else
- ret = netif_rx(nskb);
-acct:
+ local_bh_disable();
+ if (nskb) {
+ consumed = true;
+ nskb->pkt_type = pkt_type;
+ nskb->dev = ipvlan->dev;
+ if (tx_pkt)
+ ret = dev_forward_skb(ipvlan->dev, nskb);
+ else
+ ret = netif_rx(nskb);
+ }
ipvlan_count_rx(ipvlan, len, ret == NET_RX_SUCCESS, true);
+ local_bh_enable();
}
rcu_read_unlock();
- if (dlocal) {
+ if (tx_pkt) {
/* If the packet originated here, send it out. */
skb->dev = port->dev;
skb->pkt_type = pkt_type;
dev_queue_xmit(skb);
} else {
- kfree_skb(skb);
+ if (consumed)
+ consume_skb(skb);
+ else
+ kfree_skb(skb);
}
+ if (dev)
+ dev_put(dev);
}
}
@@ -470,15 +477,24 @@ out:
}
static void ipvlan_multicast_enqueue(struct ipvl_port *port,
- struct sk_buff *skb)
+ struct sk_buff *skb, bool tx_pkt)
{
if (skb->protocol == htons(ETH_P_PAUSE)) {
kfree_skb(skb);
return;
}
+ /* Record that the deferred packet is from TX or RX path. By
+ * looking at mac-addresses on packet will lead to erronus decisions.
+ * (This would be true for a loopback-mode on master device or a
+ * hair-pin mode of the switch.)
+ */
+ IPVL_SKB_CB(skb)->tx_pkt = tx_pkt;
+
spin_lock(&port->backlog.lock);
if (skb_queue_len(&port->backlog) < IPVLAN_QBACKLOG_LIMIT) {
+ if (skb->dev)
+ dev_hold(skb->dev);
__skb_queue_tail(&port->backlog, skb);
spin_unlock(&port->backlog.lock);
schedule_work(&port->wq);
@@ -537,7 +553,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
} else if (is_multicast_ether_addr(eth->h_dest)) {
ipvlan_skb_crossing_ns(skb, NULL);
- ipvlan_multicast_enqueue(ipvlan->port, skb);
+ ipvlan_multicast_enqueue(ipvlan->port, skb, true);
return NET_XMIT_SUCCESS;
}
@@ -634,7 +650,7 @@ static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb,
*/
if (nskb) {
ipvlan_skb_crossing_ns(nskb, NULL);
- ipvlan_multicast_enqueue(port, nskb);
+ ipvlan_multicast_enqueue(port, nskb, false);
}
}
} else {
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 693ec5b66222..8b0f99300cbc 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -135,6 +135,7 @@ err:
static void ipvlan_port_destroy(struct net_device *dev)
{
struct ipvl_port *port = ipvlan_port_get_rtnl(dev);
+ struct sk_buff *skb;
dev->priv_flags &= ~IFF_IPVLAN_MASTER;
if (port->mode == IPVLAN_MODE_L3S) {
@@ -144,7 +145,11 @@ static void ipvlan_port_destroy(struct net_device *dev)
}
netdev_rx_handler_unregister(dev);
cancel_work_sync(&port->wq);
- __skb_queue_purge(&port->backlog);
+ while ((skb = __skb_dequeue(&port->backlog)) != NULL) {
+ if (skb->dev)
+ dev_put(skb->dev);
+ kfree_skb(skb);
+ }
kfree(port);
}
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index 6c646e228833..6e98ede997d3 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -1367,6 +1367,7 @@ static struct usb_driver asix_driver = {
.probe = usbnet_probe,
.suspend = asix_suspend,
.resume = asix_resume,
+ .reset_resume = asix_resume,
.disconnect = usbnet_disconnect,
.supports_autosuspend = 1,
.disable_hub_initiated_lpm = 1,
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 7532646c3b7b..23dfb0eac098 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -967,6 +967,7 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
*/
need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr);
if (!ipv6_ndisc_frame(skb) && !need_strict) {
+ vrf_rx_stats(vrf_dev, skb->len);
skb->dev = vrf_dev;
skb->skb_iif = vrf_dev->ifindex;
@@ -1011,6 +1012,8 @@ static struct sk_buff *vrf_ip_rcv(struct net_device *vrf_dev,
goto out;
}
+ vrf_rx_stats(vrf_dev, skb->len);
+
skb_push(skb, skb->mac_len);
dev_queue_xmit_nit(skb, vrf_dev);
skb_pull(skb, skb->mac_len);
diff --git a/drivers/net/wan/slic_ds26522.c b/drivers/net/wan/slic_ds26522.c
index b776a0ab106c..9d9b4e0def2a 100644
--- a/drivers/net/wan/slic_ds26522.c
+++ b/drivers/net/wan/slic_ds26522.c
@@ -218,7 +218,7 @@ static int slic_ds26522_probe(struct spi_device *spi)
ret = slic_ds26522_init_configure(spi);
if (ret == 0)
- pr_info("DS26522 cs%d configurated\n", spi->chip_select);
+ pr_info("DS26522 cs%d configured\n", spi->chip_select);
return ret;
}
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index b40cfb076f02..2fc86dc7a8df 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1193,8 +1193,8 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors);
blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX));
}
- if (ctrl->stripe_size)
- blk_queue_chunk_sectors(q, ctrl->stripe_size >> 9);
+ if (ctrl->quirks & NVME_QUIRK_STRIPE_SIZE)
+ blk_queue_chunk_sectors(q, ctrl->max_hw_sectors);
blk_queue_virt_boundary(q, ctrl->page_size - 1);
if (ctrl->vwc & NVME_CTRL_VWC_PRESENT)
vwc = true;
@@ -1250,19 +1250,6 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
ctrl->max_hw_sectors =
min_not_zero(ctrl->max_hw_sectors, max_hw_sectors);
- if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && id->vs[3]) {
- unsigned int max_hw_sectors;
-
- ctrl->stripe_size = 1 << (id->vs[3] + page_shift);
- max_hw_sectors = ctrl->stripe_size >> (page_shift - 9);
- if (ctrl->max_hw_sectors) {
- ctrl->max_hw_sectors = min(max_hw_sectors,
- ctrl->max_hw_sectors);
- } else {
- ctrl->max_hw_sectors = max_hw_sectors;
- }
- }
-
nvme_set_queue_limits(ctrl, ctrl->admin_q);
ctrl->sgls = le32_to_cpu(id->sgls);
ctrl->kas = le16_to_cpu(id->kas);
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 771e2e761872..aa0bc60810a7 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -1491,19 +1491,20 @@ static int
nvme_fc_create_hw_io_queues(struct nvme_fc_ctrl *ctrl, u16 qsize)
{
struct nvme_fc_queue *queue = &ctrl->queues[1];
- int i, j, ret;
+ int i, ret;
for (i = 1; i < ctrl->queue_count; i++, queue++) {
ret = __nvme_fc_create_hw_queue(ctrl, queue, i, qsize);
- if (ret) {
- for (j = i-1; j >= 0; j--)
- __nvme_fc_delete_hw_queue(ctrl,
- &ctrl->queues[j], j);
- return ret;
- }
+ if (ret)
+ goto delete_queues;
}
return 0;
+
+delete_queues:
+ for (; i >= 0; i--)
+ __nvme_fc_delete_hw_queue(ctrl, &ctrl->queues[i], i);
+ return ret;
}
static int
@@ -2401,8 +2402,8 @@ __nvme_fc_create_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
WARN_ON_ONCE(!changed);
dev_info(ctrl->ctrl.device,
- "NVME-FC{%d}: new ctrl: NQN \"%s\" (%p)\n",
- ctrl->cnum, ctrl->ctrl.opts->subsysnqn, &ctrl);
+ "NVME-FC{%d}: new ctrl: NQN \"%s\"\n",
+ ctrl->cnum, ctrl->ctrl.opts->subsysnqn);
kref_get(&ctrl->ctrl.kref);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index bd5321441d12..6377e14586dc 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -135,7 +135,6 @@ struct nvme_ctrl {
u32 page_size;
u32 max_hw_sectors;
- u32 stripe_size;
u16 oncs;
u16 vid;
atomic_t abort_limit;
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 3d21a154dce7..19beeb7b2ac2 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -712,15 +712,8 @@ static void __nvme_process_cq(struct nvme_queue *nvmeq, unsigned int *tag)
req = blk_mq_tag_to_rq(*nvmeq->tags, cqe.command_id);
nvme_req(req)->result = cqe.result;
blk_mq_complete_request(req, le16_to_cpu(cqe.status) >> 1);
-
}
- /* If the controller ignores the cq head doorbell and continuously
- * writes to the queue, it is theoretically possible to wrap around
- * the queue twice and mistakenly return IRQ_NONE. Linux only
- * requires that 0.1% of your interrupts are handled, so this isn't
- * a big problem.
- */
if (head == nvmeq->cq_head && phase == nvmeq->cq_phase)
return;
@@ -1909,10 +1902,10 @@ static int nvme_dev_map(struct nvme_dev *dev)
if (!dev->bar)
goto release;
- return 0;
+ return 0;
release:
- pci_release_mem_regions(pdev);
- return -ENODEV;
+ pci_release_mem_regions(pdev);
+ return -ENODEV;
}
static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/nvme/host/scsi.c b/drivers/nvme/host/scsi.c
index b71e95044b43..a5c09e703bd8 100644
--- a/drivers/nvme/host/scsi.c
+++ b/drivers/nvme/host/scsi.c
@@ -2160,30 +2160,6 @@ static int nvme_trans_synchronize_cache(struct nvme_ns *ns,
return nvme_trans_status_code(hdr, nvme_sc);
}
-static int nvme_trans_start_stop(struct nvme_ns *ns, struct sg_io_hdr *hdr,
- u8 *cmd)
-{
- u8 immed, no_flush;
-
- immed = cmd[1] & 0x01;
- no_flush = cmd[4] & 0x04;
-
- if (immed != 0) {
- return nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION,
- ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
- SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
- } else {
- if (no_flush == 0) {
- /* Issue NVME FLUSH command prior to START STOP UNIT */
- int res = nvme_trans_synchronize_cache(ns, hdr);
- if (res)
- return res;
- }
-
- return 0;
- }
-}
-
static int nvme_trans_format_unit(struct nvme_ns *ns, struct sg_io_hdr *hdr,
u8 *cmd)
{
@@ -2439,9 +2415,6 @@ static int nvme_scsi_translate(struct nvme_ns *ns, struct sg_io_hdr *hdr)
case SECURITY_PROTOCOL_OUT:
retcode = nvme_trans_security_protocol(ns, hdr, cmd);
break;
- case START_STOP:
- retcode = nvme_trans_start_stop(ns, hdr, cmd);
- break;
case SYNCHRONIZE_CACHE:
retcode = nvme_trans_synchronize_cache(ns, hdr);
break;
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index ec1ad2aa0a4c..95ae52390478 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -382,7 +382,6 @@ static void nvmet_execute_set_features(struct nvmet_req *req)
{
struct nvmet_subsys *subsys = req->sq->ctrl->subsys;
u32 cdw10 = le32_to_cpu(req->cmd->common.cdw10[0]);
- u64 val;
u32 val32;
u16 status = 0;
@@ -392,8 +391,7 @@ static void nvmet_execute_set_features(struct nvmet_req *req)
(subsys->max_qid - 1) | ((subsys->max_qid - 1) << 16));
break;
case NVME_FEAT_KATO:
- val = le64_to_cpu(req->cmd->prop_set.value);
- val32 = val & 0xffff;
+ val32 = le32_to_cpu(req->cmd->common.cdw10[1]);
req->sq->ctrl->kato = DIV_ROUND_UP(val32, 1000);
nvmet_set_result(req, req->sq->ctrl->kato);
break;
diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c
index bcb8ebeb01c5..4e8e6a22bce1 100644
--- a/drivers/nvme/target/fcloop.c
+++ b/drivers/nvme/target/fcloop.c
@@ -845,7 +845,7 @@ fcloop_create_remote_port(struct device *dev, struct device_attribute *attr,
rport->lport = nport->lport;
nport->rport = rport;
- return ret ? ret : count;
+ return count;
}
@@ -952,7 +952,7 @@ fcloop_create_target_port(struct device *dev, struct device_attribute *attr,
tport->lport = nport->lport;
nport->tport = tport;
- return ret ? ret : count;
+ return count;
}
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 965911d9b36a..398ea7f54826 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -981,8 +981,8 @@ static int __nvmem_cell_read(struct nvmem_device *nvmem,
* @cell: nvmem cell to be read.
* @len: pointer to length of cell which will be populated on successful read.
*
- * Return: ERR_PTR() on error or a valid pointer to a char * buffer on success.
- * The buffer should be freed by the consumer with a kfree().
+ * Return: ERR_PTR() on error or a valid pointer to a buffer on success. The
+ * buffer should be freed by the consumer with a kfree().
*/
void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
{
diff --git a/drivers/nvmem/imx-ocotp.c b/drivers/nvmem/imx-ocotp.c
index ac27b9bac3b9..8e7b120696fa 100644
--- a/drivers/nvmem/imx-ocotp.c
+++ b/drivers/nvmem/imx-ocotp.c
@@ -71,7 +71,7 @@ static struct nvmem_config imx_ocotp_nvmem_config = {
static const struct of_device_id imx_ocotp_dt_ids[] = {
{ .compatible = "fsl,imx6q-ocotp", (void *)128 },
- { .compatible = "fsl,imx6sl-ocotp", (void *)32 },
+ { .compatible = "fsl,imx6sl-ocotp", (void *)64 },
{ .compatible = "fsl,imx6sx-ocotp", (void *)128 },
{ },
};
diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c
index b5305f08b184..2bdb6c389328 100644
--- a/drivers/nvmem/qfprom.c
+++ b/drivers/nvmem/qfprom.c
@@ -21,11 +21,11 @@ static int qfprom_reg_read(void *context,
unsigned int reg, void *_val, size_t bytes)
{
void __iomem *base = context;
- u32 *val = _val;
- int i = 0, words = bytes / 4;
+ u8 *val = _val;
+ int i = 0, words = bytes;
while (words--)
- *val++ = readl(base + reg + (i++ * 4));
+ *val++ = readb(base + reg + i++);
return 0;
}
@@ -34,11 +34,11 @@ static int qfprom_reg_write(void *context,
unsigned int reg, void *_val, size_t bytes)
{
void __iomem *base = context;
- u32 *val = _val;
- int i = 0, words = bytes / 4;
+ u8 *val = _val;
+ int i = 0, words = bytes;
while (words--)
- writel(*val++, base + reg + (i++ * 4));
+ writeb(*val++, base + reg + i++);
return 0;
}
@@ -53,7 +53,7 @@ static int qfprom_remove(struct platform_device *pdev)
static struct nvmem_config econfig = {
.name = "qfprom",
.owner = THIS_MODULE,
- .stride = 4,
+ .stride = 1,
.word_size = 1,
.reg_read = qfprom_reg_read,
.reg_write = qfprom_reg_write,
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index a579126832af..620c231a2889 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -212,7 +212,7 @@ static int meson_pmx_request_gpio(struct pinctrl_dev *pcdev,
{
struct meson_pinctrl *pc = pinctrl_dev_get_drvdata(pcdev);
- meson_pmx_disable_other_groups(pc, range->pin_base + offset, -1);
+ meson_pmx_disable_other_groups(pc, offset, -1);
return 0;
}
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index aea310a91821..c9a146948192 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -382,26 +382,21 @@ static int amd_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
int ret = 0;
u32 pin_reg;
- unsigned long flags;
- bool level_trig;
- u32 active_level;
+ unsigned long flags, irq_flags;
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
spin_lock_irqsave(&gpio_dev->lock, flags);
pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
- /*
- * When level_trig is set EDGE and active_level is set HIGH in BIOS
- * default settings, ignore incoming settings from client and use
- * BIOS settings to configure GPIO register.
+ /* Ignore the settings coming from the client and
+ * read the values from the ACPI tables
+ * while setting the trigger type
*/
- level_trig = !(pin_reg & (LEVEL_TRIGGER << LEVEL_TRIG_OFF));
- active_level = pin_reg & (ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF);
- if(level_trig &&
- ((active_level >> ACTIVE_LEVEL_OFF) == ACTIVE_HIGH))
- type = IRQ_TYPE_EDGE_FALLING;
+ irq_flags = irq_get_trigger_type(d->irq);
+ if (irq_flags != IRQ_TYPE_NONE)
+ type = irq_flags;
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 12f7d1eb65bc..07409fde02b2 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -56,6 +56,17 @@ static const struct samsung_pin_bank_type bank_type_alive = {
.reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
};
+/* Exynos5433 has the 4bit widths for PINCFG_TYPE_DRV bitfields. */
+static const struct samsung_pin_bank_type exynos5433_bank_type_off = {
+ .fld_width = { 4, 1, 2, 4, 2, 2, },
+ .reg_offset = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, },
+};
+
+static const struct samsung_pin_bank_type exynos5433_bank_type_alive = {
+ .fld_width = { 4, 1, 2, 4, },
+ .reg_offset = { 0x00, 0x04, 0x08, 0x0c, },
+};
+
static void exynos_irq_mask(struct irq_data *irqd)
{
struct irq_chip *chip = irq_data_get_irq_chip(irqd);
@@ -1335,82 +1346,82 @@ const struct samsung_pin_ctrl exynos5420_pin_ctrl[] __initconst = {
/* pin banks of exynos5433 pin-controller - ALIVE */
static const struct samsung_pin_bank_data exynos5433_pin_banks0[] = {
- EXYNOS_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
- EXYNOS_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
- EXYNOS_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
- EXYNOS_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
- EXYNOS_PIN_BANK_EINTW_EXT(8, 0x020, "gpf1", 0x1004, 1),
- EXYNOS_PIN_BANK_EINTW_EXT(4, 0x040, "gpf2", 0x1008, 1),
- EXYNOS_PIN_BANK_EINTW_EXT(4, 0x060, "gpf3", 0x100c, 1),
- EXYNOS_PIN_BANK_EINTW_EXT(8, 0x080, "gpf4", 0x1010, 1),
- EXYNOS_PIN_BANK_EINTW_EXT(8, 0x0a0, "gpf5", 0x1014, 1),
+ EXYNOS5433_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
+ EXYNOS5433_PIN_BANK_EINTW(8, 0x020, "gpa1", 0x04),
+ EXYNOS5433_PIN_BANK_EINTW(8, 0x040, "gpa2", 0x08),
+ EXYNOS5433_PIN_BANK_EINTW(8, 0x060, "gpa3", 0x0c),
+ EXYNOS5433_PIN_BANK_EINTW_EXT(8, 0x020, "gpf1", 0x1004, 1),
+ EXYNOS5433_PIN_BANK_EINTW_EXT(4, 0x040, "gpf2", 0x1008, 1),
+ EXYNOS5433_PIN_BANK_EINTW_EXT(4, 0x060, "gpf3", 0x100c, 1),
+ EXYNOS5433_PIN_BANK_EINTW_EXT(8, 0x080, "gpf4", 0x1010, 1),
+ EXYNOS5433_PIN_BANK_EINTW_EXT(8, 0x0a0, "gpf5", 0x1014, 1),
};
/* pin banks of exynos5433 pin-controller - AUD */
static const struct samsung_pin_bank_data exynos5433_pin_banks1[] = {
- EXYNOS_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
- EXYNOS_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
+ EXYNOS5433_PIN_BANK_EINTG(7, 0x000, "gpz0", 0x00),
+ EXYNOS5433_PIN_BANK_EINTG(4, 0x020, "gpz1", 0x04),
};
/* pin banks of exynos5433 pin-controller - CPIF */
static const struct samsung_pin_bank_data exynos5433_pin_banks2[] = {
- EXYNOS_PIN_BANK_EINTG(2, 0x000, "gpv6", 0x00),
+ EXYNOS5433_PIN_BANK_EINTG(2, 0x000, "gpv6", 0x00),
};
/* pin banks of exynos5433 pin-controller - eSE */
static const struct samsung_pin_bank_data exynos5433_pin_banks3[] = {
- EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj2", 0x00),
+ EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj2", 0x00),
};
/* pin banks of exynos5433 pin-controller - FINGER */
static const struct samsung_pin_bank_data exynos5433_pin_banks4[] = {
- EXYNOS_PIN_BANK_EINTG(4, 0x000, "gpd5", 0x00),
+ EXYNOS5433_PIN_BANK_EINTG(4, 0x000, "gpd5", 0x00),
};
/* pin banks of exynos5433 pin-controller - FSYS */
static const struct samsung_pin_bank_data exynos5433_pin_banks5[] = {
- EXYNOS_PIN_BANK_EINTG(6, 0x000, "gph1", 0x00),
- EXYNOS_PIN_BANK_EINTG(7, 0x020, "gpr4", 0x04),
- EXYNOS_PIN_BANK_EINTG(5, 0x040, "gpr0", 0x08),
- EXYNOS_PIN_BANK_EINTG(8, 0x060, "gpr1", 0x0c),
- EXYNOS_PIN_BANK_EINTG(2, 0x080, "gpr2", 0x10),
- EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpr3", 0x14),
+ EXYNOS5433_PIN_BANK_EINTG(6, 0x000, "gph1", 0x00),
+ EXYNOS5433_PIN_BANK_EINTG(7, 0x020, "gpr4", 0x04),
+ EXYNOS5433_PIN_BANK_EINTG(5, 0x040, "gpr0", 0x08),
+ EXYNOS5433_PIN_BANK_EINTG(8, 0x060, "gpr1", 0x0c),
+ EXYNOS5433_PIN_BANK_EINTG(2, 0x080, "gpr2", 0x10),
+ EXYNOS5433_PIN_BANK_EINTG(8, 0x0a0, "gpr3", 0x14),
};
/* pin banks of exynos5433 pin-controller - IMEM */
static const struct samsung_pin_bank_data exynos5433_pin_banks6[] = {
- EXYNOS_PIN_BANK_EINTG(8, 0x000, "gpf0", 0x00),
+ EXYNOS5433_PIN_BANK_EINTG(8, 0x000, "gpf0", 0x00),
};
/* pin banks of exynos5433 pin-controller - NFC */
static const struct samsung_pin_bank_data exynos5433_pin_banks7[] = {
- EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00),
+ EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj0", 0x00),
};
/* pin banks of exynos5433 pin-controller - PERIC */
static const struct samsung_pin_bank_data exynos5433_pin_banks8[] = {
- EXYNOS_PIN_BANK_EINTG(6, 0x000, "gpv7", 0x00),
- EXYNOS_PIN_BANK_EINTG(5, 0x020, "gpb0", 0x04),
- EXYNOS_PIN_BANK_EINTG(8, 0x040, "gpc0", 0x08),
- EXYNOS_PIN_BANK_EINTG(2, 0x060, "gpc1", 0x0c),
- EXYNOS_PIN_BANK_EINTG(6, 0x080, "gpc2", 0x10),
- EXYNOS_PIN_BANK_EINTG(8, 0x0a0, "gpc3", 0x14),
- EXYNOS_PIN_BANK_EINTG(2, 0x0c0, "gpg0", 0x18),
- EXYNOS_PIN_BANK_EINTG(4, 0x0e0, "gpd0", 0x1c),
- EXYNOS_PIN_BANK_EINTG(6, 0x100, "gpd1", 0x20),
- EXYNOS_PIN_BANK_EINTG(8, 0x120, "gpd2", 0x24),
- EXYNOS_PIN_BANK_EINTG(5, 0x140, "gpd4", 0x28),
- EXYNOS_PIN_BANK_EINTG(2, 0x160, "gpd8", 0x2c),
- EXYNOS_PIN_BANK_EINTG(7, 0x180, "gpd6", 0x30),
- EXYNOS_PIN_BANK_EINTG(3, 0x1a0, "gpd7", 0x34),
- EXYNOS_PIN_BANK_EINTG(5, 0x1c0, "gpg1", 0x38),
- EXYNOS_PIN_BANK_EINTG(2, 0x1e0, "gpg2", 0x3c),
- EXYNOS_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
+ EXYNOS5433_PIN_BANK_EINTG(6, 0x000, "gpv7", 0x00),
+ EXYNOS5433_PIN_BANK_EINTG(5, 0x020, "gpb0", 0x04),
+ EXYNOS5433_PIN_BANK_EINTG(8, 0x040, "gpc0", 0x08),
+ EXYNOS5433_PIN_BANK_EINTG(2, 0x060, "gpc1", 0x0c),
+ EXYNOS5433_PIN_BANK_EINTG(6, 0x080, "gpc2", 0x10),
+ EXYNOS5433_PIN_BANK_EINTG(8, 0x0a0, "gpc3", 0x14),
+ EXYNOS5433_PIN_BANK_EINTG(2, 0x0c0, "gpg0", 0x18),
+ EXYNOS5433_PIN_BANK_EINTG(4, 0x0e0, "gpd0", 0x1c),
+ EXYNOS5433_PIN_BANK_EINTG(6, 0x100, "gpd1", 0x20),
+ EXYNOS5433_PIN_BANK_EINTG(8, 0x120, "gpd2", 0x24),
+ EXYNOS5433_PIN_BANK_EINTG(5, 0x140, "gpd4", 0x28),
+ EXYNOS5433_PIN_BANK_EINTG(2, 0x160, "gpd8", 0x2c),
+ EXYNOS5433_PIN_BANK_EINTG(7, 0x180, "gpd6", 0x30),
+ EXYNOS5433_PIN_BANK_EINTG(3, 0x1a0, "gpd7", 0x34),
+ EXYNOS5433_PIN_BANK_EINTG(5, 0x1c0, "gpg1", 0x38),
+ EXYNOS5433_PIN_BANK_EINTG(2, 0x1e0, "gpg2", 0x3c),
+ EXYNOS5433_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
};
/* pin banks of exynos5433 pin-controller - TOUCH */
static const struct samsung_pin_bank_data exynos5433_pin_banks9[] = {
- EXYNOS_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00),
+ EXYNOS5433_PIN_BANK_EINTG(3, 0x000, "gpj1", 0x00),
};
/*
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.h b/drivers/pinctrl/samsung/pinctrl-exynos.h
index 5821525a2c84..a473092fb8d2 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.h
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.h
@@ -90,6 +90,37 @@
.pctl_res_idx = pctl_idx, \
} \
+#define EXYNOS5433_PIN_BANK_EINTG(pins, reg, id, offs) \
+ { \
+ .type = &exynos5433_bank_type_off, \
+ .pctl_offset = reg, \
+ .nr_pins = pins, \
+ .eint_type = EINT_TYPE_GPIO, \
+ .eint_offset = offs, \
+ .name = id \
+ }
+
+#define EXYNOS5433_PIN_BANK_EINTW(pins, reg, id, offs) \
+ { \
+ .type = &exynos5433_bank_type_alive, \
+ .pctl_offset = reg, \
+ .nr_pins = pins, \
+ .eint_type = EINT_TYPE_WKUP, \
+ .eint_offset = offs, \
+ .name = id \
+ }
+
+#define EXYNOS5433_PIN_BANK_EINTW_EXT(pins, reg, id, offs, pctl_idx) \
+ { \
+ .type = &exynos5433_bank_type_alive, \
+ .pctl_offset = reg, \
+ .nr_pins = pins, \
+ .eint_type = EINT_TYPE_WKUP, \
+ .eint_offset = offs, \
+ .name = id, \
+ .pctl_res_idx = pctl_idx, \
+ } \
+
/**
* struct exynos_weint_data: irq specific data for all the wakeup interrupts
* generated by the external wakeup interrupt controller.
diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c
index 47268ecedc4d..6f09da4dadb8 100644
--- a/drivers/platform/chrome/cros_ec_dev.c
+++ b/drivers/platform/chrome/cros_ec_dev.c
@@ -328,6 +328,9 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec)
case MOTIONSENSE_TYPE_ACCEL:
sensor_cells[id].name = "cros-ec-accel";
break;
+ case MOTIONSENSE_TYPE_BARO:
+ sensor_cells[id].name = "cros-ec-baro";
+ break;
case MOTIONSENSE_TYPE_GYRO:
sensor_cells[id].name = "cros-ec-gyro";
break;
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 5fe8be089b8b..59aa8e302bc3 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1034,7 +1034,7 @@ config SURFACE_PRO3_BUTTON
config SURFACE_3_BUTTON
tristate "Power/home/volume buttons driver for Microsoft Surface 3 tablet"
- depends on ACPI && KEYBOARD_GPIO
+ depends on ACPI && KEYBOARD_GPIO && I2C
---help---
This driver handles the power/home/volume buttons on the Microsoft Surface 3 tablet.
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 61f39abf5dc8..82d67715ce76 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -177,43 +177,43 @@ static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event);
#if IS_ENABLED(CONFIG_LEDS_CLASS)
static enum led_brightness logolamp_get(struct led_classdev *cdev);
-static void logolamp_set(struct led_classdev *cdev,
+static int logolamp_set(struct led_classdev *cdev,
enum led_brightness brightness);
static struct led_classdev logolamp_led = {
.name = "fujitsu::logolamp",
.brightness_get = logolamp_get,
- .brightness_set = logolamp_set
+ .brightness_set_blocking = logolamp_set
};
static enum led_brightness kblamps_get(struct led_classdev *cdev);
-static void kblamps_set(struct led_classdev *cdev,
+static int kblamps_set(struct led_classdev *cdev,
enum led_brightness brightness);
static struct led_classdev kblamps_led = {
.name = "fujitsu::kblamps",
.brightness_get = kblamps_get,
- .brightness_set = kblamps_set
+ .brightness_set_blocking = kblamps_set
};
static enum led_brightness radio_led_get(struct led_classdev *cdev);
-static void radio_led_set(struct led_classdev *cdev,
+static int radio_led_set(struct led_classdev *cdev,
enum led_brightness brightness);
static struct led_classdev radio_led = {
.name = "fujitsu::radio_led",
.brightness_get = radio_led_get,
- .brightness_set = radio_led_set
+ .brightness_set_blocking = radio_led_set
};
static enum led_brightness eco_led_get(struct led_classdev *cdev);
-static void eco_led_set(struct led_classdev *cdev,
+static int eco_led_set(struct led_classdev *cdev,
enum led_brightness brightness);
static struct led_classdev eco_led = {
.name = "fujitsu::eco_led",
.brightness_get = eco_led_get,
- .brightness_set = eco_led_set
+ .brightness_set_blocking = eco_led_set
};
#endif
@@ -267,48 +267,48 @@ static int call_fext_func(int cmd, int arg0, int arg1, int arg2)
#if IS_ENABLED(CONFIG_LEDS_CLASS)
/* LED class callbacks */
-static void logolamp_set(struct led_classdev *cdev,
+static int logolamp_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
if (brightness >= LED_FULL) {
call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON);
- call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_ON);
+ return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_ON);
} else if (brightness >= LED_HALF) {
call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_ON);
- call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_OFF);
+ return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_ALWAYS, FUNC_LED_OFF);
} else {
- call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_OFF);
+ return call_fext_func(FUNC_LEDS, 0x1, LOGOLAMP_POWERON, FUNC_LED_OFF);
}
}
-static void kblamps_set(struct led_classdev *cdev,
+static int kblamps_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
if (brightness >= LED_FULL)
- call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_ON);
+ return call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_ON);
else
- call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_OFF);
+ return call_fext_func(FUNC_LEDS, 0x1, KEYBOARD_LAMPS, FUNC_LED_OFF);
}
-static void radio_led_set(struct led_classdev *cdev,
+static int radio_led_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
if (brightness >= LED_FULL)
- call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, RADIO_LED_ON);
+ return call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, RADIO_LED_ON);
else
- call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, 0x0);
+ return call_fext_func(FUNC_RFKILL, 0x5, RADIO_LED_ON, 0x0);
}
-static void eco_led_set(struct led_classdev *cdev,
+static int eco_led_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
int curr;
curr = call_fext_func(FUNC_LEDS, 0x2, ECO_LED, 0x0);
if (brightness >= LED_FULL)
- call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr | ECO_LED_ON);
+ return call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr | ECO_LED_ON);
else
- call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr & ~ECO_LED_ON);
+ return call_fext_func(FUNC_LEDS, 0x1, ECO_LED, curr & ~ECO_LED_ON);
}
static enum led_brightness logolamp_get(struct led_classdev *cdev)
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index cd005cd41413..4c360f8071a8 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -96,12 +96,12 @@ source "drivers/staging/wilc1000/Kconfig"
source "drivers/staging/most/Kconfig"
-source "drivers/staging/i4l/Kconfig"
-
source "drivers/staging/ks7010/Kconfig"
source "drivers/staging/greybus/Kconfig"
source "drivers/staging/vc04_services/Kconfig"
+source "drivers/staging/bcm2835-audio/Kconfig"
+
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 831e2e891989..29cec5aa2945 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -37,7 +37,8 @@ obj-$(CONFIG_FB_TFT) += fbtft/
obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/
obj-$(CONFIG_WILC1000) += wilc1000/
obj-$(CONFIG_MOST) += most/
-obj-$(CONFIG_ISDN_I4L) += i4l/
obj-$(CONFIG_KS7010) += ks7010/
obj-$(CONFIG_GREYBUS) += greybus/
obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/
+obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/
+
diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c
index 7e7431d8d49f..9ff815ad1cb1 100644
--- a/drivers/staging/android/ion/ion-ioctl.c
+++ b/drivers/staging/android/ion/ion-ioctl.c
@@ -111,7 +111,8 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
struct ion_handle *handle;
mutex_lock(&client->lock);
- handle = ion_handle_get_by_id_nolock(client, data.handle.handle);
+ handle = ion_handle_get_by_id_nolock(client,
+ data.handle.handle);
if (IS_ERR(handle)) {
mutex_unlock(&client->lock);
return PTR_ERR(handle);
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index 6c7de74bc7ab..22b958259dea 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -24,8 +24,6 @@
#include "ion.h"
#include "ion_priv.h"
-#define ION_CMA_ALLOCATE_FAILED -1
-
struct ion_cma_heap {
struct ion_heap heap;
struct device *dev;
@@ -59,7 +57,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
info = kzalloc(sizeof(struct ion_cma_buffer_info), GFP_KERNEL);
if (!info)
- return ION_CMA_ALLOCATE_FAILED;
+ return -ENOMEM;
info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle),
GFP_HIGHUSER | __GFP_ZERO);
@@ -88,7 +86,7 @@ free_mem:
dma_free_coherent(dev, len, info->cpu_addr, info->handle);
err:
kfree(info);
- return ION_CMA_ALLOCATE_FAILED;
+ return -ENOMEM;
}
static void ion_cma_free(struct ion_buffer *buffer)
diff --git a/drivers/staging/android/ion/ion_of.c b/drivers/staging/android/ion/ion_of.c
index 46b2bb99bfd6..7791c705ea31 100644
--- a/drivers/staging/android/ion/ion_of.c
+++ b/drivers/staging/android/ion/ion_of.c
@@ -161,7 +161,6 @@ static int rmem_ion_device_init(struct reserved_mem *rmem, struct device *dev)
static void rmem_ion_device_release(struct reserved_mem *rmem,
struct device *dev)
{
- return;
}
static const struct reserved_mem_ops rmem_dma_ops = {
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h
index 3c3b3245275d..5b3059c78431 100644
--- a/drivers/staging/android/ion/ion_priv.h
+++ b/drivers/staging/android/ion/ion_priv.h
@@ -54,7 +54,7 @@
* handle, used for debugging
* @pid: pid of last client to reference this buffer in a
* handle, used for debugging
-*/
+ */
struct ion_buffer {
struct kref ref;
union {
@@ -287,10 +287,10 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap);
* some helpers for common operations on buffers using the sg_table
* and vaddr fields
*/
-void *ion_heap_map_kernel(struct ion_heap *, struct ion_buffer *);
-void ion_heap_unmap_kernel(struct ion_heap *, struct ion_buffer *);
-int ion_heap_map_user(struct ion_heap *, struct ion_buffer *,
- struct vm_area_struct *);
+void *ion_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer);
+void ion_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer);
+int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
+ struct vm_area_struct *vma);
int ion_heap_buffer_zero(struct ion_buffer *buffer);
int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot);
@@ -371,21 +371,21 @@ size_t ion_heap_freelist_size(struct ion_heap *heap);
* heaps as appropriate.
*/
-struct ion_heap *ion_heap_create(struct ion_platform_heap *);
-void ion_heap_destroy(struct ion_heap *);
-struct ion_heap *ion_system_heap_create(struct ion_platform_heap *);
-void ion_system_heap_destroy(struct ion_heap *);
+struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data);
+void ion_heap_destroy(struct ion_heap *heap);
+struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused);
+void ion_system_heap_destroy(struct ion_heap *heap);
-struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *);
-void ion_system_contig_heap_destroy(struct ion_heap *);
+struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *heap);
+void ion_system_contig_heap_destroy(struct ion_heap *heap);
-struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *);
-void ion_carveout_heap_destroy(struct ion_heap *);
+struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data);
+void ion_carveout_heap_destroy(struct ion_heap *heap);
-struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *);
-void ion_chunk_heap_destroy(struct ion_heap *);
-struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *);
-void ion_cma_heap_destroy(struct ion_heap *);
+struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data);
+void ion_chunk_heap_destroy(struct ion_heap *heap);
+struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data);
+void ion_cma_heap_destroy(struct ion_heap *heap);
/**
* functions for creating and destroying a heap pool -- allows you
@@ -427,9 +427,9 @@ struct ion_page_pool {
struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order,
bool cached);
-void ion_page_pool_destroy(struct ion_page_pool *);
-struct page *ion_page_pool_alloc(struct ion_page_pool *);
-void ion_page_pool_free(struct ion_page_pool *, struct page *);
+void ion_page_pool_destroy(struct ion_page_pool *pool);
+struct page *ion_page_pool_alloc(struct ion_page_pool *pool);
+void ion_page_pool_free(struct ion_page_pool *pool, struct page *page);
/** ion_page_pool_shrink - shrinks the size of the memory cached in the pool
* @pool: the pool
diff --git a/drivers/staging/bcm2835-audio/Kconfig b/drivers/staging/bcm2835-audio/Kconfig
new file mode 100644
index 000000000000..32a2ff9ef9b2
--- /dev/null
+++ b/drivers/staging/bcm2835-audio/Kconfig
@@ -0,0 +1,7 @@
+config SND_BCM2835
+ tristate "BCM2835 ALSA driver"
+ depends on ARCH_BCM2835 && BCM2835_VCHIQ && SND
+ select SND_PCM
+ help
+ Say Y or M if you want to support BCM2835 Alsa pcm card driver
+
diff --git a/drivers/staging/bcm2835-audio/Makefile b/drivers/staging/bcm2835-audio/Makefile
new file mode 100644
index 000000000000..d2719e20d1ab
--- /dev/null
+++ b/drivers/staging/bcm2835-audio/Makefile
@@ -0,0 +1,5 @@
+obj-$(CONFIG_SND_BCM2835) += snd-bcm2835.o
+snd-bcm2835-objs := bcm2835.o bcm2835-ctl.o bcm2835-pcm.o bcm2835-vchiq.o
+
+ccflags-y += -Idrivers/staging/vc04_services -Idrivers/staging/vc04_services/interface/vcos/linuxkernel -D__VCCOREVER__=0x04000000
+
diff --git a/drivers/staging/bcm2835-audio/bcm2835-ctl.c b/drivers/staging/bcm2835-audio/bcm2835-ctl.c
new file mode 100644
index 000000000000..164daa4c723c
--- /dev/null
+++ b/drivers/staging/bcm2835-audio/bcm2835-ctl.c
@@ -0,0 +1,346 @@
+/*****************************************************************************
+ * Copyright 2011 Broadcom Corporation. All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available at
+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *****************************************************************************/
+
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/moduleparam.h>
+#include <linux/sched.h>
+
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/rawmidi.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/asoundef.h>
+
+#include "bcm2835.h"
+
+/* volume maximum and minimum in terms of 0.01dB */
+#define CTRL_VOL_MAX 400
+#define CTRL_VOL_MIN -10239 /* originally -10240 */
+
+static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ audio_info(" ... IN\n");
+ if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) {
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = CTRL_VOL_MIN;
+ uinfo->value.integer.max = CTRL_VOL_MAX; /* 2303 */
+ } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) {
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) {
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = AUDIO_DEST_MAX - 1;
+ }
+ audio_info(" ... OUT\n");
+ return 0;
+}
+
+/* toggles mute on or off depending on the value of nmute, and returns
+ * 1 if the mute value was changed, otherwise 0
+ */
+static int toggle_mute(struct bcm2835_chip *chip, int nmute)
+{
+ /* if settings are ok, just return 0 */
+ if (chip->mute == nmute)
+ return 0;
+
+ /* if the sound is muted then we need to unmute */
+ if (chip->mute == CTRL_VOL_MUTE) {
+ chip->volume = chip->old_volume; /* copy the old volume back */
+ audio_info("Unmuting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume);
+ } else /* otherwise we mute */ {
+ chip->old_volume = chip->volume;
+ chip->volume = 26214; /* set volume to minimum level AKA mute */
+ audio_info("Muting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume);
+ }
+
+ chip->mute = nmute;
+ return 1;
+}
+
+static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
+
+ if (mutex_lock_interruptible(&chip->audio_mutex))
+ return -EINTR;
+
+ BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK));
+
+ if (kcontrol->private_value == PCM_PLAYBACK_VOLUME)
+ ucontrol->value.integer.value[0] = chip2alsa(chip->volume);
+ else if (kcontrol->private_value == PCM_PLAYBACK_MUTE)
+ ucontrol->value.integer.value[0] = chip->mute;
+ else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE)
+ ucontrol->value.integer.value[0] = chip->dest;
+
+ mutex_unlock(&chip->audio_mutex);
+ return 0;
+}
+
+static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
+ int changed = 0;
+
+ if (mutex_lock_interruptible(&chip->audio_mutex))
+ return -EINTR;
+
+ if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) {
+ audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int) ucontrol->value.integer.value[0]);
+ if (chip->mute == CTRL_VOL_MUTE) {
+ /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */
+ changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */
+ goto unlock;
+ }
+ if (changed
+ || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) {
+
+ chip->volume = alsa2chip(ucontrol->value.integer.value[0]);
+ changed = 1;
+ }
+
+ } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) {
+ /* Now implemented */
+ audio_info(" Mute attempted\n");
+ changed = toggle_mute(chip, ucontrol->value.integer.value[0]);
+
+ } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) {
+ if (ucontrol->value.integer.value[0] != chip->dest) {
+ chip->dest = ucontrol->value.integer.value[0];
+ changed = 1;
+ }
+ }
+
+ if (changed) {
+ if (bcm2835_audio_set_ctls(chip))
+ printk(KERN_ERR "Failed to set ALSA controls..\n");
+ }
+
+unlock:
+ mutex_unlock(&chip->audio_mutex);
+ return changed;
+}
+
+static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, CTRL_VOL_MIN, 1, 1);
+
+static struct snd_kcontrol_new snd_bcm2835_ctl[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "PCM Playback Volume",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+ .private_value = PCM_PLAYBACK_VOLUME,
+ .info = snd_bcm2835_ctl_info,
+ .get = snd_bcm2835_ctl_get,
+ .put = snd_bcm2835_ctl_put,
+ .count = 1,
+ .tlv =
+ {.p = snd_bcm2835_db_scale}
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "PCM Playback Switch",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = PCM_PLAYBACK_MUTE,
+ .info = snd_bcm2835_ctl_info,
+ .get = snd_bcm2835_ctl_get,
+ .put = snd_bcm2835_ctl_put,
+ .count = 1,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "PCM Playback Route",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .private_value = PCM_PLAYBACK_DEVICE,
+ .info = snd_bcm2835_ctl_info,
+ .get = snd_bcm2835_ctl_get,
+ .put = snd_bcm2835_ctl_put,
+ .count = 1,
+ },
+};
+
+static int snd_bcm2835_spdif_default_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+ return 0;
+}
+
+static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
+ int i;
+
+ if (mutex_lock_interruptible(&chip->audio_mutex))
+ return -EINTR;
+
+ for (i = 0; i < 4; i++)
+ ucontrol->value.iec958.status[i] =
+ (chip->spdif_status >> (i * 8)) && 0xff;
+
+ mutex_unlock(&chip->audio_mutex);
+ return 0;
+}
+
+static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
+ unsigned int val = 0;
+ int i, change;
+
+ if (mutex_lock_interruptible(&chip->audio_mutex))
+ return -EINTR;
+
+ for (i = 0; i < 4; i++)
+ val |= (unsigned int) ucontrol->value.iec958.status[i] << (i * 8);
+
+ change = val != chip->spdif_status;
+ chip->spdif_status = val;
+
+ mutex_unlock(&chip->audio_mutex);
+ return change;
+}
+
+static int snd_bcm2835_spdif_mask_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+ return 0;
+}
+
+static int snd_bcm2835_spdif_mask_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ /* bcm2835 supports only consumer mode and sets all other format flags
+ * automatically. So the only thing left is signalling non-audio
+ * content */
+ ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO;
+ return 0;
+}
+
+static int snd_bcm2835_spdif_stream_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+ return 0;
+}
+
+static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
+ int i;
+
+ if (mutex_lock_interruptible(&chip->audio_mutex))
+ return -EINTR;
+
+ for (i = 0; i < 4; i++)
+ ucontrol->value.iec958.status[i] =
+ (chip->spdif_status >> (i * 8)) & 0xff;
+
+ mutex_unlock(&chip->audio_mutex);
+ return 0;
+}
+
+static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
+ unsigned int val = 0;
+ int i, change;
+
+ if (mutex_lock_interruptible(&chip->audio_mutex))
+ return -EINTR;
+
+ for (i = 0; i < 4; i++)
+ val |= (unsigned int) ucontrol->value.iec958.status[i] << (i * 8);
+ change = val != chip->spdif_status;
+ chip->spdif_status = val;
+
+ mutex_unlock(&chip->audio_mutex);
+ return change;
+}
+
+static struct snd_kcontrol_new snd_bcm2835_spdif[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
+ .info = snd_bcm2835_spdif_default_info,
+ .get = snd_bcm2835_spdif_default_get,
+ .put = snd_bcm2835_spdif_default_put
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
+ .info = snd_bcm2835_spdif_mask_info,
+ .get = snd_bcm2835_spdif_mask_get,
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_INACTIVE,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
+ .info = snd_bcm2835_spdif_stream_info,
+ .get = snd_bcm2835_spdif_stream_get,
+ .put = snd_bcm2835_spdif_stream_put,
+ },
+};
+
+int snd_bcm2835_new_ctl(struct bcm2835_chip *chip)
+{
+ int err;
+ unsigned int idx;
+
+ strcpy(chip->card->mixername, "Broadcom Mixer");
+ for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_ctl); idx++) {
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_bcm2835_ctl[idx], chip));
+ if (err < 0)
+ return err;
+ }
+ for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) {
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_bcm2835_spdif[idx], chip));
+ if (err < 0)
+ return err;
+ }
+ return 0;
+}
diff --git a/drivers/staging/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/bcm2835-audio/bcm2835-pcm.c
new file mode 100644
index 000000000000..2c3bf63e3391
--- /dev/null
+++ b/drivers/staging/bcm2835-audio/bcm2835-pcm.c
@@ -0,0 +1,560 @@
+/*****************************************************************************
+ * Copyright 2011 Broadcom Corporation. All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available at
+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *****************************************************************************/
+
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+
+#include <sound/asoundef.h>
+
+#include "bcm2835.h"
+
+/* hardware definition */
+static struct snd_pcm_hardware snd_bcm2835_playback_hw = {
+ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
+ .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = 128 * 1024,
+ .period_bytes_min = 1 * 1024,
+ .period_bytes_max = 128 * 1024,
+ .periods_min = 1,
+ .periods_max = 128,
+};
+
+static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = {
+ .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_48000,
+ .rate_min = 44100,
+ .rate_max = 48000,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 128 * 1024,
+ .period_bytes_min = 1 * 1024,
+ .period_bytes_max = 128 * 1024,
+ .periods_min = 1,
+ .periods_max = 128,
+};
+
+static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime)
+{
+ audio_info("Freeing up alsa stream here ..\n");
+ if (runtime->private_data)
+ kfree(runtime->private_data);
+ runtime->private_data = NULL;
+}
+
+static irqreturn_t bcm2835_playback_fifo_irq(int irq, void *dev_id)
+{
+ struct bcm2835_alsa_stream *alsa_stream = dev_id;
+ unsigned int consumed = 0;
+ int new_period = 0;
+
+ audio_info(" .. IN\n");
+
+ audio_info("alsa_stream=%p substream=%p\n", alsa_stream,
+ alsa_stream ? alsa_stream->substream : 0);
+
+ if (alsa_stream->open)
+ consumed = bcm2835_audio_retrieve_buffers(alsa_stream);
+
+ /* We get called only if playback was triggered, So, the number of buffers we retrieve in
+ * each iteration are the buffers that have been played out already
+ */
+
+ if (alsa_stream->period_size) {
+ if ((alsa_stream->pos / alsa_stream->period_size) !=
+ ((alsa_stream->pos + consumed) / alsa_stream->period_size))
+ new_period = 1;
+ }
+ audio_debug("updating pos cur: %d + %d max:%d period_bytes:%d, hw_ptr: %d new_period:%d\n",
+ alsa_stream->pos,
+ consumed,
+ alsa_stream->buffer_size,
+ (int) (alsa_stream->period_size * alsa_stream->substream->runtime->periods),
+ frames_to_bytes(alsa_stream->substream->runtime, alsa_stream->substream->runtime->status->hw_ptr),
+ new_period);
+ if (alsa_stream->buffer_size) {
+ alsa_stream->pos += consumed &~(1 << 30);
+ alsa_stream->pos %= alsa_stream->buffer_size;
+ }
+
+ if (alsa_stream->substream) {
+ if (new_period)
+ snd_pcm_period_elapsed(alsa_stream->substream);
+ } else {
+ audio_warning(" unexpected NULL substream\n");
+ }
+ audio_info(" .. OUT\n");
+
+ return IRQ_HANDLED;
+}
+
+/* open callback */
+static int snd_bcm2835_playback_open_generic(
+ struct snd_pcm_substream *substream, int spdif)
+{
+ struct bcm2835_chip *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct bcm2835_alsa_stream *alsa_stream;
+ int idx;
+ int err;
+
+ audio_info(" .. IN (%d)\n", substream->number);
+
+ if (mutex_lock_interruptible(&chip->audio_mutex)) {
+ audio_error("Interrupted whilst waiting for lock\n");
+ return -EINTR;
+ }
+ audio_info("Alsa open (%d)\n", substream->number);
+ idx = substream->number;
+
+ if (spdif && chip->opened) {
+ err = -EBUSY;
+ goto out;
+ } else if (!spdif && (chip->opened & (1 << idx))) {
+ err = -EBUSY;
+ goto out;
+ }
+ if (idx > MAX_SUBSTREAMS) {
+ audio_error
+ ("substream(%d) device doesn't exist max(%d) substreams allowed\n",
+ idx, MAX_SUBSTREAMS);
+ err = -ENODEV;
+ goto out;
+ }
+
+ /* Check if we are ready */
+ if (!(chip->avail_substreams & (1 << idx))) {
+ /* We are not ready yet */
+ audio_error("substream(%d) device is not ready yet\n", idx);
+ err = -EAGAIN;
+ goto out;
+ }
+
+ alsa_stream = kzalloc(sizeof(*alsa_stream), GFP_KERNEL);
+ if (!alsa_stream) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /* Initialise alsa_stream */
+ alsa_stream->chip = chip;
+ alsa_stream->substream = substream;
+ alsa_stream->idx = idx;
+
+ sema_init(&alsa_stream->buffers_update_sem, 0);
+ sema_init(&alsa_stream->control_sem, 0);
+ spin_lock_init(&alsa_stream->lock);
+
+ /* Enabled in start trigger, called on each "fifo irq" after that */
+ alsa_stream->enable_fifo_irq = 0;
+ alsa_stream->fifo_irq_handler = bcm2835_playback_fifo_irq;
+
+ err = bcm2835_audio_open(alsa_stream);
+ if (err) {
+ kfree(alsa_stream);
+ goto out;
+ }
+ runtime->private_data = alsa_stream;
+ runtime->private_free = snd_bcm2835_playback_free;
+ if (spdif) {
+ runtime->hw = snd_bcm2835_playback_spdif_hw;
+ } else {
+ /* clear spdif status, as we are not in spdif mode */
+ chip->spdif_status = 0;
+ runtime->hw = snd_bcm2835_playback_hw;
+ }
+ /* minimum 16 bytes alignment (for vchiq bulk transfers) */
+ snd_pcm_hw_constraint_step(runtime,
+ 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
+ 16);
+
+ chip->alsa_stream[idx] = alsa_stream;
+
+ chip->opened |= (1 << idx);
+ alsa_stream->open = 1;
+ alsa_stream->draining = 1;
+
+out:
+ mutex_unlock(&chip->audio_mutex);
+
+ audio_info(" .. OUT =%d\n", err);
+
+ return err;
+}
+
+static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream)
+{
+ return snd_bcm2835_playback_open_generic(substream, 0);
+}
+
+static int snd_bcm2835_playback_spdif_open(struct snd_pcm_substream *substream)
+{
+ return snd_bcm2835_playback_open_generic(substream, 1);
+}
+
+/* close callback */
+static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream)
+{
+ /* the hardware-specific codes will be here */
+
+ struct bcm2835_chip *chip;
+ struct snd_pcm_runtime *runtime;
+ struct bcm2835_alsa_stream *alsa_stream;
+
+ audio_info(" .. IN\n");
+
+ chip = snd_pcm_substream_chip(substream);
+ if (mutex_lock_interruptible(&chip->audio_mutex)) {
+ audio_error("Interrupted whilst waiting for lock\n");
+ return -EINTR;
+ }
+ runtime = substream->runtime;
+ alsa_stream = runtime->private_data;
+
+ audio_info("Alsa close\n");
+
+ /*
+ * Call stop if it's still running. This happens when app
+ * is force killed and we don't get a stop trigger.
+ */
+ if (alsa_stream->running) {
+ int err;
+ err = bcm2835_audio_stop(alsa_stream);
+ alsa_stream->running = 0;
+ if (err)
+ audio_error(" Failed to STOP alsa device\n");
+ }
+
+ alsa_stream->period_size = 0;
+ alsa_stream->buffer_size = 0;
+
+ if (alsa_stream->open) {
+ alsa_stream->open = 0;
+ bcm2835_audio_close(alsa_stream);
+ }
+ if (alsa_stream->chip)
+ alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL;
+ /*
+ * Do not free up alsa_stream here, it will be freed up by
+ * runtime->private_free callback we registered in *_open above
+ */
+
+ chip->opened &= ~(1 << substream->number);
+
+ mutex_unlock(&chip->audio_mutex);
+ audio_info(" .. OUT\n");
+
+ return 0;
+}
+
+/* hw_params callback */
+static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
+ int err;
+
+ audio_info(" .. IN\n");
+
+ err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
+ if (err < 0) {
+ audio_error
+ (" pcm_lib_malloc failed to allocated pages for buffers\n");
+ return err;
+ }
+
+ alsa_stream->channels = params_channels(params);
+ alsa_stream->params_rate = params_rate(params);
+ alsa_stream->pcm_format_width = snd_pcm_format_width(params_format(params));
+ audio_info(" .. OUT\n");
+
+ return err;
+}
+
+/* hw_free callback */
+static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+ audio_info(" .. IN\n");
+ return snd_pcm_lib_free_pages(substream);
+}
+
+/* prepare callback */
+static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ struct bcm2835_chip *chip = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
+ int channels;
+ int err;
+
+ audio_info(" .. IN\n");
+
+ if (mutex_lock_interruptible(&chip->audio_mutex))
+ return -EINTR;
+
+ /* notify the vchiq that it should enter spdif passthrough mode by
+ * setting channels=0 (see
+ * https://github.com/raspberrypi/linux/issues/528) */
+ if (chip->spdif_status & IEC958_AES0_NONAUDIO)
+ channels = 0;
+ else
+ channels = alsa_stream->channels;
+
+ err = bcm2835_audio_set_params(alsa_stream, channels,
+ alsa_stream->params_rate,
+ alsa_stream->pcm_format_width);
+ if (err < 0) {
+ audio_error(" error setting hw params\n");
+ }
+
+ bcm2835_audio_setup(alsa_stream);
+
+ /* in preparation of the stream, set the controls (volume level) of the stream */
+ bcm2835_audio_set_ctls(alsa_stream->chip);
+
+
+ memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect));
+
+ alsa_stream->pcm_indirect.hw_buffer_size =
+ alsa_stream->pcm_indirect.sw_buffer_size =
+ snd_pcm_lib_buffer_bytes(substream);
+
+ alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream);
+ alsa_stream->period_size = snd_pcm_lib_period_bytes(substream);
+ alsa_stream->pos = 0;
+
+ audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n",
+ alsa_stream->buffer_size, alsa_stream->period_size,
+ alsa_stream->pos, runtime->frame_bits);
+
+ mutex_unlock(&chip->audio_mutex);
+ audio_info(" .. OUT\n");
+ return 0;
+}
+
+static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream,
+ struct snd_pcm_indirect *rec, size_t bytes)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
+ void *src = (void *) (substream->runtime->dma_area + rec->sw_data);
+ int err;
+
+ err = bcm2835_audio_write(alsa_stream, bytes, src);
+ if (err)
+ audio_error(" Failed to transfer to alsa device (%d)\n", err);
+
+}
+
+static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
+ struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect;
+
+ pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max;
+ snd_pcm_indirect_playback_transfer(substream, pcm_indirect,
+ snd_bcm2835_pcm_transfer);
+ return 0;
+}
+
+/* trigger callback */
+static int snd_bcm2835_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
+ int err = 0;
+
+ audio_info(" .. IN\n");
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ audio_debug("bcm2835_AUDIO_TRIGGER_START running=%d\n",
+ alsa_stream->running);
+ if (!alsa_stream->running) {
+ err = bcm2835_audio_start(alsa_stream);
+ if (!err) {
+ alsa_stream->pcm_indirect.hw_io =
+ alsa_stream->pcm_indirect.hw_data =
+ bytes_to_frames(runtime,
+ alsa_stream->pos);
+ substream->ops->ack(substream);
+ alsa_stream->running = 1;
+ alsa_stream->draining = 1;
+ } else {
+ audio_error(" Failed to START alsa device (%d)\n", err);
+ }
+ }
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ audio_debug
+ ("bcm2835_AUDIO_TRIGGER_STOP running=%d draining=%d\n",
+ alsa_stream->running, runtime->status->state == SNDRV_PCM_STATE_DRAINING);
+ if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
+ audio_info("DRAINING\n");
+ alsa_stream->draining = 1;
+ } else {
+ audio_info("DROPPING\n");
+ alsa_stream->draining = 0;
+ }
+ if (alsa_stream->running) {
+ err = bcm2835_audio_stop(alsa_stream);
+ if (err != 0)
+ audio_error(" Failed to STOP alsa device (%d)\n", err);
+ alsa_stream->running = 0;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ }
+
+ audio_info(" .. OUT\n");
+ return err;
+}
+
+/* pointer callback */
+static snd_pcm_uframes_t
+snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct bcm2835_alsa_stream *alsa_stream = runtime->private_data;
+
+ audio_info(" .. IN\n");
+
+ audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0,
+ frames_to_bytes(runtime, runtime->status->hw_ptr),
+ frames_to_bytes(runtime, runtime->control->appl_ptr),
+ alsa_stream->pos);
+
+ audio_info(" .. OUT\n");
+ return snd_pcm_indirect_playback_pointer(substream,
+ &alsa_stream->pcm_indirect,
+ alsa_stream->pos);
+}
+
+static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream,
+ unsigned int cmd, void *arg)
+{
+ int ret = snd_pcm_lib_ioctl(substream, cmd, arg);
+ audio_info(" .. substream=%p, cmd=%d, arg=%p (%x) ret=%d\n", substream,
+ cmd, arg, arg ? *(unsigned *) arg : 0, ret);
+ return ret;
+}
+
+/* operators */
+static struct snd_pcm_ops snd_bcm2835_playback_ops = {
+ .open = snd_bcm2835_playback_open,
+ .close = snd_bcm2835_playback_close,
+ .ioctl = snd_bcm2835_pcm_lib_ioctl,
+ .hw_params = snd_bcm2835_pcm_hw_params,
+ .hw_free = snd_bcm2835_pcm_hw_free,
+ .prepare = snd_bcm2835_pcm_prepare,
+ .trigger = snd_bcm2835_pcm_trigger,
+ .pointer = snd_bcm2835_pcm_pointer,
+ .ack = snd_bcm2835_pcm_ack,
+};
+
+static struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
+ .open = snd_bcm2835_playback_spdif_open,
+ .close = snd_bcm2835_playback_close,
+ .ioctl = snd_bcm2835_pcm_lib_ioctl,
+ .hw_params = snd_bcm2835_pcm_hw_params,
+ .hw_free = snd_bcm2835_pcm_hw_free,
+ .prepare = snd_bcm2835_pcm_prepare,
+ .trigger = snd_bcm2835_pcm_trigger,
+ .pointer = snd_bcm2835_pcm_pointer,
+ .ack = snd_bcm2835_pcm_ack,
+};
+
+/* create a pcm device */
+int snd_bcm2835_new_pcm(struct bcm2835_chip *chip)
+{
+ struct snd_pcm *pcm;
+ int err;
+
+ audio_info(" .. IN\n");
+ mutex_init(&chip->audio_mutex);
+ if (mutex_lock_interruptible(&chip->audio_mutex)) {
+ audio_error("Interrupted whilst waiting for lock\n");
+ return -EINTR;
+ }
+ err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, MAX_SUBSTREAMS, 0, &pcm);
+ if (err < 0)
+ goto out;
+ pcm->private_data = chip;
+ strcpy(pcm->name, "bcm2835 ALSA");
+ chip->pcm = pcm;
+ chip->dest = AUDIO_DEST_AUTO;
+ chip->volume = alsa2chip(0);
+ chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */
+ /* set operators */
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ &snd_bcm2835_playback_ops);
+
+ /* pre-allocation of buffers */
+ /* NOTE: this may fail */
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+ snd_dma_continuous_data(GFP_KERNEL),
+ snd_bcm2835_playback_hw.buffer_bytes_max,
+ snd_bcm2835_playback_hw.buffer_bytes_max);
+
+
+out:
+ mutex_unlock(&chip->audio_mutex);
+ audio_info(" .. OUT\n");
+
+ return 0;
+}
+
+int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip)
+{
+ struct snd_pcm *pcm;
+ int err;
+
+ audio_info(" .. IN\n");
+ if (mutex_lock_interruptible(&chip->audio_mutex)) {
+ audio_error("Interrupted whilst waiting for lock\n");
+ return -EINTR;
+ }
+ err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm);
+ if (err < 0)
+ goto out;
+
+ pcm->private_data = chip;
+ strcpy(pcm->name, "bcm2835 IEC958/HDMI");
+ chip->pcm_spdif = pcm;
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+ &snd_bcm2835_playback_spdif_ops);
+
+ /* pre-allocation of buffers */
+ /* NOTE: this may fail */
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+ snd_dma_continuous_data(GFP_KERNEL),
+ snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max);
+out:
+ mutex_unlock(&chip->audio_mutex);
+ audio_info(" .. OUT\n");
+
+ return 0;
+}
diff --git a/drivers/staging/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/bcm2835-audio/bcm2835-vchiq.c
new file mode 100644
index 000000000000..af70c27004cc
--- /dev/null
+++ b/drivers/staging/bcm2835-audio/bcm2835-vchiq.c
@@ -0,0 +1,903 @@
+/*****************************************************************************
+ * Copyright 2011 Broadcom Corporation. All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available at
+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *****************************************************************************/
+
+#include <linux/device.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mm.h>
+#include <linux/syscalls.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/atomic.h>
+#include <linux/module.h>
+#include <linux/completion.h>
+
+#include "bcm2835.h"
+
+/* ---- Include Files -------------------------------------------------------- */
+
+#include "interface/vchi/vchi.h"
+#include "vc_vchi_audioserv_defs.h"
+
+/* ---- Private Constants and Types ------------------------------------------ */
+
+#define BCM2835_AUDIO_STOP 0
+#define BCM2835_AUDIO_START 1
+#define BCM2835_AUDIO_WRITE 2
+
+/* Logging macros (for remapping to other logging mechanisms, i.e., printf) */
+#ifdef AUDIO_DEBUG_ENABLE
+#define LOG_ERR( fmt, arg... ) pr_err( "%s:%d " fmt, __func__, __LINE__, ##arg)
+#define LOG_WARN( fmt, arg... ) pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
+#define LOG_INFO( fmt, arg... ) pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
+#define LOG_DBG( fmt, arg... ) pr_info( "%s:%d " fmt, __func__, __LINE__, ##arg)
+#else
+#define LOG_ERR( fmt, arg... ) pr_err( "%s:%d " fmt, __func__, __LINE__, ##arg)
+#define LOG_WARN( fmt, arg... )
+#define LOG_INFO( fmt, arg... )
+#define LOG_DBG( fmt, arg... )
+#endif
+
+struct bcm2835_audio_instance {
+ unsigned int num_connections;
+ VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS];
+ struct completion msg_avail_comp;
+ struct mutex vchi_mutex;
+ struct bcm2835_alsa_stream *alsa_stream;
+ int result;
+ short peer_version;
+};
+
+bool force_bulk = false;
+
+/* ---- Private Variables ---------------------------------------------------- */
+
+/* ---- Private Function Prototypes ------------------------------------------ */
+
+/* ---- Private Functions ---------------------------------------------------- */
+
+static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream);
+static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream);
+static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream,
+ unsigned int count, void *src);
+
+
+// Routine to send a message across a service
+
+static ssize_t
+bcm2835_vchi_msg_queue_callback(void *context, void *dest,
+ size_t offset, size_t maxsize)
+{
+ memcpy(dest, context + offset, maxsize);
+ return maxsize;
+}
+
+static int
+bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle,
+ void *data,
+ unsigned int size)
+{
+ return vchi_msg_queue(handle,
+ bcm2835_vchi_msg_queue_callback,
+ data,
+ size);
+}
+
+struct bcm2835_audio_work {
+ struct work_struct my_work;
+ struct bcm2835_alsa_stream *alsa_stream;
+ int cmd;
+ void *src;
+ unsigned int count;
+};
+
+static void my_wq_function(struct work_struct *work)
+{
+ struct bcm2835_audio_work *w =
+ container_of(work, struct bcm2835_audio_work, my_work);
+ int ret = -9;
+ LOG_DBG(" .. IN %p:%d\n", w->alsa_stream, w->cmd);
+ switch (w->cmd) {
+ case BCM2835_AUDIO_START:
+ ret = bcm2835_audio_start_worker(w->alsa_stream);
+ break;
+ case BCM2835_AUDIO_STOP:
+ ret = bcm2835_audio_stop_worker(w->alsa_stream);
+ break;
+ case BCM2835_AUDIO_WRITE:
+ ret = bcm2835_audio_write_worker(w->alsa_stream, w->count,
+ w->src);
+ break;
+ default:
+ LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->cmd);
+ break;
+ }
+ kfree((void *) work);
+ LOG_DBG(" .. OUT %d\n", ret);
+}
+
+int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream)
+{
+ int ret = -1;
+ LOG_DBG(" .. IN\n");
+ if (alsa_stream->my_wq) {
+ struct bcm2835_audio_work *work =
+ kmalloc(sizeof(struct bcm2835_audio_work *), GFP_ATOMIC);
+ /*--- Queue some work (item 1) ---*/
+ if (work) {
+ INIT_WORK(&work->my_work, my_wq_function);
+ work->alsa_stream = alsa_stream;
+ work->cmd = BCM2835_AUDIO_START;
+ if (queue_work(alsa_stream->my_wq, &work->my_work))
+ ret = 0;
+ } else
+ LOG_ERR(" .. Error: NULL work kmalloc\n");
+ }
+ LOG_DBG(" .. OUT %d\n", ret);
+ return ret;
+}
+
+int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream)
+{
+ int ret = -1;
+ LOG_DBG(" .. IN\n");
+ if (alsa_stream->my_wq) {
+ struct bcm2835_audio_work *work =
+ kmalloc(sizeof(struct bcm2835_audio_work *), GFP_ATOMIC);
+ /*--- Queue some work (item 1) ---*/
+ if (work) {
+ INIT_WORK(&work->my_work, my_wq_function);
+ work->alsa_stream = alsa_stream;
+ work->cmd = BCM2835_AUDIO_STOP;
+ if (queue_work(alsa_stream->my_wq, &work->my_work))
+ ret = 0;
+ } else
+ LOG_ERR(" .. Error: NULL work kmalloc\n");
+ }
+ LOG_DBG(" .. OUT %d\n", ret);
+ return ret;
+}
+
+int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
+ unsigned int count, void *src)
+{
+ int ret = -1;
+ LOG_DBG(" .. IN\n");
+ if (alsa_stream->my_wq) {
+ struct bcm2835_audio_work *work =
+ kmalloc(sizeof(struct bcm2835_audio_work *), GFP_ATOMIC);
+ /*--- Queue some work (item 1) ---*/
+ if (work) {
+ INIT_WORK(&work->my_work, my_wq_function);
+ work->alsa_stream = alsa_stream;
+ work->cmd = BCM2835_AUDIO_WRITE;
+ work->src = src;
+ work->count = count;
+ if (queue_work(alsa_stream->my_wq, &work->my_work))
+ ret = 0;
+ } else
+ LOG_ERR(" .. Error: NULL work kmalloc\n");
+ }
+ LOG_DBG(" .. OUT %d\n", ret);
+ return ret;
+}
+
+void my_workqueue_init(struct bcm2835_alsa_stream *alsa_stream)
+{
+ alsa_stream->my_wq = alloc_workqueue("my_queue", WQ_HIGHPRI, 1);
+ return;
+}
+
+void my_workqueue_quit(struct bcm2835_alsa_stream *alsa_stream)
+{
+ if (alsa_stream->my_wq) {
+ flush_workqueue(alsa_stream->my_wq);
+ destroy_workqueue(alsa_stream->my_wq);
+ alsa_stream->my_wq = NULL;
+ }
+ return;
+}
+
+static void audio_vchi_callback(void *param,
+ const VCHI_CALLBACK_REASON_T reason,
+ void *msg_handle)
+{
+ struct bcm2835_audio_instance *instance = param;
+ int status;
+ int msg_len;
+ struct vc_audio_msg m;
+ LOG_DBG(" .. IN instance=%p, handle=%p, alsa=%p, reason=%d, handle=%p\n",
+ instance, instance ? instance->vchi_handle[0] : NULL, instance ? instance->alsa_stream : NULL, reason, msg_handle);
+
+ if (reason != VCHI_CALLBACK_MSG_AVAILABLE) {
+ return;
+ }
+ if (!instance) {
+ LOG_ERR(" .. instance is null\n");
+ BUG();
+ return;
+ }
+ if (!instance->vchi_handle[0]) {
+ LOG_ERR(" .. instance->vchi_handle[0] is null\n");
+ BUG();
+ return;
+ }
+ status = vchi_msg_dequeue(instance->vchi_handle[0],
+ &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE);
+ if (m.type == VC_AUDIO_MSG_TYPE_RESULT) {
+ LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n",
+ instance, m.u.result.success);
+ instance->result = m.u.result.success;
+ complete(&instance->msg_avail_comp);
+ } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) {
+ struct bcm2835_alsa_stream *alsa_stream = instance->alsa_stream;
+#if defined(CONFIG_64BIT)
+ irq_handler_t callback =
+ (irq_handler_t) (((unsigned long) m.u.complete.callbackl) |
+ ((unsigned long) m.u.complete.callbackh << 32));
+#else
+ irq_handler_t callback = (irq_handler_t) m.u.complete.callback;
+#endif
+ LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_COMPLETE, complete=%d\n",
+ instance, m.u.complete.count);
+ if (alsa_stream && callback) {
+ atomic_add(m.u.complete.count, &alsa_stream->retrieved);
+ callback(0, alsa_stream);
+ } else {
+ LOG_ERR(" .. unexpected alsa_stream=%p, callback=%p\n",
+ alsa_stream, callback);
+ }
+ } else {
+ LOG_ERR(" .. unexpected m.type=%d\n", m.type);
+ }
+ LOG_DBG(" .. OUT\n");
+}
+
+static struct bcm2835_audio_instance *
+vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance,
+ VCHI_CONNECTION_T **vchi_connections,
+ unsigned int num_connections)
+{
+ unsigned int i;
+ struct bcm2835_audio_instance *instance;
+ int status;
+
+ LOG_DBG("%s: start", __func__);
+
+ if (num_connections > VCHI_MAX_NUM_CONNECTIONS) {
+ LOG_ERR("%s: unsupported number of connections %u (max=%u)\n",
+ __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS);
+
+ return NULL;
+ }
+ /* Allocate memory for this instance */
+ instance = kmalloc(sizeof(*instance), GFP_KERNEL);
+ if (!instance)
+ return NULL;
+
+ memset(instance, 0, sizeof(*instance));
+ instance->num_connections = num_connections;
+
+ /* Create a lock for exclusive, serialized VCHI connection access */
+ mutex_init(&instance->vchi_mutex);
+ /* Open the VCHI service connections */
+ for (i = 0; i < num_connections; i++) {
+ SERVICE_CREATION_T params = {
+ VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER),
+ VC_AUDIO_SERVER_NAME, // 4cc service code
+ vchi_connections[i], // passed in fn pointers
+ 0, // rx fifo size (unused)
+ 0, // tx fifo size (unused)
+ audio_vchi_callback, // service callback
+ instance, // service callback parameter
+ 1, //TODO: remove VCOS_FALSE, // unaligned bulk recieves
+ 1, //TODO: remove VCOS_FALSE, // unaligned bulk transmits
+ 0 // want crc check on bulk transfers
+ };
+
+ LOG_DBG("%s: about to open %i\n", __func__, i);
+ status = vchi_service_open(vchi_instance, &params,
+ &instance->vchi_handle[i]);
+ LOG_DBG("%s: opened %i: %p=%d\n", __func__, i, instance->vchi_handle[i], status);
+ if (status) {
+ LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n",
+ __func__, status);
+
+ goto err_close_services;
+ }
+ /* Finished with the service for now */
+ vchi_service_release(instance->vchi_handle[i]);
+ }
+
+ LOG_DBG("%s: okay\n", __func__);
+ return instance;
+
+err_close_services:
+ for (i = 0; i < instance->num_connections; i++) {
+ LOG_ERR("%s: closing %i: %p\n", __func__, i, instance->vchi_handle[i]);
+ if (instance->vchi_handle[i])
+ vchi_service_close(instance->vchi_handle[i]);
+ }
+
+ kfree(instance);
+ LOG_ERR("%s: error\n", __func__);
+
+ return NULL;
+}
+
+static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance)
+{
+ unsigned int i;
+
+ LOG_DBG(" .. IN\n");
+
+ if (!instance) {
+ LOG_ERR("%s: invalid handle %p\n", __func__, instance);
+
+ return -1;
+ }
+
+ LOG_DBG(" .. about to lock (%d)\n", instance->num_connections);
+ if (mutex_lock_interruptible(&instance->vchi_mutex)) {
+ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
+ instance->num_connections);
+ return -EINTR;
+ }
+
+ /* Close all VCHI service connections */
+ for (i = 0; i < instance->num_connections; i++) {
+ int status;
+ LOG_DBG(" .. %i:closing %p\n", i, instance->vchi_handle[i]);
+ vchi_service_use(instance->vchi_handle[i]);
+
+ status = vchi_service_close(instance->vchi_handle[i]);
+ if (status) {
+ LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n",
+ __func__, status);
+ }
+ }
+
+ mutex_unlock(&instance->vchi_mutex);
+
+ kfree(instance);
+
+ LOG_DBG(" .. OUT\n");
+
+ return 0;
+}
+
+static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream)
+{
+ static VCHI_INSTANCE_T vchi_instance;
+ static VCHI_CONNECTION_T *vchi_connection;
+ static int initted;
+ struct bcm2835_audio_instance *instance =
+ (struct bcm2835_audio_instance *)alsa_stream->instance;
+ int ret;
+ LOG_DBG(" .. IN\n");
+
+ LOG_INFO("%s: start\n", __func__);
+ BUG_ON(instance);
+ if (instance) {
+ LOG_ERR("%s: VCHI instance already open (%p)\n",
+ __func__, instance);
+ instance->alsa_stream = alsa_stream;
+ alsa_stream->instance = instance;
+ ret = 0; // xxx todo -1;
+ goto err_free_mem;
+ }
+
+ /* Initialize and create a VCHI connection */
+ if (!initted) {
+ ret = vchi_initialise(&vchi_instance);
+ if (ret) {
+ LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n",
+ __func__, ret);
+
+ ret = -EIO;
+ goto err_free_mem;
+ }
+ ret = vchi_connect(NULL, 0, vchi_instance);
+ if (ret) {
+ LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n",
+ __func__, ret);
+
+ ret = -EIO;
+ goto err_free_mem;
+ }
+ initted = 1;
+ }
+
+ /* Initialize an instance of the audio service */
+ instance = vc_vchi_audio_init(vchi_instance, &vchi_connection, 1);
+
+ if (!instance) {
+ LOG_ERR("%s: failed to initialize audio service\n", __func__);
+
+ ret = -EPERM;
+ goto err_free_mem;
+ }
+
+ instance->alsa_stream = alsa_stream;
+ alsa_stream->instance = instance;
+
+ LOG_DBG(" success !\n");
+err_free_mem:
+ LOG_DBG(" .. OUT\n");
+
+ return ret;
+}
+
+int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream)
+{
+ struct bcm2835_audio_instance *instance;
+ struct vc_audio_msg m;
+ int status;
+ int ret;
+ LOG_DBG(" .. IN\n");
+
+ my_workqueue_init(alsa_stream);
+
+ ret = bcm2835_audio_open_connection(alsa_stream);
+ if (ret) {
+ ret = -1;
+ goto exit;
+ }
+ instance = alsa_stream->instance;
+ LOG_DBG(" instance (%p)\n", instance);
+
+ if (mutex_lock_interruptible(&instance->vchi_mutex)) {
+ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections);
+ return -EINTR;
+ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ m.type = VC_AUDIO_MSG_TYPE_OPEN;
+
+ /* Send the message to the videocore */
+ status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
+ &m, sizeof(m));
+
+ if (status) {
+ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
+ __func__, status);
+
+ ret = -1;
+ goto unlock;
+ }
+
+ ret = 0;
+
+unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+ mutex_unlock(&instance->vchi_mutex);
+exit:
+ LOG_DBG(" .. OUT\n");
+ return ret;
+}
+
+static int bcm2835_audio_set_ctls_chan(struct bcm2835_alsa_stream *alsa_stream,
+ struct bcm2835_chip *chip)
+{
+ struct vc_audio_msg m;
+ struct bcm2835_audio_instance *instance = alsa_stream->instance;
+ int status;
+ int ret;
+ LOG_DBG(" .. IN\n");
+
+ LOG_INFO(" Setting ALSA dest(%d), volume(%d)\n",
+ chip->dest, chip->volume);
+
+ if (mutex_lock_interruptible(&instance->vchi_mutex)) {
+ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
+ instance->num_connections);
+ return -EINTR;
+ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ instance->result = -1;
+
+ m.type = VC_AUDIO_MSG_TYPE_CONTROL;
+ m.u.control.dest = chip->dest;
+ m.u.control.volume = chip->volume;
+
+ /* Create the message available completion */
+ init_completion(&instance->msg_avail_comp);
+
+ /* Send the message to the videocore */
+ status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
+ &m, sizeof(m));
+
+ if (status) {
+ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
+ __func__, status);
+
+ ret = -1;
+ goto unlock;
+ }
+
+ /* We are expecting a reply from the videocore */
+ wait_for_completion(&instance->msg_avail_comp);
+
+ if (instance->result) {
+ LOG_ERR("%s: result=%d\n", __func__, instance->result);
+
+ ret = -1;
+ goto unlock;
+ }
+
+ ret = 0;
+
+unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+ mutex_unlock(&instance->vchi_mutex);
+
+ LOG_DBG(" .. OUT\n");
+ return ret;
+}
+
+int bcm2835_audio_set_ctls(struct bcm2835_chip *chip)
+{
+ int i;
+ int ret = 0;
+ LOG_DBG(" .. IN\n");
+ LOG_DBG(" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume);
+
+ /* change ctls for all substreams */
+ for (i = 0; i < MAX_SUBSTREAMS; i++) {
+ if (chip->avail_substreams & (1 << i)) {
+ if (!chip->alsa_stream[i]) {
+ LOG_DBG(" No ALSA stream available?! %i:%p (%x)\n", i, chip->alsa_stream[i], chip->avail_substreams);
+ ret = 0;
+ } else if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) {
+ LOG_ERR("Couldn't set the controls for stream %d\n", i);
+ ret = -1;
+ } else LOG_DBG(" Controls set for stream %d\n", i);
+ }
+ }
+ LOG_DBG(" .. OUT ret=%d\n", ret);
+ return ret;
+}
+
+int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream,
+ unsigned int channels, unsigned int samplerate,
+ unsigned int bps)
+{
+ struct vc_audio_msg m;
+ struct bcm2835_audio_instance *instance = alsa_stream->instance;
+ int status;
+ int ret;
+ LOG_DBG(" .. IN\n");
+
+ LOG_INFO(" Setting ALSA channels(%d), samplerate(%d), bits-per-sample(%d)\n",
+ channels, samplerate, bps);
+
+ /* resend ctls - alsa_stream may not have been open when first send */
+ ret = bcm2835_audio_set_ctls_chan(alsa_stream, alsa_stream->chip);
+ if (ret) {
+ LOG_ERR(" Alsa controls not supported\n");
+ return -EINVAL;
+ }
+
+ if (mutex_lock_interruptible(&instance->vchi_mutex)) {
+ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections);
+ return -EINTR;
+ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ instance->result = -1;
+
+ m.type = VC_AUDIO_MSG_TYPE_CONFIG;
+ m.u.config.channels = channels;
+ m.u.config.samplerate = samplerate;
+ m.u.config.bps = bps;
+
+ /* Create the message available completion */
+ init_completion(&instance->msg_avail_comp);
+
+ /* Send the message to the videocore */
+ status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
+ &m, sizeof(m));
+
+ if (status) {
+ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
+ __func__, status);
+
+ ret = -1;
+ goto unlock;
+ }
+
+ /* We are expecting a reply from the videocore */
+ wait_for_completion(&instance->msg_avail_comp);
+
+ if (instance->result) {
+ LOG_ERR("%s: result=%d", __func__, instance->result);
+
+ ret = -1;
+ goto unlock;
+ }
+
+ ret = 0;
+
+unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+ mutex_unlock(&instance->vchi_mutex);
+
+ LOG_DBG(" .. OUT\n");
+ return ret;
+}
+
+int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream)
+{
+ LOG_DBG(" .. IN\n");
+
+ LOG_DBG(" .. OUT\n");
+
+ return 0;
+}
+
+static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream)
+{
+ struct vc_audio_msg m;
+ struct bcm2835_audio_instance *instance = alsa_stream->instance;
+ int status;
+ int ret;
+ LOG_DBG(" .. IN\n");
+
+ if (mutex_lock_interruptible(&instance->vchi_mutex)) {
+ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
+ instance->num_connections);
+ return -EINTR;
+ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ m.type = VC_AUDIO_MSG_TYPE_START;
+
+ /* Send the message to the videocore */
+ status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
+ &m, sizeof(m));
+
+ if (status) {
+ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
+ __func__, status);
+
+ ret = -1;
+ goto unlock;
+ }
+
+ ret = 0;
+
+unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+ mutex_unlock(&instance->vchi_mutex);
+ LOG_DBG(" .. OUT\n");
+ return ret;
+}
+
+static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream)
+{
+ struct vc_audio_msg m;
+ struct bcm2835_audio_instance *instance = alsa_stream->instance;
+ int status;
+ int ret;
+ LOG_DBG(" .. IN\n");
+
+ if (mutex_lock_interruptible(&instance->vchi_mutex)) {
+ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
+ instance->num_connections);
+ return -EINTR;
+ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ m.type = VC_AUDIO_MSG_TYPE_STOP;
+ m.u.stop.draining = alsa_stream->draining;
+
+ /* Send the message to the videocore */
+ status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
+ &m, sizeof(m));
+
+ if (status) {
+ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
+ __func__, status);
+
+ ret = -1;
+ goto unlock;
+ }
+
+ ret = 0;
+
+unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+ mutex_unlock(&instance->vchi_mutex);
+ LOG_DBG(" .. OUT\n");
+ return ret;
+}
+
+int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream)
+{
+ struct vc_audio_msg m;
+ struct bcm2835_audio_instance *instance = alsa_stream->instance;
+ int status;
+ int ret;
+ LOG_DBG(" .. IN\n");
+
+ my_workqueue_quit(alsa_stream);
+
+ if (mutex_lock_interruptible(&instance->vchi_mutex)) {
+ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
+ instance->num_connections);
+ return -EINTR;
+ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ m.type = VC_AUDIO_MSG_TYPE_CLOSE;
+
+ /* Create the message available completion */
+ init_completion(&instance->msg_avail_comp);
+
+ /* Send the message to the videocore */
+ status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
+ &m, sizeof(m));
+
+ if (status) {
+ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
+ __func__, status);
+ ret = -1;
+ goto unlock;
+ }
+
+ /* We are expecting a reply from the videocore */
+ wait_for_completion(&instance->msg_avail_comp);
+
+ if (instance->result) {
+ LOG_ERR("%s: failed result (result=%d)\n",
+ __func__, instance->result);
+
+ ret = -1;
+ goto unlock;
+ }
+
+ ret = 0;
+
+unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+ mutex_unlock(&instance->vchi_mutex);
+
+ /* Stop the audio service */
+ if (instance) {
+ vc_vchi_audio_deinit(instance);
+ alsa_stream->instance = NULL;
+ }
+ LOG_DBG(" .. OUT\n");
+ return ret;
+}
+
+int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream,
+ unsigned int count, void *src)
+{
+ struct vc_audio_msg m;
+ struct bcm2835_audio_instance *instance = alsa_stream->instance;
+ int status;
+ int ret;
+
+ LOG_DBG(" .. IN\n");
+
+ LOG_INFO(" Writing %d bytes from %p\n", count, src);
+
+ if (mutex_lock_interruptible(&instance->vchi_mutex)) {
+ LOG_DBG("Interrupted whilst waiting for lock on (%d)\n",
+ instance->num_connections);
+ return -EINTR;
+ }
+ vchi_service_use(instance->vchi_handle[0]);
+
+ if (instance->peer_version == 0 && vchi_get_peer_version(instance->vchi_handle[0], &instance->peer_version) == 0) {
+ LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version);
+ }
+ m.type = VC_AUDIO_MSG_TYPE_WRITE;
+ m.u.write.count = count;
+ // old version uses bulk, new version uses control
+ m.u.write.max_packet = instance->peer_version < 2 || force_bulk ? 0 : 4000;
+#if defined(CONFIG_64BIT)
+ m.u.write.callbackl = (u32) (((unsigned long) alsa_stream->fifo_irq_handler)&0xFFFFFFFF);
+ m.u.write.callbackh = (u32) ((((unsigned long) alsa_stream->fifo_irq_handler) >> 32)&0xFFFFFFFF);
+#else
+ m.u.write.callback = alsa_stream->fifo_irq_handler;
+ m.u.write.cookie = alsa_stream;
+#endif
+ m.u.write.silence = src == NULL;
+
+ /* Send the message to the videocore */
+ status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
+ &m, sizeof(m));
+
+ if (status) {
+ LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n",
+ __func__, status);
+
+ ret = -1;
+ goto unlock;
+ }
+ if (!m.u.write.silence) {
+ if (!m.u.write.max_packet) {
+ /* Send the message to the videocore */
+ status = vchi_bulk_queue_transmit(instance->vchi_handle[0],
+ src, count,
+ 0 *
+ VCHI_FLAGS_BLOCK_UNTIL_QUEUED
+ +
+ 1 *
+ VCHI_FLAGS_BLOCK_UNTIL_DATA_READ,
+ NULL);
+ } else {
+ while (count > 0) {
+ int bytes = min((int) m.u.write.max_packet, (int) count);
+ status = bcm2835_vchi_msg_queue(instance->vchi_handle[0],
+ src, bytes);
+ src = (char *)src + bytes;
+ count -= bytes;
+ }
+ }
+ if (status) {
+ LOG_ERR("%s: failed on vchi_bulk_queue_transmit (status=%d)\n",
+ __func__, status);
+
+ ret = -1;
+ goto unlock;
+ }
+ }
+ ret = 0;
+
+unlock:
+ vchi_service_release(instance->vchi_handle[0]);
+ mutex_unlock(&instance->vchi_mutex);
+ LOG_DBG(" .. OUT\n");
+ return ret;
+}
+
+/**
+ * Returns all buffers from arm->vc
+ */
+void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream)
+{
+ LOG_DBG(" .. IN\n");
+ LOG_DBG(" .. OUT\n");
+ return;
+}
+
+/**
+ * Forces VC to flush(drop) its filled playback buffers and
+ * return them the us. (VC->ARM)
+ */
+void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream)
+{
+ LOG_DBG(" .. IN\n");
+ LOG_DBG(" .. OUT\n");
+}
+
+unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream)
+{
+ unsigned int count = atomic_read(&alsa_stream->retrieved);
+ atomic_sub(count, &alsa_stream->retrieved);
+ return count;
+}
+
+module_param(force_bulk, bool, 0444);
+MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio");
diff --git a/drivers/staging/bcm2835-audio/bcm2835.c b/drivers/staging/bcm2835-audio/bcm2835.c
new file mode 100644
index 000000000000..9e3b248c7085
--- /dev/null
+++ b/drivers/staging/bcm2835-audio/bcm2835.c
@@ -0,0 +1,519 @@
+/*****************************************************************************
+ * Copyright 2011 Broadcom Corporation. All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available at
+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *****************************************************************************/
+
+#include <linux/platform_device.h>
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include "bcm2835.h"
+
+/* module parameters (see "Module Parameters") */
+/* SNDRV_CARDS: maximum number of cards supported by this module */
+static int index[MAX_SUBSTREAMS] = {[0 ... (MAX_SUBSTREAMS - 1)] = -1};
+static char *id[MAX_SUBSTREAMS] = {[0 ... (MAX_SUBSTREAMS - 1)] = NULL};
+static int enable[MAX_SUBSTREAMS] = {[0 ... (MAX_SUBSTREAMS - 1)] = 1};
+
+/* HACKY global pointers needed for successive probes to work : ssp
+ * But compared against the changes we will have to do in VC audio_ipc code
+ * to export 8 audio_ipc devices as a single IPC device and then monitor all
+ * four devices in a thread, this gets things done quickly and should be easier
+ * to debug if we run into issues
+ */
+
+static struct snd_card *g_card = NULL;
+static struct bcm2835_chip *g_chip = NULL;
+
+static int snd_bcm2835_free(struct bcm2835_chip *chip)
+{
+ kfree(chip);
+ return 0;
+}
+
+/* component-destructor
+ * (see "Management of Cards and Components")
+ */
+static int snd_bcm2835_dev_free(struct snd_device *device)
+{
+ return snd_bcm2835_free(device->device_data);
+}
+
+/* chip-specific constructor
+ * (see "Management of Cards and Components")
+ */
+static int snd_bcm2835_create(struct snd_card *card,
+ struct platform_device *pdev,
+ struct bcm2835_chip ** rchip)
+{
+ struct bcm2835_chip *chip;
+ int err;
+ static struct snd_device_ops ops = {
+ .dev_free = snd_bcm2835_dev_free,
+ };
+
+ *rchip = NULL;
+
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ if (chip == NULL)
+ return -ENOMEM;
+
+ chip->card = card;
+
+ err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ if (err < 0) {
+ snd_bcm2835_free(chip);
+ return err;
+ }
+
+ *rchip = chip;
+ return 0;
+}
+
+static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct bcm2835_chip *chip;
+ struct snd_card *card;
+ u32 numchans;
+ int err, i;
+
+ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels",
+ &numchans);
+ if (err) {
+ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'");
+ return err;
+ }
+
+ if (numchans == 0 || numchans > MAX_SUBSTREAMS) {
+ numchans = MAX_SUBSTREAMS;
+ dev_warn(dev, "Illegal 'brcm,pwm-channels' value, will use %u\n",
+ numchans);
+ }
+
+ err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card);
+ if (err) {
+ dev_err(dev, "Failed to create soundcard structure\n");
+ return err;
+ }
+
+ snd_card_set_dev(card, dev);
+ strcpy(card->driver, "bcm2835");
+ strcpy(card->shortname, "bcm2835 ALSA");
+ sprintf(card->longname, "%s", card->shortname);
+
+ err = snd_bcm2835_create(card, pdev, &chip);
+ if (err < 0) {
+ dev_err(dev, "Failed to create bcm2835 chip\n");
+ goto err_free;
+ }
+
+ err = snd_bcm2835_new_pcm(chip);
+ if (err < 0) {
+ dev_err(dev, "Failed to create new bcm2835 pcm device\n");
+ goto err_free;
+ }
+
+ err = snd_bcm2835_new_spdif_pcm(chip);
+ if (err < 0) {
+ dev_err(dev, "Failed to create new bcm2835 spdif pcm device\n");
+ goto err_free;
+ }
+
+ err = snd_bcm2835_new_ctl(chip);
+ if (err < 0) {
+ dev_err(dev, "Failed to create new bcm2835 ctl\n");
+ goto err_free;
+ }
+
+ for (i = 0; i < numchans; i++) {
+ chip->avail_substreams |= (1 << i);
+ chip->pdev[i] = pdev;
+ }
+
+ err = snd_card_register(card);
+ if (err) {
+ dev_err(dev, "Failed to register bcm2835 ALSA card \n");
+ goto err_free;
+ }
+
+ g_card = card;
+ g_chip = chip;
+ platform_set_drvdata(pdev, card);
+ audio_info("bcm2835 ALSA card created with %u channels\n", numchans);
+
+ return 0;
+
+err_free:
+ snd_card_free(card);
+
+ return err;
+}
+
+static int snd_bcm2835_alsa_probe(struct platform_device *pdev)
+{
+ static int dev;
+ struct bcm2835_chip *chip;
+ struct snd_card *card;
+ int err;
+
+ if (pdev->dev.of_node)
+ return snd_bcm2835_alsa_probe_dt(pdev);
+
+ if (dev >= MAX_SUBSTREAMS)
+ return -ENODEV;
+
+ if (!enable[dev]) {
+ dev++;
+ return -ENOENT;
+ }
+
+ if (dev > 0)
+ goto add_register_map;
+
+ err = snd_card_new(&pdev->dev, index[dev], id[dev], THIS_MODULE, 0, &g_card);
+ if (err < 0)
+ goto out;
+
+ snd_card_set_dev(g_card, &pdev->dev);
+ strcpy(g_card->driver, "bcm2835");
+ strcpy(g_card->shortname, "bcm2835 ALSA");
+ sprintf(g_card->longname, "%s", g_card->shortname);
+
+ err = snd_bcm2835_create(g_card, pdev, &chip);
+ if (err < 0) {
+ dev_err(&pdev->dev, "Failed to create bcm2835 chip\n");
+ goto out_bcm2835_create;
+ }
+
+ g_chip = chip;
+ err = snd_bcm2835_new_pcm(chip);
+ if (err < 0) {
+ dev_err(&pdev->dev, "Failed to create new BCM2835 pcm device\n");
+ goto out_bcm2835_new_pcm;
+ }
+
+ err = snd_bcm2835_new_spdif_pcm(chip);
+ if (err < 0) {
+ dev_err(&pdev->dev, "Failed to create new BCM2835 spdif pcm device\n");
+ goto out_bcm2835_new_spdif;
+ }
+
+ err = snd_bcm2835_new_ctl(chip);
+ if (err < 0) {
+ dev_err(&pdev->dev, "Failed to create new BCM2835 ctl\n");
+ goto out_bcm2835_new_ctl;
+ }
+
+add_register_map:
+ card = g_card;
+ chip = g_chip;
+
+ BUG_ON(!(card && chip));
+
+ chip->avail_substreams |= (1 << dev);
+ chip->pdev[dev] = pdev;
+
+ if (!dev) {
+ err = snd_card_register(card);
+ if (err < 0) {
+ dev_err(&pdev->dev,
+ "Failed to register bcm2835 ALSA card \n");
+ goto out_card_register;
+ }
+ platform_set_drvdata(pdev, card);
+ audio_info("bcm2835 ALSA card created!\n");
+ } else {
+ audio_info("bcm2835 ALSA chip created!\n");
+ platform_set_drvdata(pdev, (void*)(long)dev);
+ }
+
+ dev++;
+
+ return 0;
+
+out_card_register:
+ out_bcm2835_new_ctl :
+ out_bcm2835_new_spdif :
+ out_bcm2835_new_pcm :
+ out_bcm2835_create :
+ BUG_ON(!g_card);
+ if (snd_card_free(g_card))
+ dev_err(&pdev->dev, "Failed to free Registered alsa card\n");
+ g_card = NULL;
+out:
+ dev = SNDRV_CARDS; /* stop more avail_substreams from being probed */
+ dev_err(&pdev->dev, "BCM2835 ALSA Probe failed !!\n");
+ return err;
+}
+
+static int snd_bcm2835_alsa_remove(struct platform_device *pdev)
+{
+ int idx;
+ void *drv_data;
+
+ drv_data = platform_get_drvdata(pdev);
+
+ if (drv_data == (void *) g_card) {
+ /* This is the card device */
+ snd_card_free((struct snd_card *)drv_data);
+ g_card = NULL;
+ g_chip = NULL;
+ } else {
+ idx = (int)(long)drv_data;
+ if (g_card) {
+ BUG_ON(!g_chip);
+ /* We pass chip device numbers in audio ipc devices
+ * other than the one we registered our card with
+ */
+ idx = (int)(long)drv_data;
+ BUG_ON(!idx || idx > MAX_SUBSTREAMS);
+ g_chip->avail_substreams &= ~(1 << idx);
+ /* There should be atleast one substream registered
+ * after we are done here, as it wil be removed when
+ * the *remove* is called for the card device
+ */
+ BUG_ON(!g_chip->avail_substreams);
+ }
+ }
+
+ platform_set_drvdata(pdev, NULL);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int snd_bcm2835_alsa_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ return 0;
+}
+
+static int snd_bcm2835_alsa_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+
+#endif
+
+static const struct of_device_id snd_bcm2835_of_match_table[] = {
+ { .compatible = "brcm,bcm2835-audio",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table);
+
+static struct platform_driver bcm2835_alsa0_driver = {
+ .probe = snd_bcm2835_alsa_probe,
+ .remove = snd_bcm2835_alsa_remove,
+#ifdef CONFIG_PM
+ .suspend = snd_bcm2835_alsa_suspend,
+ .resume = snd_bcm2835_alsa_resume,
+#endif
+ .driver =
+ {
+ .name = "bcm2835_AUD0",
+ .owner = THIS_MODULE,
+ .of_match_table = snd_bcm2835_of_match_table,
+ },
+};
+
+static struct platform_driver bcm2835_alsa1_driver = {
+ .probe = snd_bcm2835_alsa_probe,
+ .remove = snd_bcm2835_alsa_remove,
+#ifdef CONFIG_PM
+ .suspend = snd_bcm2835_alsa_suspend,
+ .resume = snd_bcm2835_alsa_resume,
+#endif
+ .driver =
+ {
+ .name = "bcm2835_AUD1",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver bcm2835_alsa2_driver = {
+ .probe = snd_bcm2835_alsa_probe,
+ .remove = snd_bcm2835_alsa_remove,
+#ifdef CONFIG_PM
+ .suspend = snd_bcm2835_alsa_suspend,
+ .resume = snd_bcm2835_alsa_resume,
+#endif
+ .driver =
+ {
+ .name = "bcm2835_AUD2",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver bcm2835_alsa3_driver = {
+ .probe = snd_bcm2835_alsa_probe,
+ .remove = snd_bcm2835_alsa_remove,
+#ifdef CONFIG_PM
+ .suspend = snd_bcm2835_alsa_suspend,
+ .resume = snd_bcm2835_alsa_resume,
+#endif
+ .driver =
+ {
+ .name = "bcm2835_AUD3",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver bcm2835_alsa4_driver = {
+ .probe = snd_bcm2835_alsa_probe,
+ .remove = snd_bcm2835_alsa_remove,
+#ifdef CONFIG_PM
+ .suspend = snd_bcm2835_alsa_suspend,
+ .resume = snd_bcm2835_alsa_resume,
+#endif
+ .driver =
+ {
+ .name = "bcm2835_AUD4",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver bcm2835_alsa5_driver = {
+ .probe = snd_bcm2835_alsa_probe,
+ .remove = snd_bcm2835_alsa_remove,
+#ifdef CONFIG_PM
+ .suspend = snd_bcm2835_alsa_suspend,
+ .resume = snd_bcm2835_alsa_resume,
+#endif
+ .driver =
+ {
+ .name = "bcm2835_AUD5",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver bcm2835_alsa6_driver = {
+ .probe = snd_bcm2835_alsa_probe,
+ .remove = snd_bcm2835_alsa_remove,
+#ifdef CONFIG_PM
+ .suspend = snd_bcm2835_alsa_suspend,
+ .resume = snd_bcm2835_alsa_resume,
+#endif
+ .driver =
+ {
+ .name = "bcm2835_AUD6",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver bcm2835_alsa7_driver = {
+ .probe = snd_bcm2835_alsa_probe,
+ .remove = snd_bcm2835_alsa_remove,
+#ifdef CONFIG_PM
+ .suspend = snd_bcm2835_alsa_suspend,
+ .resume = snd_bcm2835_alsa_resume,
+#endif
+ .driver =
+ {
+ .name = "bcm2835_AUD7",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int bcm2835_alsa_device_init(void)
+{
+ int err;
+ err = platform_driver_register(&bcm2835_alsa0_driver);
+ if (err) {
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
+ goto out;
+ }
+
+ err = platform_driver_register(&bcm2835_alsa1_driver);
+ if (err) {
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
+ goto unregister_0;
+ }
+
+ err = platform_driver_register(&bcm2835_alsa2_driver);
+ if (err) {
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
+ goto unregister_1;
+ }
+
+ err = platform_driver_register(&bcm2835_alsa3_driver);
+ if (err) {
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
+ goto unregister_2;
+ }
+
+ err = platform_driver_register(&bcm2835_alsa4_driver);
+ if (err) {
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
+ goto unregister_3;
+ }
+
+ err = platform_driver_register(&bcm2835_alsa5_driver);
+ if (err) {
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
+ goto unregister_4;
+ }
+
+ err = platform_driver_register(&bcm2835_alsa6_driver);
+ if (err) {
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
+ goto unregister_5;
+ }
+
+ err = platform_driver_register(&bcm2835_alsa7_driver);
+ if (err) {
+ pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
+ goto unregister_6;
+ }
+
+ return 0;
+
+unregister_6:
+ platform_driver_unregister(&bcm2835_alsa6_driver);
+unregister_5:
+ platform_driver_unregister(&bcm2835_alsa5_driver);
+unregister_4:
+ platform_driver_unregister(&bcm2835_alsa4_driver);
+unregister_3:
+ platform_driver_unregister(&bcm2835_alsa3_driver);
+unregister_2:
+ platform_driver_unregister(&bcm2835_alsa2_driver);
+unregister_1:
+ platform_driver_unregister(&bcm2835_alsa1_driver);
+unregister_0:
+ platform_driver_unregister(&bcm2835_alsa0_driver);
+out:
+ return err;
+}
+
+static void bcm2835_alsa_device_exit(void)
+{
+ platform_driver_unregister(&bcm2835_alsa0_driver);
+ platform_driver_unregister(&bcm2835_alsa1_driver);
+ platform_driver_unregister(&bcm2835_alsa2_driver);
+ platform_driver_unregister(&bcm2835_alsa3_driver);
+ platform_driver_unregister(&bcm2835_alsa4_driver);
+ platform_driver_unregister(&bcm2835_alsa5_driver);
+ platform_driver_unregister(&bcm2835_alsa6_driver);
+ platform_driver_unregister(&bcm2835_alsa7_driver);
+}
+
+late_initcall(bcm2835_alsa_device_init);
+module_exit(bcm2835_alsa_device_exit);
+
+MODULE_AUTHOR("Dom Cobley");
+MODULE_DESCRIPTION("Alsa driver for BCM2835 chip");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/bcm2835-audio/bcm2835.h b/drivers/staging/bcm2835-audio/bcm2835.h
new file mode 100644
index 000000000000..d333629e93e5
--- /dev/null
+++ b/drivers/staging/bcm2835-audio/bcm2835.h
@@ -0,0 +1,169 @@
+/*****************************************************************************
+ * Copyright 2011 Broadcom Corporation. All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available at
+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *****************************************************************************/
+
+#ifndef __SOUND_ARM_BCM2835_H
+#define __SOUND_ARM_BCM2835_H
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/pcm-indirect.h>
+#include <linux/workqueue.h>
+
+/*
+#define AUDIO_DEBUG_ENABLE
+#define AUDIO_VERBOSE_DEBUG_ENABLE
+ */
+
+/* Debug macros */
+
+#ifdef AUDIO_DEBUG_ENABLE
+#ifdef AUDIO_VERBOSE_DEBUG_ENABLE
+
+#define audio_debug(fmt, arg...) \
+ printk(KERN_INFO"%s:%d " fmt, __func__, __LINE__, ##arg)
+
+#define audio_info(fmt, arg...) \
+ printk(KERN_INFO"%s:%d " fmt, __func__, __LINE__, ##arg)
+
+#else
+
+#define audio_debug(fmt, arg...)
+
+#define audio_info(fmt, arg...)
+
+#endif /* AUDIO_VERBOSE_DEBUG_ENABLE */
+
+#else
+
+#define audio_debug(fmt, arg...)
+
+#define audio_info(fmt, arg...)
+
+#endif /* AUDIO_DEBUG_ENABLE */
+
+#define audio_error(fmt, arg...) \
+ printk(KERN_ERR"%s:%d " fmt, __func__, __LINE__, ##arg)
+
+#define audio_warning(fmt, arg...) \
+ printk(KERN_WARNING"%s:%d " fmt, __func__, __LINE__, ##arg)
+
+#define audio_alert(fmt, arg...) \
+ printk(KERN_ALERT"%s:%d " fmt, __func__, __LINE__, ##arg)
+
+#define MAX_SUBSTREAMS (8)
+#define AVAIL_SUBSTREAMS_MASK (0xff)
+
+enum {
+ CTRL_VOL_MUTE,
+ CTRL_VOL_UNMUTE
+};
+
+/* macros for alsa2chip and chip2alsa, instead of functions */
+
+#define alsa2chip(vol) (uint)(-((vol << 8) / 100)) /* convert alsa to chip volume (defined as macro rather than function call) */
+#define chip2alsa(vol) -((vol * 100) >> 8) /* convert chip to alsa volume */
+
+/* Some constants for values .. */
+enum snd_bcm2835_route {
+ AUDIO_DEST_AUTO = 0,
+ AUDIO_DEST_HEADPHONES = 1,
+ AUDIO_DEST_HDMI = 2,
+ AUDIO_DEST_MAX,
+};
+
+enum snd_bcm2835_ctrl {
+ PCM_PLAYBACK_VOLUME,
+ PCM_PLAYBACK_MUTE,
+ PCM_PLAYBACK_DEVICE,
+};
+
+/* definition of the chip-specific record */
+struct bcm2835_chip {
+ struct snd_card *card;
+ struct snd_pcm *pcm;
+ struct snd_pcm *pcm_spdif;
+ /* Bitmat for valid reg_base and irq numbers */
+ unsigned int avail_substreams;
+ struct platform_device *pdev[MAX_SUBSTREAMS];
+ struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS];
+
+ int volume;
+ int old_volume; /* stores the volume value whist muted */
+ int dest;
+ int mute;
+
+ unsigned int opened;
+ unsigned int spdif_status;
+ struct mutex audio_mutex;
+};
+
+struct bcm2835_alsa_stream {
+ struct bcm2835_chip *chip;
+ struct snd_pcm_substream *substream;
+ struct snd_pcm_indirect pcm_indirect;
+
+ struct semaphore buffers_update_sem;
+ struct semaphore control_sem;
+ spinlock_t lock;
+ volatile unsigned int control;
+ volatile unsigned int status;
+
+ int open;
+ int running;
+ int draining;
+
+ int channels;
+ int params_rate;
+ int pcm_format_width;
+
+ unsigned int pos;
+ unsigned int buffer_size;
+ unsigned int period_size;
+
+ unsigned int enable_fifo_irq;
+ irq_handler_t fifo_irq_handler;
+
+ atomic_t retrieved;
+ struct bcm2835_audio_instance *instance;
+ struct workqueue_struct *my_wq;
+ int idx;
+};
+
+int snd_bcm2835_new_ctl(struct bcm2835_chip *chip);
+int snd_bcm2835_new_pcm(struct bcm2835_chip *chip);
+int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip);
+
+int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream);
+int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream);
+int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream,
+ unsigned int channels, unsigned int samplerate,
+ unsigned int bps);
+int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream);
+int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream);
+int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream);
+int bcm2835_audio_set_ctls(struct bcm2835_chip *chip);
+int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
+ unsigned int count,
+ void *src);
+unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream);
+void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream);
+void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream);
+
+#endif /* __SOUND_ARM_BCM2835_H */
diff --git a/drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h b/drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h
new file mode 100644
index 000000000000..2cc81f062274
--- /dev/null
+++ b/drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * Copyright 2011 Broadcom Corporation. All rights reserved.
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2, available at
+ * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a
+ * license other than the GPL, without Broadcom's express prior written
+ * consent.
+ *****************************************************************************/
+
+#ifndef _VC_AUDIO_DEFS_H_
+#define _VC_AUDIO_DEFS_H_
+
+#define VC_AUDIOSERV_MIN_VER 1
+#define VC_AUDIOSERV_VER 2
+
+/* FourCC code used for VCHI connection */
+#define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS")
+
+/* Maximum message length */
+#define VC_AUDIO_MAX_MSG_LEN (sizeof( VC_AUDIO_MSG_T ))
+
+/*
+ * List of screens that are currently supported
+ * All message types supported for HOST->VC direction
+ */
+
+enum vc_audio_msg_type {
+ VC_AUDIO_MSG_TYPE_RESULT, // Generic result
+ VC_AUDIO_MSG_TYPE_COMPLETE, // Generic result
+ VC_AUDIO_MSG_TYPE_CONFIG, // Configure audio
+ VC_AUDIO_MSG_TYPE_CONTROL, // Configure audio
+ VC_AUDIO_MSG_TYPE_OPEN, // Configure audio
+ VC_AUDIO_MSG_TYPE_CLOSE, // Configure audio
+ VC_AUDIO_MSG_TYPE_START, // Configure audio
+ VC_AUDIO_MSG_TYPE_STOP, // Configure audio
+ VC_AUDIO_MSG_TYPE_WRITE, // Configure audio
+ VC_AUDIO_MSG_TYPE_MAX
+};
+
+/* configure the audio */
+
+struct vc_audio_config {
+ u32 channels;
+ u32 samplerate;
+ u32 bps;
+};
+
+struct vc_audio_control {
+ u32 volume;
+ u32 dest;
+};
+
+struct vc_audio_open {
+ u32 dummy;
+};
+
+struct vc_audio_close {
+ u32 dummy;
+};
+
+struct vc_audio_start {
+ u32 dummy;
+};
+
+struct vc_audio_stop {
+ u32 draining;
+};
+
+/* configure the write audio samples */
+struct vc_audio_write {
+ u32 count; // in bytes
+#if defined(CONFIG_64BIT)
+ u32 callbackl;
+ u32 callbackh;
+#else
+ void *callback;
+ void *cookie;
+#endif
+ s16 silence;
+ s16 max_packet;
+};
+
+/* Generic result for a request (VC->HOST) */
+struct vc_audio_result {
+ s32 success; // Success value
+};
+
+/* Generic result for a request (VC->HOST) */
+struct vc_audio_complete {
+ s32 count; // Success value
+#if defined(CONFIG_64BIT)
+ u32 callbackl;
+ u32 callbackh;
+#else
+ void *callback;
+ void *cookie;
+#endif
+};
+
+/* Message header for all messages in HOST->VC direction */
+struct vc_audio_msg {
+ s32 type; /* Message type (VC_AUDIO_MSG_TYPE) */
+ union {
+ struct vc_audio_config config;
+ struct vc_audio_control control;
+ struct vc_audio_open open;
+ struct vc_audio_close close;
+ struct vc_audio_start start;
+ struct vc_audio_stop stop;
+ struct vc_audio_write write;
+ struct vc_audio_result result;
+ struct vc_audio_complete complete;
+ } u;
+};
+
+#endif /* _VC_AUDIO_DEFS_H_ */
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index e7255f811611..942507754cab 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -1025,7 +1025,7 @@ config COMEDI_NI_660X
select COMEDI_NI_TIOCMD
---help---
Enable support for National Instruments PCI-6601 (ni_660x), PCI-6602,
- PXI-6602, PXI-6608 and PXI-6624.
+ PXI-6602, PXI-6608, PCI-6624, and PXI-6624.
To compile this driver as a module, choose M here: the module will be
called ni_660x.
@@ -1070,9 +1070,11 @@ config COMEDI_NI_PCIMIO
PCI-MIO-16E-4, PCI-6014, PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E,
PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E,
PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E, PCI-6110, PCI-6111,
- PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225, PCI-6229,
- PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259,
- PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289, PCI-6711, PXI-6711,
+ PCI-6220, PXI-6220, PCI-6221, PXI-6221, PCI-6224, PXI-6224, PCI-6225,
+ PXI-6225, PCI-6229, PXI-6229, PCI-6250, PXI-6250, PCI-6251, PXI-6251,
+ PCIe-6251, PXIe-6251, PCI-6254, PXI-6254, PCI-6259, PXI-6259,
+ PCIe-6259, PXIe-6259, PCI-6280, PXI-6280, PCI-6281, PXI-6281,
+ PCI-6284, PXI-6284, PCI-6289, PXI-6289, PCI-6711, PXI-6711,
PCI-6713, PXI-6713, PXI-6071E, PCI-6070E, PXI-6070E, PXI-6052E,
PCI-6036E, PCI-6731, PCI-6733, PXI-6733, PCI-6143, PXI-6143
diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h
index 5ce77f3e8c22..0127c1f98bbf 100644
--- a/drivers/staging/comedi/comedi_compat32.h
+++ b/drivers/staging/comedi/comedi_compat32.h
@@ -25,7 +25,8 @@
#ifdef CONFIG_COMPAT
struct file;
-long comedi_compat_ioctl(struct file *, unsigned int cmd, unsigned long arg);
+long comedi_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg);
#else /* CONFIG_COMPAT */
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 64b3966c5f1f..57e8599b54e6 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -28,15 +28,11 @@
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/kmod.h>
#include <linux/poll.h>
-#include <linux/init.h>
#include <linux/device.h>
-#include <linux/vmalloc.h>
#include <linux/fs.h>
#include "comedidev.h"
#include <linux/cdev.h>
-#include <linux/stat.h>
#include <linux/io.h>
#include <linux/uaccess.h>
@@ -2898,9 +2894,6 @@ static int __init comedi_init(void)
comedi_class->dev_groups = comedi_dev_groups;
- /* XXX requires /proc interface */
- comedi_proc_init();
-
/* create devices files for legacy/manual use */
for (i = 0; i < comedi_num_legacy_minors; i++) {
struct comedi_device *dev;
@@ -2917,6 +2910,9 @@ static int __init comedi_init(void)
mutex_unlock(&dev->mutex);
}
+ /* XXX requires /proc interface */
+ comedi_proc_init();
+
return 0;
}
module_init(comedi_init);
diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h
index 3f2c88ae6470..534415e331b6 100644
--- a/drivers/staging/comedi/comedi_internal.h
+++ b/drivers/staging/comedi/comedi_internal.h
@@ -44,11 +44,12 @@ extern unsigned int comedi_default_buf_maxsize_kb;
extern struct comedi_driver *comedi_drivers;
extern struct mutex comedi_drivers_list_lock;
-int insn_inval(struct comedi_device *, struct comedi_subdevice *,
- struct comedi_insn *, unsigned int *);
+int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
-void comedi_device_detach(struct comedi_device *);
-int comedi_device_attach(struct comedi_device *, struct comedi_devconfig *);
+void comedi_device_detach(struct comedi_device *dev);
+int comedi_device_attach(struct comedi_device *dev,
+ struct comedi_devconfig *it);
#ifdef CONFIG_PROC_FS
diff --git a/drivers/staging/comedi/comedi_pci.h b/drivers/staging/comedi/comedi_pci.h
index 4005cc9cf7f1..7dfd892c74b0 100644
--- a/drivers/staging/comedi/comedi_pci.h
+++ b/drivers/staging/comedi/comedi_pci.h
@@ -34,18 +34,20 @@
#define PCI_VENDOR_ID_RTD 0x1435
#define PCI_VENDOR_ID_HUMUSOFT 0x186c
-struct pci_dev *comedi_to_pci_dev(struct comedi_device *);
+struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev);
-int comedi_pci_enable(struct comedi_device *);
-void comedi_pci_disable(struct comedi_device *);
-void comedi_pci_detach(struct comedi_device *);
+int comedi_pci_enable(struct comedi_device *dev);
+void comedi_pci_disable(struct comedi_device *dev);
+void comedi_pci_detach(struct comedi_device *dev);
-int comedi_pci_auto_config(struct pci_dev *, struct comedi_driver *,
+int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver,
unsigned long context);
-void comedi_pci_auto_unconfig(struct pci_dev *);
+void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
-int comedi_pci_driver_register(struct comedi_driver *, struct pci_driver *);
-void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *);
+int comedi_pci_driver_register(struct comedi_driver *comedi_driver,
+ struct pci_driver *pci_driver);
+void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver,
+ struct pci_driver *pci_driver);
/**
* module_comedi_pci_driver() - Helper macro for registering a comedi PCI driver
diff --git a/drivers/staging/comedi/comedi_pcmcia.c b/drivers/staging/comedi/comedi_pcmcia.c
index d7072a5c1647..cd4742851c08 100644
--- a/drivers/staging/comedi/comedi_pcmcia.c
+++ b/drivers/staging/comedi/comedi_pcmcia.c
@@ -78,7 +78,8 @@ static int comedi_pcmcia_conf_check(struct pcmcia_device *link,
* or a negative error number from pcmcia_enable_device() if it fails.
*/
int comedi_pcmcia_enable(struct comedi_device *dev,
- int (*conf_check)(struct pcmcia_device *, void *))
+ int (*conf_check)(struct pcmcia_device *p_dev,
+ void *priv_data))
{
struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
int ret;
diff --git a/drivers/staging/comedi/comedi_pcmcia.h b/drivers/staging/comedi/comedi_pcmcia.h
index 5a572c200a8b..9e45c7c93278 100644
--- a/drivers/staging/comedi/comedi_pcmcia.h
+++ b/drivers/staging/comedi/comedi_pcmcia.h
@@ -24,19 +24,21 @@
#include "comedidev.h"
-struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *);
+struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *dev);
-int comedi_pcmcia_enable(struct comedi_device *,
- int (*conf_check)(struct pcmcia_device *, void *));
-void comedi_pcmcia_disable(struct comedi_device *);
+int comedi_pcmcia_enable(struct comedi_device *dev,
+ int (*conf_check)(struct pcmcia_device *p_dev,
+ void *priv_data));
+void comedi_pcmcia_disable(struct comedi_device *dev);
-int comedi_pcmcia_auto_config(struct pcmcia_device *, struct comedi_driver *);
-void comedi_pcmcia_auto_unconfig(struct pcmcia_device *);
+int comedi_pcmcia_auto_config(struct pcmcia_device *link,
+ struct comedi_driver *driver);
+void comedi_pcmcia_auto_unconfig(struct pcmcia_device *link);
-int comedi_pcmcia_driver_register(struct comedi_driver *,
- struct pcmcia_driver *);
-void comedi_pcmcia_driver_unregister(struct comedi_driver *,
- struct pcmcia_driver *);
+int comedi_pcmcia_driver_register(struct comedi_driver *comedi_driver,
+ struct pcmcia_driver *pcmcia_driver);
+void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver,
+ struct pcmcia_driver *pcmcia_driver);
/**
* module_comedi_pcmcia_driver() - Helper macro for registering a comedi
diff --git a/drivers/staging/comedi/comedi_usb.h b/drivers/staging/comedi/comedi_usb.h
index 721128bece3c..132154ec792f 100644
--- a/drivers/staging/comedi/comedi_usb.h
+++ b/drivers/staging/comedi/comedi_usb.h
@@ -23,15 +23,17 @@
#include "comedidev.h"
-struct usb_interface *comedi_to_usb_interface(struct comedi_device *);
-struct usb_device *comedi_to_usb_dev(struct comedi_device *);
+struct usb_interface *comedi_to_usb_interface(struct comedi_device *dev);
+struct usb_device *comedi_to_usb_dev(struct comedi_device *dev);
-int comedi_usb_auto_config(struct usb_interface *, struct comedi_driver *,
- unsigned long context);
-void comedi_usb_auto_unconfig(struct usb_interface *);
+int comedi_usb_auto_config(struct usb_interface *intf,
+ struct comedi_driver *driver, unsigned long context);
+void comedi_usb_auto_unconfig(struct usb_interface *intf);
-int comedi_usb_driver_register(struct comedi_driver *, struct usb_driver *);
-void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *);
+int comedi_usb_driver_register(struct comedi_driver *comedi_driver,
+ struct usb_driver *usb_driver);
+void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver,
+ struct usb_driver *usb_driver);
/**
* module_comedi_usb_driver() - Helper macro for registering a comedi USB driver
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index 0c7c37a8ff33..1bb9986f865e 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -612,12 +612,6 @@ extern const struct comedi_lrange range_unknown;
#define range_digital range_unipolar5
-#if __GNUC__ >= 3
-#define GCC_ZERO_LENGTH_ARRAY
-#else
-#define GCC_ZERO_LENGTH_ARRAY 0
-#endif
-
/**
* struct comedi_lrange - Describes a COMEDI range table
* @length: Number of entries in the range table.
@@ -631,7 +625,7 @@ extern const struct comedi_lrange range_unknown;
*/
struct comedi_lrange {
int length;
- struct comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
+ struct comedi_krange range[];
};
/**
@@ -982,19 +976,21 @@ unsigned int comedi_buf_read_samples(struct comedi_subdevice *s,
#define COMEDI_TIMEOUT_MS 1000
-int comedi_timeout(struct comedi_device *, struct comedi_subdevice *,
- struct comedi_insn *,
- int (*cb)(struct comedi_device *, struct comedi_subdevice *,
- struct comedi_insn *, unsigned long context),
+int comedi_timeout(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ int (*cb)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned long context),
unsigned long context);
unsigned int comedi_handle_events(struct comedi_device *dev,
struct comedi_subdevice *s);
-int comedi_dio_insn_config(struct comedi_device *, struct comedi_subdevice *,
- struct comedi_insn *, unsigned int *data,
+int comedi_dio_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data,
unsigned int mask);
-unsigned int comedi_dio_update_state(struct comedi_subdevice *,
+unsigned int comedi_dio_update_state(struct comedi_subdevice *s,
unsigned int *data);
unsigned int comedi_bytes_per_scan(struct comedi_subdevice *s);
unsigned int comedi_nscans_left(struct comedi_subdevice *s,
@@ -1004,32 +1000,33 @@ unsigned int comedi_nsamples_left(struct comedi_subdevice *s,
void comedi_inc_scan_progress(struct comedi_subdevice *s,
unsigned int num_bytes);
-void *comedi_alloc_devpriv(struct comedi_device *, size_t);
-int comedi_alloc_subdevices(struct comedi_device *, int);
-int comedi_alloc_subdev_readback(struct comedi_subdevice *);
+void *comedi_alloc_devpriv(struct comedi_device *dev, size_t size);
+int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices);
+int comedi_alloc_subdev_readback(struct comedi_subdevice *s);
-int comedi_readback_insn_read(struct comedi_device *, struct comedi_subdevice *,
- struct comedi_insn *, unsigned int *data);
+int comedi_readback_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
-int comedi_load_firmware(struct comedi_device *, struct device *,
+int comedi_load_firmware(struct comedi_device *dev, struct device *hw_dev,
const char *name,
- int (*cb)(struct comedi_device *,
+ int (*cb)(struct comedi_device *dev,
const u8 *data, size_t size,
unsigned long context),
unsigned long context);
-int __comedi_request_region(struct comedi_device *,
+int __comedi_request_region(struct comedi_device *dev,
unsigned long start, unsigned long len);
-int comedi_request_region(struct comedi_device *,
+int comedi_request_region(struct comedi_device *dev,
unsigned long start, unsigned long len);
-void comedi_legacy_detach(struct comedi_device *);
+void comedi_legacy_detach(struct comedi_device *dev);
-int comedi_auto_config(struct device *, struct comedi_driver *,
- unsigned long context);
-void comedi_auto_unconfig(struct device *);
+int comedi_auto_config(struct device *hardware_device,
+ struct comedi_driver *driver, unsigned long context);
+void comedi_auto_unconfig(struct device *hardware_device);
-int comedi_driver_register(struct comedi_driver *);
-void comedi_driver_unregister(struct comedi_driver *);
+int comedi_driver_register(struct comedi_driver *driver);
+void comedi_driver_unregister(struct comedi_driver *driver);
/**
* module_comedi_driver() - Helper macro for registering a comedi driver
diff --git a/drivers/staging/comedi/drivers/addi_watchdog.h b/drivers/staging/comedi/drivers/addi_watchdog.h
index 3f8e7388bbca..b049cfba9813 100644
--- a/drivers/staging/comedi/drivers/addi_watchdog.h
+++ b/drivers/staging/comedi/drivers/addi_watchdog.h
@@ -4,6 +4,6 @@
struct comedi_subdevice;
void addi_watchdog_reset(unsigned long iobase);
-int addi_watchdog_init(struct comedi_subdevice *, unsigned long iobase);
+int addi_watchdog_init(struct comedi_subdevice *s, unsigned long iobase);
#endif
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index cb9c2699277e..efbf27730d71 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -238,7 +238,7 @@ enum daq_atrig_low_4020_contents {
EXT_START_TRIG_BNC_BIT = 0x2000,
};
-static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold)
+static inline u16 analog_trig_low_threshold_bits(u16 threshold)
{
return threshold & 0xfff;
}
@@ -280,17 +280,17 @@ enum adc_control1_contents {
ADC_MODE_MASK = 0xf000,
};
-static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel)
+static inline u16 adc_lo_chan_4020_bits(unsigned int channel)
{
return (channel & 0x3) << 8;
};
-static inline uint16_t adc_hi_chan_4020_bits(unsigned int channel)
+static inline u16 adc_hi_chan_4020_bits(unsigned int channel)
{
return (channel & 0x3) << 10;
};
-static inline uint16_t adc_mode_bits(unsigned int mode)
+static inline u16 adc_mode_bits(unsigned int mode)
{
return (mode & 0xf) << 12;
};
@@ -318,12 +318,12 @@ enum calibration_contents {
* 7 : dac channel 1
*/
-static inline uint16_t adc_src_bits(unsigned int source)
+static inline u16 adc_src_bits(unsigned int source)
{
return (source & 0xf) << 3;
};
-static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel)
+static inline u16 adc_convert_chan_4020_bits(unsigned int channel)
{
return (channel & 0x3) << 8;
};
@@ -337,7 +337,7 @@ enum adc_queue_load_contents {
QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */
};
-static inline uint16_t adc_chan_bits(unsigned int channel)
+static inline u16 adc_chan_bits(unsigned int channel)
{
return channel & 0x3f;
};
@@ -384,22 +384,22 @@ enum hw_status_contents {
ADC_STOP_BIT = 0x200,
};
-static inline uint16_t pipe_full_bits(uint16_t hw_status_bits)
+static inline u16 pipe_full_bits(u16 hw_status_bits)
{
return (hw_status_bits >> 10) & 0x3;
};
-static inline unsigned int dma_chain_flag_bits(uint16_t prepost_bits)
+static inline unsigned int dma_chain_flag_bits(u16 prepost_bits)
{
return (prepost_bits >> 6) & 0x3;
}
-static inline unsigned int adc_upper_read_ptr_code(uint16_t prepost_bits)
+static inline unsigned int adc_upper_read_ptr_code(u16 prepost_bits)
{
return (prepost_bits >> 12) & 0x3;
}
-static inline unsigned int adc_upper_write_ptr_code(uint16_t prepost_bits)
+static inline unsigned int adc_upper_write_ptr_code(u16 prepost_bits)
{
return (prepost_bits >> 14) & 0x3;
}
@@ -418,12 +418,12 @@ enum range_cal_i2c_contents {
BNC_TRIG_THRESHOLD_0V_BIT = 0x80,
};
-static inline uint8_t adc_src_4020_bits(unsigned int source)
+static inline u8 adc_src_4020_bits(unsigned int source)
{
return (source << 4) & ADC_SRC_4020_MASK;
};
-static inline uint8_t attenuate_bit(unsigned int channel)
+static inline u8 attenuate_bit(unsigned int channel)
{
/* attenuate channel (+-5V input range) */
return 1 << (channel & 0x3);
@@ -443,7 +443,7 @@ static const struct comedi_lrange ai_ranges_64xx = {
}
};
-static const uint8_t ai_range_code_64xx[8] = {
+static const u8 ai_range_code_64xx[8] = {
0x0, 0x1, 0x2, 0x3, /* bipolar 10, 5, 2,5, 1.25 */
0x8, 0x9, 0xa, 0xb /* unipolar 10, 5, 2.5, 1.25 */
};
@@ -461,7 +461,7 @@ static const struct comedi_lrange ai_ranges_64_mx = {
}
};
-static const uint8_t ai_range_code_64_mx[7] = {
+static const u8 ai_range_code_64_mx[7] = {
0x0, 0x1, 0x2, 0x3, /* bipolar 5, 2.5, 1.25, 0.625 */
0x9, 0xa, 0xb /* unipolar 5, 2.5, 1.25 */
};
@@ -476,7 +476,7 @@ static const struct comedi_lrange ai_ranges_60xx = {
}
};
-static const uint8_t ai_range_code_60xx[4] = {
+static const u8 ai_range_code_60xx[4] = {
0x0, 0x1, 0x4, 0x7 /* bipolar 10, 5, 0.5, 0.05 */
};
@@ -500,7 +500,7 @@ static const struct comedi_lrange ai_ranges_6030 = {
}
};
-static const uint8_t ai_range_code_6030[14] = {
+static const u8 ai_range_code_6030[14] = {
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, /* bip 10, 5, 2, 1, 0.5, 0.2, 0.1 */
0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* uni 10, 5, 2, 1, 0.5, 0.2, 0.1 */
};
@@ -526,7 +526,7 @@ static const struct comedi_lrange ai_ranges_6052 = {
}
};
-static const uint8_t ai_range_code_6052[15] = {
+static const u8 ai_range_code_6052[15] = {
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, /* bipolar 10 ... 0.05 */
0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* unipolar 10 ... 0.1 */
};
@@ -594,7 +594,7 @@ struct hw_fifo_info {
unsigned int num_segments;
unsigned int max_segment_length;
unsigned int sample_packing_ratio;
- uint16_t fifo_size_reg_mask;
+ u16 fifo_size_reg_mask;
};
enum pcidas64_boardid {
@@ -634,7 +634,7 @@ struct pcidas64_board {
int ai_bits; /* analog input resolution */
int ai_speed; /* fastest conversion period in ns */
const struct comedi_lrange *ai_range_table;
- const uint8_t *ai_range_code;
+ const u8 *ai_range_code;
int ao_nchan; /* number of analog out channels */
int ao_bits; /* analog output resolution */
int ao_scan_speed; /* analog output scan speed */
@@ -1132,10 +1132,10 @@ struct pcidas64_private {
void __iomem *plx9080_iobase;
void __iomem *main_iobase;
/* local address (used by dma controller) */
- uint32_t local0_iobase;
- uint32_t local1_iobase;
+ u32 local0_iobase;
+ u32 local1_iobase;
/* dma buffers for analog input */
- uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT];
+ u16 *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];
/*
@@ -1151,7 +1151,7 @@ struct pcidas64_private {
*/
unsigned int ai_dma_index;
/* dma buffers for analog output */
- uint16_t *ao_buffer[AO_DMA_RING_COUNT];
+ u16 *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;
@@ -1162,20 +1162,20 @@ struct pcidas64_private {
/* last bits sent to INTR_ENABLE_REG register */
unsigned int intr_enable_bits;
/* last bits sent to ADC_CONTROL1_REG register */
- uint16_t adc_control1_bits;
+ u16 adc_control1_bits;
/* last bits sent to FIFO_SIZE_REG register */
- uint16_t fifo_size_bits;
+ u16 fifo_size_bits;
/* last bits sent to HW_CONFIG_REG register */
- uint16_t hw_config_bits;
- uint16_t dac_control1_bits;
+ u16 hw_config_bits;
+ u16 dac_control1_bits;
/* last bits written to plx9080 control register */
- uint32_t plx_control_bits;
+ u32 plx_control_bits;
/* last bits written to plx interrupt control and status register */
- uint32_t plx_intcsr_bits;
+ u32 plx_intcsr_bits;
/* index of calibration source readable through ai ch0 */
int calibration_source;
/* bits written to i2c calibration/range register */
- uint8_t i2c_cal_range_bits;
+ u8 i2c_cal_range_bits;
/* configure digital triggers to trigger on falling edge */
unsigned int ext_trig_falling;
short ai_cmd_running;
@@ -1193,7 +1193,7 @@ 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)
+ u16 hw_status_bits)
{
const struct pcidas64_board *board = dev->board_ptr;
@@ -1204,7 +1204,7 @@ static unsigned int hw_revision(const struct comedi_device *dev,
}
static void set_dac_range_bits(struct comedi_device *dev,
- uint16_t *bits, unsigned int channel,
+ u16 *bits, unsigned int channel,
unsigned int range)
{
const struct pcidas64_board *board = dev->board_ptr;
@@ -1266,7 +1266,7 @@ static void enable_ai_interrupts(struct comedi_device *dev,
{
const struct pcidas64_board *board = dev->board_ptr;
struct pcidas64_private *devpriv = dev->private;
- uint32_t bits;
+ u32 bits;
unsigned long flags;
bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
@@ -1292,7 +1292,7 @@ static void init_plx9080(struct comedi_device *dev)
{
const struct pcidas64_board *board = dev->board_ptr;
struct pcidas64_private *devpriv = dev->private;
- uint32_t bits;
+ u32 bits;
void __iomem *plx_iobase = devpriv->plx9080_iobase;
devpriv->plx_control_bits =
@@ -1378,7 +1378,7 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev,
static const int increment_size = 0x100;
const struct hw_fifo_info *const fifo = board->ai_fifo;
unsigned int num_increments;
- uint16_t bits;
+ u16 bits;
if (num_entries < increment_size)
num_entries = increment_size;
@@ -1437,7 +1437,7 @@ static void init_stc_registers(struct comedi_device *dev)
{
const struct pcidas64_board *board = dev->board_ptr;
struct pcidas64_private *devpriv = dev->private;
- uint16_t bits;
+ u16 bits;
unsigned long flags;
spin_lock_irqsave(&dev->spinlock, flags);
@@ -1657,9 +1657,9 @@ static void i2c_set_scl(struct comedi_device *dev, int state)
}
}
-static void i2c_write_byte(struct comedi_device *dev, uint8_t byte)
+static void i2c_write_byte(struct comedi_device *dev, u8 byte)
{
- uint8_t bit;
+ u8 bit;
unsigned int num_bits = 8;
for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
@@ -1700,11 +1700,11 @@ static void i2c_stop(struct comedi_device *dev)
}
static void i2c_write(struct comedi_device *dev, unsigned int address,
- const uint8_t *data, unsigned int length)
+ const u8 *data, unsigned int length)
{
struct pcidas64_private *devpriv = dev->private;
unsigned int i;
- uint8_t bitstream;
+ u8 bitstream;
static const int read_bit = 0x1;
/*
@@ -1831,7 +1831,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
/* set start channel, and rest of settings */
writew(bits, devpriv->main_iobase + ADC_QUEUE_LOAD_REG);
} else {
- uint8_t old_cal_range_bits = devpriv->i2c_cal_range_bits;
+ u8 old_cal_range_bits = devpriv->i2c_cal_range_bits;
devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
if (insn->chanspec & CR_ALT_SOURCE) {
@@ -1850,7 +1850,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
* as it is very slow
*/
if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
- uint8_t i2c_data = devpriv->i2c_cal_range_bits;
+ u8 i2c_data = devpriv->i2c_cal_range_bits;
i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
sizeof(i2c_data));
@@ -2273,23 +2273,23 @@ static inline unsigned int dma_transfer_size(struct comedi_device *dev)
num_samples = devpriv->ai_fifo_segment_length *
board->ai_fifo->sample_packing_ratio;
- if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t))
- num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t);
+ if (num_samples > DMA_BUFFER_SIZE / sizeof(u16))
+ num_samples = DMA_BUFFER_SIZE / sizeof(u16);
return num_samples;
}
-static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev,
+static u32 ai_convert_counter_6xxx(const struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
/* supposed to load counter with desired divisor minus 3 */
return cmd->convert_arg / TIMER_BASE - 3;
}
-static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
+static u32 ai_scan_counter_6xxx(struct comedi_device *dev,
struct comedi_cmd *cmd)
{
- uint32_t count;
+ u32 count;
/* figure out how long we need to delay at end of scan */
switch (cmd->scan_begin_src) {
@@ -2307,7 +2307,7 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev,
return count - 3;
}
-static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
+static u32 ai_convert_counter_4020(struct comedi_device *dev,
struct comedi_cmd *cmd)
{
struct pcidas64_private *devpriv = dev->private;
@@ -2382,7 +2382,7 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
{
const struct pcidas64_board *board = dev->board_ptr;
struct pcidas64_private *devpriv = dev->private;
- uint32_t convert_counter = 0, scan_counter = 0;
+ u32 convert_counter = 0, scan_counter = 0;
check_adc_timing(dev, cmd);
@@ -2529,7 +2529,7 @@ static int setup_channel_queue(struct comedi_device *dev,
* as it is very slow
*/
if (old_cal_range_bits != devpriv->i2c_cal_range_bits) {
- uint8_t i2c_data = devpriv->i2c_cal_range_bits;
+ u8 i2c_data = devpriv->i2c_cal_range_bits;
i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
sizeof(i2c_data));
@@ -2572,7 +2572,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
struct pcidas64_private *devpriv = dev->private;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
- uint32_t bits;
+ u32 bits;
unsigned int i;
unsigned long flags;
int retval;
@@ -2634,7 +2634,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
for (i = 0; i < ai_dma_ring_count(board); i++)
devpriv->ai_dma_desc[i].transfer_size =
cpu_to_le32(dma_transfer_size(dev) *
- sizeof(uint16_t));
+ sizeof(u16));
/* give location of first dma descriptor */
load_first_dma_descriptor(dev, 1,
@@ -2691,7 +2691,7 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
struct pcidas64_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int i;
- uint16_t prepost_bits;
+ u16 prepost_bits;
int read_segment, read_index, write_segment, write_index;
int num_samples;
@@ -2754,7 +2754,7 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev)
struct comedi_subdevice *s = dev->read_subdev;
unsigned int nsamples;
unsigned int i;
- uint32_t fifo_data;
+ u32 fifo_data;
int write_code =
readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
int read_code =
@@ -2794,7 +2794,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
const struct pcidas64_board *board = dev->board_ptr;
struct pcidas64_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
- uint32_t next_transfer_addr;
+ u32 next_transfer_addr;
int j;
int num_samples = 0;
void __iomem *pci_addr_reg;
@@ -2831,7 +2831,7 @@ static void handle_ai_interrupt(struct comedi_device *dev,
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s->async;
struct comedi_cmd *cmd = &async->cmd;
- uint8_t dma1_status;
+ u8 dma1_status;
unsigned long flags;
/* check for fifo overrun */
@@ -3008,7 +3008,7 @@ static void handle_ao_interrupt(struct comedi_device *dev,
struct comedi_subdevice *s = dev->write_subdev;
struct comedi_async *async;
struct comedi_cmd *cmd;
- uint8_t dma0_status;
+ u8 dma0_status;
unsigned long flags;
/* board might not support ao, in which case write_subdev is NULL */
@@ -3056,8 +3056,8 @@ 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;
+ u32 plx_status;
+ u32 plx_bits;
plx_status = readl(devpriv->plx9080_iobase + PLX_REG_INTCSR);
status = readw(devpriv->main_iobase + HW_STATUS_REG);
@@ -3180,7 +3180,7 @@ static void set_dac_select_reg(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
struct pcidas64_private *devpriv = dev->private;
- uint16_t bits;
+ u16 bits;
unsigned int first_channel, last_channel;
first_channel = CR_CHAN(cmd->chanlist[0]);
@@ -3523,7 +3523,7 @@ static int dio_60xx_wbits(struct comedi_device *dev,
*/
static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
- uint8_t value)
+ u8 value)
{
struct pcidas64_private *devpriv = dev->private;
static const int num_caldac_channels = 8;
@@ -3558,8 +3558,8 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
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;
+ u8 serial_bytes[3];
+ u8 i2c_addr;
enum pointer_bits {
/* manual has gain and offset bits switched */
OFFSET_0_2 = 0x1,
@@ -3708,7 +3708,7 @@ static int cb_pcidas64_ad8402_insn_write(struct comedi_device *dev,
return insn->n;
}
-static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
+static u16 read_eeprom(struct comedi_device *dev, u8 address)
{
struct pcidas64_private *devpriv = dev->private;
static const int bitstream_length = 11;
@@ -3717,7 +3717,7 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
unsigned int bit;
void __iomem * const plx_control_addr =
devpriv->plx9080_iobase + PLX_REG_CNTRL;
- uint16_t value;
+ u16 value;
static const int value_length = 16;
static const int eeprom_udelay = 1;
@@ -3813,7 +3813,7 @@ static int setup_subdevices(struct comedi_device *dev)
s->do_cmdtest = ai_cmdtest;
s->cancel = ai_cancel;
if (board->layout == LAYOUT_4020) {
- uint8_t data;
+ u8 data;
/*
* set adc to read from inputs
* (not internal calibration sources)
@@ -3975,7 +3975,7 @@ static int auto_attach(struct comedi_device *dev,
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
const struct pcidas64_board *board = NULL;
struct pcidas64_private *devpriv;
- uint32_t local_range, local_decode;
+ u32 local_range, local_decode;
int retval;
if (context < ARRAY_SIZE(pcidas64_boards))
@@ -4013,13 +4013,13 @@ static int auto_attach(struct comedi_device *dev,
PLX_LASRR_MEM_MASK;
local_decode = readl(devpriv->plx9080_iobase + PLX_REG_LAS0BA) &
local_range & PLX_LASBA_MEM_MASK;
- devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase &
+ devpriv->local0_iobase = ((u32)devpriv->main_phys_iobase &
~local_range) | local_decode;
local_range = readl(devpriv->plx9080_iobase + PLX_REG_LAS1RR) &
PLX_LASRR_MEM_MASK;
local_decode = readl(devpriv->plx9080_iobase + PLX_REG_LAS1BA) &
local_range & PLX_LASBA_MEM_MASK;
- devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase &
+ devpriv->local1_iobase = ((u32)devpriv->dio_counter_phys_iobase &
~local_range) | local_decode;
retval = alloc_and_init_dma_members(dev);
diff --git a/drivers/staging/comedi/drivers/comedi_8254.h b/drivers/staging/comedi/drivers/comedi_8254.h
index a12c29455d9d..326bd44b063e 100644
--- a/drivers/staging/comedi/drivers/comedi_8254.h
+++ b/drivers/staging/comedi/drivers/comedi_8254.h
@@ -100,34 +100,36 @@ struct comedi_8254 {
unsigned int gate_src[3];
bool busy[3];
- int (*insn_config)(struct comedi_device *, struct comedi_subdevice *s,
- struct comedi_insn *, unsigned int *data);
+ int (*insn_config)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
};
-unsigned int comedi_8254_status(struct comedi_8254 *, unsigned int counter);
-unsigned int comedi_8254_read(struct comedi_8254 *, unsigned int counter);
-void comedi_8254_write(struct comedi_8254 *,
+unsigned int comedi_8254_status(struct comedi_8254 *i8254,
+ unsigned int counter);
+unsigned int comedi_8254_read(struct comedi_8254 *i8254, unsigned int counter);
+void comedi_8254_write(struct comedi_8254 *i8254,
unsigned int counter, unsigned int val);
-int comedi_8254_set_mode(struct comedi_8254 *,
+int comedi_8254_set_mode(struct comedi_8254 *i8254,
unsigned int counter, unsigned int mode);
-int comedi_8254_load(struct comedi_8254 *,
+int comedi_8254_load(struct comedi_8254 *i8254,
unsigned int counter, unsigned int val, unsigned int mode);
-void comedi_8254_pacer_enable(struct comedi_8254 *,
+void comedi_8254_pacer_enable(struct comedi_8254 *i8254,
unsigned int counter1, unsigned int counter2,
bool enable);
-void comedi_8254_update_divisors(struct comedi_8254 *);
-void comedi_8254_cascade_ns_to_timer(struct comedi_8254 *,
+void comedi_8254_update_divisors(struct comedi_8254 *i8254);
+void comedi_8254_cascade_ns_to_timer(struct comedi_8254 *i8254,
unsigned int *nanosec, unsigned int flags);
-void comedi_8254_ns_to_timer(struct comedi_8254 *,
+void comedi_8254_ns_to_timer(struct comedi_8254 *i8254,
unsigned int *nanosec, unsigned int flags);
-void comedi_8254_set_busy(struct comedi_8254 *,
+void comedi_8254_set_busy(struct comedi_8254 *i8254,
unsigned int counter, bool busy);
-void comedi_8254_subdevice_init(struct comedi_subdevice *,
- struct comedi_8254 *);
+void comedi_8254_subdevice_init(struct comedi_subdevice *s,
+ struct comedi_8254 *i8254);
struct comedi_8254 *comedi_8254_init(unsigned long iobase,
unsigned int osc_base,
diff --git a/drivers/staging/comedi/drivers/comedi_isadma.h b/drivers/staging/comedi/drivers/comedi_isadma.h
index 2fb6573ba9e4..a193d3e8d185 100644
--- a/drivers/staging/comedi/drivers/comedi_isadma.h
+++ b/drivers/staging/comedi/drivers/comedi_isadma.h
@@ -63,18 +63,18 @@ struct comedi_isadma {
#if IS_ENABLED(CONFIG_ISA_DMA_API)
-void comedi_isadma_program(struct comedi_isadma_desc *);
+void comedi_isadma_program(struct comedi_isadma_desc *desc);
unsigned int comedi_isadma_disable(unsigned int dma_chan);
unsigned int comedi_isadma_disable_on_sample(unsigned int dma_chan,
unsigned int size);
-unsigned int comedi_isadma_poll(struct comedi_isadma *);
-void comedi_isadma_set_mode(struct comedi_isadma_desc *, char dma_dir);
+unsigned int comedi_isadma_poll(struct comedi_isadma *dma);
+void comedi_isadma_set_mode(struct comedi_isadma_desc *desc, char dma_dir);
-struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *,
+struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev,
int n_desc, unsigned int dma_chan1,
unsigned int dma_chan2,
unsigned int maxsize, char dma_dir);
-void comedi_isadma_free(struct comedi_isadma *);
+void comedi_isadma_free(struct comedi_isadma *dma);
#else /* !IS_ENABLED(CONFIG_ISA_DMA_API) */
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
index 0f4eb954aa80..32dd8a857b6b 100644
--- a/drivers/staging/comedi/drivers/daqboard2000.c
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -109,28 +109,11 @@
#include "../comedi_pci.h"
#include "8255.h"
+#include "plx9080.h"
-#define DAQBOARD2000_FIRMWARE "daqboard2000_firmware.bin"
+#define DB2K_FIRMWARE "daqboard2000_firmware.bin"
-#define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */
-#define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */
-
-/* Initialization bits for the Serial EEPROM Control Register */
-#define DB2K_SECR_PROG_PIN_HI 0x8001767e
-#define DB2K_SECR_PROG_PIN_LO 0x8000767e
-#define DB2K_SECR_LOCAL_BUS_HI 0xc000767e
-#define DB2K_SECR_LOCAL_BUS_LO 0x8000767e
-#define DB2K_SECR_RELOAD_HI 0xa000767e
-#define DB2K_SECR_RELOAD_LO 0x8000767e
-
-/* SECR status bits */
-#define DAQBOARD2000_EEPROM_PRESENT 0x10000000
-
-/* CPLD status bits */
-#define DAQBOARD2000_CPLD_INIT 0x0002
-#define DAQBOARD2000_CPLD_DONE 0x0004
-
-static const struct comedi_lrange range_daqboard2000_ai = {
+static const struct comedi_lrange db2k_ai_range = {
13, {
BIP_RANGE(10),
BIP_RANGE(5),
@@ -183,6 +166,10 @@ static const struct comedi_lrange range_daqboard2000_ai = {
#define DB2K_REG_TRIG_DACS 0xbc /* u16 */
#define DB2K_REG_DIO_P2_EXP_IO_16_BIT(x) (0xc0 + (x) * 2) /* s16 */
+/* CPLD registers */
+#define DB2K_REG_CPLD_STATUS 0x1000 /* u16 (r) */
+#define DB2K_REG_CPLD_WDATA 0x1000 /* u16 (w) */
+
/* Scan Sequencer programming */
#define DB2K_ACQ_CONTROL_SEQ_START_SCAN_LIST 0x0011
#define DB2K_ACQ_CONTROL_SEQ_STOP_SCAN_LIST 0x0010
@@ -248,33 +235,45 @@ static const struct comedi_lrange range_daqboard2000_ai = {
#define DB2K_REF_DACS_SELECT_POS_REF 0x0100
#define DB2K_REF_DACS_SELECT_NEG_REF 0x0000
-struct daq200_boardtype {
+/* CPLD status bits */
+#define DB2K_CPLD_STATUS_INIT 0x0002
+#define DB2K_CPLD_STATUS_TXREADY 0x0004
+#define DB2K_CPLD_VERSION_MASK 0xf000
+/* "New CPLD" signature. */
+#define DB2K_CPLD_VERSION_NEW 0x5000
+
+enum db2k_boardid {
+ BOARD_DAQBOARD2000,
+ BOARD_DAQBOARD2001
+};
+
+struct db2k_boardtype {
const char *name;
- int id;
+ bool has_2_ao:1; /* false: 4 AO chans; true: 2 AO chans */
};
-static const struct daq200_boardtype boardtypes[] = {
- {"ids2", DAQBOARD2000_SUBSYSTEM_IDS2},
- {"ids4", DAQBOARD2000_SUBSYSTEM_IDS4},
+static const struct db2k_boardtype db2k_boardtypes[] = {
+ [BOARD_DAQBOARD2000] = {
+ .name = "daqboard2000",
+ .has_2_ao = true,
+ },
+ [BOARD_DAQBOARD2001] = {
+ .name = "daqboard2001",
+ },
};
-struct daqboard2000_private {
- enum {
- card_daqboard_2000
- } card;
+struct db2k_private {
void __iomem *plx;
};
-static void daqboard2000_write_acq_scan_list_entry(struct comedi_device *dev,
- u16 entry)
+static void db2k_write_acq_scan_list_entry(struct comedi_device *dev, u16 entry)
{
writew(entry & 0x00ff, dev->mmio + DB2K_REG_ACQ_SCAN_LIST_FIFO);
writew((entry >> 8) & 0x00ff,
dev->mmio + DB2K_REG_ACQ_SCAN_LIST_FIFO);
}
-static void daqboard2000_setup_sampling(struct comedi_device *dev, int chan,
- int gain)
+static void db2k_setup_sampling(struct comedi_device *dev, int chan, int gain)
{
u16 word0, word1, word2, word3;
@@ -308,16 +307,14 @@ static void daqboard2000_setup_sampling(struct comedi_device *dev, int chan,
/* These should be read from EEPROM */
word2 |= 0x0800; /* offset */
word3 |= 0xc000; /* gain */
- daqboard2000_write_acq_scan_list_entry(dev, word0);
- daqboard2000_write_acq_scan_list_entry(dev, word1);
- daqboard2000_write_acq_scan_list_entry(dev, word2);
- daqboard2000_write_acq_scan_list_entry(dev, word3);
+ db2k_write_acq_scan_list_entry(dev, word0);
+ db2k_write_acq_scan_list_entry(dev, word1);
+ db2k_write_acq_scan_list_entry(dev, word2);
+ db2k_write_acq_scan_list_entry(dev, word3);
}
-static int daqboard2000_ai_status(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
+static int db2k_ai_status(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned long context)
{
unsigned int status;
@@ -327,10 +324,9 @@ static int daqboard2000_ai_status(struct comedi_device *dev,
return -EBUSY;
}
-static int daqboard2000_ai_insn_read(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
+static int db2k_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int gain, chan;
int ret;
@@ -359,12 +355,12 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
* forced to fix it. --ds
*/
for (i = 0; i < insn->n; i++) {
- daqboard2000_setup_sampling(dev, chan, gain);
+ db2k_setup_sampling(dev, chan, gain);
/* Enable reading from the scanlist FIFO */
writew(DB2K_ACQ_CONTROL_SEQ_START_SCAN_LIST,
dev->mmio + DB2K_REG_ACQ_CONTROL);
- ret = comedi_timeout(dev, s, insn, daqboard2000_ai_status,
+ ret = comedi_timeout(dev, s, insn, db2k_ai_status,
DB2K_ACQ_STATUS_CONFIG_PIPE_FULL);
if (ret)
return ret;
@@ -372,13 +368,13 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
writew(DB2K_ACQ_CONTROL_ADC_PACER_ENABLE,
dev->mmio + DB2K_REG_ACQ_CONTROL);
- ret = comedi_timeout(dev, s, insn, daqboard2000_ai_status,
+ ret = comedi_timeout(dev, s, insn, db2k_ai_status,
DB2K_ACQ_STATUS_LOGIC_SCANNING);
if (ret)
return ret;
ret =
- comedi_timeout(dev, s, insn, daqboard2000_ai_status,
+ comedi_timeout(dev, s, insn, db2k_ai_status,
DB2K_ACQ_STATUS_RESULTS_FIFO_HAS_DATA);
if (ret)
return ret;
@@ -393,10 +389,8 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
return i;
}
-static int daqboard2000_ao_eoc(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned long context)
+static int db2k_ao_eoc(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned long context)
{
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int status;
@@ -407,10 +401,9 @@ static int daqboard2000_ao_eoc(struct comedi_device *dev,
return -EBUSY;
}
-static int daqboard2000_ao_insn_write(struct comedi_device *dev,
- struct comedi_subdevice *s,
- struct comedi_insn *insn,
- unsigned int *data)
+static int db2k_ao_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
unsigned int chan = CR_CHAN(insn->chanspec);
int i;
@@ -421,7 +414,7 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev,
writew(val, dev->mmio + DB2K_REG_DAC_SETTING(chan));
- ret = comedi_timeout(dev, s, insn, daqboard2000_ao_eoc, 0);
+ ret = comedi_timeout(dev, s, insn, db2k_ao_eoc, 0);
if (ret)
return ret;
@@ -431,49 +424,62 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev,
return insn->n;
}
-static void daqboard2000_reset_local_bus(struct comedi_device *dev)
+static void db2k_reset_local_bus(struct comedi_device *dev)
{
- struct daqboard2000_private *devpriv = dev->private;
+ struct db2k_private *devpriv = dev->private;
+ u32 cntrl;
- writel(DB2K_SECR_LOCAL_BUS_HI, devpriv->plx + 0x6c);
+ cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
+ cntrl |= PLX_CNTRL_RESET;
+ writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
mdelay(10);
- writel(DB2K_SECR_LOCAL_BUS_LO, devpriv->plx + 0x6c);
+ cntrl &= ~PLX_CNTRL_RESET;
+ writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
mdelay(10);
}
-static void daqboard2000_reload_plx(struct comedi_device *dev)
+static void db2k_reload_plx(struct comedi_device *dev)
{
- struct daqboard2000_private *devpriv = dev->private;
+ struct db2k_private *devpriv = dev->private;
+ u32 cntrl;
- writel(DB2K_SECR_RELOAD_LO, devpriv->plx + 0x6c);
+ cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
+ cntrl &= ~PLX_CNTRL_EERELOAD;
+ writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
mdelay(10);
- writel(DB2K_SECR_RELOAD_HI, devpriv->plx + 0x6c);
+ cntrl |= PLX_CNTRL_EERELOAD;
+ writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
mdelay(10);
- writel(DB2K_SECR_RELOAD_LO, devpriv->plx + 0x6c);
+ cntrl &= ~PLX_CNTRL_EERELOAD;
+ writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
mdelay(10);
}
-static void daqboard2000_pulse_prog_pin(struct comedi_device *dev)
+static void db2k_pulse_prog_pin(struct comedi_device *dev)
{
- struct daqboard2000_private *devpriv = dev->private;
+ struct db2k_private *devpriv = dev->private;
+ u32 cntrl;
- writel(DB2K_SECR_PROG_PIN_HI, devpriv->plx + 0x6c);
+ cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
+ cntrl |= PLX_CNTRL_USERO;
+ writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
mdelay(10);
- writel(DB2K_SECR_PROG_PIN_LO, devpriv->plx + 0x6c);
+ cntrl &= ~PLX_CNTRL_USERO;
+ writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
mdelay(10); /* Not in the original code, but I like symmetry... */
}
-static int daqboard2000_poll_cpld(struct comedi_device *dev, int mask)
+static int db2k_wait_cpld_init(struct comedi_device *dev)
{
- int result = 0;
+ int result = -ETIMEDOUT;
int i;
- int cpld;
+ u16 cpld;
/* timeout after 50 tries -> 5ms */
for (i = 0; i < 50; i++) {
- cpld = readw(dev->mmio + 0x1000);
- if ((cpld & mask) == mask) {
- result = 1;
+ cpld = readw(dev->mmio + DB2K_REG_CPLD_STATUS);
+ if (cpld & DB2K_CPLD_STATUS_INIT) {
+ result = 0;
break;
}
usleep_range(100, 1000);
@@ -482,67 +488,123 @@ static int daqboard2000_poll_cpld(struct comedi_device *dev, int mask)
return result;
}
-static int daqboard2000_write_cpld(struct comedi_device *dev, int data)
+static int db2k_wait_cpld_txready(struct comedi_device *dev)
+{
+ int i;
+
+ for (i = 0; i < 100; i++) {
+ if (readw(dev->mmio + DB2K_REG_CPLD_STATUS) &
+ DB2K_CPLD_STATUS_TXREADY) {
+ return 0;
+ }
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int db2k_write_cpld(struct comedi_device *dev, u16 data, bool new_cpld)
{
int result = 0;
- usleep_range(10, 20);
- writew(data, dev->mmio + 0x1000);
- if ((readw(dev->mmio + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
- DAQBOARD2000_CPLD_INIT) {
- result = 1;
+ if (new_cpld) {
+ result = db2k_wait_cpld_txready(dev);
+ if (result)
+ return result;
+ } else {
+ usleep_range(10, 20);
}
+ writew(data, dev->mmio + DB2K_REG_CPLD_WDATA);
+ if (!(readw(dev->mmio + DB2K_REG_CPLD_STATUS) & DB2K_CPLD_STATUS_INIT))
+ result = -EIO;
+
return result;
}
-static int daqboard2000_load_firmware(struct comedi_device *dev,
- const u8 *cpld_array, size_t len,
- unsigned long context)
+static int db2k_wait_fpga_programmed(struct comedi_device *dev)
+{
+ struct db2k_private *devpriv = dev->private;
+ int i;
+
+ /* Time out after 200 tries -> 20ms */
+ for (i = 0; i < 200; i++) {
+ u32 cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
+ /* General Purpose Input (USERI) set on FPGA "DONE". */
+ if (cntrl & PLX_CNTRL_USERI)
+ return 0;
+
+ usleep_range(100, 1000);
+ }
+ return -ETIMEDOUT;
+}
+
+static int db2k_load_firmware(struct comedi_device *dev, const u8 *cpld_array,
+ size_t len, unsigned long context)
{
- struct daqboard2000_private *devpriv = dev->private;
+ struct db2k_private *devpriv = dev->private;
int result = -EIO;
- /* Read the serial EEPROM control register */
- int secr;
+ u32 cntrl;
int retry;
size_t i;
+ bool new_cpld;
+
+ /* Look for FPGA start sequence in firmware. */
+ for (i = 0; i + 1 < len; i++) {
+ if (cpld_array[i] == 0xff && cpld_array[i + 1] == 0x20)
+ break;
+ }
+ if (i + 1 >= len) {
+ dev_err(dev->class_dev, "bad firmware - no start sequence\n");
+ return -EINVAL;
+ }
+ /* Check length is even. */
+ if ((len - i) & 1) {
+ dev_err(dev->class_dev,
+ "bad firmware - odd length (%zu = %zu - %zu)\n",
+ len - i, len, i);
+ return -EINVAL;
+ }
+ /* Strip firmware header. */
+ cpld_array += i;
+ len -= i;
/* Check to make sure the serial eeprom is present on the board */
- secr = readl(devpriv->plx + 0x6c);
- if (!(secr & DAQBOARD2000_EEPROM_PRESENT))
+ cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
+ if (!(cntrl & PLX_CNTRL_EEPRESENT))
return -EIO;
for (retry = 0; retry < 3; retry++) {
- daqboard2000_reset_local_bus(dev);
- daqboard2000_reload_plx(dev);
- daqboard2000_pulse_prog_pin(dev);
- if (daqboard2000_poll_cpld(dev, DAQBOARD2000_CPLD_INIT)) {
- for (i = 0; i < len; i++) {
- if (cpld_array[i] == 0xff &&
- cpld_array[i + 1] == 0x20)
- break;
- }
- for (; i < len; i += 2) {
- int data =
- (cpld_array[i] << 8) + cpld_array[i + 1];
- if (!daqboard2000_write_cpld(dev, data))
- break;
- }
- if (i >= len) {
- daqboard2000_reset_local_bus(dev);
- daqboard2000_reload_plx(dev);
- result = 0;
+ db2k_reset_local_bus(dev);
+ db2k_reload_plx(dev);
+ db2k_pulse_prog_pin(dev);
+ result = db2k_wait_cpld_init(dev);
+ if (result)
+ continue;
+
+ new_cpld = (readw(dev->mmio + DB2K_REG_CPLD_STATUS) &
+ DB2K_CPLD_VERSION_MASK) == DB2K_CPLD_VERSION_NEW;
+ for (; i < len; i += 2) {
+ u16 data = (cpld_array[i] << 8) + cpld_array[i + 1];
+
+ result = db2k_write_cpld(dev, data, new_cpld);
+ if (result)
break;
- }
+ }
+ if (result == 0)
+ result = db2k_wait_fpga_programmed(dev);
+ if (result == 0) {
+ db2k_reset_local_bus(dev);
+ db2k_reload_plx(dev);
+ break;
}
}
return result;
}
-static void daqboard2000_adc_stop_dma_transfer(struct comedi_device *dev)
+static void db2k_adc_stop_dma_transfer(struct comedi_device *dev)
{
}
-static void daqboard2000_adc_disarm(struct comedi_device *dev)
+static void db2k_adc_disarm(struct comedi_device *dev)
{
/* Disable hardware triggers */
udelay(2);
@@ -563,10 +625,10 @@ static void daqboard2000_adc_disarm(struct comedi_device *dev)
dev->mmio + DB2K_REG_ACQ_CONTROL);
/* Stop the input dma (abort channel 1) */
- daqboard2000_adc_stop_dma_transfer(dev);
+ db2k_adc_stop_dma_transfer(dev);
}
-static void daqboard2000_activate_reference_dacs(struct comedi_device *dev)
+static void db2k_activate_reference_dacs(struct comedi_device *dev)
{
unsigned int val;
int timeout;
@@ -592,34 +654,33 @@ static void daqboard2000_activate_reference_dacs(struct comedi_device *dev)
}
}
-static void daqboard2000_initialize_ctrs(struct comedi_device *dev)
+static void db2k_initialize_ctrs(struct comedi_device *dev)
{
}
-static void daqboard2000_initialize_tmrs(struct comedi_device *dev)
+static void db2k_initialize_tmrs(struct comedi_device *dev)
{
}
-static void daqboard2000_dac_disarm(struct comedi_device *dev)
+static void db2k_dac_disarm(struct comedi_device *dev)
{
}
-static void daqboard2000_initialize_adc(struct comedi_device *dev)
+static void db2k_initialize_adc(struct comedi_device *dev)
{
- daqboard2000_adc_disarm(dev);
- daqboard2000_activate_reference_dacs(dev);
- daqboard2000_initialize_ctrs(dev);
- daqboard2000_initialize_tmrs(dev);
+ db2k_adc_disarm(dev);
+ db2k_activate_reference_dacs(dev);
+ db2k_initialize_ctrs(dev);
+ db2k_initialize_tmrs(dev);
}
-static void daqboard2000_initialize_dac(struct comedi_device *dev)
+static void db2k_initialize_dac(struct comedi_device *dev)
{
- daqboard2000_dac_disarm(dev);
+ db2k_dac_disarm(dev);
}
-static int daqboard2000_8255_cb(struct comedi_device *dev,
- int dir, int port, int data,
- unsigned long iobase)
+static int db2k_8255_cb(struct comedi_device *dev, int dir, int port, int data,
+ unsigned long iobase)
{
if (dir) {
writew(data, dev->mmio + iobase + port * 2);
@@ -628,34 +689,18 @@ static int daqboard2000_8255_cb(struct comedi_device *dev,
return readw(dev->mmio + iobase + port * 2);
}
-static const void *daqboard2000_find_boardinfo(struct comedi_device *dev,
- struct pci_dev *pcidev)
-{
- const struct daq200_boardtype *board;
- int i;
-
- if (pcidev->subsystem_vendor != PCI_VENDOR_ID_IOTECH)
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(boardtypes); i++) {
- board = &boardtypes[i];
- if (pcidev->subsystem_device == board->id)
- return board;
- }
- return NULL;
-}
-
-static int daqboard2000_auto_attach(struct comedi_device *dev,
- unsigned long context_unused)
+static int db2k_auto_attach(struct comedi_device *dev, unsigned long context)
{
struct pci_dev *pcidev = comedi_to_pci_dev(dev);
- const struct daq200_boardtype *board;
- struct daqboard2000_private *devpriv;
+ const struct db2k_boardtype *board;
+ struct db2k_private *devpriv;
struct comedi_subdevice *s;
int result;
- board = daqboard2000_find_boardinfo(dev, pcidev);
- if (!board)
+ if (context >= ARRAY_SIZE(db2k_boardtypes))
+ return -ENODEV;
+ board = &db2k_boardtypes[context];
+ if (!board->name)
return -ENODEV;
dev->board_ptr = board;
dev->board_name = board->name;
@@ -677,16 +722,13 @@ static int daqboard2000_auto_attach(struct comedi_device *dev,
if (result)
return result;
- readl(devpriv->plx + 0x6c);
-
result = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
- DAQBOARD2000_FIRMWARE,
- daqboard2000_load_firmware, 0);
+ DB2K_FIRMWARE, db2k_load_firmware, 0);
if (result < 0)
return result;
- daqboard2000_initialize_adc(dev);
- daqboard2000_initialize_dac(dev);
+ db2k_initialize_adc(dev);
+ db2k_initialize_dac(dev);
s = &dev->subdevices[0];
/* ai subdevice */
@@ -694,16 +736,16 @@ static int daqboard2000_auto_attach(struct comedi_device *dev,
s->subdev_flags = SDF_READABLE | SDF_GROUND;
s->n_chan = 24;
s->maxdata = 0xffff;
- s->insn_read = daqboard2000_ai_insn_read;
- s->range_table = &range_daqboard2000_ai;
+ s->insn_read = db2k_ai_insn_read;
+ s->range_table = &db2k_ai_range;
s = &dev->subdevices[1];
/* ao subdevice */
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITABLE;
- s->n_chan = 2;
+ s->n_chan = board->has_2_ao ? 2 : 4;
s->maxdata = 0xffff;
- s->insn_write = daqboard2000_ao_insn_write;
+ s->insn_write = db2k_ao_insn_write;
s->range_table = &range_bipolar10;
result = comedi_alloc_subdev_readback(s);
@@ -711,48 +753,49 @@ static int daqboard2000_auto_attach(struct comedi_device *dev,
return result;
s = &dev->subdevices[2];
- return subdev_8255_init(dev, s, daqboard2000_8255_cb,
+ return subdev_8255_init(dev, s, db2k_8255_cb,
DB2K_REG_DIO_P2_EXP_IO_8_BIT);
}
-static void daqboard2000_detach(struct comedi_device *dev)
+static void db2k_detach(struct comedi_device *dev)
{
- struct daqboard2000_private *devpriv = dev->private;
+ struct db2k_private *devpriv = dev->private;
if (devpriv && devpriv->plx)
iounmap(devpriv->plx);
comedi_pci_detach(dev);
}
-static struct comedi_driver daqboard2000_driver = {
+static struct comedi_driver db2k_driver = {
.driver_name = "daqboard2000",
.module = THIS_MODULE,
- .auto_attach = daqboard2000_auto_attach,
- .detach = daqboard2000_detach,
+ .auto_attach = db2k_auto_attach,
+ .detach = db2k_detach,
};
-static int daqboard2000_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int db2k_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
- return comedi_pci_auto_config(dev, &daqboard2000_driver,
- id->driver_data);
+ return comedi_pci_auto_config(dev, &db2k_driver, id->driver_data);
}
-static const struct pci_device_id daqboard2000_pci_table[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_IOTECH, 0x0409) },
+static const struct pci_device_id db2k_pci_table[] = {
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_IOTECH, 0x0409, PCI_VENDOR_ID_IOTECH,
+ 0x0002), .driver_data = BOARD_DAQBOARD2000, },
+ { PCI_DEVICE_SUB(PCI_VENDOR_ID_IOTECH, 0x0409, PCI_VENDOR_ID_IOTECH,
+ 0x0004), .driver_data = BOARD_DAQBOARD2001, },
{ 0 }
};
-MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table);
+MODULE_DEVICE_TABLE(pci, db2k_pci_table);
-static struct pci_driver daqboard2000_pci_driver = {
+static struct pci_driver db2k_pci_driver = {
.name = "daqboard2000",
- .id_table = daqboard2000_pci_table,
- .probe = daqboard2000_pci_probe,
+ .id_table = db2k_pci_table,
+ .probe = db2k_pci_probe,
.remove = comedi_pci_auto_unconfig,
};
-module_comedi_pci_driver(daqboard2000_driver, daqboard2000_pci_driver);
+module_comedi_pci_driver(db2k_driver, db2k_pci_driver);
MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(DAQBOARD2000_FIRMWARE);
+MODULE_FIRMWARE(DB2K_FIRMWARE);
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
index b6349aed97d0..02a627d3969d 100644
--- a/drivers/staging/comedi/drivers/mite.h
+++ b/drivers/staging/comedi/drivers/mite.h
@@ -60,35 +60,36 @@ struct mite {
spinlock_t lock;
};
-u32 mite_bytes_in_transit(struct mite_channel *);
+u32 mite_bytes_in_transit(struct mite_channel *mite_chan);
-void mite_sync_dma(struct mite_channel *, struct comedi_subdevice *);
-void mite_ack_linkc(struct mite_channel *, struct comedi_subdevice *s,
+void mite_sync_dma(struct mite_channel *mite_chan, struct comedi_subdevice *s);
+void mite_ack_linkc(struct mite_channel *mite_chan, struct comedi_subdevice *s,
bool sync);
-int mite_done(struct mite_channel *);
+int mite_done(struct mite_channel *mite_chan);
-void mite_dma_arm(struct mite_channel *);
-void mite_dma_disarm(struct mite_channel *);
+void mite_dma_arm(struct mite_channel *mite_chan);
+void mite_dma_disarm(struct mite_channel *mite_chan);
-void mite_prep_dma(struct mite_channel *,
+void mite_prep_dma(struct mite_channel *mite_chan,
unsigned int num_device_bits, unsigned int num_memory_bits);
-struct mite_channel *mite_request_channel_in_range(struct mite *,
- struct mite_ring *,
+struct mite_channel *mite_request_channel_in_range(struct mite *mite,
+ struct mite_ring *ring,
unsigned int min_channel,
unsigned int max_channel);
-struct mite_channel *mite_request_channel(struct mite *, struct mite_ring *);
-void mite_release_channel(struct mite_channel *);
+struct mite_channel *mite_request_channel(struct mite *mite,
+ struct mite_ring *ring);
+void mite_release_channel(struct mite_channel *mite_chan);
-int mite_init_ring_descriptors(struct mite_ring *, struct comedi_subdevice *,
- unsigned int nbytes);
-int mite_buf_change(struct mite_ring *, struct comedi_subdevice *);
+int mite_init_ring_descriptors(struct mite_ring *ring,
+ struct comedi_subdevice *s, unsigned int nbytes);
+int mite_buf_change(struct mite_ring *ring, struct comedi_subdevice *s);
-struct mite_ring *mite_alloc_ring(struct mite *);
-void mite_free_ring(struct mite_ring *);
+struct mite_ring *mite_alloc_ring(struct mite *mite);
+void mite_free_ring(struct mite_ring *ring);
-struct mite *mite_attach(struct comedi_device *, bool use_win1);
-void mite_detach(struct mite *);
+struct mite *mite_attach(struct comedi_device *dev, bool use_win1);
+void mite_detach(struct mite *mite);
/*
* Mite registers (used outside of the mite driver)
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
index 0dcb826a9f1f..6aa755ad3953 100644
--- a/drivers/staging/comedi/drivers/ni_660x.c
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -16,13 +16,13 @@
* Driver: ni_660x
* Description: National Instruments 660x counter/timer boards
* Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
- * PXI-6608, PXI-6624
+ * PXI-6608, PCI-6624, PXI-6624
* Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
* Herman.Bruyninckx@mech.kuleuven.ac.be,
* Wim.Meeussen@mech.kuleuven.ac.be,
* Klaas.Gadeyne@mech.kuleuven.ac.be,
* Frank Mori Hess <fmhess@users.sourceforge.net>
- * Updated: Fri, 15 Mar 2013 10:47:56 +0000
+ * Updated: Mon, 16 Jan 2017 14:00:43 +0000
* Status: experimental
*
* Encoders work. PulseGeneration (both single pulse and pulse train)
@@ -211,6 +211,7 @@ enum ni_660x_boardid {
BOARD_PCI6602,
BOARD_PXI6602,
BOARD_PXI6608,
+ BOARD_PCI6624,
BOARD_PXI6624
};
@@ -236,6 +237,10 @@ static const struct ni_660x_board ni_660x_boards[] = {
.name = "PXI-6608",
.n_chips = 2,
},
+ [BOARD_PCI6624] = {
+ .name = "PCI-6624",
+ .n_chips = 2,
+ },
[BOARD_PXI6624] = {
.name = "PXI-6624",
.n_chips = 2,
@@ -920,6 +925,7 @@ static const struct pci_device_id ni_660x_pci_table[] = {
{ PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 },
{ PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 },
{ PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 },
+ { PCI_VDEVICE(NI, 0x1e30), BOARD_PCI6624 },
{ PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 },
{ 0 }
};
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
index 74911dbb2561..1d3ff60efcb8 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -141,7 +141,7 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev,
/* ripped from mite.h and mite_setup2() to avoid mite dependency */
#define MITE_IODWBSR 0xc0 /* IO Device Window Base Size Register */
-#define WENAB (1 << 7) /* window enable */
+#define WENAB BIT(7) /* window enable */
static int ni_670x_mite_init(struct pci_dev *pcidev)
{
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
index f27aa0e82234..158fa29374fc 100644
--- a/drivers/staging/comedi/drivers/ni_at_ao.c
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -49,43 +49,43 @@
#define ATAO_CFG2_REG 0x02
#define ATAO_CFG2_CALLD_NOP (0 << 14)
#define ATAO_CFG2_CALLD(x) ((((x) >> 3) + 1) << 14)
-#define ATAO_CFG2_FFRTEN (1 << 13)
+#define ATAO_CFG2_FFRTEN BIT(13)
#define ATAO_CFG2_DACS(x) (1 << (((x) / 2) + 8))
#define ATAO_CFG2_LDAC(x) (1 << (((x) / 2) + 3))
-#define ATAO_CFG2_PROMEN (1 << 2)
-#define ATAO_CFG2_SCLK (1 << 1)
-#define ATAO_CFG2_SDATA (1 << 0)
+#define ATAO_CFG2_PROMEN BIT(2)
+#define ATAO_CFG2_SCLK BIT(1)
+#define ATAO_CFG2_SDATA BIT(0)
#define ATAO_CFG3_REG 0x04
-#define ATAO_CFG3_DMAMODE (1 << 6)
-#define ATAO_CFG3_CLKOUT (1 << 5)
-#define ATAO_CFG3_RCLKEN (1 << 4)
-#define ATAO_CFG3_DOUTEN2 (1 << 3)
-#define ATAO_CFG3_DOUTEN1 (1 << 2)
-#define ATAO_CFG3_EN2_5V (1 << 1)
-#define ATAO_CFG3_SCANEN (1 << 0)
+#define ATAO_CFG3_DMAMODE BIT(6)
+#define ATAO_CFG3_CLKOUT BIT(5)
+#define ATAO_CFG3_RCLKEN BIT(4)
+#define ATAO_CFG3_DOUTEN2 BIT(3)
+#define ATAO_CFG3_DOUTEN1 BIT(2)
+#define ATAO_CFG3_EN2_5V BIT(1)
+#define ATAO_CFG3_SCANEN BIT(0)
#define ATAO_82C53_BASE 0x06
#define ATAO_CFG1_REG 0x0a
-#define ATAO_CFG1_EXTINT2EN (1 << 15)
-#define ATAO_CFG1_EXTINT1EN (1 << 14)
-#define ATAO_CFG1_CNTINT2EN (1 << 13)
-#define ATAO_CFG1_CNTINT1EN (1 << 12)
-#define ATAO_CFG1_TCINTEN (1 << 11)
-#define ATAO_CFG1_CNT1SRC (1 << 10)
-#define ATAO_CFG1_CNT2SRC (1 << 9)
-#define ATAO_CFG1_FIFOEN (1 << 8)
-#define ATAO_CFG1_GRP2WR (1 << 7)
-#define ATAO_CFG1_EXTUPDEN (1 << 6)
-#define ATAO_CFG1_DMARQ (1 << 5)
-#define ATAO_CFG1_DMAEN (1 << 4)
+#define ATAO_CFG1_EXTINT2EN BIT(15)
+#define ATAO_CFG1_EXTINT1EN BIT(14)
+#define ATAO_CFG1_CNTINT2EN BIT(13)
+#define ATAO_CFG1_CNTINT1EN BIT(12)
+#define ATAO_CFG1_TCINTEN BIT(11)
+#define ATAO_CFG1_CNT1SRC BIT(10)
+#define ATAO_CFG1_CNT2SRC BIT(9)
+#define ATAO_CFG1_FIFOEN BIT(8)
+#define ATAO_CFG1_GRP2WR BIT(7)
+#define ATAO_CFG1_EXTUPDEN BIT(6)
+#define ATAO_CFG1_DMARQ BIT(5)
+#define ATAO_CFG1_DMAEN BIT(4)
#define ATAO_CFG1_CH(x) (((x) & 0xf) << 0)
#define ATAO_STATUS_REG 0x0a
-#define ATAO_STATUS_FH (1 << 6)
-#define ATAO_STATUS_FE (1 << 5)
-#define ATAO_STATUS_FF (1 << 4)
-#define ATAO_STATUS_INT2 (1 << 3)
-#define ATAO_STATUS_INT1 (1 << 2)
-#define ATAO_STATUS_TCINT (1 << 1)
-#define ATAO_STATUS_PROMOUT (1 << 0)
+#define ATAO_STATUS_FH BIT(6)
+#define ATAO_STATUS_FE BIT(5)
+#define ATAO_STATUS_FF BIT(4)
+#define ATAO_STATUS_INT2 BIT(3)
+#define ATAO_STATUS_INT1 BIT(2)
+#define ATAO_STATUS_TCINT BIT(1)
+#define ATAO_STATUS_PROMOUT BIT(0)
#define ATAO_FIFO_WRITE_REG 0x0c
#define ATAO_FIFO_CLEAR_REG 0x0c
#define ATAO_AO_REG(x) (0x0c + ((x) * 2))
@@ -95,7 +95,7 @@
#define ATAO_2_INT1CLR_REG 0x02
#define ATAO_2_INT2CLR_REG 0x04
#define ATAO_2_RTSISHFT_REG 0x06
-#define ATAO_2_RTSISHFT_RSI (1 << 0)
+#define ATAO_2_RTSISHFT_RSI BIT(0)
#define ATAO_2_RTSISTRB_REG 0x07
struct atao_board {
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
index be8d5cd3f7f0..c2edadc7b3c6 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.h
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -52,8 +52,8 @@ struct labpc_private {
* function pointers so we can use inb/outb or readb/writeb as
* appropriate
*/
- unsigned int (*read_byte)(struct comedi_device *, unsigned long reg);
- void (*write_byte)(struct comedi_device *,
+ unsigned int (*read_byte)(struct comedi_device *dev, unsigned long reg);
+ void (*write_byte)(struct comedi_device *dev,
unsigned int byte, unsigned long reg);
};
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index f13a2f7360b3..cdb66eab1292 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -25,17 +25,16 @@
* PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014,
* PCI-6040E, PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E,
* PCI-6071E, PCI-6023E, PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E,
- * PCI-6035E, PCI-6052E,
- * PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224,
- * PCI-6225, PXI-6225, PCI-6229, PCI-6250,
- * PCI-6251, PXI-6251, PCIe-6251, PXIe-6251,
- * PCI-6254, PCI-6259, PCIe-6259,
- * PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
- * PCI-6711, PXI-6711, PCI-6713, PXI-6713,
- * PXI-6071E, PCI-6070E, PXI-6070E,
+ * PCI-6035E, PCI-6052E, PCI-6110, PCI-6111, PCI-6220, PXI-6220,
+ * PCI-6221, PXI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225,
+ * PCI-6229, PXI-6229, PCI-6250, PXI-6250, PCI-6251, PXI-6251,
+ * PCIe-6251, PXIe-6251, PCI-6254, PXI-6254, PCI-6259, PXI-6259,
+ * PCIe-6259, PXIe-6259, PCI-6280, PXI-6280, PCI-6281, PXI-6281,
+ * PCI-6284, PXI-6284, PCI-6289, PXI-6289, PCI-6711, PXI-6711,
+ * PCI-6713, PXI-6713, PXI-6071E, PCI-6070E, PXI-6070E,
* PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
* PCI-6143, PXI-6143
- * Updated: Mon, 09 Jan 2012 14:52:48 +0000
+ * Updated: Mon, 16 Jan 2017 12:56:04 +0000
*
* These boards are almost identical to the AT-MIO E series, except that
* they use the PCI bus instead of ISA (i.e., AT). See the notes for the
@@ -181,26 +180,36 @@ enum ni_pcimio_boardid {
BOARD_PXI6031E,
BOARD_PCI6036E,
BOARD_PCI6220,
+ BOARD_PXI6220,
BOARD_PCI6221,
BOARD_PCI6221_37PIN,
+ BOARD_PXI6221,
BOARD_PCI6224,
BOARD_PXI6224,
BOARD_PCI6225,
BOARD_PXI6225,
BOARD_PCI6229,
+ BOARD_PXI6229,
BOARD_PCI6250,
+ BOARD_PXI6250,
BOARD_PCI6251,
BOARD_PXI6251,
BOARD_PCIE6251,
BOARD_PXIE6251,
BOARD_PCI6254,
+ BOARD_PXI6254,
BOARD_PCI6259,
+ BOARD_PXI6259,
BOARD_PCIE6259,
+ BOARD_PXIE6259,
BOARD_PCI6280,
+ BOARD_PXI6280,
BOARD_PCI6281,
BOARD_PXI6281,
BOARD_PCI6284,
+ BOARD_PXI6284,
BOARD_PCI6289,
+ BOARD_PXI6289,
BOARD_PCI6143,
BOARD_PXI6143,
};
@@ -684,6 +693,16 @@ static const struct ni_board_struct ni_boards[] = {
.reg_type = ni_reg_622x,
.caldac = { caldac_none },
},
+ [BOARD_PXI6220] = {
+ .name = "pxi-6220",
+ .n_adchan = 16,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 512, /* FIXME: guess */
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .reg_type = ni_reg_622x,
+ .caldac = { caldac_none },
+ },
[BOARD_PCI6221] = {
.name = "pci-6221",
.n_adchan = 16,
@@ -714,6 +733,21 @@ static const struct ni_board_struct ni_boards[] = {
.ao_speed = 1200,
.caldac = { caldac_none },
},
+ [BOARD_PXI6221] = {
+ .name = "pxi-6221",
+ .n_adchan = 16,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .ao_maxdata = 0xffff,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_bipolar10,
+ .reg_type = ni_reg_622x,
+ .ao_speed = 1200,
+ .caldac = { caldac_none },
+ },
[BOARD_PCI6224] = {
.name = "pci-6224",
.n_adchan = 32,
@@ -784,6 +818,22 @@ static const struct ni_board_struct ni_boards[] = {
.has_32dio_chan = 1,
.caldac = { caldac_none },
},
+ [BOARD_PXI6229] = {
+ .name = "pxi-6229",
+ .n_adchan = 32,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 4,
+ .ao_maxdata = 0xffff,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_bipolar10,
+ .reg_type = ni_reg_622x,
+ .ao_speed = 1200,
+ .has_32dio_chan = 1,
+ .caldac = { caldac_none },
+ },
[BOARD_PCI6250] = {
.name = "pci-6250",
.n_adchan = 16,
@@ -794,6 +844,16 @@ static const struct ni_board_struct ni_boards[] = {
.reg_type = ni_reg_625x,
.caldac = { caldac_none },
},
+ [BOARD_PXI6250] = {
+ .name = "pxi-6250",
+ .n_adchan = 16,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .reg_type = ni_reg_625x,
+ .caldac = { caldac_none },
+ },
[BOARD_PCI6251] = {
.name = "pci-6251",
.n_adchan = 16,
@@ -865,6 +925,17 @@ static const struct ni_board_struct ni_boards[] = {
.has_32dio_chan = 1,
.caldac = { caldac_none },
},
+ [BOARD_PXI6254] = {
+ .name = "pxi-6254",
+ .n_adchan = 32,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .reg_type = ni_reg_625x,
+ .has_32dio_chan = 1,
+ .caldac = { caldac_none },
+ },
[BOARD_PCI6259] = {
.name = "pci-6259",
.n_adchan = 32,
@@ -881,6 +952,22 @@ static const struct ni_board_struct ni_boards[] = {
.has_32dio_chan = 1,
.caldac = { caldac_none },
},
+ [BOARD_PXI6259] = {
+ .name = "pxi-6259",
+ .n_adchan = 32,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 4,
+ .ao_maxdata = 0xffff,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_speed = 350,
+ .has_32dio_chan = 1,
+ .caldac = { caldac_none },
+ },
[BOARD_PCIE6259] = {
.name = "pcie-6259",
.n_adchan = 32,
@@ -897,6 +984,22 @@ static const struct ni_board_struct ni_boards[] = {
.has_32dio_chan = 1,
.caldac = { caldac_none },
},
+ [BOARD_PXIE6259] = {
+ .name = "pxie-6259",
+ .n_adchan = 32,
+ .ai_maxdata = 0xffff,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 4,
+ .ao_maxdata = 0xffff,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_speed = 350,
+ .has_32dio_chan = 1,
+ .caldac = { caldac_none },
+ },
[BOARD_PCI6280] = {
.name = "pci-6280",
.n_adchan = 16,
@@ -908,6 +1011,17 @@ static const struct ni_board_struct ni_boards[] = {
.reg_type = ni_reg_628x,
.caldac = { caldac_none },
},
+ [BOARD_PXI6280] = {
+ .name = "pxi-6280",
+ .n_adchan = 16,
+ .ai_maxdata = 0x3ffff,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .ao_fifo_depth = 8191,
+ .reg_type = ni_reg_628x,
+ .caldac = { caldac_none },
+ },
[BOARD_PCI6281] = {
.name = "pci-6281",
.n_adchan = 16,
@@ -949,6 +1063,17 @@ static const struct ni_board_struct ni_boards[] = {
.has_32dio_chan = 1,
.caldac = { caldac_none },
},
+ [BOARD_PXI6284] = {
+ .name = "pxi-6284",
+ .n_adchan = 32,
+ .ai_maxdata = 0x3ffff,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .reg_type = ni_reg_628x,
+ .has_32dio_chan = 1,
+ .caldac = { caldac_none },
+ },
[BOARD_PCI6289] = {
.name = "pci-6289",
.n_adchan = 32,
@@ -965,6 +1090,22 @@ static const struct ni_board_struct ni_boards[] = {
.has_32dio_chan = 1,
.caldac = { caldac_none },
},
+ [BOARD_PXI6289] = {
+ .name = "pxi-6289",
+ .n_adchan = 32,
+ .ai_maxdata = 0x3ffff,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 4,
+ .ao_maxdata = 0xffff,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_speed = 350,
+ .has_32dio_chan = 1,
+ .caldac = { caldac_none },
+ },
[BOARD_PCI6143] = {
.name = "pci-6143",
.n_adchan = 8,
@@ -1284,14 +1425,24 @@ static const struct pci_device_id ni_pcimio_pci_table[] = {
{ PCI_VDEVICE(NI, 0x70aa), BOARD_PCI6229 },
{ PCI_VDEVICE(NI, 0x70ab), BOARD_PCI6259 },
{ PCI_VDEVICE(NI, 0x70ac), BOARD_PCI6289 },
+ { PCI_VDEVICE(NI, 0x70ad), BOARD_PXI6251 },
+ { PCI_VDEVICE(NI, 0x70ae), BOARD_PXI6220 },
{ PCI_VDEVICE(NI, 0x70af), BOARD_PCI6221 },
{ PCI_VDEVICE(NI, 0x70b0), BOARD_PCI6220 },
+ { PCI_VDEVICE(NI, 0x70b1), BOARD_PXI6229 },
+ { PCI_VDEVICE(NI, 0x70b2), BOARD_PXI6259 },
+ { PCI_VDEVICE(NI, 0x70b3), BOARD_PXI6289 },
{ PCI_VDEVICE(NI, 0x70b4), BOARD_PCI6250 },
+ { PCI_VDEVICE(NI, 0x70b5), BOARD_PXI6221 },
{ PCI_VDEVICE(NI, 0x70b6), BOARD_PCI6280 },
{ PCI_VDEVICE(NI, 0x70b7), BOARD_PCI6254 },
{ PCI_VDEVICE(NI, 0x70b8), BOARD_PCI6251 },
+ { PCI_VDEVICE(NI, 0x70b9), BOARD_PXI6250 },
+ { PCI_VDEVICE(NI, 0x70ba), BOARD_PXI6254 },
+ { PCI_VDEVICE(NI, 0x70bb), BOARD_PXI6280 },
{ PCI_VDEVICE(NI, 0x70bc), BOARD_PCI6284 },
{ PCI_VDEVICE(NI, 0x70bd), BOARD_PCI6281 },
+ { PCI_VDEVICE(NI, 0x70be), BOARD_PXI6284 },
{ PCI_VDEVICE(NI, 0x70bf), BOARD_PXI6281 },
{ PCI_VDEVICE(NI, 0x70c0), BOARD_PCI6143 },
{ PCI_VDEVICE(NI, 0x70f2), BOARD_PCI6224 },
@@ -1299,11 +1450,11 @@ static const struct pci_device_id ni_pcimio_pci_table[] = {
{ PCI_VDEVICE(NI, 0x710d), BOARD_PXI6143 },
{ PCI_VDEVICE(NI, 0x716c), BOARD_PCI6225 },
{ PCI_VDEVICE(NI, 0x716d), BOARD_PXI6225 },
+ { PCI_VDEVICE(NI, 0x717d), BOARD_PCIE6251 },
{ PCI_VDEVICE(NI, 0x717f), BOARD_PCIE6259 },
{ PCI_VDEVICE(NI, 0x71bc), BOARD_PCI6221_37PIN },
- { PCI_VDEVICE(NI, 0x717d), BOARD_PCIE6251 },
{ PCI_VDEVICE(NI, 0x72e8), BOARD_PXIE6251 },
- { PCI_VDEVICE(NI, 0x70ad), BOARD_PXI6251 },
+ { PCI_VDEVICE(NI, 0x72e9), BOARD_PXIE6259 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, ni_pcimio_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h
index 4978358f9b13..2012033414d3 100644
--- a/drivers/staging/comedi/drivers/ni_tio.h
+++ b/drivers/staging/comedi/drivers/ni_tio.h
@@ -110,9 +110,9 @@ struct ni_gpct {
struct ni_gpct_device {
struct comedi_device *dev;
- void (*write)(struct ni_gpct *, unsigned int value,
+ void (*write)(struct ni_gpct *counter, unsigned int value,
enum ni_gpct_register);
- unsigned int (*read)(struct ni_gpct *, enum ni_gpct_register);
+ unsigned int (*read)(struct ni_gpct *counter, enum ni_gpct_register);
enum ni_gpct_variant variant;
struct ni_gpct *counters;
unsigned int num_counters;
@@ -121,28 +121,30 @@ struct ni_gpct_device {
};
struct ni_gpct_device *
-ni_gpct_device_construct(struct comedi_device *,
- void (*write)(struct ni_gpct *,
+ni_gpct_device_construct(struct comedi_device *dev,
+ void (*write)(struct ni_gpct *counter,
unsigned int value,
enum ni_gpct_register),
- unsigned int (*read)(struct ni_gpct *,
+ unsigned int (*read)(struct ni_gpct *counter,
enum ni_gpct_register),
enum ni_gpct_variant,
unsigned int num_counters);
-void ni_gpct_device_destroy(struct ni_gpct_device *);
-void ni_tio_init_counter(struct ni_gpct *);
-int ni_tio_insn_read(struct comedi_device *, struct comedi_subdevice *,
- struct comedi_insn *, unsigned int *data);
-int ni_tio_insn_config(struct comedi_device *, struct comedi_subdevice *,
- struct comedi_insn *, unsigned int *data);
-int ni_tio_insn_write(struct comedi_device *, struct comedi_subdevice *,
- struct comedi_insn *, unsigned int *data);
-int ni_tio_cmd(struct comedi_device *, struct comedi_subdevice *);
-int ni_tio_cmdtest(struct comedi_device *, struct comedi_subdevice *,
- struct comedi_cmd *);
-int ni_tio_cancel(struct ni_gpct *);
-void ni_tio_handle_interrupt(struct ni_gpct *, struct comedi_subdevice *);
-void ni_tio_set_mite_channel(struct ni_gpct *, struct mite_channel *);
-void ni_tio_acknowledge(struct ni_gpct *);
+void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev);
+void ni_tio_init_counter(struct ni_gpct *counter);
+int ni_tio_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int ni_tio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int ni_tio_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int ni_tio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+int ni_tio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+int ni_tio_cancel(struct ni_gpct *counter);
+void ni_tio_handle_interrupt(struct ni_gpct *counter,
+ struct comedi_subdevice *s);
+void ni_tio_set_mite_channel(struct ni_gpct *counter,
+ struct mite_channel *mite_chan);
+void ni_tio_acknowledge(struct ni_gpct *counter);
#endif /* _COMEDI_NI_TIO_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h
index b15b10833c42..4e024eb5656b 100644
--- a/drivers/staging/comedi/drivers/ni_tio_internal.h
+++ b/drivers/staging/comedi/drivers/ni_tio_internal.h
@@ -160,8 +160,9 @@
#define GI_TC_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(9) : BIT(6))
#define GI_GATE_INTERRUPT_ENABLE(x) (((x) % 2) ? BIT(10) : BIT(8))
-void ni_tio_write(struct ni_gpct *, unsigned int value, enum ni_gpct_register);
-unsigned int ni_tio_read(struct ni_gpct *, enum ni_gpct_register);
+void ni_tio_write(struct ni_gpct *counter, unsigned int value,
+ enum ni_gpct_register);
+unsigned int ni_tio_read(struct ni_gpct *counter, enum ni_gpct_register);
static inline bool
ni_tio_counting_mode_registers_present(const struct ni_gpct_device *counter_dev)
@@ -170,12 +171,13 @@ ni_tio_counting_mode_registers_present(const struct ni_gpct_device *counter_dev)
return counter_dev->variant != ni_gpct_variant_e_series;
}
-void ni_tio_set_bits(struct ni_gpct *, enum ni_gpct_register reg,
+void ni_tio_set_bits(struct ni_gpct *counter, enum ni_gpct_register reg,
unsigned int mask, unsigned int value);
-unsigned int ni_tio_get_soft_copy(const struct ni_gpct *,
+unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter,
enum ni_gpct_register reg);
-int ni_tio_arm(struct ni_gpct *, bool arm, unsigned int start_trigger);
-int ni_tio_set_gate_src(struct ni_gpct *, unsigned int gate, unsigned int src);
+int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger);
+int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned int gate,
+ unsigned int src);
#endif /* _COMEDI_NI_TIO_INTERNAL_H */
diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c
index 91dea25b5724..2644dd4d6143 100644
--- a/drivers/staging/comedi/proc.c
+++ b/drivers/staging/comedi/proc.c
@@ -80,15 +80,17 @@ static int comedi_proc_open(struct inode *inode, struct file *file)
}
static const struct file_operations comedi_proc_fops = {
+ .owner = THIS_MODULE,
.open = comedi_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-void comedi_proc_init(void)
+void __init comedi_proc_init(void)
{
- proc_create("comedi", 0644, NULL, &comedi_proc_fops);
+ if (!proc_create("comedi", 0444, NULL, &comedi_proc_fops))
+ pr_warn("comedi: unable to create proc entry\n");
}
void comedi_proc_cleanup(void)
diff --git a/drivers/staging/dgnc/TODO b/drivers/staging/dgnc/TODO
index 0e0825bd70ae..e26d1d6a5941 100644
--- a/drivers/staging/dgnc/TODO
+++ b/drivers/staging/dgnc/TODO
@@ -1,10 +1,9 @@
-* checkpatch fixes
* remove unnecessary comments
* remove unnecessary error messages. Example kzalloc() has its
own error message. Adding an extra one is useless.
* use goto statements for error handling when appropriate
* there is a lot of unnecessary code in the driver. It was
- originally a standalone driver. Remove uneeded code.
+ originally a standalone driver. Remove unneeded code.
Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
Cc: Lidza Louina <lidza.louina@gmail.com>
diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c
index 3f42fa8b0bf3..77b242e09932 100644
--- a/drivers/staging/emxx_udc/emxx_udc.c
+++ b/drivers/staging/emxx_udc/emxx_udc.c
@@ -553,28 +553,22 @@ static void _nbu2ss_dma_unmap_single(
/*-------------------------------------------------------------------------*/
/* Endpoint 0 OUT Transfer (PIO) */
-static int EP0_out_PIO(struct nbu2ss_udc *udc, u8 *pBuf, u32 length)
+static int ep0_out_pio(struct nbu2ss_udc *udc, u8 *buf, u32 length)
{
u32 i;
- int nret = 0;
- u32 iWordLength = 0;
- union usb_reg_access *pBuf32 = (union usb_reg_access *)pBuf;
+ u32 numreads = length / sizeof(u32);
+ union usb_reg_access *buf32 = (union usb_reg_access *)buf;
- /*------------------------------------------------------------*/
- /* Read Length */
- iWordLength = length / sizeof(u32);
+ if (!numreads)
+ return 0;
- /*------------------------------------------------------------*/
/* PIO Read */
- if (iWordLength) {
- for (i = 0; i < iWordLength; i++) {
- pBuf32->dw = _nbu2ss_readl(&udc->p_regs->EP0_READ);
- pBuf32++;
- }
- nret = iWordLength * sizeof(u32);
+ for (i = 0; i < numreads; i++) {
+ buf32->dw = _nbu2ss_readl(&udc->p_regs->EP0_READ);
+ buf32++;
}
- return nret;
+ return numreads * sizeof(u32);
}
/*-------------------------------------------------------------------------*/
@@ -758,7 +752,7 @@ static int _nbu2ss_ep0_out_transfer(
pBuffer = (u8 *)req->req.buf;
pBuffer += req->req.actual;
- result = EP0_out_PIO(udc, pBuffer
+ result = ep0_out_pio(udc, pBuffer
, min(iRemainSize, iRecvLength));
if (result < 0)
return result;
@@ -3137,7 +3131,7 @@ static const struct {
};
/*-------------------------------------------------------------------------*/
-static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
+static void nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
{
int i;
@@ -3168,7 +3162,7 @@ static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
/*-------------------------------------------------------------------------*/
/* platform_driver */
-static int __init nbu2ss_drv_contest_init(
+static int nbu2ss_drv_contest_init(
struct platform_device *pdev,
struct nbu2ss_udc *udc)
{
diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c
index a6e3af74a904..4ee76dbd30b5 100644
--- a/drivers/staging/fbtft/fb_agm1264k-fl.c
+++ b/drivers/staging/fbtft/fb_agm1264k-fl.c
@@ -185,9 +185,9 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
buf[i] = (u8)va_arg(args, unsigned int);
va_end(args);
- fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par,
- par->info->device, u8, buf, len, "%s: ", __func__);
- }
+ fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, par->info->device,
+ u8, buf, len, "%s: ", __func__);
+}
va_start(args, len);
@@ -246,7 +246,7 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
static void
construct_line_bitmap(struct fbtft_par *par, u8 *dest, signed short *src,
- int xs, int xe, int y)
+ int xs, int xe, int y)
{
int x, i;
@@ -361,7 +361,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
/* left half of display */
if (addr_win.xs < par->info->var.xres / 2) {
construct_line_bitmap(par, buf, convert_buf,
- addr_win.xs, par->info->var.xres / 2, y);
+ addr_win.xs,
+ par->info->var.xres / 2, y);
len = par->info->var.xres / 2 - addr_win.xs;
@@ -382,8 +383,9 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
/* right half of display */
if (addr_win.xe >= par->info->var.xres / 2) {
construct_line_bitmap(par, buf,
- convert_buf, par->info->var.xres / 2,
- addr_win.xe + 1, y);
+ convert_buf,
+ par->info->var.xres / 2,
+ addr_win.xe + 1, y);
len = addr_win.xe + 1 - par->info->var.xres / 2;
@@ -413,7 +415,7 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
static int write(struct fbtft_par *par, void *buf, size_t len)
{
fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
- "%s(len=%d): ", __func__, len);
+ "%s(len=%d): ", __func__, len);
gpio_set_value(par->RW, 0); /* set write mode */
diff --git a/drivers/staging/fbtft/fb_hx8340bn.c b/drivers/staging/fbtft/fb_hx8340bn.c
index 9970ed74bb38..c24331cc179c 100644
--- a/drivers/staging/fbtft/fb_hx8340bn.c
+++ b/drivers/staging/fbtft/fb_hx8340bn.c
@@ -37,7 +37,7 @@
"3 3 17 8 4 7 05 7 6 0 3 1 6 0 0 "
static bool emulate;
-module_param(emulate, bool, 0);
+module_param(emulate, bool, 0000);
MODULE_PARM_DESC(emulate, "Force emulation in 9-bit mode");
static int init_display(struct fbtft_par *par)
diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c
index a4710dc067ef..636cc83594bc 100644
--- a/drivers/staging/fbtft/fb_pcd8544.c
+++ b/drivers/staging/fbtft/fb_pcd8544.c
@@ -33,11 +33,11 @@
#define DEFAULT_GAMMA "40" /* gamma controls the contrast in this driver */
static unsigned int tc;
-module_param(tc, uint, 0);
+module_param(tc, uint, 0000);
MODULE_PARM_DESC(tc, "TC[1:0] Temperature coefficient: 0-3 (default: 0)");
static unsigned int bs = 4;
-module_param(bs, uint, 0);
+module_param(bs, uint, 0000);
MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
static int init_display(struct fbtft_par *par)
diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c
index 308a244972aa..89d36d6d0cd3 100644
--- a/drivers/staging/fbtft/fb_ra8875.c
+++ b/drivers/staging/fbtft/fb_ra8875.c
@@ -33,7 +33,7 @@ static int write_spi(struct fbtft_par *par, void *buf, size_t len)
struct spi_message m;
fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
- "%s(len=%d): ", __func__, len);
+ "%s(len=%d): ", __func__, len);
if (!par->spi) {
dev_err(par->info->device,
@@ -42,10 +42,6 @@ static int write_spi(struct fbtft_par *par, void *buf, size_t len)
}
spi_message_init(&m);
- if (par->txbuf.dma && buf == par->txbuf.buf) {
- t.tx_dma = par->txbuf.dma;
- m.is_dma_mapped = 1;
- }
spi_message_add_tail(&t, &m);
return spi_sync(par->spi, &m);
}
@@ -55,9 +51,9 @@ static int init_display(struct fbtft_par *par)
gpio_set_value(par->gpio.dc, 1);
fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
- "%s()\n", __func__);
+ "%s()\n", __func__);
fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
- "display size %dx%d\n",
+ "display size %dx%d\n",
par->info->var.xres,
par->info->var.yres);
@@ -215,7 +211,7 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
buf[i] = (u8)va_arg(args, unsigned int);
va_end(args);
fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, par->info->device,
- u8, buf, len, "%s: ", __func__);
+ u8, buf, len, "%s: ", __func__);
}
va_start(args, len);
@@ -266,7 +262,7 @@ static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
size_t startbyte_size = 0;
fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
- __func__, offset, len);
+ __func__, offset, len);
remain = len / 2;
vmem16 = (u16 *)(par->info->screen_buffer + offset);
diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c
index 25f9fbe1e76f..6dc085846948 100644
--- a/drivers/staging/fbtft/fb_ssd1289.c
+++ b/drivers/staging/fbtft/fb_ssd1289.c
@@ -30,7 +30,7 @@
"02 03 2 5 7 5 4 2 4 2"
static unsigned int reg11 = 0x6040;
-module_param(reg11, uint, 0);
+module_param(reg11, uint, 0000);
MODULE_PARM_DESC(reg11, "Register 11h value");
static int init_display(struct fbtft_par *par)
diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c
index 80fc57029fee..76f7da3c7703 100644
--- a/drivers/staging/fbtft/fb_ssd1306.c
+++ b/drivers/staging/fbtft/fb_ssd1306.c
@@ -62,6 +62,8 @@ static int init_display(struct fbtft_par *par)
write_reg(par, 0xA8);
if (par->info->var.yres == 64)
write_reg(par, 0x3F);
+ else if (par->info->var.yres == 48)
+ write_reg(par, 0x2F);
else
write_reg(par, 0x1F);
@@ -82,7 +84,7 @@ static int init_display(struct fbtft_par *par)
/* Vertical addressing mode */
write_reg(par, 0x01);
- /*Set Segment Re-map */
+ /* Set Segment Re-map */
/* column address 127 is mapped to SEG0 */
write_reg(par, 0xA0 | 0x1);
@@ -95,6 +97,9 @@ static int init_display(struct fbtft_par *par)
if (par->info->var.yres == 64)
/* A[4]=1b, Alternative COM pin configuration */
write_reg(par, 0x12);
+ else if (par->info->var.yres == 48)
+ /* A[4]=1b, Alternative COM pin configuration */
+ write_reg(par, 0x12);
else
/* A[4]=0b, Sequential COM pin configuration */
write_reg(par, 0x02);
@@ -124,6 +129,19 @@ static int init_display(struct fbtft_par *par)
return 0;
}
+static void set_addr_win_64x48(struct fbtft_par *par)
+{
+ /* Set Column Address */
+ write_reg(par, 0x21);
+ write_reg(par, 0x20);
+ write_reg(par, 0x5F);
+
+ /* Set Page Address */
+ write_reg(par, 0x22);
+ write_reg(par, 0x0);
+ write_reg(par, 0x5);
+}
+
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
/* Set Lower Column Start Address for Page Addressing Mode */
@@ -132,6 +150,9 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
write_reg(par, 0x10 | 0x0);
/* Set Display Start Line */
write_reg(par, 0x40 | 0x0);
+
+ if (par->info->var.xres == 64 && par->info->var.yres == 48)
+ set_addr_win_64x48(par);
}
static int blank(struct fbtft_par *par, bool on)
@@ -162,26 +183,24 @@ static int set_gamma(struct fbtft_par *par, unsigned long *curves)
static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
{
u16 *vmem16 = (u16 *)par->info->screen_buffer;
+ u32 xres = par->info->var.xres;
+ u32 yres = par->info->var.yres;
u8 *buf = par->txbuf.buf;
int x, y, i;
int ret = 0;
- for (x = 0; x < par->info->var.xres; x++) {
- for (y = 0; y < par->info->var.yres/8; y++) {
+ for (x = 0; x < xres; x++) {
+ for (y = 0; y < yres / 8; y++) {
*buf = 0x00;
for (i = 0; i < 8; i++)
- *buf |= (vmem16[(y * 8 + i) *
- par->info->var.xres + x] ?
- 1 : 0) << i;
+ *buf |= (vmem16[(y * 8 + i) * xres + x] ? 1 : 0) << i;
buf++;
}
}
/* Write data */
gpio_set_value(par->gpio.dc, 1);
- ret = par->fbtftops.write(par, par->txbuf.buf,
- par->info->var.xres * par->info->var.yres /
- 8);
+ ret = par->fbtftops.write(par, par->txbuf.buf, xres * yres / 8);
if (ret < 0)
dev_err(par->info->device, "write failed and returned: %d\n",
ret);
diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c
index ea2ddacb9468..ae8393b023e4 100644
--- a/drivers/staging/fbtft/fb_tls8204.c
+++ b/drivers/staging/fbtft/fb_tls8204.c
@@ -36,7 +36,7 @@
#define DEFAULT_GAMMA "40"
static unsigned int bs = 4;
-module_param(bs, uint, 0);
+module_param(bs, uint, 0000);
MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
static int init_display(struct fbtft_par *par)
diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c
index b33b73f17da4..48e3b3fd9fed 100644
--- a/drivers/staging/fbtft/fb_uc1611.c
+++ b/drivers/staging/fbtft/fb_uc1611.c
@@ -42,30 +42,30 @@
/* BR -> actual ratio: 0-3 -> 5, 10, 11, 13 */
static unsigned int ratio = 2;
-module_param(ratio, uint, 0);
+module_param(ratio, uint, 0000);
MODULE_PARM_DESC(ratio, "BR[1:0] Bias voltage ratio: 0-3 (default: 2)");
static unsigned int gain = 3;
-module_param(gain, uint, 0);
+module_param(gain, uint, 0000);
MODULE_PARM_DESC(gain, "GN[1:0] Bias voltage gain: 0-3 (default: 3)");
static unsigned int pot = 16;
-module_param(pot, uint, 0);
+module_param(pot, uint, 0000);
MODULE_PARM_DESC(pot, "PM[6:0] Bias voltage pot.: 0-63 (default: 16)");
/* TC -> % compensation per deg C: 0-3 -> -.05, -.10, -.015, -.20 */
static unsigned int temp;
-module_param(temp, uint, 0);
+module_param(temp, uint, 0000);
MODULE_PARM_DESC(temp, "TC[1:0] Temperature compensation: 0-3 (default: 0)");
/* PC[1:0] -> LCD capacitance: 0-3 -> <20nF, 20-28 nF, 29-40 nF, 40-56 nF */
static unsigned int load = 1;
-module_param(load, uint, 0);
+module_param(load, uint, 0000);
MODULE_PARM_DESC(load, "PC[1:0] Panel Loading: 0-3 (default: 1)");
/* PC[3:2] -> V_LCD: 0, 1, 3 -> ext., int. with ratio = 5, int. standard */
static unsigned int pump = 3;
-module_param(pump, uint, 0);
+module_param(pump, uint, 0000);
MODULE_PARM_DESC(pump, "PC[3:2] Pump control: 0,1,3 (default: 3)");
static int init_display(struct fbtft_par *par)
diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c
index a52e28a48825..429304546b44 100644
--- a/drivers/staging/fbtft/fb_watterott.c
+++ b/drivers/staging/fbtft/fb_watterott.c
@@ -40,7 +40,7 @@
#define COLOR_RGB565 16
static short mode = 565;
-module_param(mode, short, 0);
+module_param(mode, short, 0000);
MODULE_PARM_DESC(mode, "RGB color transfer mode: 332, 565 (default)");
static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
index bbe89c9c4fb9..51c4481db451 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -32,7 +32,6 @@
#include <linux/backlight.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
-#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <video/mipi_display.h>
@@ -41,15 +40,9 @@
#include "internal.h"
static unsigned long debug;
-module_param(debug, ulong, 0);
+module_param(debug, ulong, 0000);
MODULE_PARM_DESC(debug, "override device debug level");
-#ifdef CONFIG_HAS_DMA
-static bool dma = true;
-module_param(dma, bool, 0);
-MODULE_PARM_DESC(dma, "Use DMA buffer");
-#endif
-
void fbtft_dbg_hex(const struct device *dev, int groupsize,
void *buf, size_t len, const char *fmt, ...)
{
@@ -337,10 +330,10 @@ static void fbtft_reset(struct fbtft_par *par)
if (par->gpio.reset == -1)
return;
fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__);
- gpio_set_value(par->gpio.reset, 0);
- udelay(20);
- gpio_set_value(par->gpio.reset, 1);
- mdelay(120);
+ gpio_set_value_cansleep(par->gpio.reset, 0);
+ usleep_range(20, 40);
+ gpio_set_value_cansleep(par->gpio.reset, 1);
+ msleep(120);
}
static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line,
@@ -836,17 +829,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
#endif
if (txbuflen > 0) {
-#ifdef CONFIG_HAS_DMA
- if (dma) {
- dev->coherent_dma_mask = ~0;
- txbuf = dmam_alloc_coherent(dev, txbuflen,
- &par->txbuf.dma, GFP_DMA);
- } else
-#endif
- {
- txbuf = devm_kzalloc(par->info->device,
- txbuflen, GFP_KERNEL);
- }
+ txbuf = devm_kzalloc(par->info->device, txbuflen, GFP_KERNEL);
if (!txbuf)
goto alloc_fail;
par->txbuf.buf = txbuf;
@@ -975,8 +958,7 @@ int fbtft_register_framebuffer(struct fb_info *fb_info)
fbtft_sysfs_init(par);
if (par->txbuf.buf)
- sprintf(text1, ", %zu KiB %sbuffer memory",
- par->txbuf.len >> 10, par->txbuf.dma ? "DMA " : "");
+ sprintf(text1, ", %zu KiB buffer memory", par->txbuf.len >> 10);
if (spi)
sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num,
spi->chip_select, spi->max_speed_hz / 1000000);
diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c
index 4dcea2e0b3ae..d86840548b74 100644
--- a/drivers/staging/fbtft/fbtft-io.c
+++ b/drivers/staging/fbtft/fbtft-io.c
@@ -22,10 +22,6 @@ int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len)
}
spi_message_init(&m);
- if (par->txbuf.dma && buf == par->txbuf.buf) {
- t.tx_dma = par->txbuf.dma;
- m.is_dma_mapped = 1;
- }
spi_message_add_tail(&t, &m);
return spi_sync(par->spi, &m);
}
diff --git a/drivers/staging/fbtft/fbtft-sysfs.c b/drivers/staging/fbtft/fbtft-sysfs.c
index 8d8bd12b90a1..5922f1b6d8d6 100644
--- a/drivers/staging/fbtft/fbtft-sysfs.c
+++ b/drivers/staging/fbtft/fbtft-sysfs.c
@@ -4,7 +4,6 @@
static int get_next_ulong(char **str_p, unsigned long *val, char *sep, int base)
{
char *p_val;
- int ret;
if (!str_p || !(*str_p))
return -EINVAL;
@@ -14,11 +13,7 @@ static int get_next_ulong(char **str_p, unsigned long *val, char *sep, int base)
if (!p_val)
return -EINVAL;
- ret = kstrtoul(p_val, base, val);
- if (ret)
- return -EINVAL;
-
- return 0;
+ return kstrtoul(p_val, base, val);
}
int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves,
diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h
index aacdde92cc2e..b09804773ff2 100644
--- a/drivers/staging/fbtft/fbtft.h
+++ b/drivers/staging/fbtft/fbtft.h
@@ -209,7 +209,6 @@ struct fbtft_par {
u32 pseudo_palette[16];
struct {
void *buf;
- dma_addr_t dma;
size_t len;
} txbuf;
u8 *buf;
diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c
index de46f8d988d2..9ffb9cecc465 100644
--- a/drivers/staging/fbtft/fbtft_device.c
+++ b/drivers/staging/fbtft/fbtft_device.c
@@ -29,85 +29,85 @@ static struct spi_device *spi_device;
static struct platform_device *p_device;
static char *name;
-module_param(name, charp, 0);
+module_param(name, charp, 0000);
MODULE_PARM_DESC(name, "Devicename (required). name=list => list all supported devices.");
static unsigned int rotate;
-module_param(rotate, uint, 0);
+module_param(rotate, uint, 0000);
MODULE_PARM_DESC(rotate,
"Angle to rotate display counter clockwise: 0, 90, 180, 270");
static unsigned int busnum;
-module_param(busnum, uint, 0);
+module_param(busnum, uint, 0000);
MODULE_PARM_DESC(busnum, "SPI bus number (default=0)");
static unsigned int cs;
-module_param(cs, uint, 0);
+module_param(cs, uint, 0000);
MODULE_PARM_DESC(cs, "SPI chip select (default=0)");
static unsigned int speed;
-module_param(speed, uint, 0);
+module_param(speed, uint, 0000);
MODULE_PARM_DESC(speed, "SPI speed (override device default)");
static int mode = -1;
-module_param(mode, int, 0);
+module_param(mode, int, 0000);
MODULE_PARM_DESC(mode, "SPI mode (override device default)");
static char *gpios;
-module_param(gpios, charp, 0);
+module_param(gpios, charp, 0000);
MODULE_PARM_DESC(gpios,
"List of gpios. Comma separated with the form: reset:23,dc:24 (when overriding the default, all gpios must be specified)");
static unsigned int fps;
-module_param(fps, uint, 0);
+module_param(fps, uint, 0000);
MODULE_PARM_DESC(fps, "Frames per second (override driver default)");
static char *gamma;
-module_param(gamma, charp, 0);
+module_param(gamma, charp, 0000);
MODULE_PARM_DESC(gamma,
"String representation of Gamma Curve(s). Driver specific.");
static int txbuflen;
-module_param(txbuflen, int, 0);
+module_param(txbuflen, int, 0000);
MODULE_PARM_DESC(txbuflen, "txbuflen (override driver default)");
static int bgr = -1;
-module_param(bgr, int, 0);
+module_param(bgr, int, 0000);
MODULE_PARM_DESC(bgr,
"BGR bit (supported by some drivers).");
static unsigned int startbyte;
-module_param(startbyte, uint, 0);
+module_param(startbyte, uint, 0000);
MODULE_PARM_DESC(startbyte, "Sets the Start byte used by some SPI displays.");
static bool custom;
-module_param(custom, bool, 0);
+module_param(custom, bool, 0000);
MODULE_PARM_DESC(custom, "Add a custom display device. Use speed= argument to make it a SPI device, else platform_device");
static unsigned int width;
-module_param(width, uint, 0);
+module_param(width, uint, 0000);
MODULE_PARM_DESC(width, "Display width, used with the custom argument");
static unsigned int height;
-module_param(height, uint, 0);
+module_param(height, uint, 0000);
MODULE_PARM_DESC(height, "Display height, used with the custom argument");
static unsigned int buswidth = 8;
-module_param(buswidth, uint, 0);
+module_param(buswidth, uint, 0000);
MODULE_PARM_DESC(buswidth, "Display bus width, used with the custom argument");
static s16 init[FBTFT_MAX_INIT_SEQUENCE];
static int init_num;
-module_param_array(init, short, &init_num, 0);
+module_param_array(init, short, &init_num, 0000);
MODULE_PARM_DESC(init, "Init sequence, used with the custom argument");
static unsigned long debug;
-module_param(debug, ulong, 0);
+module_param(debug, ulong, 0000);
MODULE_PARM_DESC(debug,
"level: 0-7 (the remaining 29 bits is for advanced usage)");
static unsigned int verbose = 3;
-module_param(verbose, uint, 0);
+module_param(verbose, uint, 0000);
MODULE_PARM_DESC(verbose,
"0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c
index ded10718712b..af8422e18780 100644
--- a/drivers/staging/fbtft/flexfb.c
+++ b/drivers/staging/fbtft/flexfb.c
@@ -27,40 +27,40 @@
#define DRVNAME "flexfb"
static char *chip;
-module_param(chip, charp, 0);
+module_param(chip, charp, 0000);
MODULE_PARM_DESC(chip, "LCD controller");
static unsigned int width;
-module_param(width, uint, 0);
+module_param(width, uint, 0000);
MODULE_PARM_DESC(width, "Display width");
static unsigned int height;
-module_param(height, uint, 0);
+module_param(height, uint, 0000);
MODULE_PARM_DESC(height, "Display height");
static s16 init[512];
static int init_num;
-module_param_array(init, short, &init_num, 0);
+module_param_array(init, short, &init_num, 0000);
MODULE_PARM_DESC(init, "Init sequence");
static unsigned int setaddrwin;
-module_param(setaddrwin, uint, 0);
+module_param(setaddrwin, uint, 0000);
MODULE_PARM_DESC(setaddrwin, "Which set_addr_win() implementation to use");
static unsigned int buswidth = 8;
-module_param(buswidth, uint, 0);
+module_param(buswidth, uint, 0000);
MODULE_PARM_DESC(buswidth, "Width of databus (default: 8)");
static unsigned int regwidth = 8;
-module_param(regwidth, uint, 0);
+module_param(regwidth, uint, 0000);
MODULE_PARM_DESC(regwidth, "Width of controller register (default: 8)");
static bool nobacklight;
-module_param(nobacklight, bool, 0);
+module_param(nobacklight, bool, 0000);
MODULE_PARM_DESC(nobacklight, "Turn off backlight functionality.");
static bool latched;
-module_param(latched, bool, 0);
+module_param(latched, bool, 0000);
MODULE_PARM_DESC(latched, "Use with latched 16-bit databus");
static s16 *initp;
@@ -418,22 +418,6 @@ static const struct flexfb_lcd_controller flexfb_chip_table[] = {
.init_seq_sz = ARRAY_SIZE(ili9225_init),
},
{
- .name = "ili9225",
- .width = 176,
- .height = 220,
- .regwidth = 16,
- .init_seq = ili9225_init,
- .init_seq_sz = ARRAY_SIZE(ili9225_init),
- },
- {
- .name = "ili9225",
- .width = 176,
- .height = 220,
- .regwidth = 16,
- .init_seq = ili9225_init,
- .init_seq_sz = ARRAY_SIZE(ili9225_init),
- },
- {
.name = "ili9320",
.width = 240,
.height = 320,
diff --git a/drivers/staging/gdm724x/gdm_endian.c b/drivers/staging/gdm724x/gdm_endian.c
index d7144e7afa32..d0b43e20ec06 100644
--- a/drivers/staging/gdm724x/gdm_endian.c
+++ b/drivers/staging/gdm724x/gdm_endian.c
@@ -22,34 +22,34 @@ void gdm_set_endian(struct gdm_endian *ed, u8 dev_endian)
ed->dev_ed = ENDIANNESS_LITTLE;
}
-u16 gdm_cpu_to_dev16(struct gdm_endian *ed, u16 x)
+__dev16 gdm_cpu_to_dev16(struct gdm_endian *ed, u16 x)
{
if (ed->dev_ed == ENDIANNESS_LITTLE)
- return cpu_to_le16(x);
+ return (__force __dev16)cpu_to_le16(x);
else
- return cpu_to_be16(x);
+ return (__force __dev16)cpu_to_be16(x);
}
-u16 gdm_dev16_to_cpu(struct gdm_endian *ed, u16 x)
+u16 gdm_dev16_to_cpu(struct gdm_endian *ed, __dev16 x)
{
if (ed->dev_ed == ENDIANNESS_LITTLE)
- return le16_to_cpu(x);
+ return le16_to_cpu((__force __le16)x);
else
- return be16_to_cpu(x);
+ return be16_to_cpu((__force __be16)x);
}
-u32 gdm_cpu_to_dev32(struct gdm_endian *ed, u32 x)
+__dev32 gdm_cpu_to_dev32(struct gdm_endian *ed, u32 x)
{
if (ed->dev_ed == ENDIANNESS_LITTLE)
- return cpu_to_le32(x);
+ return (__force __dev32)cpu_to_le32(x);
else
- return cpu_to_be32(x);
+ return (__force __dev32)cpu_to_be32(x);
}
-u32 gdm_dev32_to_cpu(struct gdm_endian *ed, u32 x)
+u32 gdm_dev32_to_cpu(struct gdm_endian *ed, __dev32 x)
{
if (ed->dev_ed == ENDIANNESS_LITTLE)
- return le32_to_cpu(x);
+ return le32_to_cpu((__force __le32)x);
else
- return be32_to_cpu(x);
+ return be32_to_cpu((__force __be32)x);
}
diff --git a/drivers/staging/gdm724x/gdm_endian.h b/drivers/staging/gdm724x/gdm_endian.h
index 6177870830e5..a785f30bb369 100644
--- a/drivers/staging/gdm724x/gdm_endian.h
+++ b/drivers/staging/gdm724x/gdm_endian.h
@@ -16,6 +16,13 @@
#include <linux/types.h>
+/*
+ * For data in "device-endian" byte order (device endianness is model
+ * dependent). Analogous to __leXX or __beXX.
+ */
+typedef __u32 __bitwise __dev32;
+typedef __u16 __bitwise __dev16;
+
enum {
ENDIANNESS_MIN = 0,
ENDIANNESS_UNKNOWN,
@@ -30,9 +37,9 @@ struct gdm_endian {
};
void gdm_set_endian(struct gdm_endian *ed, u8 dev_endian);
-u16 gdm_cpu_to_dev16(struct gdm_endian *ed, u16 x);
-u16 gdm_dev16_to_cpu(struct gdm_endian *ed, u16 x);
-u32 gdm_cpu_to_dev32(struct gdm_endian *ed, u32 x);
-u32 gdm_dev32_to_cpu(struct gdm_endian *ed, u32 x);
+__dev16 gdm_cpu_to_dev16(struct gdm_endian *ed, u16 x);
+u16 gdm_dev16_to_cpu(struct gdm_endian *ed, __dev16 x);
+__dev32 gdm_cpu_to_dev32(struct gdm_endian *ed, u32 x);
+u32 gdm_dev32_to_cpu(struct gdm_endian *ed, __dev32 x);
#endif /*__GDM_ENDIAN_H__*/
diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c
index e72dfa9699f3..a182757544c8 100644
--- a/drivers/staging/gdm724x/gdm_lte.c
+++ b/drivers/staging/gdm724x/gdm_lte.c
@@ -688,6 +688,7 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len)
struct net_device *dev;
struct multi_sdu *multi_sdu = (struct multi_sdu *)buf;
struct sdu *sdu = NULL;
+ struct gdm_endian *endian = phy_dev->get_endian(phy_dev->priv_dev);
u8 *data = (u8 *)multi_sdu->data;
u16 i = 0;
u16 num_packet;
@@ -696,20 +697,15 @@ static void gdm_lte_multi_sdu_pkt(struct phy_dev *phy_dev, char *buf, int len)
u32 nic_type;
u8 index;
- hci_len = gdm_dev16_to_cpu(phy_dev->get_endian(phy_dev->priv_dev),
- multi_sdu->len);
- num_packet = gdm_dev16_to_cpu(phy_dev->get_endian(phy_dev->priv_dev),
- multi_sdu->num_packet);
+ hci_len = gdm_dev16_to_cpu(endian, multi_sdu->len);
+ num_packet = gdm_dev16_to_cpu(endian, multi_sdu->num_packet);
for (i = 0; i < num_packet; i++) {
sdu = (struct sdu *)data;
- cmd_evt = gdm_dev16_to_cpu(phy_dev->
- get_endian(phy_dev->priv_dev), sdu->cmd_evt);
- hci_len = gdm_dev16_to_cpu(phy_dev->
- get_endian(phy_dev->priv_dev), sdu->len);
- nic_type = gdm_dev32_to_cpu(phy_dev->
- get_endian(phy_dev->priv_dev), sdu->nic_type);
+ cmd_evt = gdm_dev16_to_cpu(endian, sdu->cmd_evt);
+ hci_len = gdm_dev16_to_cpu(endian, sdu->len);
+ nic_type = gdm_dev32_to_cpu(endian, sdu->nic_type);
if (cmd_evt != LTE_RX_SDU) {
pr_err("rx sdu wrong hci %04x\n", cmd_evt);
@@ -761,6 +757,7 @@ static int gdm_lte_receive_pkt(struct phy_dev *phy_dev, char *buf, int len)
{
struct hci_packet *hci = (struct hci_packet *)buf;
struct hci_pdn_table_ind *pdn_table = (struct hci_pdn_table_ind *)buf;
+ struct gdm_endian *endian = phy_dev->get_endian(phy_dev->priv_dev);
struct sdu *sdu;
struct net_device *dev;
int ret = 0;
@@ -771,8 +768,7 @@ static int gdm_lte_receive_pkt(struct phy_dev *phy_dev, char *buf, int len)
if (!len)
return ret;
- cmd_evt = gdm_dev16_to_cpu(phy_dev->get_endian(phy_dev->priv_dev),
- hci->cmd_evt);
+ cmd_evt = gdm_dev16_to_cpu(endian, hci->cmd_evt);
dev = phy_dev->dev[0];
if (!dev)
@@ -781,8 +777,7 @@ static int gdm_lte_receive_pkt(struct phy_dev *phy_dev, char *buf, int len)
switch (cmd_evt) {
case LTE_RX_SDU:
sdu = (struct sdu *)hci->data;
- nic_type = gdm_dev32_to_cpu(phy_dev->
- get_endian(phy_dev->priv_dev), sdu->nic_type);
+ nic_type = gdm_dev32_to_cpu(endian, sdu->nic_type);
index = find_dev_index(nic_type);
dev = phy_dev->dev[index];
gdm_lte_netif_rx(dev, hci->data, len, nic_type);
@@ -797,9 +792,7 @@ static int gdm_lte_receive_pkt(struct phy_dev *phy_dev, char *buf, int len)
break;
case LTE_PDN_TABLE_IND:
pdn_table = (struct hci_pdn_table_ind *)buf;
- nic_type = gdm_dev32_to_cpu(phy_dev->
- get_endian(phy_dev->priv_dev),
- pdn_table->nic_type);
+ nic_type = gdm_dev32_to_cpu(endian, pdn_table->nic_type);
index = find_dev_index(nic_type);
dev = phy_dev->dev[index];
gdm_lte_pdn_table(dev, buf, len);
diff --git a/drivers/staging/gdm724x/hci_packet.h b/drivers/staging/gdm724x/hci_packet.h
index 4644f84038c9..22ce8b9477b6 100644
--- a/drivers/staging/gdm724x/hci_packet.h
+++ b/drivers/staging/gdm724x/hci_packet.h
@@ -36,8 +36,8 @@
#define NIC_TYPE_F_VLAN 0x00100000
struct hci_packet {
- u16 cmd_evt;
- u16 len;
+ __dev16 cmd_evt;
+ __dev16 len;
u8 data[0];
} __packed;
@@ -48,45 +48,45 @@ struct tlv {
} __packed;
struct sdu_header {
- u16 cmd_evt;
- u16 len;
- u32 dftEpsId;
- u32 bearer_ID;
- u32 nic_type;
+ __dev16 cmd_evt;
+ __dev16 len;
+ __dev32 dftEpsId;
+ __dev32 bearer_ID;
+ __dev32 nic_type;
} __packed;
struct sdu {
- u16 cmd_evt;
- u16 len;
- u32 dft_eps_ID;
- u32 bearer_ID;
- u32 nic_type;
+ __dev16 cmd_evt;
+ __dev16 len;
+ __dev32 dft_eps_ID;
+ __dev32 bearer_ID;
+ __dev32 nic_type;
u8 data[0];
} __packed;
struct multi_sdu {
- u16 cmd_evt;
- u16 len;
- u16 num_packet;
- u16 reserved;
+ __dev16 cmd_evt;
+ __dev16 len;
+ __dev16 num_packet;
+ __dev16 reserved;
u8 data[0];
} __packed;
struct hci_pdn_table_ind {
- u16 cmd_evt;
- u16 len;
+ __dev16 cmd_evt;
+ __dev16 len;
u8 activate;
- u32 dft_eps_id;
- u32 nic_type;
+ __dev32 dft_eps_id;
+ __dev32 nic_type;
u8 pdn_type;
u8 ipv4_addr[4];
u8 ipv6_intf_id[8];
} __packed;
struct hci_connect_ind {
- u16 cmd_evt;
- u16 len;
- u32 connect;
+ __dev16 cmd_evt;
+ __dev16 len;
+ __dev32 connect;
} __packed;
#endif /* _HCI_PACKET_H_ */
diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile
index f337b7b70782..b26b9a35bdd5 100644
--- a/drivers/staging/greybus/Makefile
+++ b/drivers/staging/greybus/Makefile
@@ -10,9 +10,7 @@ greybus-y := core.o \
control.o \
svc.o \
svc_watchdog.o \
- operation.o \
- timesync.o \
- timesync_platform.o
+ operation.o
obj-$(CONFIG_GREYBUS) += greybus.o
diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c
index 3fda0cd6bb42..17fa29061e5b 100644
--- a/drivers/staging/greybus/arche-apb-ctrl.c
+++ b/drivers/staging/greybus/arche-apb-ctrl.c
@@ -461,7 +461,7 @@ static int arche_apb_ctrl_remove(struct platform_device *pdev)
return 0;
}
-static int arche_apb_ctrl_suspend(struct device *dev)
+static int __maybe_unused arche_apb_ctrl_suspend(struct device *dev)
{
/*
* If timing profile permits, we may shutdown bridge
@@ -475,7 +475,7 @@ static int arche_apb_ctrl_suspend(struct device *dev)
return 0;
}
-static int arche_apb_ctrl_resume(struct device *dev)
+static int __maybe_unused arche_apb_ctrl_resume(struct device *dev)
{
/*
* Atleast for ES2 we have to meet the delay requirement between
diff --git a/drivers/staging/greybus/arche_platform.h b/drivers/staging/greybus/arche_platform.h
index bd12345b82a2..c0591df9b9d6 100644
--- a/drivers/staging/greybus/arche_platform.h
+++ b/drivers/staging/greybus/arche_platform.h
@@ -10,8 +10,6 @@
#ifndef __ARCHE_PLATFORM_H
#define __ARCHE_PLATFORM_H
-#include "timesync.h"
-
enum arche_platform_state {
ARCHE_PLATFORM_STATE_OFF,
ARCHE_PLATFORM_STATE_ACTIVE,
diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c
index f8862c6d7102..30941f9e380d 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -496,6 +496,11 @@ static int gbcodec_hw_params(struct snd_pcm_substream *substream,
gb_pm_runtime_put_noidle(bundle);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ sig_bits = dai->driver->playback.sig_bits;
+ else
+ sig_bits = dai->driver->capture.sig_bits;
+
params->state = GBAUDIO_CODEC_HWPARAMS;
params->format = format;
params->rate = rate;
@@ -689,6 +694,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.rate_min = 48000,
.channels_min = 1,
.channels_max = 2,
+ .sig_bits = 16,
},
.capture = {
.stream_name = "I2S 0 Capture",
@@ -698,6 +704,7 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
.rate_min = 48000,
.channels_min = 1,
.channels_max = 2,
+ .sig_bits = 16,
},
.ops = &gbcodec_dai_ops,
},
@@ -1019,47 +1026,16 @@ static int gbcodec_remove(struct snd_soc_codec *codec)
return 0;
}
-static u8 gbcodec_reg[GBCODEC_REG_COUNT] = {
- [GBCODEC_CTL_REG] = GBCODEC_CTL_REG_DEFAULT,
- [GBCODEC_MUTE_REG] = GBCODEC_MUTE_REG_DEFAULT,
- [GBCODEC_PB_LVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT,
- [GBCODEC_PB_RVOL_REG] = GBCODEC_PB_VOL_REG_DEFAULT,
- [GBCODEC_CAP_LVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT,
- [GBCODEC_CAP_RVOL_REG] = GBCODEC_CAP_VOL_REG_DEFAULT,
- [GBCODEC_APB1_MUX_REG] = GBCODEC_APB1_MUX_REG_DEFAULT,
- [GBCODEC_APB2_MUX_REG] = GBCODEC_APB2_MUX_REG_DEFAULT,
-};
-
static int gbcodec_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- int ret = 0;
-
- if (reg == SND_SOC_NOPM)
- return 0;
-
- BUG_ON(reg >= GBCODEC_REG_COUNT);
-
- gbcodec_reg[reg] = value;
- dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, value);
-
- return ret;
+ return 0;
}
static unsigned int gbcodec_read(struct snd_soc_codec *codec,
unsigned int reg)
{
- unsigned int val = 0;
-
- if (reg == SND_SOC_NOPM)
- return 0;
-
- BUG_ON(reg >= GBCODEC_REG_COUNT);
-
- val = gbcodec_reg[reg];
- dev_dbg(codec->dev, "reg[%d] = 0x%x\n", reg, val);
-
- return val;
+ return 0;
}
static struct snd_soc_codec_driver soc_codec_dev_gbaudio = {
@@ -1069,10 +1045,6 @@ static struct snd_soc_codec_driver soc_codec_dev_gbaudio = {
.read = gbcodec_read,
.write = gbcodec_write,
- .reg_cache_size = GBCODEC_REG_COUNT,
- .reg_cache_default = gbcodec_reg_defaults,
- .reg_word_size = 1,
-
.idle_bias_off = true,
.ignore_pmdown_time = 1,
};
diff --git a/drivers/staging/greybus/audio_codec.h b/drivers/staging/greybus/audio_codec.h
index 62fd93939a1f..6fb064c69a36 100644
--- a/drivers/staging/greybus/audio_codec.h
+++ b/drivers/staging/greybus/audio_codec.h
@@ -24,18 +24,6 @@ enum {
NUM_CODEC_DAIS,
};
-enum gbcodec_reg_index {
- GBCODEC_CTL_REG,
- GBCODEC_MUTE_REG,
- GBCODEC_PB_LVOL_REG,
- GBCODEC_PB_RVOL_REG,
- GBCODEC_CAP_LVOL_REG,
- GBCODEC_CAP_RVOL_REG,
- GBCODEC_APB1_MUX_REG,
- GBCODEC_APB2_MUX_REG,
- GBCODEC_REG_COUNT
-};
-
/* device_type should be same as defined in audio.h (Android media layer) */
enum {
GBAUDIO_DEVICE_NONE = 0x0,
@@ -51,42 +39,9 @@ enum {
GBAUDIO_DEVICE_IN_WIRED_HEADSET = GBAUDIO_DEVICE_BIT_IN | 0x10,
};
-/* bit 0-SPK, 1-HP, 2-DAC,
- * 4-MIC, 5-HSMIC, 6-MIC2
- */
-#define GBCODEC_CTL_REG_DEFAULT 0x00
-
-/* bit 0,1 - APB1-PB-L/R
- * bit 2,3 - APB2-PB-L/R
- * bit 4,5 - APB1-Cap-L/R
- * bit 6,7 - APB2-Cap-L/R
- */
-#define GBCODEC_MUTE_REG_DEFAULT 0x00
-
-/* 0-127 steps */
-#define GBCODEC_PB_VOL_REG_DEFAULT 0x00
-#define GBCODEC_CAP_VOL_REG_DEFAULT 0x00
-
-/* bit 0,1,2 - PB stereo, left, right
- * bit 8,9,10 - Cap stereo, left, right
- */
-#define GBCODEC_APB1_MUX_REG_DEFAULT 0x00
-#define GBCODEC_APB2_MUX_REG_DEFAULT 0x00
-
#define GBCODEC_JACK_MASK 0x0000FFFF
#define GBCODEC_JACK_BUTTON_MASK 0xFFFF0000
-static const u8 gbcodec_reg_defaults[GBCODEC_REG_COUNT] = {
- GBCODEC_CTL_REG_DEFAULT,
- GBCODEC_MUTE_REG_DEFAULT,
- GBCODEC_PB_VOL_REG_DEFAULT,
- GBCODEC_PB_VOL_REG_DEFAULT,
- GBCODEC_CAP_VOL_REG_DEFAULT,
- GBCODEC_CAP_VOL_REG_DEFAULT,
- GBCODEC_APB1_MUX_REG_DEFAULT,
- GBCODEC_APB2_MUX_REG_DEFAULT,
-};
-
enum gbaudio_codec_state {
GBAUDIO_CODEC_SHUTDOWN = 0,
GBAUDIO_CODEC_STARTUP,
@@ -116,7 +71,6 @@ struct gbaudio_codec_info {
/* to maintain runtime stream params for each DAI */
struct list_head dai_list;
struct mutex lock;
- u8 reg[GBCODEC_REG_COUNT];
};
struct gbaudio_widget {
diff --git a/drivers/staging/greybus/audio_gb.c b/drivers/staging/greybus/audio_gb.c
index 42f287dd7b84..7884d8482dc0 100644
--- a/drivers/staging/greybus/audio_gb.c
+++ b/drivers/staging/greybus/audio_gb.c
@@ -108,7 +108,7 @@ int gb_audio_gb_disable_widget(struct gb_connection *connection,
EXPORT_SYMBOL_GPL(gb_audio_gb_disable_widget);
int gb_audio_gb_get_pcm(struct gb_connection *connection, u16 data_cport,
- uint32_t *format, uint32_t *rate, u8 *channels,
+ u32 *format, u32 *rate, u8 *channels,
u8 *sig_bits)
{
struct gb_audio_get_pcm_request req;
@@ -132,7 +132,7 @@ int gb_audio_gb_get_pcm(struct gb_connection *connection, u16 data_cport,
EXPORT_SYMBOL_GPL(gb_audio_gb_get_pcm);
int gb_audio_gb_set_pcm(struct gb_connection *connection, u16 data_cport,
- uint32_t format, uint32_t rate, u8 channels,
+ u32 format, u32 rate, u8 channels,
u8 sig_bits)
{
struct gb_audio_set_pcm_request req;
diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c
index 17a9948b1ba1..094c3be79b33 100644
--- a/drivers/staging/greybus/audio_module.c
+++ b/drivers/staging/greybus/audio_module.c
@@ -134,7 +134,7 @@ static int gbaudio_request_stream(struct gbaudio_module_info *module,
struct gb_audio_streaming_event_request *req)
{
dev_warn(module->dev, "Audio Event received: cport: %u, event: %u\n",
- req->data_cport, req->event);
+ le16_to_cpu(req->data_cport), req->event);
return 0;
}
diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c
index 8b216ca99cf9..07fac3948f3a 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -141,13 +141,14 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb,
{
const char **strings;
int i;
+ unsigned int items;
__u8 *data;
- strings = devm_kzalloc(gb->dev, sizeof(char *) * gbenum->items,
- GFP_KERNEL);
+ items = le32_to_cpu(gbenum->items);
+ strings = devm_kzalloc(gb->dev, sizeof(char *) * items, GFP_KERNEL);
data = gbenum->names;
- for (i = 0; i < gbenum->items; i++) {
+ for (i = 0; i < items; i++) {
strings[i] = (const char *)data;
while (*data != '\0')
data++;
@@ -185,11 +186,11 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol *kcontrol,
switch (info->type) {
case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
- uinfo->value.integer.min = info->value.integer.min;
- uinfo->value.integer.max = info->value.integer.max;
+ uinfo->value.integer.min = le32_to_cpu(info->value.integer.min);
+ uinfo->value.integer.max = le32_to_cpu(info->value.integer.max);
break;
case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
- max = info->value.enumerated.items;
+ max = le32_to_cpu(info->value.enumerated.items);
uinfo->value.enumerated.items = max;
if (uinfo->value.enumerated.item > max - 1)
uinfo->value.enumerated.item = max - 1;
@@ -249,17 +250,17 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol *kcontrol,
case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
ucontrol->value.integer.value[0] =
- gbvalue.value.integer_value[0];
+ le32_to_cpu(gbvalue.value.integer_value[0]);
if (data->vcount == 2)
ucontrol->value.integer.value[1] =
- gbvalue.value.integer_value[1];
+ le32_to_cpu(gbvalue.value.integer_value[1]);
break;
case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
ucontrol->value.enumerated.item[0] =
- gbvalue.value.enumerated_item[0];
+ le32_to_cpu(gbvalue.value.enumerated_item[0]);
if (data->vcount == 2)
ucontrol->value.enumerated.item[1] =
- gbvalue.value.enumerated_item[1];
+ le32_to_cpu(gbvalue.value.enumerated_item[1]);
break;
default:
dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
@@ -296,17 +297,17 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol *kcontrol,
case GB_AUDIO_CTL_ELEM_TYPE_BOOLEAN:
case GB_AUDIO_CTL_ELEM_TYPE_INTEGER:
gbvalue.value.integer_value[0] =
- ucontrol->value.integer.value[0];
+ cpu_to_le32(ucontrol->value.integer.value[0]);
if (data->vcount == 2)
gbvalue.value.integer_value[1] =
- ucontrol->value.integer.value[1];
+ cpu_to_le32(ucontrol->value.integer.value[1]);
break;
case GB_AUDIO_CTL_ELEM_TYPE_ENUMERATED:
gbvalue.value.enumerated_item[0] =
- ucontrol->value.enumerated.item[0];
+ cpu_to_le32(ucontrol->value.enumerated.item[0]);
if (data->vcount == 2)
gbvalue.value.enumerated_item[1] =
- ucontrol->value.enumerated.item[1];
+ cpu_to_le32(ucontrol->value.enumerated.item[1]);
break;
default:
dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
@@ -361,8 +362,8 @@ static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol,
info = (struct gb_audio_ctl_elem_info *)data->info;
/* update uinfo */
- platform_max = info->value.integer.max;
- platform_min = info->value.integer.min;
+ platform_max = le32_to_cpu(info->value.integer.max);
+ platform_min = le32_to_cpu(info->value.integer.min);
if (platform_max == 1 &&
!strnstr(kcontrol->id.name, " Volume", NAME_SIZE))
@@ -371,12 +372,8 @@ static int gbcodec_mixer_dapm_ctl_info(struct snd_kcontrol *kcontrol,
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = data->vcount;
- uinfo->value.integer.min = 0;
- if (info->value.integer.min < 0 &&
- (uinfo->type == SNDRV_CTL_ELEM_TYPE_INTEGER))
- uinfo->value.integer.max = platform_max - platform_min;
- else
- uinfo->value.integer.max = platform_max;
+ uinfo->value.integer.min = platform_min;
+ uinfo->value.integer.max = platform_max;
return 0;
}
@@ -424,7 +421,8 @@ static int gbcodec_mixer_dapm_ctl_get(struct snd_kcontrol *kcontrol,
return ret;
}
/* update ucontrol */
- ucontrol->value.integer.value[0] = gbvalue.value.integer_value[0];
+ ucontrol->value.integer.value[0] =
+ le32_to_cpu(gbvalue.value.integer_value[0]);
return ret;
}
@@ -458,7 +456,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
"GB: Control '%s' is stereo, which is not supported\n",
kcontrol->id.name);
- max = info->value.integer.max;
+ max = le32_to_cpu(info->value.integer.max);
mask = (1 << fls(max)) - 1;
val = ucontrol->value.integer.value[0] & mask;
connect = !!val;
@@ -474,7 +472,7 @@ static int gbcodec_mixer_dapm_ctl_put(struct snd_kcontrol *kcontrol,
connect);
}
gbvalue.value.integer_value[0] =
- ucontrol->value.integer.value[0];
+ cpu_to_le32(ucontrol->value.integer.value[0]);
ret = gb_pm_runtime_get_sync(bundle);
if (ret)
@@ -588,10 +586,11 @@ static int gbcodec_enum_ctl_get(struct snd_kcontrol *kcontrol,
return ret;
}
- ucontrol->value.enumerated.item[0] = gbvalue.value.enumerated_item[0];
+ ucontrol->value.enumerated.item[0] =
+ le32_to_cpu(gbvalue.value.enumerated_item[0]);
if (e->shift_l != e->shift_r)
ucontrol->value.enumerated.item[1] =
- gbvalue.value.enumerated_item[1];
+ le32_to_cpu(gbvalue.value.enumerated_item[1]);
return 0;
}
@@ -617,13 +616,14 @@ static int gbcodec_enum_ctl_put(struct snd_kcontrol *kcontrol,
if (ucontrol->value.enumerated.item[0] > e->max - 1)
return -EINVAL;
- gbvalue.value.enumerated_item[0] = ucontrol->value.enumerated.item[0];
+ gbvalue.value.enumerated_item[0] =
+ cpu_to_le32(ucontrol->value.enumerated.item[0]);
if (e->shift_l != e->shift_r) {
if (ucontrol->value.enumerated.item[1] > e->max - 1)
return -EINVAL;
gbvalue.value.enumerated_item[1] =
- ucontrol->value.enumerated.item[1];
+ cpu_to_le32(ucontrol->value.enumerated.item[1]);
}
bundle = to_gb_bundle(module->dev);
@@ -660,13 +660,13 @@ static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb,
gb_enum = &ctl->info.value.enumerated;
/* since count=1, and reg is dummy */
- gbe->max = gb_enum->items;
+ gbe->max = le32_to_cpu(gb_enum->items);
gbe->texts = gb_generate_enum_strings(gb, gb_enum);
/* debug enum info */
- dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
- gb_enum->names_length);
- for (i = 0; i < gb_enum->items; i++)
+ dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
+ le16_to_cpu(gb_enum->names_length));
+ for (i = 0; i < gbe->max; i++)
dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
*kctl = (struct snd_kcontrol_new)
@@ -695,7 +695,7 @@ static int gbaudio_tplg_create_kcontrol(struct gbaudio_module_info *gb,
if (!ctldata)
return -ENOMEM;
ctldata->ctl_id = ctl->id;
- ctldata->data_cport = ctl->data_cport;
+ ctldata->data_cport = le16_to_cpu(ctl->data_cport);
ctldata->access = ctl->access;
ctldata->vcount = ctl->count_values;
ctldata->info = &ctl->info;
@@ -869,13 +869,13 @@ static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb,
gb_enum = &ctl->info.value.enumerated;
/* since count=1, and reg is dummy */
- gbe->max = gb_enum->items;
+ gbe->max = le32_to_cpu(gb_enum->items);
gbe->texts = gb_generate_enum_strings(gb, gb_enum);
/* debug enum info */
- dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gb_enum->items,
- gb_enum->names_length);
- for (i = 0; i < gb_enum->items; i++)
+ dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->max,
+ le16_to_cpu(gb_enum->names_length));
+ for (i = 0; i < gbe->max; i++)
dev_dbg(gb->dev, "src[%d]: %s\n", i, gbe->texts[i]);
*kctl = (struct snd_kcontrol_new)
@@ -895,7 +895,7 @@ static int gbaudio_tplg_create_mixer_ctl(struct gbaudio_module_info *gb,
if (!ctldata)
return -ENOMEM;
ctldata->ctl_id = ctl->id;
- ctldata->data_cport = ctl->data_cport;
+ ctldata->data_cport = le16_to_cpu(ctl->data_cport);
ctldata->access = ctl->access;
ctldata->vcount = ctl->count_values;
ctldata->info = &ctl->info;
@@ -1041,10 +1041,10 @@ static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module,
csize = offsetof(struct gb_audio_control, info);
csize += offsetof(struct gb_audio_ctl_elem_info, value);
csize += offsetof(struct gb_audio_enumerated, names);
- csize += gbenum->names_length;
+ csize += le16_to_cpu(gbenum->names_length);
control->texts = (const char * const *)
gb_generate_enum_strings(module, gbenum);
- control->items = gbenum->items;
+ control->items = le32_to_cpu(gbenum->items);
} else {
csize = sizeof(struct gb_audio_control);
}
@@ -1189,10 +1189,10 @@ static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module,
csize = offsetof(struct gb_audio_control, info);
csize += offsetof(struct gb_audio_ctl_elem_info, value);
csize += offsetof(struct gb_audio_enumerated, names);
- csize += gbenum->names_length;
+ csize += le16_to_cpu(gbenum->names_length);
control->texts = (const char * const *)
gb_generate_enum_strings(module, gbenum);
- control->items = gbenum->items;
+ control->items = le32_to_cpu(gbenum->items);
} else {
csize = sizeof(struct gb_audio_control);
}
@@ -1312,7 +1312,7 @@ static int gbaudio_tplg_process_routes(struct gbaudio_module_info *module,
goto error;
}
dev_dbg(module->dev, "Route {%s, %s, %s}\n", dapm_routes->sink,
- (dapm_routes->control) ? dapm_routes->control:"NULL",
+ (dapm_routes->control) ? dapm_routes->control : "NULL",
dapm_routes->source);
dapm_routes++;
curr++;
@@ -1335,11 +1335,12 @@ static int gbaudio_tplg_process_header(struct gbaudio_module_info *module,
/* update block offset */
module->dai_offset = (unsigned long)&tplg_data->data;
- module->control_offset = module->dai_offset + tplg_data->size_dais;
+ module->control_offset = module->dai_offset +
+ le32_to_cpu(tplg_data->size_dais);
module->widget_offset = module->control_offset +
- tplg_data->size_controls;
+ le32_to_cpu(tplg_data->size_controls);
module->route_offset = module->widget_offset +
- tplg_data->size_widgets;
+ le32_to_cpu(tplg_data->size_widgets);
dev_dbg(module->dev, "DAI offset is 0x%lx\n", module->dai_offset);
dev_dbg(module->dev, "control offset is %lx\n",
@@ -1357,6 +1358,7 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
struct gb_audio_control *controls;
struct gb_audio_widget *widgets;
struct gb_audio_route *routes;
+ unsigned int jack_type;
if (!tplg_data)
return -EINVAL;
@@ -1399,10 +1401,10 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module,
dev_dbg(module->dev, "Route parsing finished\n");
/* parse jack capabilities */
- if (tplg_data->jack_type) {
- module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK;
- module->button_mask = tplg_data->jack_type &
- GBCODEC_JACK_BUTTON_MASK;
+ jack_type = le32_to_cpu(tplg_data->jack_type);
+ if (jack_type) {
+ module->jack_mask = jack_type & GBCODEC_JACK_MASK;
+ module->button_mask = jack_type & GBCODEC_JACK_BUTTON_MASK;
}
return ret;
diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c
index 0ee291ca2c72..a64517eabff4 100644
--- a/drivers/staging/greybus/camera.c
+++ b/drivers/staging/greybus/camera.c
@@ -1067,22 +1067,22 @@ struct gb_camera_debugfs_entry {
static const struct gb_camera_debugfs_entry gb_camera_debugfs_entries[] = {
{
.name = "capabilities",
- .mask = S_IFREG | S_IRUGO,
+ .mask = S_IFREG | 0444,
.buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPABILITIES,
.execute = gb_camera_debugfs_capabilities,
}, {
.name = "configure_streams",
- .mask = S_IFREG | S_IRUGO | S_IWUGO,
+ .mask = S_IFREG | 0666,
.buffer = GB_CAMERA_DEBUGFS_BUFFER_STREAMS,
.execute = gb_camera_debugfs_configure_streams,
}, {
.name = "capture",
- .mask = S_IFREG | S_IRUGO | S_IWUGO,
+ .mask = S_IFREG | 0666,
.buffer = GB_CAMERA_DEBUGFS_BUFFER_CAPTURE,
.execute = gb_camera_debugfs_capture,
}, {
.name = "flush",
- .mask = S_IFREG | S_IRUGO | S_IWUGO,
+ .mask = S_IFREG | 0666,
.buffer = GB_CAMERA_DEBUGFS_BUFFER_FLUSH,
.execute = gb_camera_debugfs_flush,
},
@@ -1097,7 +1097,7 @@ static ssize_t gb_camera_debugfs_read(struct file *file, char __user *buf,
ssize_t ret;
/* For read-only entries the operation is triggered by a read. */
- if (!(op->mask & S_IWUGO)) {
+ if (!(op->mask & 0222)) {
ret = op->execute(gcam, NULL, 0);
if (ret < 0)
return ret;
diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c
index 557075147f2d..1bf0ee403106 100644
--- a/drivers/staging/greybus/connection.c
+++ b/drivers/staging/greybus/connection.c
@@ -357,6 +357,9 @@ static int gb_connection_hd_cport_quiesce(struct gb_connection *connection)
size_t peer_space;
int ret;
+ if (!hd->driver->cport_quiesce)
+ return 0;
+
peer_space = sizeof(struct gb_operation_msg_hdr) +
sizeof(struct gb_cport_shutdown_request);
@@ -380,6 +383,9 @@ static int gb_connection_hd_cport_clear(struct gb_connection *connection)
struct gb_host_device *hd = connection->hd;
int ret;
+ if (!hd->driver->cport_clear)
+ return 0;
+
ret = hd->driver->cport_clear(hd, connection->hd_cport_id);
if (ret) {
dev_err(&hd->dev, "%s: failed to clear host cport: %d\n",
diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c
index 4716190e740a..5b30be30a3a4 100644
--- a/drivers/staging/greybus/control.c
+++ b/drivers/staging/greybus/control.c
@@ -198,56 +198,6 @@ int gb_control_mode_switch_operation(struct gb_control *control)
return ret;
}
-int gb_control_timesync_enable(struct gb_control *control, u8 count,
- u64 frame_time, u32 strobe_delay, u32 refclk)
-{
- struct gb_control_timesync_enable_request request;
-
- request.count = count;
- request.frame_time = cpu_to_le64(frame_time);
- request.strobe_delay = cpu_to_le32(strobe_delay);
- request.refclk = cpu_to_le32(refclk);
- return gb_operation_sync(control->connection,
- GB_CONTROL_TYPE_TIMESYNC_ENABLE, &request,
- sizeof(request), NULL, 0);
-}
-
-int gb_control_timesync_disable(struct gb_control *control)
-{
- return gb_operation_sync(control->connection,
- GB_CONTROL_TYPE_TIMESYNC_DISABLE, NULL, 0,
- NULL, 0);
-}
-
-int gb_control_timesync_get_last_event(struct gb_control *control,
- u64 *frame_time)
-{
- struct gb_control_timesync_get_last_event_response response;
- int ret;
-
- ret = gb_operation_sync(control->connection,
- GB_CONTROL_TYPE_TIMESYNC_GET_LAST_EVENT,
- NULL, 0, &response, sizeof(response));
- if (!ret)
- *frame_time = le64_to_cpu(response.frame_time);
- return ret;
-}
-
-int gb_control_timesync_authoritative(struct gb_control *control,
- u64 *frame_time)
-{
- struct gb_control_timesync_authoritative_request request;
- int i;
-
- for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
- request.frame_time[i] = cpu_to_le64(frame_time[i]);
-
- return gb_operation_sync(control->connection,
- GB_CONTROL_TYPE_TIMESYNC_AUTHORITATIVE,
- &request, sizeof(request),
- NULL, 0);
-}
-
static int gb_control_bundle_pm_status_map(u8 status)
{
switch (status) {
diff --git a/drivers/staging/greybus/control.h b/drivers/staging/greybus/control.h
index f9a60daf9a72..4dcaec8b9cfe 100644
--- a/drivers/staging/greybus/control.h
+++ b/drivers/staging/greybus/control.h
@@ -48,13 +48,6 @@ void gb_control_mode_switch_complete(struct gb_control *control);
int gb_control_get_manifest_size_operation(struct gb_interface *intf);
int gb_control_get_manifest_operation(struct gb_interface *intf, void *manifest,
size_t size);
-int gb_control_timesync_enable(struct gb_control *control, u8 count,
- u64 frame_time, u32 strobe_delay, u32 refclk);
-int gb_control_timesync_disable(struct gb_control *control);
-int gb_control_timesync_get_last_event(struct gb_control *control,
- u64 *frame_time);
-int gb_control_timesync_authoritative(struct gb_control *control,
- u64 *frame_time);
int gb_control_bundle_suspend(struct gb_control *control, u8 bundle_id);
int gb_control_bundle_resume(struct gb_control *control, u8 bundle_id);
int gb_control_bundle_deactivate(struct gb_control *control, u8 bundle_id);
diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c
index 1049e9c0edb0..ba761905b790 100644
--- a/drivers/staging/greybus/core.c
+++ b/drivers/staging/greybus/core.c
@@ -218,8 +218,6 @@ static int greybus_probe(struct device *dev)
return retval;
}
- gb_timesync_schedule_synchronous(bundle->intf);
-
pm_runtime_put(&bundle->intf->dev);
return 0;
@@ -326,16 +324,8 @@ static int __init gb_init(void)
pr_err("gb_operation_init failed (%d)\n", retval);
goto error_operation;
}
-
- retval = gb_timesync_init();
- if (retval) {
- pr_err("gb_timesync_init failed\n");
- goto error_timesync;
- }
return 0; /* Success */
-error_timesync:
- gb_operation_exit();
error_operation:
gb_hd_exit();
error_hd:
@@ -349,7 +339,6 @@ module_init(gb_init);
static void __exit gb_exit(void)
{
- gb_timesync_exit();
gb_operation_exit();
gb_hd_exit();
bus_unregister(&greybus_bus_type);
diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c
index c1929dfa9b31..93afd9374f04 100644
--- a/drivers/staging/greybus/es2.c
+++ b/drivers/staging/greybus/es2.c
@@ -127,29 +127,6 @@ struct es2_ap_dev {
struct list_head arpcs;
};
-/**
- * timesync_enable_request - Enable timesync in an APBridge
- * @count: number of TimeSync Pulses to expect
- * @frame_time: the initial FrameTime at the first TimeSync Pulse
- * @strobe_delay: the expected delay in microseconds between each TimeSync Pulse
- * @refclk: The AP mandated reference clock to run FrameTime at
- */
-struct timesync_enable_request {
- __u8 count;
- __le64 frame_time;
- __le32 strobe_delay;
- __le32 refclk;
-} __packed;
-
-/**
- * timesync_authoritative_request - Transmit authoritative FrameTime to APBridge
- * @frame_time: An array of authoritative FrameTimes provided by the SVC
- * and relayed to the APBridge by the AP
- */
-struct timesync_authoritative_request {
- __le64 frame_time[GB_TIMESYNC_MAX_STROBES];
-} __packed;
-
struct arpc {
struct list_head list;
struct arpc_request_message *req;
@@ -754,111 +731,6 @@ static int latency_tag_disable(struct gb_host_device *hd, u16 cport_id)
return retval;
}
-static int timesync_enable(struct gb_host_device *hd, u8 count,
- u64 frame_time, u32 strobe_delay, u32 refclk)
-{
- int retval;
- struct es2_ap_dev *es2 = hd_to_es2(hd);
- struct usb_device *udev = es2->usb_dev;
- struct gb_control_timesync_enable_request *request;
-
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (!request)
- return -ENOMEM;
-
- request->count = count;
- request->frame_time = cpu_to_le64(frame_time);
- request->strobe_delay = cpu_to_le32(strobe_delay);
- request->refclk = cpu_to_le32(refclk);
- retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- GB_APB_REQUEST_TIMESYNC_ENABLE,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_INTERFACE, 0, 0, request,
- sizeof(*request), ES2_USB_CTRL_TIMEOUT);
- if (retval < 0)
- dev_err(&udev->dev, "Cannot enable timesync %d\n", retval);
-
- kfree(request);
- return retval;
-}
-
-static int timesync_disable(struct gb_host_device *hd)
-{
- int retval;
- struct es2_ap_dev *es2 = hd_to_es2(hd);
- struct usb_device *udev = es2->usb_dev;
-
- retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- GB_APB_REQUEST_TIMESYNC_DISABLE,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_INTERFACE, 0, 0, NULL,
- 0, ES2_USB_CTRL_TIMEOUT);
- if (retval < 0)
- dev_err(&udev->dev, "Cannot disable timesync %d\n", retval);
-
- return retval;
-}
-
-static int timesync_authoritative(struct gb_host_device *hd, u64 *frame_time)
-{
- int retval, i;
- struct es2_ap_dev *es2 = hd_to_es2(hd);
- struct usb_device *udev = es2->usb_dev;
- struct timesync_authoritative_request *request;
-
- request = kzalloc(sizeof(*request), GFP_KERNEL);
- if (!request)
- return -ENOMEM;
-
- for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
- request->frame_time[i] = cpu_to_le64(frame_time[i]);
-
- retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- GB_APB_REQUEST_TIMESYNC_AUTHORITATIVE,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_INTERFACE, 0, 0, request,
- sizeof(*request), ES2_USB_CTRL_TIMEOUT);
- if (retval < 0)
- dev_err(&udev->dev, "Cannot timesync authoritative out %d\n", retval);
-
- kfree(request);
- return retval;
-}
-
-static int timesync_get_last_event(struct gb_host_device *hd, u64 *frame_time)
-{
- int retval;
- struct es2_ap_dev *es2 = hd_to_es2(hd);
- struct usb_device *udev = es2->usb_dev;
- __le64 *response_frame_time;
-
- response_frame_time = kzalloc(sizeof(*response_frame_time), GFP_KERNEL);
- if (!response_frame_time)
- return -ENOMEM;
-
- retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- GB_APB_REQUEST_TIMESYNC_GET_LAST_EVENT,
- USB_DIR_IN | USB_TYPE_VENDOR |
- USB_RECIP_INTERFACE, 0, 0, response_frame_time,
- sizeof(*response_frame_time),
- ES2_USB_CTRL_TIMEOUT);
-
- if (retval != sizeof(*response_frame_time)) {
- dev_err(&udev->dev, "Cannot get last TimeSync event: %d\n",
- retval);
-
- if (retval >= 0)
- retval = -EIO;
-
- goto out;
- }
- *frame_time = le64_to_cpu(*response_frame_time);
- retval = 0;
-out:
- kfree(response_frame_time);
- return retval;
-}
-
static struct gb_hd_driver es2_driver = {
.hd_priv_size = sizeof(struct es2_ap_dev),
.message_send = message_send,
@@ -874,10 +746,6 @@ static struct gb_hd_driver es2_driver = {
.latency_tag_enable = latency_tag_enable,
.latency_tag_disable = latency_tag_disable,
.output = output,
- .timesync_enable = timesync_enable,
- .timesync_disable = timesync_disable,
- .timesync_authoritative = timesync_authoritative,
- .timesync_get_last_event = timesync_get_last_event,
};
/* Common function to report consistent warnings based on URB status */
diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c
index 250caa00de5e..558550cfe687 100644
--- a/drivers/staging/greybus/gpio.c
+++ b/drivers/staging/greybus/gpio.c
@@ -410,21 +410,21 @@ static int gb_gpio_request_handler(struct gb_operation *op)
return 0;
}
-static int gb_gpio_request(struct gpio_chip *chip, unsigned offset)
+static int gb_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
return gb_gpio_activate_operation(ggc, (u8)offset);
}
-static void gb_gpio_free(struct gpio_chip *chip, unsigned offset)
+static void gb_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
gb_gpio_deactivate_operation(ggc, (u8)offset);
}
-static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{
struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
u8 which;
@@ -438,22 +438,22 @@ static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
return ggc->lines[which].direction ? 1 : 0;
}
-static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
{
struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
return gb_gpio_direction_in_operation(ggc, (u8)offset);
}
-static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
- int value)
+static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
+ int value)
{
struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
return gb_gpio_direction_out_operation(ggc, (u8)offset, !!value);
}
-static int gb_gpio_get(struct gpio_chip *chip, unsigned offset)
+static int gb_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
u8 which;
@@ -467,15 +467,15 @@ static int gb_gpio_get(struct gpio_chip *chip, unsigned offset)
return ggc->lines[which].value;
}
-static void gb_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+static void gb_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
{
struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
gb_gpio_set_value_operation(ggc, (u8)offset, !!value);
}
-static int gb_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
- unsigned debounce)
+static int gb_gpio_set_debounce(struct gpio_chip *chip, unsigned int offset,
+ unsigned int debounce)
{
struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
u16 usec;
@@ -593,7 +593,7 @@ static int gb_gpio_irqchip_add(struct gpio_chip *chip,
{
struct gb_gpio_controller *ggc;
unsigned int offset;
- unsigned irq_base;
+ unsigned int irq_base;
if (!chip || !irqchip)
return -EINVAL;
@@ -625,7 +625,7 @@ static int gb_gpio_irqchip_add(struct gpio_chip *chip,
return 0;
}
-static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
{
struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h
index 12526887ae2e..c9bb93f23927 100644
--- a/drivers/staging/greybus/greybus.h
+++ b/drivers/staging/greybus/greybus.h
@@ -33,7 +33,6 @@
#include "bundle.h"
#include "connection.h"
#include "operation.h"
-#include "timesync.h"
/* Matches up with the Greybus Protocol specification document */
#define GREYBUS_VERSION_MAJOR 0x00
diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h
index 639578309c2a..b1be0b0af464 100644
--- a/drivers/staging/greybus/greybus_protocols.h
+++ b/drivers/staging/greybus/greybus_protocols.h
@@ -173,26 +173,6 @@ struct gb_control_disconnected_request {
} __packed;
/* Control protocol [dis]connected response has no payload */
-#define GB_TIMESYNC_MAX_STROBES 0x04
-
-struct gb_control_timesync_enable_request {
- __u8 count;
- __le64 frame_time;
- __le32 strobe_delay;
- __le32 refclk;
-} __packed;
-/* timesync enable response has no payload */
-
-struct gb_control_timesync_authoritative_request {
- __le64 frame_time[GB_TIMESYNC_MAX_STROBES];
-} __packed;
-/* timesync authoritative response has no payload */
-
-/* timesync get_last_event_request has no payload */
-struct gb_control_timesync_get_last_event_response {
- __le64 frame_time;
-} __packed;
-
/*
* All Bundle power management operations use the same request and response
* layout and status codes.
@@ -1169,33 +1149,6 @@ struct gb_svc_intf_unipro_response {
#define GB_SVC_INTF_UNIPRO_NOT_OFF 0x03
} __packed;
-struct gb_svc_timesync_enable_request {
- __u8 count;
- __le64 frame_time;
- __le32 strobe_delay;
- __le32 refclk;
-} __packed;
-/* timesync enable response has no payload */
-
-/* timesync authoritative request has no payload */
-struct gb_svc_timesync_authoritative_response {
- __le64 frame_time[GB_TIMESYNC_MAX_STROBES];
-};
-
-struct gb_svc_timesync_wake_pins_acquire_request {
- __le32 strobe_mask;
-};
-
-/* timesync wake pins acquire response has no payload */
-
-/* timesync wake pins release request has no payload */
-/* timesync wake pins release response has no payload */
-
-/* timesync svc ping request has no payload */
-struct gb_svc_timesync_ping_response {
- __le64 frame_time;
-} __packed;
-
#define GB_SVC_UNIPRO_FAST_MODE 0x01
#define GB_SVC_UNIPRO_SLOW_MODE 0x02
#define GB_SVC_UNIPRO_FAST_AUTO_MODE 0x04
diff --git a/drivers/staging/greybus/greybus_trace.h b/drivers/staging/greybus/greybus_trace.h
index 6f8692da9ec8..f8feae4dc3b5 100644
--- a/drivers/staging/greybus/greybus_trace.h
+++ b/drivers/staging/greybus/greybus_trace.h
@@ -488,34 +488,6 @@ DEFINE_HD_EVENT(gb_hd_in);
#undef DEFINE_HD_EVENT
-/*
- * Occurs on a TimeSync synchronization event or a TimeSync ping event.
- */
-TRACE_EVENT(gb_timesync_irq,
-
- TP_PROTO(u8 ping, u8 strobe, u8 count, u64 frame_time),
-
- TP_ARGS(ping, strobe, count, frame_time),
-
- TP_STRUCT__entry(
- __field(u8, ping)
- __field(u8, strobe)
- __field(u8, count)
- __field(u64, frame_time)
- ),
-
- TP_fast_assign(
- __entry->ping = ping;
- __entry->strobe = strobe;
- __entry->count = count;
- __entry->frame_time = frame_time;
- ),
-
- TP_printk("%s %d/%d frame-time %llu\n",
- __entry->ping ? "ping" : "strobe", __entry->strobe,
- __entry->count, __entry->frame_time)
-);
-
#endif /* _TRACE_GREYBUS_H */
/* This part must be outside protection */
diff --git a/drivers/staging/greybus/hd.h b/drivers/staging/greybus/hd.h
index c4250cfe595f..e7927bb1761c 100644
--- a/drivers/staging/greybus/hd.h
+++ b/drivers/staging/greybus/hd.h
@@ -37,13 +37,6 @@ struct gb_hd_driver {
int (*latency_tag_disable)(struct gb_host_device *hd, u16 cport_id);
int (*output)(struct gb_host_device *hd, void *req, u16 size, u8 cmd,
bool async);
- int (*timesync_enable)(struct gb_host_device *hd, u8 count,
- u64 frame_time, u32 strobe_delay, u32 refclk);
- int (*timesync_disable)(struct gb_host_device *hd);
- int (*timesync_authoritative)(struct gb_host_device *hd,
- u64 *frame_time);
- int (*timesync_get_last_event)(struct gb_host_device *hd,
- u64 *frame_time);
};
struct gb_host_device {
diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c
index 546b090e2d51..a4fd51632232 100644
--- a/drivers/staging/greybus/interface.c
+++ b/drivers/staging/greybus/interface.c
@@ -702,14 +702,12 @@ static void gb_interface_release(struct device *dev)
static int gb_interface_suspend(struct device *dev)
{
struct gb_interface *intf = to_gb_interface(dev);
- int ret, timesync_ret;
+ int ret;
ret = gb_control_interface_suspend_prepare(intf->control);
if (ret)
return ret;
- gb_timesync_interface_remove(intf);
-
ret = gb_control_suspend(intf->control);
if (ret)
goto err_hibernate_abort;
@@ -730,12 +728,6 @@ static int gb_interface_suspend(struct device *dev)
err_hibernate_abort:
gb_control_interface_hibernate_abort(intf->control);
- timesync_ret = gb_timesync_interface_add(intf);
- if (timesync_ret) {
- dev_err(dev, "failed to add to timesync: %d\n", timesync_ret);
- return timesync_ret;
- }
-
return ret;
}
@@ -757,18 +749,6 @@ static int gb_interface_resume(struct device *dev)
if (ret)
return ret;
- ret = gb_timesync_interface_add(intf);
- if (ret) {
- dev_err(dev, "failed to add to timesync: %d\n", ret);
- return ret;
- }
-
- ret = gb_timesync_schedule_synchronous(intf);
- if (ret) {
- dev_err(dev, "failed to synchronize FrameTime: %d\n", ret);
- return ret;
- }
-
return 0;
}
@@ -1152,16 +1132,10 @@ int gb_interface_enable(struct gb_interface *intf)
if (ret)
goto err_destroy_bundles;
- ret = gb_timesync_interface_add(intf);
- if (ret) {
- dev_err(&intf->dev, "failed to add to timesync: %d\n", ret);
- goto err_destroy_bundles;
- }
-
/* Register the control device and any bundles */
ret = gb_control_add(intf->control);
if (ret)
- goto err_remove_timesync;
+ goto err_destroy_bundles;
pm_runtime_use_autosuspend(&intf->dev);
pm_runtime_get_noresume(&intf->dev);
@@ -1186,8 +1160,6 @@ int gb_interface_enable(struct gb_interface *intf)
return 0;
-err_remove_timesync:
- gb_timesync_interface_remove(intf);
err_destroy_bundles:
list_for_each_entry_safe(bundle, tmp, &intf->bundles, links)
gb_bundle_destroy(bundle);
@@ -1230,7 +1202,6 @@ void gb_interface_disable(struct gb_interface *intf)
gb_control_interface_deactivate_prepare(intf->control);
gb_control_del(intf->control);
- gb_timesync_interface_remove(intf);
gb_control_disable(intf->control);
gb_control_put(intf->control);
intf->control = NULL;
@@ -1243,29 +1214,6 @@ void gb_interface_disable(struct gb_interface *intf)
pm_runtime_put_noidle(&intf->dev);
}
-/* Enable TimeSync on an Interface control connection. */
-int gb_interface_timesync_enable(struct gb_interface *intf, u8 count,
- u64 frame_time, u32 strobe_delay, u32 refclk)
-{
- return gb_control_timesync_enable(intf->control, count,
- frame_time, strobe_delay,
- refclk);
-}
-
-/* Disable TimeSync on an Interface control connection. */
-int gb_interface_timesync_disable(struct gb_interface *intf)
-{
- return gb_control_timesync_disable(intf->control);
-}
-
-/* Transmit the Authoritative FrameTime via an Interface control connection. */
-int gb_interface_timesync_authoritative(struct gb_interface *intf,
- u64 *frame_time)
-{
- return gb_control_timesync_authoritative(intf->control,
- frame_time);
-}
-
/* Register an interface. */
int gb_interface_add(struct gb_interface *intf)
{
diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h
index 03299d2a8be5..bd31b8c18d5b 100644
--- a/drivers/staging/greybus/interface.h
+++ b/drivers/staging/greybus/interface.h
@@ -72,11 +72,6 @@ int gb_interface_activate(struct gb_interface *intf);
void gb_interface_deactivate(struct gb_interface *intf);
int gb_interface_enable(struct gb_interface *intf);
void gb_interface_disable(struct gb_interface *intf);
-int gb_interface_timesync_enable(struct gb_interface *intf, u8 count,
- u64 frame_time, u32 strobe_delay, u32 refclk);
-int gb_interface_timesync_authoritative(struct gb_interface *intf,
- u64 *frame_time);
-int gb_interface_timesync_disable(struct gb_interface *intf);
int gb_interface_add(struct gb_interface *intf);
void gb_interface_del(struct gb_interface *intf);
void gb_interface_put(struct gb_interface *intf);
diff --git a/drivers/staging/greybus/log.c b/drivers/staging/greybus/log.c
index 1a18ab1ff8aa..5c5bedaf69a6 100644
--- a/drivers/staging/greybus/log.c
+++ b/drivers/staging/greybus/log.c
@@ -37,9 +37,9 @@ static int gb_log_request_handler(struct gb_operation *op)
}
receive = op->request->payload;
len = le16_to_cpu(receive->len);
- if (len != (int)(op->request->payload_size - sizeof(*receive))) {
- dev_err(dev, "log request wrong size %d vs %d\n", len,
- (int)(op->request->payload_size - sizeof(*receive)));
+ if (len != (op->request->payload_size - sizeof(*receive))) {
+ dev_err(dev, "log request wrong size %d vs %zu\n", len,
+ (op->request->payload_size - sizeof(*receive)));
return -EINVAL;
}
if (len == 0) {
diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
index 7882306adeca..a8329daf1e57 100644
--- a/drivers/staging/greybus/loopback.c
+++ b/drivers/staging/greybus/loopback.c
@@ -124,7 +124,7 @@ static DEFINE_IDA(loopback_ida);
#define GB_LOOPBACK_FIFO_DEFAULT 8192
-static unsigned kfifo_depth = GB_LOOPBACK_FIFO_DEFAULT;
+static unsigned int kfifo_depth = GB_LOOPBACK_FIFO_DEFAULT;
module_param(kfifo_depth, uint, 0444);
/* Maximum size of any one send data buffer we support */
@@ -1008,11 +1008,22 @@ static int gb_loopback_fn(void *data)
/* Optionally terminate */
if (gb->send_count == gb->iteration_max) {
+ mutex_unlock(&gb->mutex);
+
+ /* Wait for synchronous and asynchronus completion */
+ gb_loopback_async_wait_all(gb);
+
+ /* Mark complete unless user-space has poked us */
+ mutex_lock(&gb->mutex);
if (gb->iteration_count == gb->iteration_max) {
gb->type = 0;
gb->send_count = 0;
sysfs_notify(&gb->dev->kobj, NULL,
"iteration_count");
+ dev_dbg(&bundle->dev, "load test complete\n");
+ } else {
+ dev_dbg(&bundle->dev,
+ "continuing on with new test set\n");
}
mutex_unlock(&gb->mutex);
continue;
@@ -1026,13 +1037,12 @@ static int gb_loopback_fn(void *data)
/* Else operations to perform */
if (gb->async) {
- if (type == GB_LOOPBACK_TYPE_PING) {
+ if (type == GB_LOOPBACK_TYPE_PING)
error = gb_loopback_async_ping(gb);
- } else if (type == GB_LOOPBACK_TYPE_TRANSFER) {
+ else if (type == GB_LOOPBACK_TYPE_TRANSFER)
error = gb_loopback_async_transfer(gb, size);
- } else if (type == GB_LOOPBACK_TYPE_SINK) {
+ else if (type == GB_LOOPBACK_TYPE_SINK)
error = gb_loopback_async_sink(gb, size);
- }
if (error)
gb->error++;
@@ -1051,8 +1061,13 @@ static int gb_loopback_fn(void *data)
gb_loopback_calculate_stats(gb, !!error);
}
gb->send_count++;
- if (us_wait)
- udelay(us_wait);
+
+ if (us_wait) {
+ if (us_wait < 20000)
+ usleep_range(us_wait, us_wait + 100);
+ else
+ msleep(us_wait / 1000);
+ }
}
gb_pm_runtime_put_autosuspend(bundle);
diff --git a/drivers/staging/greybus/sdio.c b/drivers/staging/greybus/sdio.c
index 66b37ea29ef0..101ca5097fc9 100644
--- a/drivers/staging/greybus/sdio.c
+++ b/drivers/staging/greybus/sdio.c
@@ -52,7 +52,7 @@ struct gb_sdio_host {
static inline bool single_op(struct mmc_command *cmd)
{
- uint32_t opcode = cmd->opcode;
+ u32 opcode = cmd->opcode;
return opcode == MMC_WRITE_BLOCK ||
opcode == MMC_READ_SINGLE_BLOCK;
diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c
index 8779270cadc1..be151a64ea03 100644
--- a/drivers/staging/greybus/svc.c
+++ b/drivers/staging/greybus/svc.c
@@ -518,85 +518,6 @@ void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
}
}
-int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time,
- u32 strobe_delay, u32 refclk)
-{
- struct gb_connection *connection = svc->connection;
- struct gb_svc_timesync_enable_request request;
-
- request.count = count;
- request.frame_time = cpu_to_le64(frame_time);
- request.strobe_delay = cpu_to_le32(strobe_delay);
- request.refclk = cpu_to_le32(refclk);
- return gb_operation_sync(connection,
- GB_SVC_TYPE_TIMESYNC_ENABLE,
- &request, sizeof(request), NULL, 0);
-}
-
-int gb_svc_timesync_disable(struct gb_svc *svc)
-{
- struct gb_connection *connection = svc->connection;
-
- return gb_operation_sync(connection,
- GB_SVC_TYPE_TIMESYNC_DISABLE,
- NULL, 0, NULL, 0);
-}
-
-int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time)
-{
- struct gb_connection *connection = svc->connection;
- struct gb_svc_timesync_authoritative_response response;
- int ret, i;
-
- ret = gb_operation_sync(connection,
- GB_SVC_TYPE_TIMESYNC_AUTHORITATIVE, NULL, 0,
- &response, sizeof(response));
- if (ret < 0)
- return ret;
-
- for (i = 0; i < GB_TIMESYNC_MAX_STROBES; i++)
- frame_time[i] = le64_to_cpu(response.frame_time[i]);
- return 0;
-}
-
-int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time)
-{
- struct gb_connection *connection = svc->connection;
- struct gb_svc_timesync_ping_response response;
- int ret;
-
- ret = gb_operation_sync(connection,
- GB_SVC_TYPE_TIMESYNC_PING,
- NULL, 0,
- &response, sizeof(response));
- if (ret < 0)
- return ret;
-
- *frame_time = le64_to_cpu(response.frame_time);
- return 0;
-}
-
-int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask)
-{
- struct gb_connection *connection = svc->connection;
- struct gb_svc_timesync_wake_pins_acquire_request request;
-
- request.strobe_mask = cpu_to_le32(strobe_mask);
- return gb_operation_sync(connection,
- GB_SVC_TYPE_TIMESYNC_WAKE_PINS_ACQUIRE,
- &request, sizeof(request),
- NULL, 0);
-}
-
-int gb_svc_timesync_wake_pins_release(struct gb_svc *svc)
-{
- struct gb_connection *connection = svc->connection;
-
- return gb_operation_sync(connection,
- GB_SVC_TYPE_TIMESYNC_WAKE_PINS_RELEASE,
- NULL, 0, NULL, 0);
-}
-
/* Creates bi-directional routes between the devices */
int gb_svc_route_create(struct gb_svc *svc, u8 intf1_id, u8 dev1_id,
u8 intf2_id, u8 dev2_id)
@@ -945,13 +866,6 @@ static int gb_svc_hello(struct gb_operation *op)
gb_svc_debugfs_init(svc);
- ret = gb_timesync_svc_add(svc);
- if (ret) {
- dev_err(&svc->dev, "failed to add SVC to timesync: %d\n", ret);
- gb_svc_debugfs_exit(svc);
- goto err_unregister_device;
- }
-
return gb_svc_queue_deferred_request(op);
err_unregister_device:
@@ -1467,7 +1381,6 @@ void gb_svc_del(struct gb_svc *svc)
* The SVC device may have been registered from the request handler.
*/
if (device_is_registered(&svc->dev)) {
- gb_timesync_svc_remove(svc);
gb_svc_debugfs_exit(svc);
gb_svc_watchdog_destroy(svc);
device_del(&svc->dev);
diff --git a/drivers/staging/greybus/svc.h b/drivers/staging/greybus/svc.h
index d1d7ef967385..226c2a396fc8 100644
--- a/drivers/staging/greybus/svc.h
+++ b/drivers/staging/greybus/svc.h
@@ -95,13 +95,6 @@ void gb_svc_watchdog_destroy(struct gb_svc *svc);
bool gb_svc_watchdog_enabled(struct gb_svc *svc);
int gb_svc_watchdog_enable(struct gb_svc *svc);
int gb_svc_watchdog_disable(struct gb_svc *svc);
-int gb_svc_timesync_enable(struct gb_svc *svc, u8 count, u64 frame_time,
- u32 strobe_delay, u32 refclk);
-int gb_svc_timesync_disable(struct gb_svc *svc);
-int gb_svc_timesync_authoritative(struct gb_svc *svc, u64 *frame_time);
-int gb_svc_timesync_ping(struct gb_svc *svc, u64 *frame_time);
-int gb_svc_timesync_wake_pins_acquire(struct gb_svc *svc, u32 strobe_mask);
-int gb_svc_timesync_wake_pins_release(struct gb_svc *svc);
int gb_svc_protocol_init(void);
void gb_svc_protocol_exit(void);
diff --git a/drivers/staging/greybus/svc_watchdog.c b/drivers/staging/greybus/svc_watchdog.c
index 3729460fb954..d8af2d5d0025 100644
--- a/drivers/staging/greybus/svc_watchdog.c
+++ b/drivers/staging/greybus/svc_watchdog.c
@@ -11,7 +11,7 @@
#include <linux/workqueue.h>
#include "greybus.h"
-#define SVC_WATCHDOG_PERIOD (2*HZ)
+#define SVC_WATCHDOG_PERIOD (2 * HZ)
struct gb_svc_watchdog {
struct delayed_work work;
@@ -56,7 +56,7 @@ static void greybus_reset(struct work_struct *work)
NULL,
};
- printk(KERN_ERR "svc_watchdog: calling \"%s %s\" to reset greybus network!\n",
+ pr_err("svc_watchdog: calling \"%s %s\" to reset greybus network!\n",
argv[0], argv[1]);
call_usermodehelper(start_path, argv, envp, UMH_WAIT_EXEC);
}
diff --git a/drivers/staging/greybus/timesync.c b/drivers/staging/greybus/timesync.c
deleted file mode 100644
index 29e6c1c12807..000000000000
--- a/drivers/staging/greybus/timesync.c
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * TimeSync API driver.
- *
- * Copyright 2016 Google Inc.
- * Copyright 2016 Linaro Ltd.
- *
- * Released under the GPLv2 only.
- */
-#include <linux/debugfs.h>
-#include <linux/hrtimer.h>
-#include "greybus.h"
-#include "timesync.h"
-#include "greybus_trace.h"
-
-/*
- * Minimum inter-strobe value of one millisecond is chosen because it
- * just-about fits the common definition of a jiffy.
- *
- * Maximum value OTOH is constrained by the number of bits the SVC can fit
- * into a 16 bit up-counter. The SVC configures the timer in microseconds
- * so the maximum allowable value is 65535 microseconds. We clip that value
- * to 10000 microseconds for the sake of using nice round base 10 numbers
- * and since right-now there's no imaginable use-case requiring anything
- * other than a one millisecond inter-strobe time, let alone something
- * higher than ten milliseconds.
- */
-#define GB_TIMESYNC_STROBE_DELAY_US 1000
-#define GB_TIMESYNC_DEFAULT_OFFSET_US 1000
-
-/* Work queue timers long, short and SVC strobe timeout */
-#define GB_TIMESYNC_DELAYED_WORK_LONG msecs_to_jiffies(10)
-#define GB_TIMESYNC_DELAYED_WORK_SHORT msecs_to_jiffies(1)
-#define GB_TIMESYNC_MAX_WAIT_SVC msecs_to_jiffies(5000)
-#define GB_TIMESYNC_KTIME_UPDATE msecs_to_jiffies(1000)
-#define GB_TIMESYNC_MAX_KTIME_CONVERSION 15
-
-/* Maximum number of times we'll retry a failed synchronous sync */
-#define GB_TIMESYNC_MAX_RETRIES 5
-
-/* Reported nanoseconds/femtoseconds per clock */
-static u64 gb_timesync_ns_per_clock;
-static u64 gb_timesync_fs_per_clock;
-
-/* Maximum difference we will accept converting FrameTime to ktime */
-static u32 gb_timesync_max_ktime_diff;
-
-/* Reported clock rate */
-static unsigned long gb_timesync_clock_rate;
-
-/* Workqueue */
-static void gb_timesync_worker(struct work_struct *work);
-
-/* List of SVCs with one FrameTime per SVC */
-static LIST_HEAD(gb_timesync_svc_list);
-
-/* Synchronize parallel contexts accessing a valid timesync_svc pointer */
-static DEFINE_MUTEX(gb_timesync_svc_list_mutex);
-
-/* Structure to convert from FrameTime to timespec/ktime */
-struct gb_timesync_frame_time_data {
- u64 frame_time;
- struct timespec ts;
-};
-
-struct gb_timesync_svc {
- struct list_head list;
- struct list_head interface_list;
- struct gb_svc *svc;
- struct gb_timesync_host_device *timesync_hd;
-
- spinlock_t spinlock; /* Per SVC spinlock to sync with ISR */
- struct mutex mutex; /* Per SVC mutex for regular synchronization */
-
- struct dentry *frame_time_dentry;
- struct dentry *frame_ktime_dentry;
- struct workqueue_struct *work_queue;
- wait_queue_head_t wait_queue;
- struct delayed_work delayed_work;
- struct timer_list ktime_timer;
-
- /* The current local FrameTime */
- u64 frame_time_offset;
- struct gb_timesync_frame_time_data strobe_data[GB_TIMESYNC_MAX_STROBES];
- struct gb_timesync_frame_time_data ktime_data;
-
- /* The SVC FrameTime and relative AP FrameTime @ last TIMESYNC_PING */
- u64 svc_ping_frame_time;
- u64 ap_ping_frame_time;
-
- /* Transitory settings */
- u32 strobe_mask;
- bool offset_down;
- bool print_ping;
- bool capture_ping;
- int strobe;
-
- /* Current state */
- int state;
-};
-
-struct gb_timesync_host_device {
- struct list_head list;
- struct gb_host_device *hd;
- u64 ping_frame_time;
-};
-
-struct gb_timesync_interface {
- struct list_head list;
- struct gb_interface *interface;
- u64 ping_frame_time;
-};
-
-enum gb_timesync_state {
- GB_TIMESYNC_STATE_INVALID = 0,
- GB_TIMESYNC_STATE_INACTIVE = 1,
- GB_TIMESYNC_STATE_INIT = 2,
- GB_TIMESYNC_STATE_WAIT_SVC = 3,
- GB_TIMESYNC_STATE_AUTHORITATIVE = 4,
- GB_TIMESYNC_STATE_PING = 5,
- GB_TIMESYNC_STATE_ACTIVE = 6,
-};
-
-static void gb_timesync_ktime_timer_fn(unsigned long data);
-
-static u64 gb_timesync_adjust_count(struct gb_timesync_svc *timesync_svc,
- u64 counts)
-{
- if (timesync_svc->offset_down)
- return counts - timesync_svc->frame_time_offset;
- else
- return counts + timesync_svc->frame_time_offset;
-}
-
-/*
- * This function provides the authoritative FrameTime to a calling function. It
- * is designed to be lockless and should remain that way the caller is assumed
- * to be state-aware.
- */
-static u64 __gb_timesync_get_frame_time(struct gb_timesync_svc *timesync_svc)
-{
- u64 clocks = gb_timesync_platform_get_counter();
-
- return gb_timesync_adjust_count(timesync_svc, clocks);
-}
-
-static void gb_timesync_schedule_svc_timeout(struct gb_timesync_svc
- *timesync_svc)
-{
- queue_delayed_work(timesync_svc->work_queue,
- &timesync_svc->delayed_work,
- GB_TIMESYNC_MAX_WAIT_SVC);
-}
-
-static void gb_timesync_set_state(struct gb_timesync_svc *timesync_svc,
- int state)
-{
- switch (state) {
- case GB_TIMESYNC_STATE_INVALID:
- timesync_svc->state = state;
- wake_up(&timesync_svc->wait_queue);
- break;
- case GB_TIMESYNC_STATE_INACTIVE:
- timesync_svc->state = state;
- wake_up(&timesync_svc->wait_queue);
- break;
- case GB_TIMESYNC_STATE_INIT:
- if (timesync_svc->state != GB_TIMESYNC_STATE_INVALID) {
- timesync_svc->strobe = 0;
- timesync_svc->frame_time_offset = 0;
- timesync_svc->state = state;
- cancel_delayed_work(&timesync_svc->delayed_work);
- queue_delayed_work(timesync_svc->work_queue,
- &timesync_svc->delayed_work,
- GB_TIMESYNC_DELAYED_WORK_LONG);
- }
- break;
- case GB_TIMESYNC_STATE_WAIT_SVC:
- if (timesync_svc->state == GB_TIMESYNC_STATE_INIT)
- timesync_svc->state = state;
- break;
- case GB_TIMESYNC_STATE_AUTHORITATIVE:
- if (timesync_svc->state == GB_TIMESYNC_STATE_WAIT_SVC) {
- timesync_svc->state = state;
- cancel_delayed_work(&timesync_svc->delayed_work);
- queue_delayed_work(timesync_svc->work_queue,
- &timesync_svc->delayed_work, 0);
- }
- break;
- case GB_TIMESYNC_STATE_PING:
- if (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE) {
- timesync_svc->state = state;
- queue_delayed_work(timesync_svc->work_queue,
- &timesync_svc->delayed_work,
- GB_TIMESYNC_DELAYED_WORK_SHORT);
- }
- break;
- case GB_TIMESYNC_STATE_ACTIVE:
- if (timesync_svc->state == GB_TIMESYNC_STATE_AUTHORITATIVE ||
- timesync_svc->state == GB_TIMESYNC_STATE_PING) {
- timesync_svc->state = state;
- wake_up(&timesync_svc->wait_queue);
- }
- break;
- }
-
- if (WARN_ON(timesync_svc->state != state)) {
- pr_err("Invalid state transition %d=>%d\n",
- timesync_svc->state, state);
- }
-}
-
-static void gb_timesync_set_state_atomic(struct gb_timesync_svc *timesync_svc,
- int state)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&timesync_svc->spinlock, flags);
- gb_timesync_set_state(timesync_svc, state);
- spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
-}
-
-static u64 gb_timesync_diff(u64 x, u64 y)
-{
- if (x > y)
- return x - y;
- else
- return y - x;
-}
-
-static void gb_timesync_adjust_to_svc(struct gb_timesync_svc *svc,
- u64 svc_frame_time, u64 ap_frame_time)
-{
- if (svc_frame_time > ap_frame_time) {
- svc->frame_time_offset = svc_frame_time - ap_frame_time;
- svc->offset_down = false;
- } else {
- svc->frame_time_offset = ap_frame_time - svc_frame_time;
- svc->offset_down = true;
- }
-}
-
-/*
- * Associate a FrameTime with a ktime timestamp represented as struct timespec
- * Requires the calling context to hold timesync_svc->mutex
- */
-static void gb_timesync_store_ktime(struct gb_timesync_svc *timesync_svc,
- struct timespec ts, u64 frame_time)
-{
- timesync_svc->ktime_data.ts = ts;
- timesync_svc->ktime_data.frame_time = frame_time;
-}
-
-/*
- * Find the two pulses that best-match our expected inter-strobe gap and
- * then calculate the difference between the SVC time at the second pulse
- * to the local time at the second pulse.
- */
-static void gb_timesync_collate_frame_time(struct gb_timesync_svc *timesync_svc,
- u64 *frame_time)
-{
- int i = 0;
- u64 delta, ap_frame_time;
- u64 strobe_delay_ns = GB_TIMESYNC_STROBE_DELAY_US * NSEC_PER_USEC;
- u64 least = 0;
-
- for (i = 1; i < GB_TIMESYNC_MAX_STROBES; i++) {
- delta = timesync_svc->strobe_data[i].frame_time -
- timesync_svc->strobe_data[i - 1].frame_time;
- delta *= gb_timesync_ns_per_clock;
- delta = gb_timesync_diff(delta, strobe_delay_ns);
-
- if (!least || delta < least) {
- least = delta;
- gb_timesync_adjust_to_svc(timesync_svc, frame_time[i],
- timesync_svc->strobe_data[i].frame_time);
-
- ap_frame_time = timesync_svc->strobe_data[i].frame_time;
- ap_frame_time = gb_timesync_adjust_count(timesync_svc,
- ap_frame_time);
- gb_timesync_store_ktime(timesync_svc,
- timesync_svc->strobe_data[i].ts,
- ap_frame_time);
-
- pr_debug("adjust %s local %llu svc %llu delta %llu\n",
- timesync_svc->offset_down ? "down" : "up",
- timesync_svc->strobe_data[i].frame_time,
- frame_time[i], delta);
- }
- }
-}
-
-static void gb_timesync_teardown(struct gb_timesync_svc *timesync_svc)
-{
- struct gb_timesync_interface *timesync_interface;
- struct gb_svc *svc = timesync_svc->svc;
- struct gb_interface *interface;
- struct gb_host_device *hd;
- int ret;
-
- list_for_each_entry(timesync_interface,
- &timesync_svc->interface_list, list) {
- interface = timesync_interface->interface;
- ret = gb_interface_timesync_disable(interface);
- if (ret) {
- dev_err(&interface->dev,
- "interface timesync_disable %d\n", ret);
- }
- }
-
- hd = timesync_svc->timesync_hd->hd;
- ret = hd->driver->timesync_disable(hd);
- if (ret < 0) {
- dev_err(&hd->dev, "host timesync_disable %d\n",
- ret);
- }
-
- gb_svc_timesync_wake_pins_release(svc);
- gb_svc_timesync_disable(svc);
- gb_timesync_platform_unlock_bus();
-
- gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INACTIVE);
-}
-
-static void gb_timesync_platform_lock_bus_fail(struct gb_timesync_svc
- *timesync_svc, int ret)
-{
- if (ret == -EAGAIN) {
- gb_timesync_set_state(timesync_svc, timesync_svc->state);
- } else {
- pr_err("Failed to lock timesync bus %d\n", ret);
- gb_timesync_set_state(timesync_svc, GB_TIMESYNC_STATE_INACTIVE);
- }
-}
-
-static void gb_timesync_enable(struct gb_timesync_svc *timesync_svc)
-{
- struct gb_svc *svc = timesync_svc->svc;
- struct gb_host_device *hd;
- struct gb_timesync_interface *timesync_interface;
- struct gb_interface *interface;
- u64 init_frame_time;
- unsigned long clock_rate = gb_timesync_clock_rate;
- int ret;
-
- /*
- * Get access to the wake pins in the AP and SVC
- * Release these pins either in gb_timesync_teardown() or in
- * gb_timesync_authoritative()
- */
- ret = gb_timesync_platform_lock_bus(timesync_svc);
- if (ret < 0) {
- gb_timesync_platform_lock_bus_fail(timesync_svc, ret);
- return;
- }
- ret = gb_svc_timesync_wake_pins_acquire(svc, timesync_svc->strobe_mask);
- if (ret) {
- dev_err(&svc->dev,
- "gb_svc_timesync_wake_pins_acquire %d\n", ret);
- gb_timesync_teardown(timesync_svc);
- return;
- }
-
- /* Choose an initial time in the future */
- init_frame_time = __gb_timesync_get_frame_time(timesync_svc) + 100000UL;
-
- /* Send enable command to all relevant participants */
- list_for_each_entry(timesync_interface, &timesync_svc->interface_list,
- list) {
- interface = timesync_interface->interface;
- ret = gb_interface_timesync_enable(interface,
- GB_TIMESYNC_MAX_STROBES,
- init_frame_time,
- GB_TIMESYNC_STROBE_DELAY_US,
- clock_rate);
- if (ret) {
- dev_err(&interface->dev,
- "interface timesync_enable %d\n", ret);
- }
- }
-
- hd = timesync_svc->timesync_hd->hd;
- ret = hd->driver->timesync_enable(hd, GB_TIMESYNC_MAX_STROBES,
- init_frame_time,
- GB_TIMESYNC_STROBE_DELAY_US,
- clock_rate);
- if (ret < 0) {
- dev_err(&hd->dev, "host timesync_enable %d\n",
- ret);
- }
-
- gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_WAIT_SVC);
- ret = gb_svc_timesync_enable(svc, GB_TIMESYNC_MAX_STROBES,
- init_frame_time,
- GB_TIMESYNC_STROBE_DELAY_US,
- clock_rate);
- if (ret) {
- dev_err(&svc->dev,
- "gb_svc_timesync_enable %d\n", ret);
- gb_timesync_teardown(timesync_svc);
- return;
- }
-
- /* Schedule a timeout waiting for SVC to complete strobing */
- gb_timesync_schedule_svc_timeout(timesync_svc);
-}
-
-static void gb_timesync_authoritative(struct gb_timesync_svc *timesync_svc)
-{
- struct gb_svc *svc = timesync_svc->svc;
- struct gb_host_device *hd;
- struct gb_timesync_interface *timesync_interface;
- struct gb_interface *interface;
- u64 svc_frame_time[GB_TIMESYNC_MAX_STROBES];
- int ret;
-
- /* Get authoritative time from SVC and adjust local clock */
- ret = gb_svc_timesync_authoritative(svc, svc_frame_time);
- if (ret) {
- dev_err(&svc->dev,
- "gb_svc_timesync_authoritative %d\n", ret);
- gb_timesync_teardown(timesync_svc);
- return;
- }
- gb_timesync_collate_frame_time(timesync_svc, svc_frame_time);
-
- /* Transmit authoritative time to downstream slaves */
- hd = timesync_svc->timesync_hd->hd;
- ret = hd->driver->timesync_authoritative(hd, svc_frame_time);
- if (ret < 0)
- dev_err(&hd->dev, "host timesync_authoritative %d\n", ret);
-
- list_for_each_entry(timesync_interface,
- &timesync_svc->interface_list, list) {
- interface = timesync_interface->interface;
- ret = gb_interface_timesync_authoritative(
- interface,
- svc_frame_time);
- if (ret) {
- dev_err(&interface->dev,
- "interface timesync_authoritative %d\n", ret);
- }
- }
-
- /* Release wake pins */
- gb_svc_timesync_wake_pins_release(svc);
- gb_timesync_platform_unlock_bus();
-
- /* Transition to state ACTIVE */
- gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_ACTIVE);
-
- /* Schedule a ping to verify the synchronized system time */
- timesync_svc->print_ping = true;
- gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_PING);
-}
-
-static int __gb_timesync_get_status(struct gb_timesync_svc *timesync_svc)
-{
- int ret = -EINVAL;
-
- switch (timesync_svc->state) {
- case GB_TIMESYNC_STATE_INVALID:
- case GB_TIMESYNC_STATE_INACTIVE:
- ret = -ENODEV;
- break;
- case GB_TIMESYNC_STATE_INIT:
- case GB_TIMESYNC_STATE_WAIT_SVC:
- case GB_TIMESYNC_STATE_AUTHORITATIVE:
- ret = -EAGAIN;
- break;
- case GB_TIMESYNC_STATE_PING:
- case GB_TIMESYNC_STATE_ACTIVE:
- ret = 0;
- break;
- }
- return ret;
-}
-
-/*
- * This routine takes a FrameTime and derives the difference with-respect
- * to a reference FrameTime/ktime pair. It then returns the calculated
- * ktime based on the difference between the supplied FrameTime and
- * the reference FrameTime.
- *
- * The time difference is calculated to six decimal places. Taking 19.2MHz
- * as an example this means we have 52.083333~ nanoseconds per clock or
- * 52083333~ femtoseconds per clock.
- *
- * Naively taking the count difference and converting to
- * seconds/nanoseconds would quickly see the 0.0833 component produce
- * noticeable errors. For example a time difference of one second would
- * loose 19200000 * 0.08333x nanoseconds or 1.59 seconds.
- *
- * In contrast calculating in femtoseconds the same example of 19200000 *
- * 0.000000083333x nanoseconds per count of error is just 1.59 nanoseconds!
- *
- * Continuing the example of 19.2 MHz we cap the maximum error difference
- * at a worst-case 0.3 microseconds over a potential calculation window of
- * abount 15 seconds, meaning you can convert a FrameTime that is <= 15
- * seconds older/younger than the reference time with a maximum error of
- * 0.2385 useconds. Note 19.2MHz is an example frequency not a requirement.
- */
-static int gb_timesync_to_timespec(struct gb_timesync_svc *timesync_svc,
- u64 frame_time, struct timespec *ts)
-{
- unsigned long flags;
- u64 delta_fs, counts, sec, nsec;
- bool add;
- int ret = 0;
-
- memset(ts, 0x00, sizeof(*ts));
- mutex_lock(&timesync_svc->mutex);
- spin_lock_irqsave(&timesync_svc->spinlock, flags);
-
- ret = __gb_timesync_get_status(timesync_svc);
- if (ret)
- goto done;
-
- /* Support calculating ktime upwards or downwards from the reference */
- if (frame_time < timesync_svc->ktime_data.frame_time) {
- add = false;
- counts = timesync_svc->ktime_data.frame_time - frame_time;
- } else {
- add = true;
- counts = frame_time - timesync_svc->ktime_data.frame_time;
- }
-
- /* Enforce the .23 of a usecond boundary @ 19.2MHz */
- if (counts > gb_timesync_max_ktime_diff) {
- ret = -EINVAL;
- goto done;
- }
-
- /* Determine the time difference in femtoseconds */
- delta_fs = counts * gb_timesync_fs_per_clock;
-
- /* Convert to seconds */
- sec = delta_fs;
- do_div(sec, NSEC_PER_SEC);
- do_div(sec, 1000000UL);
-
- /* Get the nanosecond remainder */
- nsec = do_div(delta_fs, sec);
- do_div(nsec, 1000000UL);
-
- if (add) {
- /* Add the calculated offset - overflow nanoseconds upwards */
- ts->tv_sec = timesync_svc->ktime_data.ts.tv_sec + sec;
- ts->tv_nsec = timesync_svc->ktime_data.ts.tv_nsec + nsec;
- if (ts->tv_nsec >= NSEC_PER_SEC) {
- ts->tv_sec++;
- ts->tv_nsec -= NSEC_PER_SEC;
- }
- } else {
- /* Subtract the difference over/underflow as necessary */
- if (nsec > timesync_svc->ktime_data.ts.tv_nsec) {
- sec++;
- nsec = nsec + timesync_svc->ktime_data.ts.tv_nsec;
- nsec = do_div(nsec, NSEC_PER_SEC);
- } else {
- nsec = timesync_svc->ktime_data.ts.tv_nsec - nsec;
- }
- /* Cannot return a negative second value */
- if (sec > timesync_svc->ktime_data.ts.tv_sec) {
- ret = -EINVAL;
- goto done;
- }
- ts->tv_sec = timesync_svc->ktime_data.ts.tv_sec - sec;
- ts->tv_nsec = nsec;
- }
-done:
- spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
- mutex_unlock(&timesync_svc->mutex);
- return ret;
-}
-
-static size_t gb_timesync_log_frame_time(struct gb_timesync_svc *timesync_svc,
- char *buf, size_t buflen)
-{
- struct gb_svc *svc = timesync_svc->svc;
- struct gb_host_device *hd;
- struct gb_timesync_interface *timesync_interface;
- struct gb_interface *interface;
- unsigned int len;
- size_t off;
-
- /* AP/SVC */
- off = snprintf(buf, buflen, "%s frametime: ap=%llu %s=%llu ",
- greybus_bus_type.name,
- timesync_svc->ap_ping_frame_time, dev_name(&svc->dev),
- timesync_svc->svc_ping_frame_time);
- len = buflen - off;
-
- /* APB/GPB */
- if (len < buflen) {
- hd = timesync_svc->timesync_hd->hd;
- off += snprintf(&buf[off], len, "%s=%llu ", dev_name(&hd->dev),
- timesync_svc->timesync_hd->ping_frame_time);
- len = buflen - off;
- }
-
- list_for_each_entry(timesync_interface,
- &timesync_svc->interface_list, list) {
- if (len < buflen) {
- interface = timesync_interface->interface;
- off += snprintf(&buf[off], len, "%s=%llu ",
- dev_name(&interface->dev),
- timesync_interface->ping_frame_time);
- len = buflen - off;
- }
- }
- if (len < buflen)
- off += snprintf(&buf[off], len, "\n");
- return off;
-}
-
-static size_t gb_timesync_log_frame_ktime(struct gb_timesync_svc *timesync_svc,
- char *buf, size_t buflen)
-{
- struct gb_svc *svc = timesync_svc->svc;
- struct gb_host_device *hd;
- struct gb_timesync_interface *timesync_interface;
- struct gb_interface *interface;
- struct timespec ts;
- unsigned int len;
- size_t off;
-
- /* AP */
- gb_timesync_to_timespec(timesync_svc, timesync_svc->ap_ping_frame_time,
- &ts);
- off = snprintf(buf, buflen, "%s frametime: ap=%lu.%lu ",
- greybus_bus_type.name, ts.tv_sec, ts.tv_nsec);
- len = buflen - off;
- if (len >= buflen)
- goto done;
-
- /* SVC */
- gb_timesync_to_timespec(timesync_svc, timesync_svc->svc_ping_frame_time,
- &ts);
- off += snprintf(&buf[off], len, "%s=%lu.%lu ", dev_name(&svc->dev),
- ts.tv_sec, ts.tv_nsec);
- len = buflen - off;
- if (len >= buflen)
- goto done;
-
- /* APB/GPB */
- hd = timesync_svc->timesync_hd->hd;
- gb_timesync_to_timespec(timesync_svc,
- timesync_svc->timesync_hd->ping_frame_time,
- &ts);
- off += snprintf(&buf[off], len, "%s=%lu.%lu ",
- dev_name(&hd->dev),
- ts.tv_sec, ts.tv_nsec);
- len = buflen - off;
- if (len >= buflen)
- goto done;
-
- list_for_each_entry(timesync_interface,
- &timesync_svc->interface_list, list) {
- interface = timesync_interface->interface;
- gb_timesync_to_timespec(timesync_svc,
- timesync_interface->ping_frame_time,
- &ts);
- off += snprintf(&buf[off], len, "%s=%lu.%lu ",
- dev_name(&interface->dev),
- ts.tv_sec, ts.tv_nsec);
- len = buflen - off;
- if (len >= buflen)
- goto done;
- }
- off += snprintf(&buf[off], len, "\n");
-done:
- return off;
-}
-
-/*
- * Send an SVC initiated wake 'ping' to each TimeSync participant.
- * Get the FrameTime from each participant associated with the wake
- * ping.
- */
-static void gb_timesync_ping(struct gb_timesync_svc *timesync_svc)
-{
- struct gb_svc *svc = timesync_svc->svc;
- struct gb_host_device *hd;
- struct gb_timesync_interface *timesync_interface;
- struct gb_control *control;
- u64 *ping_frame_time;
- int ret;
-
- /* Get access to the wake pins in the AP and SVC */
- ret = gb_timesync_platform_lock_bus(timesync_svc);
- if (ret < 0) {
- gb_timesync_platform_lock_bus_fail(timesync_svc, ret);
- return;
- }
- ret = gb_svc_timesync_wake_pins_acquire(svc, timesync_svc->strobe_mask);
- if (ret) {
- dev_err(&svc->dev,
- "gb_svc_timesync_wake_pins_acquire %d\n", ret);
- gb_timesync_teardown(timesync_svc);
- return;
- }
-
- /* Have SVC generate a timesync ping */
- timesync_svc->capture_ping = true;
- timesync_svc->svc_ping_frame_time = 0;
- ret = gb_svc_timesync_ping(svc, &timesync_svc->svc_ping_frame_time);
- timesync_svc->capture_ping = false;
- if (ret) {
- dev_err(&svc->dev,
- "gb_svc_timesync_ping %d\n", ret);
- gb_timesync_teardown(timesync_svc);
- return;
- }
-
- /* Get the ping FrameTime from each APB/GPB */
- hd = timesync_svc->timesync_hd->hd;
- timesync_svc->timesync_hd->ping_frame_time = 0;
- ret = hd->driver->timesync_get_last_event(hd,
- &timesync_svc->timesync_hd->ping_frame_time);
- if (ret)
- dev_err(&hd->dev, "host timesync_get_last_event %d\n", ret);
-
- list_for_each_entry(timesync_interface,
- &timesync_svc->interface_list, list) {
- control = timesync_interface->interface->control;
- timesync_interface->ping_frame_time = 0;
- ping_frame_time = &timesync_interface->ping_frame_time;
- ret = gb_control_timesync_get_last_event(control,
- ping_frame_time);
- if (ret) {
- dev_err(&timesync_interface->interface->dev,
- "gb_control_timesync_get_last_event %d\n", ret);
- }
- }
-
- /* Ping success - move to timesync active */
- gb_svc_timesync_wake_pins_release(svc);
- gb_timesync_platform_unlock_bus();
- gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_ACTIVE);
-}
-
-static void gb_timesync_log_ping_time(struct gb_timesync_svc *timesync_svc)
-{
- char *buf;
-
- if (!timesync_svc->print_ping)
- return;
-
- buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
- if (buf) {
- gb_timesync_log_frame_time(timesync_svc, buf, PAGE_SIZE);
- dev_dbg(&timesync_svc->svc->dev, "%s", buf);
- kfree(buf);
- }
-}
-
-/*
- * Perform the actual work of scheduled TimeSync logic.
- */
-static void gb_timesync_worker(struct work_struct *work)
-{
- struct delayed_work *delayed_work = to_delayed_work(work);
- struct gb_timesync_svc *timesync_svc =
- container_of(delayed_work, struct gb_timesync_svc, delayed_work);
-
- mutex_lock(&timesync_svc->mutex);
-
- switch (timesync_svc->state) {
- case GB_TIMESYNC_STATE_INIT:
- gb_timesync_enable(timesync_svc);
- break;
-
- case GB_TIMESYNC_STATE_WAIT_SVC:
- dev_err(&timesync_svc->svc->dev,
- "timeout SVC strobe completion %d/%d\n",
- timesync_svc->strobe, GB_TIMESYNC_MAX_STROBES);
- gb_timesync_teardown(timesync_svc);
- break;
-
- case GB_TIMESYNC_STATE_AUTHORITATIVE:
- gb_timesync_authoritative(timesync_svc);
- break;
-
- case GB_TIMESYNC_STATE_PING:
- gb_timesync_ping(timesync_svc);
- gb_timesync_log_ping_time(timesync_svc);
- break;
-
- default:
- pr_err("Invalid state %d for delayed work\n",
- timesync_svc->state);
- break;
- }
-
- mutex_unlock(&timesync_svc->mutex);
-}
-
-/*
- * Schedule a new TimeSync INIT or PING operation serialized w/r to
- * gb_timesync_worker().
- */
-static int gb_timesync_schedule(struct gb_timesync_svc *timesync_svc, int state)
-{
- int ret = 0;
-
- if (state != GB_TIMESYNC_STATE_INIT && state != GB_TIMESYNC_STATE_PING)
- return -EINVAL;
-
- mutex_lock(&timesync_svc->mutex);
- if (timesync_svc->state != GB_TIMESYNC_STATE_INVALID)
- gb_timesync_set_state_atomic(timesync_svc, state);
- else
- ret = -ENODEV;
-
- mutex_unlock(&timesync_svc->mutex);
- return ret;
-}
-
-static int __gb_timesync_schedule_synchronous(
- struct gb_timesync_svc *timesync_svc, int state)
-{
- unsigned long flags;
- int ret;
-
- ret = gb_timesync_schedule(timesync_svc, state);
- if (ret)
- return ret;
-
- ret = wait_event_interruptible(timesync_svc->wait_queue,
- (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE ||
- timesync_svc->state == GB_TIMESYNC_STATE_INACTIVE ||
- timesync_svc->state == GB_TIMESYNC_STATE_INVALID));
- if (ret)
- return ret;
-
- mutex_lock(&timesync_svc->mutex);
- spin_lock_irqsave(&timesync_svc->spinlock, flags);
-
- ret = __gb_timesync_get_status(timesync_svc);
-
- spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
- mutex_unlock(&timesync_svc->mutex);
-
- return ret;
-}
-
-static struct gb_timesync_svc *gb_timesync_find_timesync_svc(
- struct gb_host_device *hd)
-{
- struct gb_timesync_svc *timesync_svc;
-
- list_for_each_entry(timesync_svc, &gb_timesync_svc_list, list) {
- if (timesync_svc->svc == hd->svc)
- return timesync_svc;
- }
- return NULL;
-}
-
-static struct gb_timesync_interface *gb_timesync_find_timesync_interface(
- struct gb_timesync_svc *timesync_svc,
- struct gb_interface *interface)
-{
- struct gb_timesync_interface *timesync_interface;
-
- list_for_each_entry(timesync_interface, &timesync_svc->interface_list, list) {
- if (timesync_interface->interface == interface)
- return timesync_interface;
- }
- return NULL;
-}
-
-int gb_timesync_schedule_synchronous(struct gb_interface *interface)
-{
- int ret;
- struct gb_timesync_svc *timesync_svc;
- int retries;
-
- if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
- return 0;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- for (retries = 0; retries < GB_TIMESYNC_MAX_RETRIES; retries++) {
- timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
- if (!timesync_svc) {
- ret = -ENODEV;
- goto done;
- }
-
- ret = __gb_timesync_schedule_synchronous(timesync_svc,
- GB_TIMESYNC_STATE_INIT);
- if (!ret)
- break;
- }
- if (ret && retries == GB_TIMESYNC_MAX_RETRIES)
- ret = -ETIMEDOUT;
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gb_timesync_schedule_synchronous);
-
-void gb_timesync_schedule_asynchronous(struct gb_interface *interface)
-{
- struct gb_timesync_svc *timesync_svc;
-
- if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
- return;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
- if (!timesync_svc)
- goto done;
-
- gb_timesync_schedule(timesync_svc, GB_TIMESYNC_STATE_INIT);
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
- return;
-}
-EXPORT_SYMBOL_GPL(gb_timesync_schedule_asynchronous);
-
-static ssize_t gb_timesync_ping_read(struct file *file, char __user *ubuf,
- size_t len, loff_t *offset, bool ktime)
-{
- struct gb_timesync_svc *timesync_svc = file_inode(file)->i_private;
- char *buf;
- ssize_t ret = 0;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- mutex_lock(&timesync_svc->mutex);
- if (list_empty(&timesync_svc->interface_list))
- ret = -ENODEV;
- timesync_svc->print_ping = false;
- mutex_unlock(&timesync_svc->mutex);
- if (ret)
- goto done;
-
- ret = __gb_timesync_schedule_synchronous(timesync_svc,
- GB_TIMESYNC_STATE_PING);
- if (ret)
- goto done;
-
- buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
- if (!buf) {
- ret = -ENOMEM;
- goto done;
- }
-
- if (ktime)
- ret = gb_timesync_log_frame_ktime(timesync_svc, buf, PAGE_SIZE);
- else
- ret = gb_timesync_log_frame_time(timesync_svc, buf, PAGE_SIZE);
- if (ret > 0)
- ret = simple_read_from_buffer(ubuf, len, offset, buf, ret);
- kfree(buf);
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
- return ret;
-}
-
-static ssize_t gb_timesync_ping_read_frame_time(struct file *file,
- char __user *buf,
- size_t len, loff_t *offset)
-{
- return gb_timesync_ping_read(file, buf, len, offset, false);
-}
-
-static ssize_t gb_timesync_ping_read_frame_ktime(struct file *file,
- char __user *buf,
- size_t len, loff_t *offset)
-{
- return gb_timesync_ping_read(file, buf, len, offset, true);
-}
-
-static const struct file_operations gb_timesync_debugfs_frame_time_ops = {
- .read = gb_timesync_ping_read_frame_time,
-};
-
-static const struct file_operations gb_timesync_debugfs_frame_ktime_ops = {
- .read = gb_timesync_ping_read_frame_ktime,
-};
-
-static int gb_timesync_hd_add(struct gb_timesync_svc *timesync_svc,
- struct gb_host_device *hd)
-{
- struct gb_timesync_host_device *timesync_hd;
-
- timesync_hd = kzalloc(sizeof(*timesync_hd), GFP_KERNEL);
- if (!timesync_hd)
- return -ENOMEM;
-
- WARN_ON(timesync_svc->timesync_hd);
- timesync_hd->hd = hd;
- timesync_svc->timesync_hd = timesync_hd;
-
- return 0;
-}
-
-static void gb_timesync_hd_remove(struct gb_timesync_svc *timesync_svc,
- struct gb_host_device *hd)
-{
- if (timesync_svc->timesync_hd->hd == hd) {
- kfree(timesync_svc->timesync_hd);
- timesync_svc->timesync_hd = NULL;
- return;
- }
- WARN_ON(1);
-}
-
-int gb_timesync_svc_add(struct gb_svc *svc)
-{
- struct gb_timesync_svc *timesync_svc;
- int ret;
-
- timesync_svc = kzalloc(sizeof(*timesync_svc), GFP_KERNEL);
- if (!timesync_svc)
- return -ENOMEM;
-
- timesync_svc->work_queue =
- create_singlethread_workqueue("gb-timesync-work_queue");
-
- if (!timesync_svc->work_queue) {
- kfree(timesync_svc);
- return -ENOMEM;
- }
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- INIT_LIST_HEAD(&timesync_svc->interface_list);
- INIT_DELAYED_WORK(&timesync_svc->delayed_work, gb_timesync_worker);
- mutex_init(&timesync_svc->mutex);
- spin_lock_init(&timesync_svc->spinlock);
- init_waitqueue_head(&timesync_svc->wait_queue);
-
- timesync_svc->svc = svc;
- timesync_svc->frame_time_offset = 0;
- timesync_svc->capture_ping = false;
- gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INACTIVE);
-
- timesync_svc->frame_time_dentry =
- debugfs_create_file("frame-time", S_IRUGO, svc->debugfs_dentry,
- timesync_svc,
- &gb_timesync_debugfs_frame_time_ops);
- timesync_svc->frame_ktime_dentry =
- debugfs_create_file("frame-ktime", S_IRUGO, svc->debugfs_dentry,
- timesync_svc,
- &gb_timesync_debugfs_frame_ktime_ops);
-
- list_add(&timesync_svc->list, &gb_timesync_svc_list);
- ret = gb_timesync_hd_add(timesync_svc, svc->hd);
- if (ret) {
- list_del(&timesync_svc->list);
- debugfs_remove(timesync_svc->frame_ktime_dentry);
- debugfs_remove(timesync_svc->frame_time_dentry);
- destroy_workqueue(timesync_svc->work_queue);
- kfree(timesync_svc);
- goto done;
- }
-
- init_timer(&timesync_svc->ktime_timer);
- timesync_svc->ktime_timer.function = gb_timesync_ktime_timer_fn;
- timesync_svc->ktime_timer.expires = jiffies + GB_TIMESYNC_KTIME_UPDATE;
- timesync_svc->ktime_timer.data = (unsigned long)timesync_svc;
- add_timer(&timesync_svc->ktime_timer);
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gb_timesync_svc_add);
-
-void gb_timesync_svc_remove(struct gb_svc *svc)
-{
- struct gb_timesync_svc *timesync_svc;
- struct gb_timesync_interface *timesync_interface;
- struct gb_timesync_interface *next;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- timesync_svc = gb_timesync_find_timesync_svc(svc->hd);
- if (!timesync_svc)
- goto done;
-
- cancel_delayed_work_sync(&timesync_svc->delayed_work);
-
- mutex_lock(&timesync_svc->mutex);
-
- gb_timesync_set_state_atomic(timesync_svc, GB_TIMESYNC_STATE_INVALID);
- del_timer_sync(&timesync_svc->ktime_timer);
- gb_timesync_teardown(timesync_svc);
-
- gb_timesync_hd_remove(timesync_svc, svc->hd);
- list_for_each_entry_safe(timesync_interface, next,
- &timesync_svc->interface_list, list) {
- list_del(&timesync_interface->list);
- kfree(timesync_interface);
- }
- debugfs_remove(timesync_svc->frame_ktime_dentry);
- debugfs_remove(timesync_svc->frame_time_dentry);
- destroy_workqueue(timesync_svc->work_queue);
- list_del(&timesync_svc->list);
-
- mutex_unlock(&timesync_svc->mutex);
-
- kfree(timesync_svc);
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
-}
-EXPORT_SYMBOL_GPL(gb_timesync_svc_remove);
-
-/*
- * Add a Greybus Interface to the set of TimeSync Interfaces.
- */
-int gb_timesync_interface_add(struct gb_interface *interface)
-{
- struct gb_timesync_svc *timesync_svc;
- struct gb_timesync_interface *timesync_interface;
- int ret = 0;
-
- if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
- return 0;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
- if (!timesync_svc) {
- ret = -ENODEV;
- goto done;
- }
-
- timesync_interface = kzalloc(sizeof(*timesync_interface), GFP_KERNEL);
- if (!timesync_interface) {
- ret = -ENOMEM;
- goto done;
- }
-
- mutex_lock(&timesync_svc->mutex);
- timesync_interface->interface = interface;
- list_add(&timesync_interface->list, &timesync_svc->interface_list);
- timesync_svc->strobe_mask |= 1 << interface->interface_id;
- mutex_unlock(&timesync_svc->mutex);
-
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gb_timesync_interface_add);
-
-/*
- * Remove a Greybus Interface from the set of TimeSync Interfaces.
- */
-void gb_timesync_interface_remove(struct gb_interface *interface)
-{
- struct gb_timesync_svc *timesync_svc;
- struct gb_timesync_interface *timesync_interface;
-
- if (!(interface->features & GREYBUS_INTERFACE_FEATURE_TIMESYNC))
- return;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
- if (!timesync_svc)
- goto done;
-
- timesync_interface = gb_timesync_find_timesync_interface(timesync_svc,
- interface);
- if (!timesync_interface)
- goto done;
-
- mutex_lock(&timesync_svc->mutex);
- timesync_svc->strobe_mask &= ~(1 << interface->interface_id);
- list_del(&timesync_interface->list);
- kfree(timesync_interface);
- mutex_unlock(&timesync_svc->mutex);
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
-}
-EXPORT_SYMBOL_GPL(gb_timesync_interface_remove);
-
-/*
- * Give the authoritative FrameTime to the calling function. Returns zero if we
- * are not in GB_TIMESYNC_STATE_ACTIVE.
- */
-static u64 gb_timesync_get_frame_time(struct gb_timesync_svc *timesync_svc)
-{
- unsigned long flags;
- u64 ret;
-
- spin_lock_irqsave(&timesync_svc->spinlock, flags);
- if (timesync_svc->state == GB_TIMESYNC_STATE_ACTIVE)
- ret = __gb_timesync_get_frame_time(timesync_svc);
- else
- ret = 0;
- spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
- return ret;
-}
-
-u64 gb_timesync_get_frame_time_by_interface(struct gb_interface *interface)
-{
- struct gb_timesync_svc *timesync_svc;
- u64 ret = 0;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
- if (!timesync_svc)
- goto done;
-
- ret = gb_timesync_get_frame_time(timesync_svc);
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gb_timesync_get_frame_time_by_interface);
-
-u64 gb_timesync_get_frame_time_by_svc(struct gb_svc *svc)
-{
- struct gb_timesync_svc *timesync_svc;
- u64 ret = 0;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- timesync_svc = gb_timesync_find_timesync_svc(svc->hd);
- if (!timesync_svc)
- goto done;
-
- ret = gb_timesync_get_frame_time(timesync_svc);
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gb_timesync_get_frame_time_by_svc);
-
-/* Incrementally updates the conversion base from FrameTime to ktime */
-static void gb_timesync_ktime_timer_fn(unsigned long data)
-{
- struct gb_timesync_svc *timesync_svc =
- (struct gb_timesync_svc *)data;
- unsigned long flags;
- u64 frame_time;
- struct timespec ts;
-
- spin_lock_irqsave(&timesync_svc->spinlock, flags);
-
- if (timesync_svc->state != GB_TIMESYNC_STATE_ACTIVE)
- goto done;
-
- ktime_get_ts(&ts);
- frame_time = __gb_timesync_get_frame_time(timesync_svc);
- gb_timesync_store_ktime(timesync_svc, ts, frame_time);
-
-done:
- spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
- mod_timer(&timesync_svc->ktime_timer,
- jiffies + GB_TIMESYNC_KTIME_UPDATE);
-}
-
-int gb_timesync_to_timespec_by_svc(struct gb_svc *svc, u64 frame_time,
- struct timespec *ts)
-{
- struct gb_timesync_svc *timesync_svc;
- int ret = 0;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- timesync_svc = gb_timesync_find_timesync_svc(svc->hd);
- if (!timesync_svc) {
- ret = -ENODEV;
- goto done;
- }
- ret = gb_timesync_to_timespec(timesync_svc, frame_time, ts);
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gb_timesync_to_timespec_by_svc);
-
-int gb_timesync_to_timespec_by_interface(struct gb_interface *interface,
- u64 frame_time, struct timespec *ts)
-{
- struct gb_timesync_svc *timesync_svc;
- int ret = 0;
-
- mutex_lock(&gb_timesync_svc_list_mutex);
- timesync_svc = gb_timesync_find_timesync_svc(interface->hd);
- if (!timesync_svc) {
- ret = -ENODEV;
- goto done;
- }
-
- ret = gb_timesync_to_timespec(timesync_svc, frame_time, ts);
-done:
- mutex_unlock(&gb_timesync_svc_list_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gb_timesync_to_timespec_by_interface);
-
-void gb_timesync_irq(struct gb_timesync_svc *timesync_svc)
-{
- unsigned long flags;
- u64 strobe_time;
- bool strobe_is_ping = true;
- struct timespec ts;
-
- ktime_get_ts(&ts);
- strobe_time = __gb_timesync_get_frame_time(timesync_svc);
-
- spin_lock_irqsave(&timesync_svc->spinlock, flags);
-
- if (timesync_svc->state == GB_TIMESYNC_STATE_PING) {
- if (!timesync_svc->capture_ping)
- goto done_nolog;
- timesync_svc->ap_ping_frame_time = strobe_time;
- goto done_log;
- } else if (timesync_svc->state != GB_TIMESYNC_STATE_WAIT_SVC) {
- goto done_nolog;
- }
-
- timesync_svc->strobe_data[timesync_svc->strobe].frame_time = strobe_time;
- timesync_svc->strobe_data[timesync_svc->strobe].ts = ts;
-
- if (++timesync_svc->strobe == GB_TIMESYNC_MAX_STROBES) {
- gb_timesync_set_state(timesync_svc,
- GB_TIMESYNC_STATE_AUTHORITATIVE);
- }
- strobe_is_ping = false;
-done_log:
- trace_gb_timesync_irq(strobe_is_ping, timesync_svc->strobe,
- GB_TIMESYNC_MAX_STROBES, strobe_time);
-done_nolog:
- spin_unlock_irqrestore(&timesync_svc->spinlock, flags);
-}
-EXPORT_SYMBOL(gb_timesync_irq);
-
-int __init gb_timesync_init(void)
-{
- int ret = 0;
-
- ret = gb_timesync_platform_init();
- if (ret) {
- pr_err("timesync platform init fail!\n");
- return ret;
- }
-
- gb_timesync_clock_rate = gb_timesync_platform_get_clock_rate();
-
- /* Calculate nanoseconds and femtoseconds per clock */
- gb_timesync_fs_per_clock = FSEC_PER_SEC;
- do_div(gb_timesync_fs_per_clock, gb_timesync_clock_rate);
- gb_timesync_ns_per_clock = NSEC_PER_SEC;
- do_div(gb_timesync_ns_per_clock, gb_timesync_clock_rate);
-
- /* Calculate the maximum number of clocks we will convert to ktime */
- gb_timesync_max_ktime_diff =
- GB_TIMESYNC_MAX_KTIME_CONVERSION * gb_timesync_clock_rate;
-
- pr_info("Time-Sync @ %lu Hz max ktime conversion +/- %d seconds\n",
- gb_timesync_clock_rate, GB_TIMESYNC_MAX_KTIME_CONVERSION);
- return 0;
-}
-
-void gb_timesync_exit(void)
-{
- gb_timesync_platform_exit();
-}
diff --git a/drivers/staging/greybus/timesync.h b/drivers/staging/greybus/timesync.h
deleted file mode 100644
index 72fc9a35a002..000000000000
--- a/drivers/staging/greybus/timesync.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * TimeSync API driver.
- *
- * Copyright 2016 Google Inc.
- * Copyright 2016 Linaro Ltd.
- *
- * Released under the GPLv2 only.
- */
-
-#ifndef __TIMESYNC_H
-#define __TIMESYNC_H
-
-struct gb_svc;
-struct gb_interface;
-struct gb_timesync_svc;
-
-/* Platform */
-u64 gb_timesync_platform_get_counter(void);
-u32 gb_timesync_platform_get_clock_rate(void);
-int gb_timesync_platform_lock_bus(struct gb_timesync_svc *pdata);
-void gb_timesync_platform_unlock_bus(void);
-
-int gb_timesync_platform_init(void);
-void gb_timesync_platform_exit(void);
-
-/* Core API */
-int gb_timesync_interface_add(struct gb_interface *interface);
-void gb_timesync_interface_remove(struct gb_interface *interface);
-int gb_timesync_svc_add(struct gb_svc *svc);
-void gb_timesync_svc_remove(struct gb_svc *svc);
-
-u64 gb_timesync_get_frame_time_by_interface(struct gb_interface *interface);
-u64 gb_timesync_get_frame_time_by_svc(struct gb_svc *svc);
-int gb_timesync_to_timespec_by_svc(struct gb_svc *svc, u64 frame_time,
- struct timespec *ts);
-int gb_timesync_to_timespec_by_interface(struct gb_interface *interface,
- u64 frame_time, struct timespec *ts);
-
-int gb_timesync_schedule_synchronous(struct gb_interface *intf);
-void gb_timesync_schedule_asynchronous(struct gb_interface *intf);
-void gb_timesync_irq(struct gb_timesync_svc *timesync_svc);
-int gb_timesync_init(void);
-void gb_timesync_exit(void);
-
-#endif /* __TIMESYNC_H */
diff --git a/drivers/staging/greybus/timesync_platform.c b/drivers/staging/greybus/timesync_platform.c
deleted file mode 100644
index 113f3d6c4b3a..000000000000
--- a/drivers/staging/greybus/timesync_platform.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * TimeSync API driver.
- *
- * Copyright 2016 Google Inc.
- * Copyright 2016 Linaro Ltd.
- *
- * Released under the GPLv2 only.
- *
- * This code reads directly from an ARMv7 memory-mapped timer that lives in
- * MMIO space. Since this counter lives inside of MMIO space its shared between
- * cores and that means we don't have to worry about issues like TSC on x86
- * where each time-stamp-counter (TSC) is local to a particular core.
- *
- * Register-level access code is based on
- * drivers/clocksource/arm_arch_timer.c
- */
-#include <linux/cpufreq.h>
-#include <linux/of_platform.h>
-
-#include "greybus.h"
-#include "arche_platform.h"
-
-#define DEFAULT_FRAMETIME_CLOCK_HZ 19200000
-
-static u32 gb_timesync_clock_frequency;
-int (*arche_platform_change_state_cb)(enum arche_platform_state state,
- struct gb_timesync_svc *pdata);
-EXPORT_SYMBOL_GPL(arche_platform_change_state_cb);
-
-u64 gb_timesync_platform_get_counter(void)
-{
- return (u64)get_cycles();
-}
-
-u32 gb_timesync_platform_get_clock_rate(void)
-{
- if (unlikely(!gb_timesync_clock_frequency)) {
- gb_timesync_clock_frequency = cpufreq_get(0);
- if (!gb_timesync_clock_frequency)
- gb_timesync_clock_frequency = DEFAULT_FRAMETIME_CLOCK_HZ;
- }
-
- return gb_timesync_clock_frequency;
-}
-
-int gb_timesync_platform_lock_bus(struct gb_timesync_svc *pdata)
-{
- return arche_platform_change_state_cb(ARCHE_PLATFORM_STATE_TIME_SYNC,
- pdata);
-}
-
-void gb_timesync_platform_unlock_bus(void)
-{
- arche_platform_change_state_cb(ARCHE_PLATFORM_STATE_ACTIVE, NULL);
-}
-
-static const struct of_device_id arch_timer_of_match[] = {
- { .compatible = "google,greybus-frame-time-counter", },
- {},
-};
-
-int __init gb_timesync_platform_init(void)
-{
- struct device_node *np;
-
- np = of_find_matching_node(NULL, arch_timer_of_match);
- if (!np) {
- /* Tolerate not finding to allow BBB etc to continue */
- pr_warn("Unable to find a compatible ARMv7 timer\n");
- return 0;
- }
-
- if (of_property_read_u32(np, "clock-frequency",
- &gb_timesync_clock_frequency)) {
- pr_err("Unable to find timer clock-frequency\n");
- return -ENODEV;
- }
-
- return 0;
-}
-
-void gb_timesync_platform_exit(void) {}
diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c
index f7f4cd6fb55b..18d7a3d1f3c7 100644
--- a/drivers/staging/greybus/tools/loopback_test.c
+++ b/drivers/staging/greybus/tools/loopback_test.c
@@ -168,7 +168,7 @@ GET_AVG(latency_avg);
GET_AVG(apbridge_unipro_latency_avg);
GET_AVG(gbphy_firmware_latency_avg);
-void abort()
+void abort(void)
{
_exit(1);
}
@@ -521,7 +521,6 @@ static int log_results(struct loopback_test *t)
int fd, i, len, ret;
struct tm tm;
time_t local_time;
- mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
char file_name[MAX_SYSFS_PATH];
char data[CSV_MAX_LINE];
@@ -538,7 +537,7 @@ static int log_results(struct loopback_test *t)
snprintf(file_name, sizeof(file_name), "%s_%d_%d.csv",
t->test_name, t->size, t->iteration_max);
- fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, mode);
+ fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (fd < 0) {
fprintf(stderr, "unable to open %s for appendation\n", file_name);
abort();
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 6d39f4a04754..248ad6661a02 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -624,7 +624,6 @@ static int get_serial_info(struct gb_tty *gb_tty,
struct serial_struct tmp;
memset(&tmp, 0, sizeof(tmp));
- tmp.flags = ASYNC_LOW_LATENCY | ASYNC_SKIP_TEST;
tmp.type = PORT_16550A;
tmp.line = gb_tty->minor;
tmp.xmit_fifo_size = 16;
diff --git a/drivers/staging/i4l/Documentation/README.act2000 b/drivers/staging/i4l/Documentation/README.act2000
deleted file mode 100644
index ce7115e7f4ce..000000000000
--- a/drivers/staging/i4l/Documentation/README.act2000
+++ /dev/null
@@ -1,104 +0,0 @@
-$Id: README.act2000,v 1.3 2000/08/06 09:22:51 armin Exp $
-
-This document describes the ACT2000 driver for the
-IBM Active 2000 ISDN card.
-
-There are 3 Types of this card available. A ISA-, MCA-, and PCMCIA-Bus
-Version. Currently, only the ISA-Bus version of the card is supported.
-However MCA and PCMCIA will follow soon.
-
-The ISA-Bus Version uses 8 IO-ports. The base port address has to be set
-manually using the DIP switches.
-
-Setting up the DIP switches for the IBM Active 2000 ISDN card:
-
- Note: S5 and S6 always set off!
-
- S1 S2 S3 S4 Base-port
- on on on on 0x0200 (Factory default)
- off on on on 0x0240
- on off on on 0x0280
- off off on on 0x02c0
- on on off on 0x0300
- off on off on 0x0340
- on off off on 0x0380
- on on on off 0xcfe0
- off on on off 0xcfa0
- on off on off 0xcf60
- off off on off 0xcf20
- on on off off 0xcee0
- off on off off 0xcea0
- on off off off 0xce60
- off off off off Card disabled
-
-IRQ is configured by software. Possible values are:
-
- 3, 5, 7, 10, 11, 12, 15 and none (polled mode)
-
-
-The ACT2000 driver may either be built into the kernel or as a module.
-Initialization depends on how the driver is built:
-
-Driver built into the kernel:
-
- The ACT2000 driver can be configured using the commandline-feature while
- loading the kernel with LILO or LOADLIN. It accepts the following syntax:
-
- act2000=b,p,i[,idstring]
-
- where
-
- b = Bus-Type (1=ISA, 2=MCA, 3=PCMCIA)
- p = portbase (-1 means autoprobe)
- i = Interrupt (-1 means use next free IRQ, 0 means polled mode)
-
- The idstring is an arbitrary string used for referencing the card
- by the actctrl tool later.
-
- Defaults used, when no parameters given at all:
-
- 1,-1,-1,""
-
- which means: Autoprobe for an ISA card, use next free IRQ, let the
- ISDN linklevel fill the IdString (usually "line0" for the first card).
-
- If you like to use more than one card, you can use the program
- "actctrl" from the utility-package to configure additional cards.
-
- Using the "actctrl"-utility, portbase and irq can also be changed
- during runtime. The D-channel protocol is configured by the "dproto"
- option of the "actctrl"-utility after loading the firmware into the
- card's memory using the "actctrl"-utility.
-
-Driver built as module:
-
- The module act2000.o can be configured during modprobe (insmod) by
- appending its parameters to the modprobe resp. insmod commandline.
- The following syntax is accepted:
-
- act_bus=b act_port=p act_irq=i act_id=idstring
-
- where b, p, i and idstring have the same meanings as the parameters
- described for the builtin version above.
-
- Using the "actctrl"-utility, the same features apply to the modularized
- version as to the kernel-builtin one. (i.e. loading of firmware and
- configuring the D-channel protocol)
-
-Loading the firmware into the card:
-
- The firmware is supplied together with the isdn4k-utils package. It
- can be found in the subdirectory act2000/firmware/
-
- Assuming you have installed the utility-package correctly, the firmware
- will be downloaded into the card using the following command:
-
- actctrl -d idstring load /etc/isdn/bip11.btl
-
- where idstring is the Name of the card, given during insmod-time or
- (for kernel-builtin driver) on the kernel commandline. If only one
- ISDN card is used, the -d isdstrin may be omitted.
-
- For further documentation (adding more IBM Active 2000 cards), refer to
- the manpage actctrl.8 which is included in the isdn4k-utils package.
-
diff --git a/drivers/staging/i4l/Documentation/README.icn b/drivers/staging/i4l/Documentation/README.icn
deleted file mode 100644
index 13f833d4e910..000000000000
--- a/drivers/staging/i4l/Documentation/README.icn
+++ /dev/null
@@ -1,148 +0,0 @@
-$Id: README.icn,v 1.7 2000/08/06 09:22:51 armin Exp $
-
-You can get the ICN-ISDN-card from:
-
-Thinking Objects Software GmbH
-Versbacher Röthe 159
-97078 Würzburg
-Tel: +49 931 2877950
-Fax: +49 931 2877951
-
-email info@think.de
-WWW http:/www.think.de
-
-
-The card communicates with the PC by two interfaces:
- 1. A range of 4 successive port-addresses, whose base address can be
- configured with the switches.
- 2. A memory window with 16KB-256KB size, which can be setup in 16k steps
- over the whole range of 16MB. Isdn4linux only uses a 16k window.
- The base address of the window can be configured when loading
- the lowlevel-module (see README). If using more than one card,
- all cards are mapped to the same window and activated as needed.
-
-Setting up the IO-address dipswitches for the ICN-ISDN-card:
-
- Two types of cards exist, one with dip-switches and one with
- hook-switches.
-
- 1. Setting for the card with hook-switches:
-
- (0 = switch closed, 1 = switch open)
-
- S3 S2 S1 Base-address
- 0 0 0 0x300
- 0 0 1 0x310
- 0 1 0 0x320 (Default for isdn4linux)
- 0 1 1 0x330
- 1 0 0 0x340
- 1 0 1 0x350
- 1 1 0 0x360
- 1 1 1 NOT ALLOWED!
-
- 2. Setting for the card with dip-switches:
-
- (0 = switch closed, 1 = switch open)
-
- S1 S2 S3 S4 Base-Address
- 0 0 0 0 0x300
- 0 0 0 1 0x310
- 0 0 1 0 0x320 (Default for isdn4linux)
- 0 0 1 1 0x330
- 0 1 0 0 0x340
- 0 1 0 1 0x350
- 0 1 1 0 0x360
- 0 1 1 1 NOT ALLOWED!
- 1 0 0 0 0x308
- 1 0 0 1 0x318
- 1 0 1 0 0x328
- 1 0 1 1 0x338
- 1 1 0 0 0x348
- 1 1 0 1 0x358
- 1 1 1 0 0x368
- 1 1 1 1 NOT ALLOWED!
-
-The ICN driver may be built into the kernel or as a module. Initialization
-depends on how the driver is built:
-
-Driver built into the kernel:
-
- The ICN driver can be configured using the commandline-feature while
- loading the kernel with LILO or LOADLIN. It accepts the following syntax:
-
- icn=p,m[,idstring1[,idstring2]]
-
- where
-
- p = portbase (default: 0x320)
- m = shared memory (default: 0xd0000)
-
- When using the ICN double card (4B), you MUST define TWO idstrings.
- idstring must start with a character! There is no way for the driver
- to distinguish between a 2B and 4B type card. Therefore, by supplying
- TWO idstrings, you tell the driver that you have a 4B installed.
-
- If you like to use more than one card, you can use the program
- "icnctrl" from the utility-package to configure additional cards.
- You need to configure shared memory only once, since the icn-driver
- maps all cards into the same address-space.
-
- Using the "icnctrl"-utility, portbase and shared memory can also be
- changed during runtime.
-
- The D-channel protocol is configured by loading different firmware
- into the card's memory using the "icnctrl"-utility.
-
-
-Driver built as module:
-
- The module icn.o can be configured during "insmod'ing" it by
- appending its parameters to the insmod-commandline. The following
- syntax is accepted:
-
- portbase=p membase=m icn_id=idstring [icn_id2=idstring2]
-
- where p, m, idstring1 and idstring2 have the same meanings as the
- parameters described for the kernel-version above.
-
- When using the ICN double card (4B), you MUST define TWO idstrings.
- idstring must start with a character! There is no way for the driver
- to distinguish between a 2B and 4B type card. Therefore, by supplying
- TWO idstrings, you tell the driver that you have a 4B installed.
-
- Using the "icnctrl"-utility, the same features apply to the modularized
- version like to the kernel-builtin one.
-
- The D-channel protocol is configured by loading different firmware
- into the card's memory using the "icnctrl"-utility.
-
-Loading the firmware into the card:
-
- The firmware is supplied together with the isdn4k-utils package. It
- can be found in the subdirectory icnctrl/firmware/
-
- There are 3 files:
-
- loadpg.bin - Image of the bootstrap loader.
- pc_1t_ca.bin - Image of firmware for german 1TR6 protocol.
- pc_eu_ca.bin - Image if firmware for EDSS1 (Euro-ISDN) protocol.
-
- Assuming you have installed the utility-package correctly, the firmware
- will be downloaded into the 2B-card using the following command:
-
- icnctrl -d Idstring load /etc/isdn/loadpg.bin /etc/isdn/pc_XX_ca.bin
-
- where XX is either "1t" or "eu", depending on the D-Channel protocol
- used on your S0-bus and Idstring is the Name of the card, given during
- insmod-time or (for kernel-builtin driver) on the kernel commandline.
-
- To load a 4B-card, the same command is used, except a second firmware
- file is appended to the commandline of icnctrl.
-
- -> After downloading firmware, the two LEDs at the back cover of the card
- (ICN-4B: 4 LEDs) must be blinking intermittently now. If a connection
- is up, the corresponding led is lit continuously.
-
- For further documentation (adding more ICN-cards), refer to the manpage
- icnctrl.8 which is included in the isdn4k-utils package.
-
diff --git a/drivers/staging/i4l/Documentation/README.pcbit b/drivers/staging/i4l/Documentation/README.pcbit
deleted file mode 100644
index 5125002282e5..000000000000
--- a/drivers/staging/i4l/Documentation/README.pcbit
+++ /dev/null
@@ -1,40 +0,0 @@
-------------------------------------------------------------------------------
- README file for the PCBIT-D Device Driver.
-------------------------------------------------------------------------------
-
-The PCBIT is a Euro ISDN adapter manufactured in Portugal by Octal and
-developed in cooperation with Portugal Telecom and Inesc.
-The driver interfaces with the standard kernel isdn facilities
-originally developed by Fritz Elfert in the isdn4linux project.
-
-The common versions of the pcbit board require a firmware that is
-distributed (and copyrighted) by the manufacturer. To load this
-firmware you need "pcbitctl" available on the standard isdn4k-utils
-package or in the pcbit package available in:
-
-ftp://ftp.di.fc.ul.pt/pub/systems/Linux/isdn
-
-Known Limitations:
-
-- The board reset procedure is at the moment incorrect and will only
-allow you to load the firmware after a hard reset.
-
-- Only HDLC in B-channels is supported at the moment. There is no
-current support for X.25 in B or D channels nor LAPD in B
-channels. The main reason is that these two other protocol modes have,
-to my knowledge, very little use. If you want to see them implemented
-*do* send me a mail.
-
-- The driver often triggers errors in the board that I and the
-manufacturer believe to be caused by bugs in the firmware. The current
-version includes several procedures for error recovery that should
-allow normal operation. Plans for the future include cooperation with
-the manufacturer in order to solve this problem.
-
-Information/hints/help can be obtained in the linux isdn
-mailing list (isdn4linux@listserv.isdn4linux.de) or directly from me.
-
-regards,
- Pedro.
-
-<roque@di.fc.ul.pt>
diff --git a/drivers/staging/i4l/Documentation/README.sc b/drivers/staging/i4l/Documentation/README.sc
deleted file mode 100644
index 1153cd926059..000000000000
--- a/drivers/staging/i4l/Documentation/README.sc
+++ /dev/null
@@ -1,281 +0,0 @@
-Welcome to Beta Release 2 of the combination ISDN driver for SpellCaster's
-ISA ISDN adapters. Please note this release 2 includes support for the
-DataCommute/BRI and TeleCommute/BRI adapters only and any other use is
-guaranteed to fail. If you have a DataCommute/PRI installed in the test
-computer, we recommend removing it as it will be detected but will not
-be usable. To see what we have done to Beta Release 2, see section 3.
-
-Speaking of guarantees, THIS IS BETA SOFTWARE and as such contains
-bugs and defects either known or unknown. Use this software at your own
-risk. There is NO SUPPORT for this software. Some help may be available
-through the web site or the mailing list but such support is totally at
-our own option and without warranty. If you choose to assume all and
-total risk by using this driver, we encourage you to join the beta
-mailing list.
-
-To join the Linux beta mailing list, send a message to:
-majordomo@spellcast.com with the words "subscribe linux-beta" as the only
-contents of the message. Do not include a signature. If you choose to
-remove yourself from this list at a later date, send another message to
-the same address with the words "unsubscribe linux-beta" as its only
-contents.
-
-TABLE OF CONTENTS
------------------
- 1. Introduction
- 1.1 What is ISDN4Linux?
- 1.2 What is different between this driver and previous drivers?
- 1.3 How do I setup my system with the correct software to use
- this driver release?
-
- 2. Basic Operations
- 2.1 Unpacking and installing the driver
- 2.2 Read the man pages!!!
- 2.3 Installing the driver
- 2.4 Removing the driver
- 2.5 What to do if it doesn't load
- 2.6 How to setup ISDN4Linux with the driver
-
- 3. Beta Change Summaries and Miscellaneous Notes
-
-1. Introduction
----------------
-
-The revision 2 Linux driver for SpellCaster ISA ISDN adapters is built
-upon ISDN4Linux available separately or as included in Linux 2.0 and later.
-The driver will support a maximum of 4 adapters in any one system of any
-type including DataCommute/BRI, DataCommute/PRI and TeleCommute/BRI for a
-maximum of 92 channels for host. The driver is supplied as a module in
-source form and needs to be complied before it can be used. It has been
-tested on Linux 2.0.20.
-
-1.1 What Is ISDN4Linux
-
-ISDN4Linux is a driver and set of tools used to access and use ISDN devices
-on a Linux platform in a common and standard way. It supports HDLC and PPP
-protocols and offers channel bundling and MLPPP support. To use ISDN4Linux
-you need to configure your kernel for ISDN support and get the ISDN4Linux
-tool kit from our web site.
-
-ISDN4Linux creates a channel pool from all of the available ISDN channels
-and therefore can function across adapters. When an ISDN4Linux compliant
-driver (such as ours) is loaded, all of the channels go into a pool and
-are used on a first-come first-served basis. In addition, individual
-channels can be specifically bound to particular interfaces.
-
-1.2 What is different between this driver and previous drivers?
-
-The revision 2 driver besides adopting the ISDN4Linux architecture has many
-subtle and not so subtle functional differences from previous releases. These
-include:
- - More efficient shared memory management combined with a simpler
- configuration. All adapters now use only 16Kbytes of shared RAM
- versus between 16K and 64K. New methods for using the shared RAM
- allow us to utilize all of the available RAM on the adapter through
- only one 16K page.
- - Better detection of available upper memory. The probing routines
- have been improved to better detect available shared RAM pages and
- used pages are now locked.
- - Decreased loading time and a wider range of I/O ports probed.
- We have significantly reduced the amount of time it takes to load
- the driver and at the same time doubled the number of I/O ports
- probed increasing the likelihood of finding an adapter.
- - We now support all ISA adapter models with a single driver instead
- of separate drivers for each model. The revision 2 driver supports
- the DataCommute/BRI, DataCommute/PRI and TeleCommute/BRI in any
- combination up to a maximum of four adapters per system.
- - On board PPP protocol support has been removed in favour of the
- sync-PPP support used in ISDN4Linux. This means more control of
- the protocol parameters, faster negotiation time and a more
- familiar interface.
-
-1.3 How do I setup my system with the correct software to use
- this driver release?
-
-Before you can compile, install and use the SpellCaster ISA ISDN driver, you
-must ensure that the following software is installed, configured and running:
-
- - Linux kernel 2.0.20 or later with the required init and ps
- versions. Please see your distribution vendor for the correct
- utility packages. The latest kernel is available from
- ftp://sunsite.unc.edu/pub/Linux/kernel/v2.0/
-
- - The latest modules package (modules-2.0.0.tar.gz) from
- ftp://sunsite.unc.edu/pub/Linux/kernel/modules-2.0.0.tar.gz
-
- - The ISDN4Linux tools available from
- ftp://ftp.franken.de/pub/isdn4linux/v2.0/isdn4k-utils-2.0.tar.gz
- This package may fail to compile for you so you can alternatively
- get a pre-compiled version from
- ftp://ftp.spellcast.com/pub/drivers/isdn4linux/isdn4k-bin-2.0.tar.gz
-
-
-2. Basic Operations
--------------------
-
-2.1 Unpacking and installing the driver
-
- 1. As root, create a directory in a convenient place. We suggest
- /usr/src/spellcaster.
-
- 2. Unpack the archive with :
- tar xzf sc-n.nn.tar.gz -C /usr/src/spellcaster
-
- 3. Change directory to /usr/src/spellcaster
-
- 4. Read the README and RELNOTES files.
-
- 5. Run 'make' and if all goes well, run 'make install'.
-
-2.2 Read the man pages!!!
-
-Make sure you read the scctrl(8) and sc(4) manual pages before continuing
-any further. Type 'man 8 scctrl' and 'man 4 sc'.
-
-2.3 Installing the driver
-
-To install the driver, type '/sbin/insmod sc' as root. sc(4) details options
-you can specify but you shouldn't need to use any unless this doesn't work.
-
-Make sure the driver loaded and detected all of the adapters by typing
-'dmesg'.
-
-The driver can be configured so that it is loaded upon startup. To do this,
-edit the file "/etc/modules/'uname -f'/'uname -v'" and insert the driver name
-"sc" into this file.
-
-2.4 Removing the driver
-
-To remove the driver, delete any interfaces that may exist (see isdnctrl(8)
-for more on this) and then type '/sbin/rmmod sc'.
-
-2.5 What to do if it doesn't load
-
-If, when you try to install the driver, you get a message mentioning
-'register_isdn' then you do not have the ISDN4Linux system installed. Please
-make sure that ISDN support is configured in the kernel.
-
-If you get a message that says 'initialization of sc failed', then the
-driver failed to detect an adapter or failed to find resources needed such
-as a free IRQ line or shared memory segment. If you are sure there are free
-resources available, use the insmod options detailed in sc(4) to override
-the probing function.
-
-Upon testing, the following problem was noted, the driver would load without
-problems, but the board would not respond beyond that point. When a check was
-done with 'cat /proc/interrupts' the interrupt count for sc was 0. In the event
-of this problem, change the BIOS settings so that the interrupts in question are
-reserved for ISA use only.
-
-
-2.6 How to setup ISDN4Linux with the driver
-
-There are three main configurations which you can use with the driver:
-
-A) Basic HDLC connection
-B) PPP connection
-C) MLPPP connection
-
-It should be mentioned here that you may also use a tty connection if you
-desire. The Documentation directory of the isdn4linux subsystem offers good
-documentation on this feature.
-
-A) 10 steps to the establishment of a basic HDLC connection
------------------------------------------------------------
-
-- please open the isdn-hdlc file in the examples directory and follow along...
-
- This file is a script used to configure a BRI ISDN TA to establish a
- basic HDLC connection between its two channels. Two network
- interfaces are created and two routes added between the channels.
-
- i) using the isdnctrl utility, add an interface with "addif" and
- name it "isdn0"
- ii) add the outgoing and inbound telephone numbers
- iii) set the Layer 2 protocol to hdlc
- iv) set the eaz of the interface to be the phone number of that
- specific channel
- v) to turn the callback features off, set the callback to "off" and
- the callback delay (cbdelay) to 0.
- vi) the hangup timeout can be set to a specified number of seconds
- vii) the hangup upon incoming call can be set on or off
- viii) use the ifconfig command to bring up the network interface with
- a specific IP address and point to point address
- ix) add a route to the IP address through the isdn0 interface
- x) a ping should result in the establishment of the connection
-
-
-B) Establishment of a PPP connection
-------------------------------------
-
-- please open the isdn-ppp file in the examples directory and follow along...
-
- This file is a script used to configure a BRI ISDN TA to establish a
- PPP connection between the two channels. The file is almost
- identical to the HDLC connection example except that the packet
- encapsulation type has to be set.
-
- use the same procedure as in the HDLC connection from steps i) to
- iii) then, after the Layer 2 protocol is set, set the encapsulation
- "encap" to syncppp. With this done, the rest of the steps, iv) to x)
- can be followed from above.
-
- Then, the ipppd (ippp daemon) must be setup:
-
- xi) use the ipppd function found in /sbin/ipppd to set the following:
- xii) take out (minus) VJ compression and bsd compression
- xiii) set the mru size to 2000
- xiv) link the two /dev interfaces to the daemon
-
-NOTE: A "*" in the inbound telephone number specifies that a call can be
-accepted on any number.
-
-C) Establishment of a MLPPP connection
---------------------------------------
-
-- please open the isdn-mppp file in the examples directory and follow along...
-
- This file is a script used to configure a BRI ISDN TA to accept a
- Multi Link PPP connection.
-
- i) using the isdnctrl utility, add an interface with "addif" and
- name it "ippp0"
- ii) add the inbound telephone number
- iii) set the Layer 2 protocol to hdlc and the Layer 3 protocol to
- trans (transparent)
- iv) set the packet encapsulation to syncppp
- v) set the eaz of the interface to be the phone number of that
- specific channel
- vi) to turn the callback features off, set the callback to "off" and
- the callback delay (cbdelay) to 0.
- vi) the hangup timeout can be set to a specified number of seconds
- vii) the hangup upon incoming call can be set on or off
- viii) add a slave interface and name it "ippp32" for example
- ix) set the similar parameters for the ippp32 interface
- x) use the ifconfig command to bring-up the ippp0 interface with a
- specific IP address and point to point address
- xi) add a route to the IP address through the ippp0 interface
- xii) use the ipppd function found in /sbin/ipppd to set the following:
- xiii) take out (minus) bsd compression
- xiv) set the mru size to 2000
- xv) add (+) the multi-link function "+mp"
- xvi) link the two /dev interfaces to the daemon
-
-NOTE: To use the MLPPP connection to dial OUT to a MLPPP connection, change
-the inbound telephone numbers to the outgoing telephone numbers of the MLPPP
-host.
-
-
-3. Beta Change Summaries and Miscellaneous Notes
-------------------------------------------------
-When using the "scctrl" utility to upload firmware revisions on the board,
-please note that the byte count displayed at the end of the operation may be
-different from the total number of bytes in the "dcbfwn.nn.sr" file. Please
-disregard the displayed byte count.
-
-It was noted that in Beta Release 1, the module would fail to load and result
-in a segmentation fault when 'insmod'ed. This problem was created when one of
-the isdn4linux parameters, (isdn_ctrl, data field) was filled in. In some
-cases, this data field was NULL, and was left unchecked, so when it was
-referenced... segv. The bug has been fixed around line 63-68 of event.c.
-
diff --git a/drivers/staging/i4l/Kconfig b/drivers/staging/i4l/Kconfig
deleted file mode 100644
index 920216e88de7..000000000000
--- a/drivers/staging/i4l/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Old ISDN4Linux config
-#
-menu "Old ISDN4Linux (deprecated)"
- depends on ISDN_I4L
-
-source "drivers/staging/i4l/icn/Kconfig"
-
-source "drivers/staging/i4l/pcbit/Kconfig"
-
-source "drivers/staging/i4l/act2000/Kconfig"
-
-endmenu
diff --git a/drivers/staging/i4l/Makefile b/drivers/staging/i4l/Makefile
deleted file mode 100644
index 158b87093db5..000000000000
--- a/drivers/staging/i4l/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Makefile for the old ISDN I4L subsystem and device drivers.
-
-obj-$(CONFIG_ISDN_DRV_ICN) += icn/
-obj-$(CONFIG_ISDN_DRV_PCBIT) += pcbit/
-obj-$(CONFIG_ISDN_DRV_ACT2000) += act2000/
diff --git a/drivers/staging/i4l/TODO b/drivers/staging/i4l/TODO
deleted file mode 100644
index 6fe2c08bec7a..000000000000
--- a/drivers/staging/i4l/TODO
+++ /dev/null
@@ -1,3 +0,0 @@
-* The icn, pcbit and act2000 drivers are dead, remove them in 2017
- after another longterm kernel has been released, just in the
- unlikely case someone still has this hardware.
diff --git a/drivers/staging/i4l/act2000/Kconfig b/drivers/staging/i4l/act2000/Kconfig
deleted file mode 100644
index fa2673fc69c2..000000000000
--- a/drivers/staging/i4l/act2000/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-config ISDN_DRV_ACT2000
- tristate "IBM Active 2000 support"
- depends on ISA
- help
- Say Y here if you have an IBM Active 2000 ISDN card. In order to use
- this card, additional firmware is necessary, which has to be loaded
- into the card using a utility which is part of the latest
- isdn4k-utils package. Please read the file
- <file:Documentation/isdn/README.act2000> for more information.
diff --git a/drivers/staging/i4l/act2000/Makefile b/drivers/staging/i4l/act2000/Makefile
deleted file mode 100644
index 05e582fb5c00..000000000000
--- a/drivers/staging/i4l/act2000/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Makefile for the act2000 ISDN device driver
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_ISDN_DRV_ACT2000) += act2000.o
-
-# Multipart objects.
-
-act2000-y := module.o capi.o act2000_isa.o
diff --git a/drivers/staging/i4l/act2000/act2000.h b/drivers/staging/i4l/act2000/act2000.h
deleted file mode 100644
index 321d437f579e..000000000000
--- a/drivers/staging/i4l/act2000/act2000.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/* $Id: act2000.h,v 1.8.6.3 2001/09/23 22:24:32 kai Exp $
- *
- * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
- *
- * Author Fritz Elfert
- * Copyright by Fritz Elfert <fritz@isdn4linux.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- */
-
-#ifndef act2000_h
-#define act2000_h
-
-#include <linux/compiler.h>
-
-#define ACT2000_IOCTL_SETPORT 1
-#define ACT2000_IOCTL_GETPORT 2
-#define ACT2000_IOCTL_SETIRQ 3
-#define ACT2000_IOCTL_GETIRQ 4
-#define ACT2000_IOCTL_SETBUS 5
-#define ACT2000_IOCTL_GETBUS 6
-#define ACT2000_IOCTL_SETPROTO 7
-#define ACT2000_IOCTL_GETPROTO 8
-#define ACT2000_IOCTL_SETMSN 9
-#define ACT2000_IOCTL_GETMSN 10
-#define ACT2000_IOCTL_LOADBOOT 11
-#define ACT2000_IOCTL_ADDCARD 12
-
-#define ACT2000_IOCTL_TEST 98
-#define ACT2000_IOCTL_DEBUGVAR 99
-
-#define ACT2000_BUS_ISA 1
-#define ACT2000_BUS_MCA 2
-#define ACT2000_BUS_PCMCIA 3
-
-/* Struct for adding new cards */
-typedef struct act2000_cdef {
- int bus;
- int port;
- int irq;
- char id[10];
-} act2000_cdef;
-
-/* Struct for downloading firmware */
-typedef struct act2000_ddef {
- int length; /* Length of code */
- char __user *buffer; /* Ptr. to code */
-} act2000_ddef;
-
-typedef struct act2000_fwid {
- char isdn[4];
- char revlen[2];
- char revision[504];
-} act2000_fwid;
-
-#if defined(__KERNEL__) || defined(__DEBUGVAR__)
-
-#ifdef __KERNEL__
-/* Kernel includes */
-
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/skbuff.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/major.h>
-#include <asm/io.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/ctype.h>
-#include <linux/isdnif.h>
-
-#endif /* __KERNEL__ */
-
-#define ACT2000_PORTLEN 8
-
-#define ACT2000_FLAGS_RUNNING 1 /* Cards driver activated */
-#define ACT2000_FLAGS_PVALID 2 /* Cards port is valid */
-#define ACT2000_FLAGS_IVALID 4 /* Cards irq is valid */
-#define ACT2000_FLAGS_LOADED 8 /* Firmware loaded */
-
-#define ACT2000_BCH 2 /* # of channels per card */
-
-/* D-Channel states */
-#define ACT2000_STATE_NULL 0
-#define ACT2000_STATE_ICALL 1
-#define ACT2000_STATE_OCALL 2
-#define ACT2000_STATE_IWAIT 3
-#define ACT2000_STATE_OWAIT 4
-#define ACT2000_STATE_IBWAIT 5
-#define ACT2000_STATE_OBWAIT 6
-#define ACT2000_STATE_BWAIT 7
-#define ACT2000_STATE_BHWAIT 8
-#define ACT2000_STATE_BHWAIT2 9
-#define ACT2000_STATE_DHWAIT 10
-#define ACT2000_STATE_DHWAIT2 11
-#define ACT2000_STATE_BSETUP 12
-#define ACT2000_STATE_ACTIVE 13
-
-#define ACT2000_MAX_QUEUED 8000 /* 2 * maxbuff */
-
-#define ACT2000_LOCK_TX 0
-#define ACT2000_LOCK_RX 1
-
-typedef struct act2000_chan {
- unsigned short callref; /* Call Reference */
- unsigned short fsm_state; /* Current D-Channel state */
- unsigned short eazmask; /* EAZ-Mask for this Channel */
- short queued; /* User-Data Bytes in TX queue */
- unsigned short plci;
- unsigned short ncci;
- unsigned char l2prot; /* Layer 2 protocol */
- unsigned char l3prot; /* Layer 3 protocol */
-} act2000_chan;
-
-typedef struct msn_entry {
- char eaz;
- char msn[16];
- struct msn_entry *next;
-} msn_entry;
-
-typedef struct irq_data_isa {
- __u8 *rcvptr;
- __u16 rcvidx;
- __u16 rcvlen;
- struct sk_buff *rcvskb;
- __u8 rcvignore;
- __u8 rcvhdr[8];
-} irq_data_isa;
-
-typedef union act2000_irq_data {
- irq_data_isa isa;
-} act2000_irq_data;
-
-/*
- * Per card driver data
- */
-typedef struct act2000_card {
- unsigned short port; /* Base-port-address */
- unsigned short irq; /* Interrupt */
- u_char ptype; /* Protocol type (1TR6 or Euro) */
- u_char bus; /* Cardtype (ISA, MCA, PCMCIA) */
- struct act2000_card *next; /* Pointer to next device struct */
- spinlock_t lock; /* protect critical operations */
- int myid; /* Driver-Nr. assigned by linklevel */
- unsigned long flags; /* Statusflags */
- unsigned long ilock; /* Semaphores for IRQ-Routines */
- struct sk_buff_head rcvq; /* Receive-Message queue */
- struct sk_buff_head sndq; /* Send-Message queue */
- struct sk_buff_head ackq; /* Data-Ack-Message queue */
- u_char *ack_msg; /* Ptr to User Data in User skb */
- __u16 need_b3ack; /* Flag: Need ACK for current skb */
- struct sk_buff *sbuf; /* skb which is currently sent */
- struct timer_list ptimer; /* Poll timer */
- struct work_struct snd_tq; /* Task struct for xmit bh */
- struct work_struct rcv_tq; /* Task struct for rcv bh */
- struct work_struct poll_tq; /* Task struct for polled rcv bh */
- msn_entry *msn_list;
- unsigned short msgnum; /* Message number for sending */
- spinlock_t mnlock; /* lock for msgnum */
- act2000_chan bch[ACT2000_BCH]; /* B-Channel status/control */
- char status_buf[256]; /* Buffer for status messages */
- char *status_buf_read;
- char *status_buf_write;
- char *status_buf_end;
- act2000_irq_data idat; /* Data used for IRQ handler */
- isdn_if interface; /* Interface to upper layer */
- char regname[35]; /* Name used for request_region */
-} act2000_card;
-
-static inline void act2000_schedule_tx(act2000_card *card)
-{
- schedule_work(&card->snd_tq);
-}
-
-static inline void act2000_schedule_rx(act2000_card *card)
-{
- schedule_work(&card->rcv_tq);
-}
-
-static inline void act2000_schedule_poll(act2000_card *card)
-{
- schedule_work(&card->poll_tq);
-}
-
-extern char *act2000_find_eaz(act2000_card *, char);
-
-#endif /* defined(__KERNEL__) || defined(__DEBUGVAR__) */
-#endif /* act2000_h */
diff --git a/drivers/staging/i4l/act2000/act2000_isa.c b/drivers/staging/i4l/act2000/act2000_isa.c
deleted file mode 100644
index 76ff5de65781..000000000000
--- a/drivers/staging/i4l/act2000/act2000_isa.c
+++ /dev/null
@@ -1,444 +0,0 @@
-/* $Id: act2000_isa.c,v 1.11.6.3 2001/09/23 22:24:32 kai Exp $
- *
- * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version).
- *
- * Author Fritz Elfert
- * Copyright by Fritz Elfert <fritz@isdn4linux.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- */
-
-#include "act2000.h"
-#include "act2000_isa.h"
-#include "capi.h"
-
-/*
- * Reset Controller, then try to read the Card's signature.
- + Return:
- * 1 = Signature found.
- * 0 = Signature not found.
- */
-static int
-act2000_isa_reset(unsigned short portbase)
-{
- unsigned char reg;
- int i;
- int found;
- int serial = 0;
-
- found = 0;
- reg = inb(portbase + ISA_COR);
- if (reg != 0xff) {
- outb(reg | ISA_COR_RESET, portbase + ISA_COR);
- mdelay(10);
- outb(reg, portbase + ISA_COR);
- mdelay(10);
-
- for (i = 0; i < 16; i++) {
- if (inb(portbase + ISA_ISR) & ISA_ISR_SERIAL)
- serial |= 0x10000;
- serial >>= 1;
- }
- if (serial == ISA_SER_ID)
- found++;
- }
- return found;
-}
-
-int
-act2000_isa_detect(unsigned short portbase)
-{
- int ret = 0;
-
- if (request_region(portbase, ACT2000_PORTLEN, "act2000isa")) {
- ret = act2000_isa_reset(portbase);
- release_region(portbase, ISA_REGION);
- }
- return ret;
-}
-
-static irqreturn_t
-act2000_isa_interrupt(int dummy, void *dev_id)
-{
- act2000_card *card = dev_id;
- u_char istatus;
-
- istatus = (inb(ISA_PORT_ISR) & 0x07);
- if (istatus & ISA_ISR_OUT) {
- /* RX fifo has data */
- istatus &= ISA_ISR_OUT_MASK;
- outb(0, ISA_PORT_SIS);
- act2000_isa_receive(card);
- outb(ISA_SIS_INT, ISA_PORT_SIS);
- }
- if (istatus & ISA_ISR_ERR) {
- /* Error Interrupt */
- istatus &= ISA_ISR_ERR_MASK;
- printk(KERN_WARNING "act2000: errIRQ\n");
- }
- if (istatus)
- printk(KERN_DEBUG "act2000: ?IRQ %d %02x\n", card->irq, istatus);
- return IRQ_HANDLED;
-}
-
-static void
-act2000_isa_select_irq(act2000_card *card)
-{
- unsigned char reg;
-
- reg = (inb(ISA_PORT_COR) & ~ISA_COR_IRQOFF) | ISA_COR_PERR;
- switch (card->irq) {
- case 3:
- reg = ISA_COR_IRQ03;
- break;
- case 5:
- reg = ISA_COR_IRQ05;
- break;
- case 7:
- reg = ISA_COR_IRQ07;
- break;
- case 10:
- reg = ISA_COR_IRQ10;
- break;
- case 11:
- reg = ISA_COR_IRQ11;
- break;
- case 12:
- reg = ISA_COR_IRQ12;
- break;
- case 15:
- reg = ISA_COR_IRQ15;
- break;
- }
- outb(reg, ISA_PORT_COR);
-}
-
-static void
-act2000_isa_enable_irq(act2000_card *card)
-{
- act2000_isa_select_irq(card);
- /* Enable READ irq */
- outb(ISA_SIS_INT, ISA_PORT_SIS);
-}
-
-/*
- * Install interrupt handler, enable irq on card.
- * If irq is -1, choose next free irq, else irq is given explicitly.
- */
-int
-act2000_isa_config_irq(act2000_card *card, short irq)
-{
- int old_irq;
-
- if (card->flags & ACT2000_FLAGS_IVALID)
- free_irq(card->irq, card);
-
- card->flags &= ~ACT2000_FLAGS_IVALID;
- outb(ISA_COR_IRQOFF, ISA_PORT_COR);
- if (!irq)
- return 0;
-
- old_irq = card->irq;
- card->irq = irq;
- if (request_irq(irq, &act2000_isa_interrupt, 0, card->regname, card)) {
- card->irq = old_irq;
- card->flags |= ACT2000_FLAGS_IVALID;
- printk(KERN_WARNING
- "act2000: Could not request irq %d\n", irq);
- return -EBUSY;
- } else {
- act2000_isa_select_irq(card);
- /* Disable READ and WRITE irq */
- outb(0, ISA_PORT_SIS);
- outb(0, ISA_PORT_SOS);
- }
- return 0;
-}
-
-int
-act2000_isa_config_port(act2000_card *card, unsigned short portbase)
-{
- if (card->flags & ACT2000_FLAGS_PVALID) {
- release_region(card->port, ISA_REGION);
- card->flags &= ~ACT2000_FLAGS_PVALID;
- }
- if (!request_region(portbase, ACT2000_PORTLEN, card->regname))
- return -EBUSY;
- else {
- card->port = portbase;
- card->flags |= ACT2000_FLAGS_PVALID;
- return 0;
- }
-}
-
-/*
- * Release resources, used by an adaptor.
- */
-void
-act2000_isa_release(act2000_card *card)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
- if (card->flags & ACT2000_FLAGS_IVALID)
- free_irq(card->irq, card);
-
- card->flags &= ~ACT2000_FLAGS_IVALID;
- if (card->flags & ACT2000_FLAGS_PVALID)
- release_region(card->port, ISA_REGION);
- card->flags &= ~ACT2000_FLAGS_PVALID;
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static int
-act2000_isa_writeb(act2000_card *card, u_char data)
-{
- u_char timeout = 40;
-
- while (timeout) {
- if (inb(ISA_PORT_SOS) & ISA_SOS_READY) {
- outb(data, ISA_PORT_SDO);
- return 0;
- } else {
- timeout--;
- udelay(10);
- }
- }
- return 1;
-}
-
-static int
-act2000_isa_readb(act2000_card *card, u_char *data)
-{
- u_char timeout = 40;
-
- while (timeout) {
- if (inb(ISA_PORT_SIS) & ISA_SIS_READY) {
- *data = inb(ISA_PORT_SDI);
- return 0;
- } else {
- timeout--;
- udelay(10);
- }
- }
- return 1;
-}
-
-void
-act2000_isa_receive(act2000_card *card)
-{
- u_char c;
-
- if (test_and_set_bit(ACT2000_LOCK_RX, (void *)&card->ilock) != 0)
- return;
- while (!act2000_isa_readb(card, &c)) {
- if (card->idat.isa.rcvidx < 8) {
- card->idat.isa.rcvhdr[card->idat.isa.rcvidx++] = c;
- if (card->idat.isa.rcvidx == 8) {
- int valid = actcapi_chkhdr(card, (actcapi_msghdr *)&card->idat.isa.rcvhdr);
-
- if (valid) {
- card->idat.isa.rcvlen = ((actcapi_msghdr *)&card->idat.isa.rcvhdr)->len;
- card->idat.isa.rcvskb = dev_alloc_skb(card->idat.isa.rcvlen);
- if (!card->idat.isa.rcvskb) {
- card->idat.isa.rcvignore = 1;
- printk(KERN_WARNING
- "act2000_isa_receive: no memory\n");
- test_and_clear_bit(ACT2000_LOCK_RX, (void *)&card->ilock);
- return;
- }
- memcpy(skb_put(card->idat.isa.rcvskb, 8), card->idat.isa.rcvhdr, 8);
- card->idat.isa.rcvptr = skb_put(card->idat.isa.rcvskb, card->idat.isa.rcvlen - 8);
- } else {
- card->idat.isa.rcvidx = 0;
- printk(KERN_WARNING
- "act2000_isa_receive: Invalid CAPI msg\n");
- {
- int i; __u8 *p; __u8 *t; __u8 tmp[30];
-
- for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, t = tmp; i < 8; i++)
- t += sprintf(t, "%02x ", *(p++));
- printk(KERN_WARNING "act2000_isa_receive: %s\n", tmp);
- }
- }
- }
- } else {
- if (!card->idat.isa.rcvignore)
- *card->idat.isa.rcvptr++ = c;
- if (++card->idat.isa.rcvidx >= card->idat.isa.rcvlen) {
- if (!card->idat.isa.rcvignore) {
- skb_queue_tail(&card->rcvq, card->idat.isa.rcvskb);
- act2000_schedule_rx(card);
- }
- card->idat.isa.rcvidx = 0;
- card->idat.isa.rcvlen = 8;
- card->idat.isa.rcvignore = 0;
- card->idat.isa.rcvskb = NULL;
- card->idat.isa.rcvptr = card->idat.isa.rcvhdr;
- }
- }
- }
- if (!(card->flags & ACT2000_FLAGS_IVALID)) {
- /* In polling mode, schedule myself */
- if ((card->idat.isa.rcvidx) &&
- (card->idat.isa.rcvignore ||
- (card->idat.isa.rcvidx < card->idat.isa.rcvlen)))
- act2000_schedule_poll(card);
- }
- test_and_clear_bit(ACT2000_LOCK_RX, (void *)&card->ilock);
-}
-
-void
-act2000_isa_send(act2000_card *card)
-{
- unsigned long flags;
- struct sk_buff *skb;
- actcapi_msg *msg;
- int l;
-
- if (test_and_set_bit(ACT2000_LOCK_TX, (void *)&card->ilock) != 0)
- return;
- while (1) {
- spin_lock_irqsave(&card->lock, flags);
- if (!(card->sbuf)) {
- card->sbuf = skb_dequeue(&card->sndq);
- if (card->sbuf) {
- card->ack_msg = card->sbuf->data;
- msg = (actcapi_msg *)card->sbuf->data;
- if ((msg->hdr.cmd.cmd == 0x86) &&
- (msg->hdr.cmd.subcmd == 0)) {
- /* Save flags in message */
- card->need_b3ack = msg->msg.data_b3_req.flags;
- msg->msg.data_b3_req.flags = 0;
- }
- }
- }
- spin_unlock_irqrestore(&card->lock, flags);
- if (!(card->sbuf)) {
- /* No more data to send */
- test_and_clear_bit(ACT2000_LOCK_TX, (void *)&card->ilock);
- return;
- }
- skb = card->sbuf;
- l = 0;
- while (skb->len) {
- if (act2000_isa_writeb(card, *(skb->data))) {
- /* Fifo is full, but more data to send */
- test_and_clear_bit(ACT2000_LOCK_TX, (void *)&card->ilock);
- /* Schedule myself */
- act2000_schedule_tx(card);
- return;
- }
- skb_pull(skb, 1);
- l++;
- }
- msg = (actcapi_msg *)card->ack_msg;
- if ((msg->hdr.cmd.cmd == 0x86) &&
- (msg->hdr.cmd.subcmd == 0)) {
- /*
- * If it's user data, reset data-ptr
- * and put skb into ackq.
- */
- skb->data = card->ack_msg;
- /* Restore flags in message */
- msg->msg.data_b3_req.flags = card->need_b3ack;
- skb_queue_tail(&card->ackq, skb);
- } else
- dev_kfree_skb(skb);
- card->sbuf = NULL;
- }
-}
-
-/*
- * Get firmware ID, check for 'ISDN' signature.
- */
-static int
-act2000_isa_getid(act2000_card *card)
-{
- act2000_fwid fid;
- u_char *p = (u_char *)&fid;
- int count = 0;
-
- while (1) {
- if (count > 510)
- return -EPROTO;
- if (act2000_isa_readb(card, p++))
- break;
- count++;
- }
- if (count <= 20) {
- printk(KERN_WARNING "act2000: No Firmware-ID!\n");
- return -ETIME;
- }
- *p = '\0';
- fid.revlen[0] = '\0';
- if (strcmp(fid.isdn, "ISDN")) {
- printk(KERN_WARNING "act2000: Wrong Firmware-ID!\n");
- return -EPROTO;
- }
- p = strchr(fid.revision, '\n');
- if (p)
- *p = '\0';
- printk(KERN_INFO "act2000: Firmware-ID: %s\n", fid.revision);
- if (card->flags & ACT2000_FLAGS_IVALID) {
- printk(KERN_DEBUG "Enabling Interrupts ...\n");
- act2000_isa_enable_irq(card);
- }
- return 0;
-}
-
-/*
- * Download microcode into card, check Firmware signature.
- */
-int
-act2000_isa_download(act2000_card *card, act2000_ddef __user *cb)
-{
- unsigned int length;
- int l;
- int c;
- u_char *b;
- u_char __user *p;
- u_char *buf;
- act2000_ddef cblock;
-
- if (!act2000_isa_reset(card->port))
- return -ENXIO;
- msleep_interruptible(500);
- if (copy_from_user(&cblock, cb, sizeof(cblock)))
- return -EFAULT;
- length = cblock.length;
- p = cblock.buffer;
- if (!access_ok(VERIFY_READ, p, length))
- return -EFAULT;
- buf = kmalloc(1024, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- while (length) {
- l = (length > 1024) ? 1024 : length;
- c = 0;
- b = buf;
- if (copy_from_user(buf, p, l)) {
- kfree(buf);
- return -EFAULT;
- }
- while (c < l) {
- if (act2000_isa_writeb(card, *b++)) {
- printk(KERN_WARNING
- "act2000: loader timed out"
- " len=%d c=%d\n", length, c);
- kfree(buf);
- return -ETIME;
- }
- c++;
- }
- length -= l;
- p += l;
- }
- kfree(buf);
- msleep_interruptible(500);
- return act2000_isa_getid(card);
-}
diff --git a/drivers/staging/i4l/act2000/act2000_isa.h b/drivers/staging/i4l/act2000/act2000_isa.h
deleted file mode 100644
index 1a728984ede1..000000000000
--- a/drivers/staging/i4l/act2000/act2000_isa.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* $Id: act2000_isa.h,v 1.4.6.1 2001/09/23 22:24:32 kai Exp $
- *
- * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version).
- *
- * Author Fritz Elfert
- * Copyright by Fritz Elfert <fritz@isdn4linux.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- */
-
-#ifndef act2000_isa_h
-#define act2000_isa_h
-
-#define ISA_POLL_LOOP 40 /* Try to read-write before give up */
-
-typedef enum {
- INT_NO_CHANGE = 0, /* Do not change the Mask */
- INT_ON = 1, /* Set to Enable */
- INT_OFF = 2, /* Set to Disable */
-} ISA_INT_T;
-
-/**************************************************************************/
-/* Configuration Register COR (RW) */
-/**************************************************************************/
-/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */
-/* Soft Res| IRQM | IRQ Select | N/A | WAIT |Proc err */
-/**************************************************************************/
-#define ISA_COR 0 /* Offset for ISA config register */
-#define ISA_COR_PERR 0x01 /* Processor Error Enabled */
-#define ISA_COR_WS 0x02 /* Insert Wait State if 1 */
-#define ISA_COR_IRQOFF 0x38 /* No Interrupt */
-#define ISA_COR_IRQ07 0x30 /* IRQ 7 Enable */
-#define ISA_COR_IRQ05 0x28 /* IRQ 5 Enable */
-#define ISA_COR_IRQ03 0x20 /* IRQ 3 Enable */
-#define ISA_COR_IRQ10 0x18 /* IRQ 10 Enable */
-#define ISA_COR_IRQ11 0x10 /* IRQ 11 Enable */
-#define ISA_COR_IRQ12 0x08 /* IRQ 12 Enable */
-#define ISA_COR_IRQ15 0x00 /* IRQ 15 Enable */
-#define ISA_COR_IRQPULSE 0x40 /* 0 = Level 1 = Pulse Interrupt */
-#define ISA_COR_RESET 0x80 /* Soft Reset for Transputer */
-
-/**************************************************************************/
-/* Interrupt Source Register ISR (RO) */
-/**************************************************************************/
-/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */
-/* N/A | N/A | N/A |Err sig |Ser ID |IN Intr |Out Intr| Error */
-/**************************************************************************/
-#define ISA_ISR 1 /* Offset for Interrupt Register */
-#define ISA_ISR_ERR 0x01 /* Error Interrupt */
-#define ISA_ISR_OUT 0x02 /* Output Interrupt */
-#define ISA_ISR_INP 0x04 /* Input Interrupt */
-#define ISA_ISR_SERIAL 0x08 /* Read out Serial ID after Reset */
-#define ISA_ISR_ERRSIG 0x10 /* Error Signal Input */
-#define ISA_ISR_ERR_MASK 0xfe /* Mask Error Interrupt */
-#define ISA_ISR_OUT_MASK 0xfd /* Mask Output Interrupt */
-#define ISA_ISR_INP_MASK 0xfb /* Mask Input Interrupt */
-
-/* Signature delivered after Reset at ISA_ISR_SERIAL (LSB first) */
-#define ISA_SER_ID 0x0201 /* ID for ISA Card */
-
-/**************************************************************************/
-/* EEPROM Register EPR (RW) */
-/**************************************************************************/
-/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */
-/* N/A | N/A | N/A |ROM Hold| ROM CS |ROM CLK | ROM IN |ROM Out */
-/**************************************************************************/
-#define ISA_EPR 2 /* Offset for this Register */
-#define ISA_EPR_OUT 0x01 /* Rome Register Out (RO) */
-#define ISA_EPR_IN 0x02 /* Rom Register In (WR) */
-#define ISA_EPR_CLK 0x04 /* Rom Clock (WR) */
-#define ISA_EPR_CS 0x08 /* Rom Cip Select (WR) */
-#define ISA_EPR_HOLD 0x10 /* Rom Hold Signal (WR) */
-
-/**************************************************************************/
-/* EEPROM enable Register EER (unused) */
-/**************************************************************************/
-#define ISA_EER 3 /* Offset for this Register */
-
-/**************************************************************************/
-/* SLC Data Input SDI (RO) */
-/**************************************************************************/
-#define ISA_SDI 4 /* Offset for this Register */
-
-/**************************************************************************/
-/* SLC Data Output SDO (WO) */
-/**************************************************************************/
-#define ISA_SDO 5 /* Offset for this Register */
-
-/**************************************************************************/
-/* IMS C011 Mode 2 Input Status Register for INMOS CPU SIS (RW) */
-/**************************************************************************/
-/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */
-/* N/A | N/A | N/A | N/A | N/A | N/A |Int Ena |Data Pre */
-/**************************************************************************/
-#define ISA_SIS 6 /* Offset for this Register */
-#define ISA_SIS_READY 0x01 /* If 1 : data is available */
-#define ISA_SIS_INT 0x02 /* Enable Interrupt for READ */
-
-/**************************************************************************/
-/* IMS C011 Mode 2 Output Status Register from INMOS CPU SOS (RW) */
-/**************************************************************************/
-/* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 */
-/* N/A | N/A | N/A | N/A | N/A | N/A |Int Ena |Out Rdy */
-/**************************************************************************/
-#define ISA_SOS 7 /* Offset for this Register */
-#define ISA_SOS_READY 0x01 /* If 1 : we can write Data */
-#define ISA_SOS_INT 0x02 /* Enable Interrupt for WRITE */
-
-#define ISA_REGION 8 /* Number of Registers */
-
-
-/* Macros for accessing ports */
-#define ISA_PORT_COR (card->port + ISA_COR)
-#define ISA_PORT_ISR (card->port + ISA_ISR)
-#define ISA_PORT_EPR (card->port + ISA_EPR)
-#define ISA_PORT_EER (card->port + ISA_EER)
-#define ISA_PORT_SDI (card->port + ISA_SDI)
-#define ISA_PORT_SDO (card->port + ISA_SDO)
-#define ISA_PORT_SIS (card->port + ISA_SIS)
-#define ISA_PORT_SOS (card->port + ISA_SOS)
-
-/* Prototypes */
-
-extern int act2000_isa_detect(unsigned short portbase);
-extern int act2000_isa_config_irq(act2000_card *card, short irq);
-extern int act2000_isa_config_port(act2000_card *card, unsigned short portbase);
-extern int act2000_isa_download(act2000_card *card, act2000_ddef __user *cb);
-extern void act2000_isa_release(act2000_card *card);
-extern void act2000_isa_receive(act2000_card *card);
-extern void act2000_isa_send(act2000_card *card);
-
-#endif /* act2000_isa_h */
diff --git a/drivers/staging/i4l/act2000/capi.c b/drivers/staging/i4l/act2000/capi.c
deleted file mode 100644
index 61386a78fb91..000000000000
--- a/drivers/staging/i4l/act2000/capi.c
+++ /dev/null
@@ -1,1187 +0,0 @@
-/* $Id: capi.c,v 1.9.6.2 2001/09/23 22:24:32 kai Exp $
- *
- * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
- * CAPI encoder/decoder
- *
- * Author Fritz Elfert
- * Copyright by Fritz Elfert <fritz@isdn4linux.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- */
-
-#include "act2000.h"
-#include "capi.h"
-
-static actcapi_msgdsc valid_msg[] = {
- {{ 0x86, 0x02}, "DATA_B3_IND"}, /* DATA_B3_IND/CONF must be first because of speed!!! */
- {{ 0x86, 0x01}, "DATA_B3_CONF"},
- {{ 0x02, 0x01}, "CONNECT_CONF"},
- {{ 0x02, 0x02}, "CONNECT_IND"},
- {{ 0x09, 0x01}, "CONNECT_INFO_CONF"},
- {{ 0x03, 0x02}, "CONNECT_ACTIVE_IND"},
- {{ 0x04, 0x01}, "DISCONNECT_CONF"},
- {{ 0x04, 0x02}, "DISCONNECT_IND"},
- {{ 0x05, 0x01}, "LISTEN_CONF"},
- {{ 0x06, 0x01}, "GET_PARAMS_CONF"},
- {{ 0x07, 0x01}, "INFO_CONF"},
- {{ 0x07, 0x02}, "INFO_IND"},
- {{ 0x08, 0x01}, "DATA_CONF"},
- {{ 0x08, 0x02}, "DATA_IND"},
- {{ 0x40, 0x01}, "SELECT_B2_PROTOCOL_CONF"},
- {{ 0x80, 0x01}, "SELECT_B3_PROTOCOL_CONF"},
- {{ 0x81, 0x01}, "LISTEN_B3_CONF"},
- {{ 0x82, 0x01}, "CONNECT_B3_CONF"},
- {{ 0x82, 0x02}, "CONNECT_B3_IND"},
- {{ 0x83, 0x02}, "CONNECT_B3_ACTIVE_IND"},
- {{ 0x84, 0x01}, "DISCONNECT_B3_CONF"},
- {{ 0x84, 0x02}, "DISCONNECT_B3_IND"},
- {{ 0x85, 0x01}, "GET_B3_PARAMS_CONF"},
- {{ 0x01, 0x01}, "RESET_B3_CONF"},
- {{ 0x01, 0x02}, "RESET_B3_IND"},
- /* {{ 0x87, 0x02, "HANDSET_IND"}, not implemented */
- {{ 0xff, 0x01}, "MANUFACTURER_CONF"},
- {{ 0xff, 0x02}, "MANUFACTURER_IND"},
-#ifdef DEBUG_MSG
- /* Requests */
- {{ 0x01, 0x00}, "RESET_B3_REQ"},
- {{ 0x02, 0x00}, "CONNECT_REQ"},
- {{ 0x04, 0x00}, "DISCONNECT_REQ"},
- {{ 0x05, 0x00}, "LISTEN_REQ"},
- {{ 0x06, 0x00}, "GET_PARAMS_REQ"},
- {{ 0x07, 0x00}, "INFO_REQ"},
- {{ 0x08, 0x00}, "DATA_REQ"},
- {{ 0x09, 0x00}, "CONNECT_INFO_REQ"},
- {{ 0x40, 0x00}, "SELECT_B2_PROTOCOL_REQ"},
- {{ 0x80, 0x00}, "SELECT_B3_PROTOCOL_REQ"},
- {{ 0x81, 0x00}, "LISTEN_B3_REQ"},
- {{ 0x82, 0x00}, "CONNECT_B3_REQ"},
- {{ 0x84, 0x00}, "DISCONNECT_B3_REQ"},
- {{ 0x85, 0x00}, "GET_B3_PARAMS_REQ"},
- {{ 0x86, 0x00}, "DATA_B3_REQ"},
- {{ 0xff, 0x00}, "MANUFACTURER_REQ"},
- /* Responses */
- {{ 0x01, 0x03}, "RESET_B3_RESP"},
- {{ 0x02, 0x03}, "CONNECT_RESP"},
- {{ 0x03, 0x03}, "CONNECT_ACTIVE_RESP"},
- {{ 0x04, 0x03}, "DISCONNECT_RESP"},
- {{ 0x07, 0x03}, "INFO_RESP"},
- {{ 0x08, 0x03}, "DATA_RESP"},
- {{ 0x82, 0x03}, "CONNECT_B3_RESP"},
- {{ 0x83, 0x03}, "CONNECT_B3_ACTIVE_RESP"},
- {{ 0x84, 0x03}, "DISCONNECT_B3_RESP"},
- {{ 0x86, 0x03}, "DATA_B3_RESP"},
- {{ 0xff, 0x03}, "MANUFACTURER_RESP"},
-#endif
- {{ 0x00, 0x00}, NULL},
-};
-#define num_valid_imsg 27 /* MANUFACTURER_IND */
-
-/*
- * Check for a valid incoming CAPI message.
- * Return:
- * 0 = Invalid message
- * 1 = Valid message, no B-Channel-data
- * 2 = Valid message, B-Channel-data
- */
-int
-actcapi_chkhdr(act2000_card *card, actcapi_msghdr *hdr)
-{
- int i;
-
- if (hdr->applicationID != 1)
- return 0;
- if (hdr->len < 9)
- return 0;
- for (i = 0; i < num_valid_imsg; i++)
- if ((hdr->cmd.cmd == valid_msg[i].cmd.cmd) &&
- (hdr->cmd.subcmd == valid_msg[i].cmd.subcmd)) {
- return i ? 1 : 2;
- }
- return 0;
-}
-
-#define ACTCAPI_MKHDR(l, c, s) { \
- skb = alloc_skb(l + 8, GFP_ATOMIC); \
- if (skb) { \
- m = (actcapi_msg *)skb_put(skb, l + 8); \
- m->hdr.len = l + 8; \
- m->hdr.applicationID = 1; \
- m->hdr.cmd.cmd = c; \
- m->hdr.cmd.subcmd = s; \
- m->hdr.msgnum = actcapi_nextsmsg(card); \
- } else { \
- m = NULL; \
- } \
- }
-
-#define ACTCAPI_CHKSKB if (!skb) { \
- printk(KERN_WARNING "actcapi: alloc_skb failed\n"); \
- return; \
- }
-
-#define ACTCAPI_QUEUE_TX { \
- actcapi_debug_msg(skb, 1); \
- skb_queue_tail(&card->sndq, skb); \
- act2000_schedule_tx(card); \
- }
-
-int
-actcapi_listen_req(act2000_card *card)
-{
- __u16 eazmask = 0;
- int i;
- actcapi_msg *m;
- struct sk_buff *skb;
-
- for (i = 0; i < ACT2000_BCH; i++)
- eazmask |= card->bch[i].eazmask;
- ACTCAPI_MKHDR(9, 0x05, 0x00);
- if (!skb) {
- printk(KERN_WARNING "actcapi: alloc_skb failed\n");
- return -ENOMEM;
- }
- m->msg.listen_req.controller = 0;
- m->msg.listen_req.infomask = 0x3f; /* All information */
- m->msg.listen_req.eazmask = eazmask;
- m->msg.listen_req.simask = (eazmask) ? 0x86 : 0; /* All SI's */
- ACTCAPI_QUEUE_TX;
- return 0;
-}
-
-int
-actcapi_connect_req(act2000_card *card, act2000_chan *chan, char *phone,
- char eaz, int si1, int si2)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR((11 + strlen(phone)), 0x02, 0x00);
- if (!skb) {
- printk(KERN_WARNING "actcapi: alloc_skb failed\n");
- chan->fsm_state = ACT2000_STATE_NULL;
- return -ENOMEM;
- }
- m->msg.connect_req.controller = 0;
- m->msg.connect_req.bchan = 0x83;
- m->msg.connect_req.infomask = 0x3f;
- m->msg.connect_req.si1 = si1;
- m->msg.connect_req.si2 = si2;
- m->msg.connect_req.eaz = eaz ? eaz : '0';
- m->msg.connect_req.addr.len = strlen(phone) + 1;
- m->msg.connect_req.addr.tnp = 0x81;
- memcpy(m->msg.connect_req.addr.num, phone, strlen(phone));
- chan->callref = m->hdr.msgnum;
- ACTCAPI_QUEUE_TX;
- return 0;
-}
-
-static void
-actcapi_connect_b3_req(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(17, 0x82, 0x00);
- ACTCAPI_CHKSKB;
- m->msg.connect_b3_req.plci = chan->plci;
- memset(&m->msg.connect_b3_req.ncpi, 0,
- sizeof(m->msg.connect_b3_req.ncpi));
- m->msg.connect_b3_req.ncpi.len = 13;
- m->msg.connect_b3_req.ncpi.modulo = 8;
- ACTCAPI_QUEUE_TX;
-}
-
-/*
- * Set net type (1TR6) or (EDSS1)
- */
-int
-actcapi_manufacturer_req_net(act2000_card *card)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(5, 0xff, 0x00);
- if (!skb) {
- printk(KERN_WARNING "actcapi: alloc_skb failed\n");
- return -ENOMEM;
- }
- m->msg.manufacturer_req_net.manuf_msg = 0x11;
- m->msg.manufacturer_req_net.controller = 1;
- m->msg.manufacturer_req_net.nettype = (card->ptype == ISDN_PTYPE_EURO) ? 1 : 0;
- ACTCAPI_QUEUE_TX;
- printk(KERN_INFO "act2000 %s: D-channel protocol now %s\n",
- card->interface.id, (card->ptype == ISDN_PTYPE_EURO) ? "euro" : "1tr6");
- card->interface.features &=
- ~(ISDN_FEATURE_P_UNKNOWN | ISDN_FEATURE_P_EURO | ISDN_FEATURE_P_1TR6);
- card->interface.features |=
- ((card->ptype == ISDN_PTYPE_EURO) ? ISDN_FEATURE_P_EURO : ISDN_FEATURE_P_1TR6);
- return 0;
-}
-
-/*
- * Switch V.42 on or off
- */
-#if 0
-int
-actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(8, 0xff, 0x00);
- if (!skb) {
-
- printk(KERN_WARNING "actcapi: alloc_skb failed\n");
- return -ENOMEM;
- }
- m->msg.manufacturer_req_v42.manuf_msg = 0x10;
- m->msg.manufacturer_req_v42.controller = 0;
- m->msg.manufacturer_req_v42.v42control = (arg ? 1 : 0);
- ACTCAPI_QUEUE_TX;
- return 0;
-}
-#endif /* 0 */
-
-/*
- * Set error-handler
- */
-int
-actcapi_manufacturer_req_errh(act2000_card *card)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(4, 0xff, 0x00);
- if (!skb) {
-
- printk(KERN_WARNING "actcapi: alloc_skb failed\n");
- return -ENOMEM;
- }
- m->msg.manufacturer_req_err.manuf_msg = 0x03;
- m->msg.manufacturer_req_err.controller = 0;
- ACTCAPI_QUEUE_TX;
- return 0;
-}
-
-/*
- * Set MSN-Mapping.
- */
-int
-actcapi_manufacturer_req_msn(act2000_card *card)
-{
- msn_entry *p = card->msn_list;
- actcapi_msg *m;
- struct sk_buff *skb;
- int len;
-
- while (p) {
- int i;
-
- len = strlen(p->msn);
- for (i = 0; i < 2; i++) {
- ACTCAPI_MKHDR(6 + len, 0xff, 0x00);
- if (!skb) {
- printk(KERN_WARNING "actcapi: alloc_skb failed\n");
- return -ENOMEM;
- }
- m->msg.manufacturer_req_msn.manuf_msg = 0x13 + i;
- m->msg.manufacturer_req_msn.controller = 0;
- m->msg.manufacturer_req_msn.msnmap.eaz = p->eaz;
- m->msg.manufacturer_req_msn.msnmap.len = len;
- memcpy(m->msg.manufacturer_req_msn.msnmap.msn, p->msn, len);
- ACTCAPI_QUEUE_TX;
- }
- p = p->next;
- }
- return 0;
-}
-
-void
-actcapi_select_b2_protocol_req(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(10, 0x40, 0x00);
- ACTCAPI_CHKSKB;
- m->msg.select_b2_protocol_req.plci = chan->plci;
- memset(&m->msg.select_b2_protocol_req.dlpd, 0,
- sizeof(m->msg.select_b2_protocol_req.dlpd));
- m->msg.select_b2_protocol_req.dlpd.len = 6;
- switch (chan->l2prot) {
- case ISDN_PROTO_L2_TRANS:
- m->msg.select_b2_protocol_req.protocol = 0x03;
- m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
- break;
- case ISDN_PROTO_L2_HDLC:
- m->msg.select_b2_protocol_req.protocol = 0x02;
- m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
- break;
- case ISDN_PROTO_L2_X75I:
- case ISDN_PROTO_L2_X75UI:
- case ISDN_PROTO_L2_X75BUI:
- m->msg.select_b2_protocol_req.protocol = 0x01;
- m->msg.select_b2_protocol_req.dlpd.dlen = 4000;
- m->msg.select_b2_protocol_req.dlpd.laa = 3;
- m->msg.select_b2_protocol_req.dlpd.lab = 1;
- m->msg.select_b2_protocol_req.dlpd.win = 7;
- m->msg.select_b2_protocol_req.dlpd.modulo = 8;
- break;
- }
- ACTCAPI_QUEUE_TX;
-}
-
-static void
-actcapi_select_b3_protocol_req(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(17, 0x80, 0x00);
- ACTCAPI_CHKSKB;
- m->msg.select_b3_protocol_req.plci = chan->plci;
- memset(&m->msg.select_b3_protocol_req.ncpd, 0,
- sizeof(m->msg.select_b3_protocol_req.ncpd));
- switch (chan->l3prot) {
- case ISDN_PROTO_L3_TRANS:
- m->msg.select_b3_protocol_req.protocol = 0x04;
- m->msg.select_b3_protocol_req.ncpd.len = 13;
- m->msg.select_b3_protocol_req.ncpd.modulo = 8;
- break;
- }
- ACTCAPI_QUEUE_TX;
-}
-
-static void
-actcapi_listen_b3_req(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(2, 0x81, 0x00);
- ACTCAPI_CHKSKB;
- m->msg.listen_b3_req.plci = chan->plci;
- ACTCAPI_QUEUE_TX;
-}
-
-static void
-actcapi_disconnect_req(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(3, 0x04, 0x00);
- ACTCAPI_CHKSKB;
- m->msg.disconnect_req.plci = chan->plci;
- m->msg.disconnect_req.cause = 0;
- ACTCAPI_QUEUE_TX;
-}
-
-void
-actcapi_disconnect_b3_req(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(17, 0x84, 0x00);
- ACTCAPI_CHKSKB;
- m->msg.disconnect_b3_req.ncci = chan->ncci;
- memset(&m->msg.disconnect_b3_req.ncpi, 0,
- sizeof(m->msg.disconnect_b3_req.ncpi));
- m->msg.disconnect_b3_req.ncpi.len = 13;
- m->msg.disconnect_b3_req.ncpi.modulo = 8;
- chan->fsm_state = ACT2000_STATE_BHWAIT;
- ACTCAPI_QUEUE_TX;
-}
-
-void
-actcapi_connect_resp(act2000_card *card, act2000_chan *chan, __u8 cause)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(3, 0x02, 0x03);
- ACTCAPI_CHKSKB;
- m->msg.connect_resp.plci = chan->plci;
- m->msg.connect_resp.rejectcause = cause;
- if (cause) {
- chan->fsm_state = ACT2000_STATE_NULL;
- chan->plci = 0x8000;
- } else
- chan->fsm_state = ACT2000_STATE_IWAIT;
- ACTCAPI_QUEUE_TX;
-}
-
-static void
-actcapi_connect_active_resp(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(2, 0x03, 0x03);
- ACTCAPI_CHKSKB;
- m->msg.connect_resp.plci = chan->plci;
- if (chan->fsm_state == ACT2000_STATE_IWAIT)
- chan->fsm_state = ACT2000_STATE_IBWAIT;
- ACTCAPI_QUEUE_TX;
-}
-
-static void
-actcapi_connect_b3_resp(act2000_card *card, act2000_chan *chan, __u8 rejectcause)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR((rejectcause ? 3 : 17), 0x82, 0x03);
- ACTCAPI_CHKSKB;
- m->msg.connect_b3_resp.ncci = chan->ncci;
- m->msg.connect_b3_resp.rejectcause = rejectcause;
- if (!rejectcause) {
- memset(&m->msg.connect_b3_resp.ncpi, 0,
- sizeof(m->msg.connect_b3_resp.ncpi));
- m->msg.connect_b3_resp.ncpi.len = 13;
- m->msg.connect_b3_resp.ncpi.modulo = 8;
- chan->fsm_state = ACT2000_STATE_BWAIT;
- }
- ACTCAPI_QUEUE_TX;
-}
-
-static void
-actcapi_connect_b3_active_resp(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(2, 0x83, 0x03);
- ACTCAPI_CHKSKB;
- m->msg.connect_b3_active_resp.ncci = chan->ncci;
- chan->fsm_state = ACT2000_STATE_ACTIVE;
- ACTCAPI_QUEUE_TX;
-}
-
-static void
-actcapi_info_resp(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(2, 0x07, 0x03);
- ACTCAPI_CHKSKB;
- m->msg.info_resp.plci = chan->plci;
- ACTCAPI_QUEUE_TX;
-}
-
-static void
-actcapi_disconnect_b3_resp(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(2, 0x84, 0x03);
- ACTCAPI_CHKSKB;
- m->msg.disconnect_b3_resp.ncci = chan->ncci;
- chan->ncci = 0x8000;
- chan->queued = 0;
- ACTCAPI_QUEUE_TX;
-}
-
-static void
-actcapi_disconnect_resp(act2000_card *card, act2000_chan *chan)
-{
- actcapi_msg *m;
- struct sk_buff *skb;
-
- ACTCAPI_MKHDR(2, 0x04, 0x03);
- ACTCAPI_CHKSKB;
- m->msg.disconnect_resp.plci = chan->plci;
- chan->plci = 0x8000;
- ACTCAPI_QUEUE_TX;
-}
-
-static int
-new_plci(act2000_card *card, __u16 plci)
-{
- int i;
-
- for (i = 0; i < ACT2000_BCH; i++)
- if (card->bch[i].plci == 0x8000) {
- card->bch[i].plci = plci;
- return i;
- }
- return -1;
-}
-
-static int
-find_plci(act2000_card *card, __u16 plci)
-{
- int i;
-
- for (i = 0; i < ACT2000_BCH; i++)
- if (card->bch[i].plci == plci)
- return i;
- return -1;
-}
-
-static int
-find_ncci(act2000_card *card, __u16 ncci)
-{
- int i;
-
- for (i = 0; i < ACT2000_BCH; i++)
- if (card->bch[i].ncci == ncci)
- return i;
- return -1;
-}
-
-static int
-find_dialing(act2000_card *card, __u16 callref)
-{
- int i;
-
- for (i = 0; i < ACT2000_BCH; i++)
- if ((card->bch[i].callref == callref) &&
- (card->bch[i].fsm_state == ACT2000_STATE_OCALL))
- return i;
- return -1;
-}
-
-static int
-actcapi_data_b3_ind(act2000_card *card, struct sk_buff *skb) {
- __u16 plci;
- __u16 ncci;
- __u8 blocknr;
- int chan;
- actcapi_msg *msg = (actcapi_msg *)skb->data;
-
- EVAL_NCCI(msg->msg.data_b3_ind.fakencci, plci, ncci);
- chan = find_ncci(card, ncci);
- if (chan < 0)
- return 0;
- if (card->bch[chan].fsm_state != ACT2000_STATE_ACTIVE)
- return 0;
- if (card->bch[chan].plci != plci)
- return 0;
- blocknr = msg->msg.data_b3_ind.blocknr;
- skb_pull(skb, 19);
- card->interface.rcvcallb_skb(card->myid, chan, skb);
- if (!(skb = alloc_skb(11, GFP_ATOMIC))) {
- printk(KERN_WARNING "actcapi: alloc_skb failed\n");
- return 1;
- }
- msg = (actcapi_msg *)skb_put(skb, 11);
- msg->hdr.len = 11;
- msg->hdr.applicationID = 1;
- msg->hdr.cmd.cmd = 0x86;
- msg->hdr.cmd.subcmd = 0x03;
- msg->hdr.msgnum = actcapi_nextsmsg(card);
- msg->msg.data_b3_resp.ncci = ncci;
- msg->msg.data_b3_resp.blocknr = blocknr;
- ACTCAPI_QUEUE_TX;
- return 1;
-}
-
-/*
- * Walk over ackq, unlink DATA_B3_REQ from it, if
- * ncci and blocknr are matching.
- * Decrement queued-bytes counter.
- */
-static int
-handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) {
- unsigned long flags;
- struct sk_buff *skb;
- struct sk_buff *tmp;
- struct actcapi_msg *m;
- int ret = 0;
-
- spin_lock_irqsave(&card->lock, flags);
- skb = skb_peek(&card->ackq);
- spin_unlock_irqrestore(&card->lock, flags);
- if (!skb) {
- printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
- return 0;
- }
- tmp = skb;
- while (1) {
- m = (actcapi_msg *)tmp->data;
- if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) &&
- (m->msg.data_b3_req.blocknr == blocknr)) {
- /* found corresponding DATA_B3_REQ */
- skb_unlink(tmp, &card->ackq);
- chan->queued -= m->msg.data_b3_req.datalen;
- if (m->msg.data_b3_req.flags)
- ret = m->msg.data_b3_req.datalen;
- dev_kfree_skb(tmp);
- if (chan->queued < 0)
- chan->queued = 0;
- return ret;
- }
- spin_lock_irqsave(&card->lock, flags);
- tmp = skb_peek((struct sk_buff_head *)tmp);
- spin_unlock_irqrestore(&card->lock, flags);
- if ((tmp == skb) || !tmp) {
- /* reached end of queue */
- printk(KERN_WARNING "act2000: handle_ack nothing found!\n");
- return 0;
- }
- }
-}
-
-void
-actcapi_dispatch(struct work_struct *work)
-{
- struct act2000_card *card =
- container_of(work, struct act2000_card, rcv_tq);
- struct sk_buff *skb;
- actcapi_msg *msg;
- __u16 ccmd;
- int chan;
- int len;
- act2000_chan *ctmp;
- isdn_ctrl cmd;
- char tmp[170];
-
- while ((skb = skb_dequeue(&card->rcvq))) {
- actcapi_debug_msg(skb, 0);
- msg = (actcapi_msg *)skb->data;
- ccmd = ((msg->hdr.cmd.cmd << 8) | msg->hdr.cmd.subcmd);
- switch (ccmd) {
- case 0x8602:
- /* DATA_B3_IND */
- if (actcapi_data_b3_ind(card, skb))
- return;
- break;
- case 0x8601:
- /* DATA_B3_CONF */
- chan = find_ncci(card, msg->msg.data_b3_conf.ncci);
- if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_ACTIVE)) {
- if (msg->msg.data_b3_conf.info != 0)
- printk(KERN_WARNING "act2000: DATA_B3_CONF: %04x\n",
- msg->msg.data_b3_conf.info);
- len = handle_ack(card, &card->bch[chan],
- msg->msg.data_b3_conf.blocknr);
- if (len) {
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_BSENT;
- cmd.arg = chan;
- cmd.parm.length = len;
- card->interface.statcallb(&cmd);
- }
- }
- break;
- case 0x0201:
- /* CONNECT_CONF */
- chan = find_dialing(card, msg->hdr.msgnum);
- if (chan >= 0) {
- if (msg->msg.connect_conf.info) {
- card->bch[chan].fsm_state = ACT2000_STATE_NULL;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- } else {
- card->bch[chan].fsm_state = ACT2000_STATE_OWAIT;
- card->bch[chan].plci = msg->msg.connect_conf.plci;
- }
- }
- break;
- case 0x0202:
- /* CONNECT_IND */
- chan = new_plci(card, msg->msg.connect_ind.plci);
- if (chan < 0) {
- ctmp = (act2000_chan *)tmp;
- ctmp->plci = msg->msg.connect_ind.plci;
- actcapi_connect_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
- } else {
- card->bch[chan].fsm_state = ACT2000_STATE_ICALL;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_ICALL;
- cmd.arg = chan;
- cmd.parm.setup.si1 = msg->msg.connect_ind.si1;
- cmd.parm.setup.si2 = msg->msg.connect_ind.si2;
- if (card->ptype == ISDN_PTYPE_EURO)
- strcpy(cmd.parm.setup.eazmsn,
- act2000_find_eaz(card, msg->msg.connect_ind.eaz));
- else {
- cmd.parm.setup.eazmsn[0] = msg->msg.connect_ind.eaz;
- cmd.parm.setup.eazmsn[1] = 0;
- }
- memset(cmd.parm.setup.phone, 0, sizeof(cmd.parm.setup.phone));
- memcpy(cmd.parm.setup.phone, msg->msg.connect_ind.addr.num,
- msg->msg.connect_ind.addr.len - 1);
- cmd.parm.setup.plan = msg->msg.connect_ind.addr.tnp;
- cmd.parm.setup.screen = 0;
- if (card->interface.statcallb(&cmd) == 2)
- actcapi_connect_resp(card, &card->bch[chan], 0x15); /* Reject Call */
- }
- break;
- case 0x0302:
- /* CONNECT_ACTIVE_IND */
- chan = find_plci(card, msg->msg.connect_active_ind.plci);
- if (chan >= 0)
- switch (card->bch[chan].fsm_state) {
- case ACT2000_STATE_IWAIT:
- actcapi_connect_active_resp(card, &card->bch[chan]);
- break;
- case ACT2000_STATE_OWAIT:
- actcapi_connect_active_resp(card, &card->bch[chan]);
- actcapi_select_b2_protocol_req(card, &card->bch[chan]);
- break;
- }
- break;
- case 0x8202:
- /* CONNECT_B3_IND */
- chan = find_plci(card, msg->msg.connect_b3_ind.plci);
- if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_IBWAIT)) {
- card->bch[chan].ncci = msg->msg.connect_b3_ind.ncci;
- actcapi_connect_b3_resp(card, &card->bch[chan], 0);
- } else {
- ctmp = (act2000_chan *)tmp;
- ctmp->ncci = msg->msg.connect_b3_ind.ncci;
- actcapi_connect_b3_resp(card, ctmp, 0x11); /* All Card-Cannels busy */
- }
- break;
- case 0x8302:
- /* CONNECT_B3_ACTIVE_IND */
- chan = find_ncci(card, msg->msg.connect_b3_active_ind.ncci);
- if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BWAIT)) {
- actcapi_connect_b3_active_resp(card, &card->bch[chan]);
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_BCONN;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- }
- break;
- case 0x8402:
- /* DISCONNECT_B3_IND */
- chan = find_ncci(card, msg->msg.disconnect_b3_ind.ncci);
- if (chan >= 0) {
- ctmp = &card->bch[chan];
- actcapi_disconnect_b3_resp(card, ctmp);
- switch (ctmp->fsm_state) {
- case ACT2000_STATE_ACTIVE:
- ctmp->fsm_state = ACT2000_STATE_DHWAIT2;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_BHUP;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- break;
- case ACT2000_STATE_BHWAIT2:
- actcapi_disconnect_req(card, ctmp);
- ctmp->fsm_state = ACT2000_STATE_DHWAIT;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_BHUP;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- break;
- }
- }
- break;
- case 0x0402:
- /* DISCONNECT_IND */
- chan = find_plci(card, msg->msg.disconnect_ind.plci);
- if (chan >= 0) {
- ctmp = &card->bch[chan];
- actcapi_disconnect_resp(card, ctmp);
- ctmp->fsm_state = ACT2000_STATE_NULL;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- } else {
- ctmp = (act2000_chan *)tmp;
- ctmp->plci = msg->msg.disconnect_ind.plci;
- actcapi_disconnect_resp(card, ctmp);
- }
- break;
- case 0x4001:
- /* SELECT_B2_PROTOCOL_CONF */
- chan = find_plci(card, msg->msg.select_b2_protocol_conf.plci);
- if (chan >= 0)
- switch (card->bch[chan].fsm_state) {
- case ACT2000_STATE_ICALL:
- case ACT2000_STATE_OWAIT:
- ctmp = &card->bch[chan];
- if (msg->msg.select_b2_protocol_conf.info == 0)
- actcapi_select_b3_protocol_req(card, ctmp);
- else {
- ctmp->fsm_state = ACT2000_STATE_NULL;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- }
- break;
- }
- break;
- case 0x8001:
- /* SELECT_B3_PROTOCOL_CONF */
- chan = find_plci(card, msg->msg.select_b3_protocol_conf.plci);
- if (chan >= 0)
- switch (card->bch[chan].fsm_state) {
- case ACT2000_STATE_ICALL:
- case ACT2000_STATE_OWAIT:
- ctmp = &card->bch[chan];
- if (msg->msg.select_b3_protocol_conf.info == 0)
- actcapi_listen_b3_req(card, ctmp);
- else {
- ctmp->fsm_state = ACT2000_STATE_NULL;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- }
- }
- break;
- case 0x8101:
- /* LISTEN_B3_CONF */
- chan = find_plci(card, msg->msg.listen_b3_conf.plci);
- if (chan >= 0)
- switch (card->bch[chan].fsm_state) {
- case ACT2000_STATE_ICALL:
- ctmp = &card->bch[chan];
- if (msg->msg.listen_b3_conf.info == 0)
- actcapi_connect_resp(card, ctmp, 0);
- else {
- ctmp->fsm_state = ACT2000_STATE_NULL;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- }
- break;
- case ACT2000_STATE_OWAIT:
- ctmp = &card->bch[chan];
- if (msg->msg.listen_b3_conf.info == 0) {
- actcapi_connect_b3_req(card, ctmp);
- ctmp->fsm_state = ACT2000_STATE_OBWAIT;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DCONN;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- } else {
- ctmp->fsm_state = ACT2000_STATE_NULL;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- }
- break;
- }
- break;
- case 0x8201:
- /* CONNECT_B3_CONF */
- chan = find_plci(card, msg->msg.connect_b3_conf.plci);
- if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_OBWAIT)) {
- ctmp = &card->bch[chan];
- if (msg->msg.connect_b3_conf.info) {
- ctmp->fsm_state = ACT2000_STATE_NULL;
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = chan;
- card->interface.statcallb(&cmd);
- } else {
- ctmp->ncci = msg->msg.connect_b3_conf.ncci;
- ctmp->fsm_state = ACT2000_STATE_BWAIT;
- }
- }
- break;
- case 0x8401:
- /* DISCONNECT_B3_CONF */
- chan = find_ncci(card, msg->msg.disconnect_b3_conf.ncci);
- if ((chan >= 0) && (card->bch[chan].fsm_state == ACT2000_STATE_BHWAIT))
- card->bch[chan].fsm_state = ACT2000_STATE_BHWAIT2;
- break;
- case 0x0702:
- /* INFO_IND */
- chan = find_plci(card, msg->msg.info_ind.plci);
- if (chan >= 0)
- /* TODO: Eval Charging info / cause */
- actcapi_info_resp(card, &card->bch[chan]);
- break;
- case 0x0401:
- /* LISTEN_CONF */
- case 0x0501:
- /* LISTEN_CONF */
- case 0xff01:
- /* MANUFACTURER_CONF */
- break;
- case 0xff02:
- /* MANUFACTURER_IND */
- if (msg->msg.manuf_msg == 3) {
- memset(tmp, 0, sizeof(tmp));
- strncpy(tmp,
- &msg->msg.manufacturer_ind_err.errstring,
- msg->hdr.len - 16);
- if (msg->msg.manufacturer_ind_err.errcode)
- printk(KERN_WARNING "act2000: %s\n", tmp);
- else {
- printk(KERN_DEBUG "act2000: %s\n", tmp);
- if ((!strncmp(tmp, "INFO: Trace buffer con", 22)) ||
- (!strncmp(tmp, "INFO: Compile Date/Tim", 22))) {
- card->flags |= ACT2000_FLAGS_RUNNING;
- cmd.command = ISDN_STAT_RUN;
- cmd.driver = card->myid;
- cmd.arg = 0;
- actcapi_manufacturer_req_net(card);
- actcapi_manufacturer_req_msn(card);
- actcapi_listen_req(card);
- card->interface.statcallb(&cmd);
- }
- }
- }
- break;
- default:
- printk(KERN_WARNING "act2000: UNHANDLED Message %04x\n", ccmd);
- break;
- }
- dev_kfree_skb(skb);
- }
-}
-
-#ifdef DEBUG_MSG
-static void
-actcapi_debug_caddr(actcapi_addr *addr)
-{
- char tmp[30];
-
- printk(KERN_DEBUG " Alen = %d\n", addr->len);
- if (addr->len > 0)
- printk(KERN_DEBUG " Atnp = 0x%02x\n", addr->tnp);
- if (addr->len > 1) {
- memset(tmp, 0, 30);
- memcpy(tmp, addr->num, addr->len - 1);
- printk(KERN_DEBUG " Anum = '%s'\n", tmp);
- }
-}
-
-static void
-actcapi_debug_ncpi(actcapi_ncpi *ncpi)
-{
- printk(KERN_DEBUG " ncpi.len = %d\n", ncpi->len);
- if (ncpi->len >= 2)
- printk(KERN_DEBUG " ncpi.lic = 0x%04x\n", ncpi->lic);
- if (ncpi->len >= 4)
- printk(KERN_DEBUG " ncpi.hic = 0x%04x\n", ncpi->hic);
- if (ncpi->len >= 6)
- printk(KERN_DEBUG " ncpi.ltc = 0x%04x\n", ncpi->ltc);
- if (ncpi->len >= 8)
- printk(KERN_DEBUG " ncpi.htc = 0x%04x\n", ncpi->htc);
- if (ncpi->len >= 10)
- printk(KERN_DEBUG " ncpi.loc = 0x%04x\n", ncpi->loc);
- if (ncpi->len >= 12)
- printk(KERN_DEBUG " ncpi.hoc = 0x%04x\n", ncpi->hoc);
- if (ncpi->len >= 13)
- printk(KERN_DEBUG " ncpi.mod = %d\n", ncpi->modulo);
-}
-
-static void
-actcapi_debug_dlpd(actcapi_dlpd *dlpd)
-{
- printk(KERN_DEBUG " dlpd.len = %d\n", dlpd->len);
- if (dlpd->len >= 2)
- printk(KERN_DEBUG " dlpd.dlen = 0x%04x\n", dlpd->dlen);
- if (dlpd->len >= 3)
- printk(KERN_DEBUG " dlpd.laa = 0x%02x\n", dlpd->laa);
- if (dlpd->len >= 4)
- printk(KERN_DEBUG " dlpd.lab = 0x%02x\n", dlpd->lab);
- if (dlpd->len >= 5)
- printk(KERN_DEBUG " dlpd.modulo = %d\n", dlpd->modulo);
- if (dlpd->len >= 6)
- printk(KERN_DEBUG " dlpd.win = %d\n", dlpd->win);
-}
-
-#ifdef DEBUG_DUMP_SKB
-static void dump_skb(struct sk_buff *skb)
-{
- char tmp[80];
- char *p = skb->data;
- char *t = tmp;
- int i;
-
- for (i = 0; i < skb->len; i++) {
- t += sprintf(t, "%02x ", *p++ & 0xff);
- if ((i & 0x0f) == 8) {
- printk(KERN_DEBUG "dump: %s\n", tmp);
- t = tmp;
- }
- }
- if (i & 0x07)
- printk(KERN_DEBUG "dump: %s\n", tmp);
-}
-#endif
-
-void
-actcapi_debug_msg(struct sk_buff *skb, int direction)
-{
- actcapi_msg *msg = (actcapi_msg *)skb->data;
- char *descr;
- int i;
- char tmp[170];
-
-#ifndef DEBUG_DATA_MSG
- if (msg->hdr.cmd.cmd == 0x86)
- return;
-#endif
- descr = "INVALID";
-#ifdef DEBUG_DUMP_SKB
- dump_skb(skb);
-#endif
- for (i = 0; i < ARRAY_SIZE(valid_msg); i++)
- if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) &&
- (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) {
- descr = valid_msg[i].description;
- break;
- }
- printk(KERN_DEBUG "%s %s msg\n", direction ? "Outgoing" : "Incoming", descr);
- printk(KERN_DEBUG " ApplID = %d\n", msg->hdr.applicationID);
- printk(KERN_DEBUG " Len = %d\n", msg->hdr.len);
- printk(KERN_DEBUG " MsgNum = 0x%04x\n", msg->hdr.msgnum);
- printk(KERN_DEBUG " Cmd = 0x%02x\n", msg->hdr.cmd.cmd);
- printk(KERN_DEBUG " SubCmd = 0x%02x\n", msg->hdr.cmd.subcmd);
- switch (i) {
- case 0:
- /* DATA B3 IND */
- printk(KERN_DEBUG " BLOCK = 0x%02x\n",
- msg->msg.data_b3_ind.blocknr);
- break;
- case 2:
- /* CONNECT CONF */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.connect_conf.plci);
- printk(KERN_DEBUG " Info = 0x%04x\n",
- msg->msg.connect_conf.info);
- break;
- case 3:
- /* CONNECT IND */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.connect_ind.plci);
- printk(KERN_DEBUG " Contr = %d\n",
- msg->msg.connect_ind.controller);
- printk(KERN_DEBUG " SI1 = %d\n",
- msg->msg.connect_ind.si1);
- printk(KERN_DEBUG " SI2 = %d\n",
- msg->msg.connect_ind.si2);
- printk(KERN_DEBUG " EAZ = '%c'\n",
- msg->msg.connect_ind.eaz);
- actcapi_debug_caddr(&msg->msg.connect_ind.addr);
- break;
- case 5:
- /* CONNECT ACTIVE IND */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.connect_active_ind.plci);
- actcapi_debug_caddr(&msg->msg.connect_active_ind.addr);
- break;
- case 8:
- /* LISTEN CONF */
- printk(KERN_DEBUG " Contr = %d\n",
- msg->msg.listen_conf.controller);
- printk(KERN_DEBUG " Info = 0x%04x\n",
- msg->msg.listen_conf.info);
- break;
- case 11:
- /* INFO IND */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.info_ind.plci);
- printk(KERN_DEBUG " Imsk = 0x%04x\n",
- msg->msg.info_ind.nr.mask);
- if (msg->hdr.len > 12) {
- int l = msg->hdr.len - 12;
- int j;
- char *p = tmp;
-
- for (j = 0; j < l; j++)
- p += sprintf(p, "%02x ", msg->msg.info_ind.el.display[j]);
- printk(KERN_DEBUG " D = '%s'\n", tmp);
- }
- break;
- case 14:
- /* SELECT B2 PROTOCOL CONF */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.select_b2_protocol_conf.plci);
- printk(KERN_DEBUG " Info = 0x%04x\n",
- msg->msg.select_b2_protocol_conf.info);
- break;
- case 15:
- /* SELECT B3 PROTOCOL CONF */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.select_b3_protocol_conf.plci);
- printk(KERN_DEBUG " Info = 0x%04x\n",
- msg->msg.select_b3_protocol_conf.info);
- break;
- case 16:
- /* LISTEN B3 CONF */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.listen_b3_conf.plci);
- printk(KERN_DEBUG " Info = 0x%04x\n",
- msg->msg.listen_b3_conf.info);
- break;
- case 18:
- /* CONNECT B3 IND */
- printk(KERN_DEBUG " NCCI = 0x%04x\n",
- msg->msg.connect_b3_ind.ncci);
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.connect_b3_ind.plci);
- actcapi_debug_ncpi(&msg->msg.connect_b3_ind.ncpi);
- break;
- case 19:
- /* CONNECT B3 ACTIVE IND */
- printk(KERN_DEBUG " NCCI = 0x%04x\n",
- msg->msg.connect_b3_active_ind.ncci);
- actcapi_debug_ncpi(&msg->msg.connect_b3_active_ind.ncpi);
- break;
- case 26:
- /* MANUFACTURER IND */
- printk(KERN_DEBUG " Mmsg = 0x%02x\n",
- msg->msg.manufacturer_ind_err.manuf_msg);
- switch (msg->msg.manufacturer_ind_err.manuf_msg) {
- case 3:
- printk(KERN_DEBUG " Contr = %d\n",
- msg->msg.manufacturer_ind_err.controller);
- printk(KERN_DEBUG " Code = 0x%08x\n",
- msg->msg.manufacturer_ind_err.errcode);
- memset(tmp, 0, sizeof(tmp));
- strncpy(tmp, &msg->msg.manufacturer_ind_err.errstring,
- msg->hdr.len - 16);
- printk(KERN_DEBUG " Emsg = '%s'\n", tmp);
- break;
- }
- break;
- case 30:
- /* LISTEN REQ */
- printk(KERN_DEBUG " Imsk = 0x%08x\n",
- msg->msg.listen_req.infomask);
- printk(KERN_DEBUG " Emsk = 0x%04x\n",
- msg->msg.listen_req.eazmask);
- printk(KERN_DEBUG " Smsk = 0x%04x\n",
- msg->msg.listen_req.simask);
- break;
- case 35:
- /* SELECT_B2_PROTOCOL_REQ */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.select_b2_protocol_req.plci);
- printk(KERN_DEBUG " prot = 0x%02x\n",
- msg->msg.select_b2_protocol_req.protocol);
- if (msg->hdr.len >= 11)
- printk(KERN_DEBUG "No dlpd\n");
- else
- actcapi_debug_dlpd(&msg->msg.select_b2_protocol_req.dlpd);
- break;
- case 44:
- /* CONNECT RESP */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.connect_resp.plci);
- printk(KERN_DEBUG " CAUSE = 0x%02x\n",
- msg->msg.connect_resp.rejectcause);
- break;
- case 45:
- /* CONNECT ACTIVE RESP */
- printk(KERN_DEBUG " PLCI = 0x%04x\n",
- msg->msg.connect_active_resp.plci);
- break;
- }
-}
-#endif
diff --git a/drivers/staging/i4l/act2000/capi.h b/drivers/staging/i4l/act2000/capi.h
deleted file mode 100644
index 34884a5efee5..000000000000
--- a/drivers/staging/i4l/act2000/capi.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/* $Id: capi.h,v 1.6.6.2 2001/09/23 22:24:32 kai Exp $
- *
- * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
- *
- * Author Fritz Elfert
- * Copyright by Fritz Elfert <fritz@isdn4linux.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- */
-
-#ifndef CAPI_H
-#define CAPI_H
-
-/* Command-part of a CAPI message */
-typedef struct actcapi_msgcmd {
- __u8 cmd;
- __u8 subcmd;
-} actcapi_msgcmd;
-
-/* CAPI message header */
-typedef struct actcapi_msghdr {
- __u16 len;
- __u16 applicationID;
- actcapi_msgcmd cmd;
- __u16 msgnum;
-} actcapi_msghdr;
-
-/* CAPI message description (for debugging) */
-typedef struct actcapi_msgdsc {
- actcapi_msgcmd cmd;
- char *description;
-} actcapi_msgdsc;
-
-/* CAPI Address */
-typedef struct actcapi_addr {
- __u8 len; /* Length of element */
- __u8 tnp; /* Type/Numbering Plan */
- __u8 num[20]; /* Caller ID */
-} actcapi_addr;
-
-/* CAPI INFO element mask */
-typedef union actcapi_infonr { /* info number */
- __u16 mask; /* info-mask field */
- struct bmask { /* bit definitions */
- unsigned codes:3; /* code set */
- unsigned rsvd:5; /* reserved */
- unsigned svind:1; /* single, variable length ind. */
- unsigned wtype:7; /* W-element type */
- } bmask;
-} actcapi_infonr;
-
-/* CAPI INFO element */
-typedef union actcapi_infoel { /* info element */
- __u8 len; /* length of info element */
- __u8 display[40]; /* display contents */
- __u8 uuinfo[40]; /* User-user info field */
- struct cause { /* Cause information */
- unsigned ext2:1; /* extension */
- unsigned cod:2; /* coding standard */
- unsigned spare:1; /* spare */
- unsigned loc:4; /* location */
- unsigned ext1:1; /* extension */
- unsigned cval:7; /* Cause value */
- } cause;
- struct charge { /* Charging information */
- __u8 toc; /* type of charging info */
- __u8 unit[10]; /* charging units */
- } charge;
- __u8 date[20]; /* date fields */
- __u8 stat; /* state of remote party */
-} actcapi_infoel;
-
-/* Message for EAZ<->MSN Mapping */
-typedef struct actcapi_msn {
- __u8 eaz;
- __u8 len; /* Length of MSN */
- __u8 msn[15];
-} __attribute__((packed)) actcapi_msn;
-
-typedef struct actcapi_dlpd {
- __u8 len; /* Length of structure */
- __u16 dlen; /* Data Length */
- __u8 laa; /* Link Address A */
- __u8 lab; /* Link Address B */
- __u8 modulo; /* Modulo Mode */
- __u8 win; /* Window size */
- __u8 xid[100]; /* XID Information */
-} __attribute__((packed)) actcapi_dlpd;
-
-typedef struct actcapi_ncpd {
- __u8 len; /* Length of structure */
- __u16 lic;
- __u16 hic;
- __u16 ltc;
- __u16 htc;
- __u16 loc;
- __u16 hoc;
- __u8 modulo;
-} __attribute__((packed)) actcapi_ncpd;
-#define actcapi_ncpi actcapi_ncpd
-
-/*
- * Layout of NCCI field in a B3 DATA CAPI message is different from
- * standard at act2000:
- *
- * Bit 0-4 = PLCI
- * Bit 5-7 = Controller
- * Bit 8-15 = NCCI
- */
-#define MAKE_NCCI(plci, contr, ncci) \
- ((plci & 0x1f) | ((contr & 0x7) << 5) | ((ncci & 0xff) << 8))
-
-#define EVAL_NCCI(fakencci, plci, ncci) { \
- plci = fakencci & 0x1f; \
- ncci = (fakencci >> 8) & 0xff; \
- }
-
-/*
- * Layout of PLCI field in a B3 DATA CAPI message is different from
- * standard at act2000:
- *
- * Bit 0-4 = PLCI
- * Bit 5-7 = Controller
- * Bit 8-15 = reserved (must be 0)
- */
-
-typedef struct actcapi_msg {
- actcapi_msghdr hdr;
- union {
- __u16 manuf_msg;
- struct manufacturer_req_net {
- __u16 manuf_msg;
- __u16 controller;
- __u8 nettype;
- } manufacturer_req_net;
- struct manufacturer_req_v42 {
- __u16 manuf_msg;
- __u16 controller;
- __u32 v42control;
- } manufacturer_req_v42;
- struct manufacturer_conf_v42 {
- __u16 manuf_msg;
- __u16 controller;
- } manufacturer_conf_v42;
- struct manufacturer_req_err {
- __u16 manuf_msg;
- __u16 controller;
- } manufacturer_req_err;
- struct manufacturer_ind_err {
- __u16 manuf_msg;
- __u16 controller;
- __u32 errcode;
- __u8 errstring; /* actually up to 160 */
- } manufacturer_ind_err;
- struct manufacturer_req_msn {
- __u16 manuf_msg;
- __u16 controller;
- actcapi_msn msnmap;
- } __attribute ((packed)) manufacturer_req_msn;
- /* TODO: TraceInit-req/conf/ind/resp and
- * TraceDump-req/conf/ind/resp
- */
- struct connect_req {
- __u8 controller;
- __u8 bchan;
- __u32 infomask;
- __u8 si1;
- __u8 si2;
- __u8 eaz;
- actcapi_addr addr;
- } __attribute__ ((packed)) connect_req;
- struct connect_conf {
- __u16 plci;
- __u16 info;
- } connect_conf;
- struct connect_ind {
- __u16 plci;
- __u8 controller;
- __u8 si1;
- __u8 si2;
- __u8 eaz;
- actcapi_addr addr;
- } __attribute__ ((packed)) connect_ind;
- struct connect_resp {
- __u16 plci;
- __u8 rejectcause;
- } connect_resp;
- struct connect_active_ind {
- __u16 plci;
- actcapi_addr addr;
- } __attribute__ ((packed)) connect_active_ind;
- struct connect_active_resp {
- __u16 plci;
- } connect_active_resp;
- struct connect_b3_req {
- __u16 plci;
- actcapi_ncpi ncpi;
- } __attribute__ ((packed)) connect_b3_req;
- struct connect_b3_conf {
- __u16 plci;
- __u16 ncci;
- __u16 info;
- } connect_b3_conf;
- struct connect_b3_ind {
- __u16 ncci;
- __u16 plci;
- actcapi_ncpi ncpi;
- } __attribute__ ((packed)) connect_b3_ind;
- struct connect_b3_resp {
- __u16 ncci;
- __u8 rejectcause;
- actcapi_ncpi ncpi;
- } __attribute__ ((packed)) connect_b3_resp;
- struct disconnect_req {
- __u16 plci;
- __u8 cause;
- } disconnect_req;
- struct disconnect_conf {
- __u16 plci;
- __u16 info;
- } disconnect_conf;
- struct disconnect_ind {
- __u16 plci;
- __u16 info;
- } disconnect_ind;
- struct disconnect_resp {
- __u16 plci;
- } disconnect_resp;
- struct connect_b3_active_ind {
- __u16 ncci;
- actcapi_ncpi ncpi;
- } __attribute__ ((packed)) connect_b3_active_ind;
- struct connect_b3_active_resp {
- __u16 ncci;
- } connect_b3_active_resp;
- struct disconnect_b3_req {
- __u16 ncci;
- actcapi_ncpi ncpi;
- } __attribute__ ((packed)) disconnect_b3_req;
- struct disconnect_b3_conf {
- __u16 ncci;
- __u16 info;
- } disconnect_b3_conf;
- struct disconnect_b3_ind {
- __u16 ncci;
- __u16 info;
- actcapi_ncpi ncpi;
- } __attribute__ ((packed)) disconnect_b3_ind;
- struct disconnect_b3_resp {
- __u16 ncci;
- } disconnect_b3_resp;
- struct info_ind {
- __u16 plci;
- actcapi_infonr nr;
- actcapi_infoel el;
- } __attribute__ ((packed)) info_ind;
- struct info_resp {
- __u16 plci;
- } info_resp;
- struct listen_b3_req {
- __u16 plci;
- } listen_b3_req;
- struct listen_b3_conf {
- __u16 plci;
- __u16 info;
- } listen_b3_conf;
- struct select_b2_protocol_req {
- __u16 plci;
- __u8 protocol;
- actcapi_dlpd dlpd;
- } __attribute__ ((packed)) select_b2_protocol_req;
- struct select_b2_protocol_conf {
- __u16 plci;
- __u16 info;
- } select_b2_protocol_conf;
- struct select_b3_protocol_req {
- __u16 plci;
- __u8 protocol;
- actcapi_ncpd ncpd;
- } __attribute__ ((packed)) select_b3_protocol_req;
- struct select_b3_protocol_conf {
- __u16 plci;
- __u16 info;
- } select_b3_protocol_conf;
- struct listen_req {
- __u8 controller;
- __u32 infomask;
- __u16 eazmask;
- __u16 simask;
- } __attribute__ ((packed)) listen_req;
- struct listen_conf {
- __u8 controller;
- __u16 info;
- } __attribute__ ((packed)) listen_conf;
- struct data_b3_req {
- __u16 fakencci;
- __u16 datalen;
- __u32 unused;
- __u8 blocknr;
- __u16 flags;
- } __attribute ((packed)) data_b3_req;
- struct data_b3_ind {
- __u16 fakencci;
- __u16 datalen;
- __u32 unused;
- __u8 blocknr;
- __u16 flags;
- } __attribute__ ((packed)) data_b3_ind;
- struct data_b3_resp {
- __u16 ncci;
- __u8 blocknr;
- } __attribute__ ((packed)) data_b3_resp;
- struct data_b3_conf {
- __u16 ncci;
- __u8 blocknr;
- __u16 info;
- } __attribute__ ((packed)) data_b3_conf;
- } msg;
-} __attribute__ ((packed)) actcapi_msg;
-
-static inline unsigned short
-actcapi_nextsmsg(act2000_card *card)
-{
- unsigned long flags;
- unsigned short n;
-
- spin_lock_irqsave(&card->mnlock, flags);
- n = card->msgnum;
- card->msgnum++;
- card->msgnum &= 0x7fff;
- spin_unlock_irqrestore(&card->mnlock, flags);
- return n;
-}
-#define DEBUG_MSG
-#undef DEBUG_DATA_MSG
-#undef DEBUG_DUMP_SKB
-
-extern int actcapi_chkhdr(act2000_card *, actcapi_msghdr *);
-extern int actcapi_listen_req(act2000_card *);
-extern int actcapi_manufacturer_req_net(act2000_card *);
-extern int actcapi_manufacturer_req_errh(act2000_card *);
-extern int actcapi_manufacturer_req_msn(act2000_card *);
-extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int, int);
-extern void actcapi_select_b2_protocol_req(act2000_card *, act2000_chan *);
-extern void actcapi_disconnect_b3_req(act2000_card *, act2000_chan *);
-extern void actcapi_connect_resp(act2000_card *, act2000_chan *, __u8);
-extern void actcapi_dispatch(struct work_struct *);
-#ifdef DEBUG_MSG
-extern void actcapi_debug_msg(struct sk_buff *skb, int);
-#else
-#define actcapi_debug_msg(skb, len)
-#endif
-#endif
diff --git a/drivers/staging/i4l/act2000/module.c b/drivers/staging/i4l/act2000/module.c
deleted file mode 100644
index 6aa120319e52..000000000000
--- a/drivers/staging/i4l/act2000/module.c
+++ /dev/null
@@ -1,816 +0,0 @@
-/* $Id: module.c,v 1.14.6.4 2001/09/23 22:24:32 kai Exp $
- *
- * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
- *
- * Author Fritz Elfert
- * Copyright by Fritz Elfert <fritz@isdn4linux.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * Thanks to Friedemann Baitinger and IBM Germany
- *
- */
-
-#include "act2000.h"
-#include "act2000_isa.h"
-#include "capi.h"
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-static unsigned short act2000_isa_ports[] = {
- 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380,
- 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60,
-};
-
-static act2000_card *cards = (act2000_card *) NULL;
-
-/* Parameters to be set by insmod */
-static int act_bus;
-static int act_port = -1; /* -1 = Autoprobe */
-static int act_irq = -1;
-static char *act_id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
-
-MODULE_DESCRIPTION("ISDN4Linux: Driver for IBM Active 2000 ISDN card");
-MODULE_AUTHOR("Fritz Elfert");
-MODULE_LICENSE("GPL");
-MODULE_PARM_DESC(act_bus, "BusType of first card, 1=ISA, 2=MCA, 3=PCMCIA, currently only ISA");
-MODULE_PARM_DESC(act_port, "Base port address of first card");
-MODULE_PARM_DESC(act_irq, "IRQ of first card");
-MODULE_PARM_DESC(act_id, "ID-String of first card");
-module_param(act_bus, int, 0);
-module_param(act_port, int, 0);
-module_param(act_irq, int, 0);
-module_param(act_id, charp, 0);
-
-static int act2000_addcard(int, int, int, char *);
-
-static act2000_chan *
-find_channel(act2000_card *card, int channel)
-{
- if ((channel >= 0) && (channel < ACT2000_BCH))
- return &(card->bch[channel]);
- printk(KERN_WARNING "act2000: Invalid channel %d\n", channel);
- return NULL;
-}
-
-/*
- * Free MSN list
- */
-static void
-act2000_clear_msn(act2000_card *card)
-{
- struct msn_entry *p = card->msn_list;
- struct msn_entry *q;
- unsigned long flags;
-
- spin_lock_irqsave(&card->lock, flags);
- card->msn_list = NULL;
- spin_unlock_irqrestore(&card->lock, flags);
- while (p) {
- q = p->next;
- kfree(p);
- p = q;
- }
-}
-
-/*
- * Find an MSN entry in the list.
- * If ia5 != 0, return IA5-encoded EAZ, else
- * return a bitmask with corresponding bit set.
- */
-static __u16
-act2000_find_msn(act2000_card *card, char *msn, int ia5)
-{
- struct msn_entry *p = card->msn_list;
- __u8 eaz = '0';
-
- while (p) {
- if (!strcmp(p->msn, msn)) {
- eaz = p->eaz;
- break;
- }
- p = p->next;
- }
- if (!ia5)
- return 1 << (eaz - '0');
- else
- return eaz;
-}
-
-/*
- * Find an EAZ entry in the list.
- * return a string with corresponding msn.
- */
-char *
-act2000_find_eaz(act2000_card *card, char eaz)
-{
- struct msn_entry *p = card->msn_list;
-
- while (p) {
- if (p->eaz == eaz)
- return p->msn;
- p = p->next;
- }
- return "\0";
-}
-
-/*
- * Add or delete an MSN to the MSN list
- *
- * First character of msneaz is EAZ, rest is MSN.
- * If length of eazmsn is 1, delete that entry.
- */
-static int
-act2000_set_msn(act2000_card *card, char *eazmsn)
-{
- struct msn_entry *p = card->msn_list;
- struct msn_entry *q = NULL;
- unsigned long flags;
- int i;
-
- if (!strlen(eazmsn))
- return 0;
- if (strlen(eazmsn) > 16)
- return -EINVAL;
- for (i = 0; i < strlen(eazmsn); i++)
- if (!isdigit(eazmsn[i]))
- return -EINVAL;
- if (strlen(eazmsn) == 1) {
- /* Delete a single MSN */
- while (p) {
- if (p->eaz == eazmsn[0]) {
- spin_lock_irqsave(&card->lock, flags);
- if (q)
- q->next = p->next;
- else
- card->msn_list = p->next;
- spin_unlock_irqrestore(&card->lock, flags);
- kfree(p);
- printk(KERN_DEBUG
- "Mapping for EAZ %c deleted\n",
- eazmsn[0]);
- return 0;
- }
- q = p;
- p = p->next;
- }
- return 0;
- }
- /* Add a single MSN */
- while (p) {
- /* Found in list, replace MSN */
- if (p->eaz == eazmsn[0]) {
- spin_lock_irqsave(&card->lock, flags);
- strcpy(p->msn, &eazmsn[1]);
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_DEBUG
- "Mapping for EAZ %c changed to %s\n",
- eazmsn[0],
- &eazmsn[1]);
- return 0;
- }
- p = p->next;
- }
- /* Not found in list, add new entry */
- p = kmalloc(sizeof(msn_entry), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
- p->eaz = eazmsn[0];
- strcpy(p->msn, &eazmsn[1]);
- p->next = card->msn_list;
- spin_lock_irqsave(&card->lock, flags);
- card->msn_list = p;
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_DEBUG
- "Mapping %c -> %s added\n",
- eazmsn[0],
- &eazmsn[1]);
- return 0;
-}
-
-static void
-act2000_transmit(struct work_struct *work)
-{
- struct act2000_card *card =
- container_of(work, struct act2000_card, snd_tq);
-
- switch (card->bus) {
- case ACT2000_BUS_ISA:
- act2000_isa_send(card);
- break;
- case ACT2000_BUS_PCMCIA:
- case ACT2000_BUS_MCA:
- default:
- printk(KERN_WARNING
- "act2000_transmit: Illegal bustype %d\n", card->bus);
- }
-}
-
-static void
-act2000_receive(struct work_struct *work)
-{
- struct act2000_card *card =
- container_of(work, struct act2000_card, poll_tq);
-
- switch (card->bus) {
- case ACT2000_BUS_ISA:
- act2000_isa_receive(card);
- break;
- case ACT2000_BUS_PCMCIA:
- case ACT2000_BUS_MCA:
- default:
- printk(KERN_WARNING
- "act2000_receive: Illegal bustype %d\n", card->bus);
- }
-}
-
-static void
-act2000_poll(unsigned long data)
-{
- act2000_card *card = (act2000_card *)data;
- unsigned long flags;
-
- act2000_receive(&card->poll_tq);
- spin_lock_irqsave(&card->lock, flags);
- mod_timer(&card->ptimer, jiffies + 3);
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static int
-act2000_command(act2000_card *card, isdn_ctrl *c)
-{
- ulong a;
- act2000_chan *chan;
- act2000_cdef cdef;
- isdn_ctrl cmd;
- char tmp[17];
- int ret;
- unsigned long flags;
- void __user *arg;
-
- switch (c->command) {
- case ISDN_CMD_IOCTL:
- memcpy(&a, c->parm.num, sizeof(ulong));
- arg = (void __user *)a;
- switch (c->arg) {
- case ACT2000_IOCTL_LOADBOOT:
- switch (card->bus) {
- case ACT2000_BUS_ISA:
- ret = act2000_isa_download(card,
- arg);
- if (!ret) {
- card->flags |= ACT2000_FLAGS_LOADED;
- if (!(card->flags & ACT2000_FLAGS_IVALID)) {
- card->ptimer.expires = jiffies + 3;
- card->ptimer.function = act2000_poll;
- card->ptimer.data = (unsigned long)card;
- add_timer(&card->ptimer);
- }
- actcapi_manufacturer_req_errh(card);
- }
- break;
- default:
- printk(KERN_WARNING
- "act2000: Illegal BUS type %d\n",
- card->bus);
- ret = -EIO;
- }
- return ret;
- case ACT2000_IOCTL_SETPROTO:
- card->ptype = a ? ISDN_PTYPE_EURO : ISDN_PTYPE_1TR6;
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return 0;
- actcapi_manufacturer_req_net(card);
- return 0;
- case ACT2000_IOCTL_SETMSN:
- if (copy_from_user(tmp, arg,
- sizeof(tmp)))
- return -EFAULT;
- ret = act2000_set_msn(card, tmp);
- if (ret)
- return ret;
- if (card->flags & ACT2000_FLAGS_RUNNING)
- return actcapi_manufacturer_req_msn(card);
- return 0;
- case ACT2000_IOCTL_ADDCARD:
- if (copy_from_user(&cdef, arg,
- sizeof(cdef)))
- return -EFAULT;
- if (act2000_addcard(cdef.bus, cdef.port, cdef.irq, cdef.id))
- return -EIO;
- return 0;
- case ACT2000_IOCTL_TEST:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- return 0;
- default:
- return -EINVAL;
- }
- break;
- case ISDN_CMD_DIAL:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x0f)))
- break;
- spin_lock_irqsave(&card->lock, flags);
- if (chan->fsm_state != ACT2000_STATE_NULL) {
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_WARNING "Dial on channel with state %d\n",
- chan->fsm_state);
- return -EBUSY;
- }
- if (card->ptype == ISDN_PTYPE_EURO)
- tmp[0] = act2000_find_msn(card, c->parm.setup.eazmsn, 1);
- else
- tmp[0] = c->parm.setup.eazmsn[0];
- chan->fsm_state = ACT2000_STATE_OCALL;
- chan->callref = 0xffff;
- spin_unlock_irqrestore(&card->lock, flags);
- ret = actcapi_connect_req(card, chan, c->parm.setup.phone,
- tmp[0], c->parm.setup.si1,
- c->parm.setup.si2);
- if (ret) {
- cmd.driver = card->myid;
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg &= 0x0f;
- card->interface.statcallb(&cmd);
- }
- return ret;
- case ISDN_CMD_ACCEPTD:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x0f)))
- break;
- if (chan->fsm_state == ACT2000_STATE_ICALL)
- actcapi_select_b2_protocol_req(card, chan);
- return 0;
- case ISDN_CMD_ACCEPTB:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- return 0;
- case ISDN_CMD_HANGUP:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x0f)))
- break;
- switch (chan->fsm_state) {
- case ACT2000_STATE_ICALL:
- case ACT2000_STATE_BSETUP:
- actcapi_connect_resp(card, chan, 0x15);
- break;
- case ACT2000_STATE_ACTIVE:
- actcapi_disconnect_b3_req(card, chan);
- break;
- }
- return 0;
- case ISDN_CMD_SETEAZ:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x0f)))
- break;
- if (strlen(c->parm.num)) {
- if (card->ptype == ISDN_PTYPE_EURO) {
- chan->eazmask = act2000_find_msn(card, c->parm.num, 0);
- }
- if (card->ptype == ISDN_PTYPE_1TR6) {
- int i;
-
- chan->eazmask = 0;
- for (i = 0; i < strlen(c->parm.num); i++)
- if (isdigit(c->parm.num[i]))
- chan->eazmask |= (1 << (c->parm.num[i] - '0'));
- }
- } else
- chan->eazmask = 0x3ff;
- actcapi_listen_req(card);
- return 0;
- case ISDN_CMD_CLREAZ:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x0f)))
- break;
- chan->eazmask = 0;
- actcapi_listen_req(card);
- return 0;
- case ISDN_CMD_SETL2:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- if (!(chan = find_channel(card, c->arg & 0x0f)))
- break;
- chan->l2prot = (c->arg >> 8);
- return 0;
- case ISDN_CMD_SETL3:
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) {
- printk(KERN_WARNING "L3 protocol unknown\n");
- return -1;
- }
- if (!(chan = find_channel(card, c->arg & 0x0f)))
- break;
- chan->l3prot = (c->arg >> 8);
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int
-act2000_sendbuf(act2000_card *card, int channel, int ack, struct sk_buff *skb)
-{
- struct sk_buff *xmit_skb;
- int len;
- act2000_chan *chan;
- actcapi_msg *msg;
-
- if (!(chan = find_channel(card, channel)))
- return -1;
- if (chan->fsm_state != ACT2000_STATE_ACTIVE)
- return -1;
- len = skb->len;
- if ((chan->queued + len) >= ACT2000_MAX_QUEUED)
- return 0;
- if (!len)
- return 0;
- if (skb_headroom(skb) < 19) {
- printk(KERN_WARNING "act2000_sendbuf: Headroom only %d\n",
- skb_headroom(skb));
- xmit_skb = alloc_skb(len + 19, GFP_ATOMIC);
- if (!xmit_skb) {
- printk(KERN_WARNING "act2000_sendbuf: Out of memory\n");
- return 0;
- }
- skb_reserve(xmit_skb, 19);
- skb_copy_from_linear_data(skb, skb_put(xmit_skb, len), len);
- } else {
- xmit_skb = skb_clone(skb, GFP_ATOMIC);
- if (!xmit_skb) {
- printk(KERN_WARNING "act2000_sendbuf: Out of memory\n");
- return 0;
- }
- }
- dev_kfree_skb(skb);
- msg = (actcapi_msg *)skb_push(xmit_skb, 19);
- msg->hdr.len = 19 + len;
- msg->hdr.applicationID = 1;
- msg->hdr.cmd.cmd = 0x86;
- msg->hdr.cmd.subcmd = 0x00;
- msg->hdr.msgnum = actcapi_nextsmsg(card);
- msg->msg.data_b3_req.datalen = len;
- msg->msg.data_b3_req.blocknr = (msg->hdr.msgnum & 0xff);
- msg->msg.data_b3_req.fakencci = MAKE_NCCI(chan->plci, 0, chan->ncci);
- msg->msg.data_b3_req.flags = ack; /* Will be set to 0 on actual sending */
- actcapi_debug_msg(xmit_skb, 1);
- chan->queued += len;
- skb_queue_tail(&card->sndq, xmit_skb);
- act2000_schedule_tx(card);
- return len;
-}
-
-
-/* Read the Status-replies from the Interface */
-static int
-act2000_readstatus(u_char __user *buf, int len, act2000_card *card)
-{
- int count;
- u_char __user *p;
-
- for (p = buf, count = 0; count < len; p++, count++) {
- if (card->status_buf_read == card->status_buf_write)
- return count;
- put_user(*card->status_buf_read++, p);
- if (card->status_buf_read > card->status_buf_end)
- card->status_buf_read = card->status_buf;
- }
- return count;
-}
-
-/*
- * Find card with given driverId
- */
-static inline act2000_card *
-act2000_findcard(int driverid)
-{
- act2000_card *p = cards;
-
- while (p) {
- if (p->myid == driverid)
- return p;
- p = p->next;
- }
- return (act2000_card *) 0;
-}
-
-/*
- * Wrapper functions for interface to linklevel
- */
-static int
-if_command(isdn_ctrl *c)
-{
- act2000_card *card = act2000_findcard(c->driver);
-
- if (card)
- return act2000_command(card, c);
- printk(KERN_ERR
- "act2000: if_command %d called with invalid driverId %d!\n",
- c->command, c->driver);
- return -ENODEV;
-}
-
-static int
-if_writecmd(const u_char __user *buf, int len, int id, int channel)
-{
- act2000_card *card = act2000_findcard(id);
-
- if (card) {
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- return len;
- }
- printk(KERN_ERR
- "act2000: if_writecmd called with invalid driverId!\n");
- return -ENODEV;
-}
-
-static int
-if_readstatus(u_char __user *buf, int len, int id, int channel)
-{
- act2000_card *card = act2000_findcard(id);
-
- if (card) {
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- return act2000_readstatus(buf, len, card);
- }
- printk(KERN_ERR
- "act2000: if_readstatus called with invalid driverId!\n");
- return -ENODEV;
-}
-
-static int
-if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
-{
- act2000_card *card = act2000_findcard(id);
-
- if (card) {
- if (!(card->flags & ACT2000_FLAGS_RUNNING))
- return -ENODEV;
- return act2000_sendbuf(card, channel, ack, skb);
- }
- printk(KERN_ERR
- "act2000: if_sendbuf called with invalid driverId!\n");
- return -ENODEV;
-}
-
-
-/*
- * Allocate a new card-struct, initialize it
- * link it into cards-list.
- */
-static void
-act2000_alloccard(int bus, int port, int irq, char *id)
-{
- int i;
- act2000_card *card;
-
- if (!(card = kzalloc(sizeof(act2000_card), GFP_KERNEL))) {
- printk(KERN_WARNING
- "act2000: (%s) Could not allocate card-struct.\n", id);
- return;
- }
- spin_lock_init(&card->lock);
- spin_lock_init(&card->mnlock);
- skb_queue_head_init(&card->sndq);
- skb_queue_head_init(&card->rcvq);
- skb_queue_head_init(&card->ackq);
- INIT_WORK(&card->snd_tq, act2000_transmit);
- INIT_WORK(&card->rcv_tq, actcapi_dispatch);
- INIT_WORK(&card->poll_tq, act2000_receive);
- init_timer(&card->ptimer);
- card->interface.owner = THIS_MODULE;
- card->interface.channels = ACT2000_BCH;
- card->interface.maxbufsize = 4000;
- card->interface.command = if_command;
- card->interface.writebuf_skb = if_sendbuf;
- card->interface.writecmd = if_writecmd;
- card->interface.readstat = if_readstatus;
- card->interface.features =
- ISDN_FEATURE_L2_X75I |
- ISDN_FEATURE_L2_HDLC |
- ISDN_FEATURE_L3_TRANS |
- ISDN_FEATURE_P_UNKNOWN;
- card->interface.hl_hdrlen = 20;
- card->ptype = ISDN_PTYPE_EURO;
- strlcpy(card->interface.id, id, sizeof(card->interface.id));
- for (i = 0; i < ACT2000_BCH; i++) {
- card->bch[i].plci = 0x8000;
- card->bch[i].ncci = 0x8000;
- card->bch[i].l2prot = ISDN_PROTO_L2_X75I;
- card->bch[i].l3prot = ISDN_PROTO_L3_TRANS;
- }
- card->myid = -1;
- card->bus = bus;
- card->port = port;
- card->irq = irq;
- card->next = cards;
- cards = card;
-}
-
-/*
- * register card at linklevel
- */
-static int
-act2000_registercard(act2000_card *card)
-{
- switch (card->bus) {
- case ACT2000_BUS_ISA:
- break;
- case ACT2000_BUS_MCA:
- case ACT2000_BUS_PCMCIA:
- default:
- printk(KERN_WARNING
- "act2000: Illegal BUS type %d\n",
- card->bus);
- return -1;
- }
- if (!register_isdn(&card->interface)) {
- printk(KERN_WARNING
- "act2000: Unable to register %s\n",
- card->interface.id);
- return -1;
- }
- card->myid = card->interface.channels;
- sprintf(card->regname, "act2000-isdn (%s)", card->interface.id);
- return 0;
-}
-
-static void
-unregister_card(act2000_card *card)
-{
- isdn_ctrl cmd;
-
- cmd.command = ISDN_STAT_UNLOAD;
- cmd.driver = card->myid;
- card->interface.statcallb(&cmd);
- switch (card->bus) {
- case ACT2000_BUS_ISA:
- act2000_isa_release(card);
- break;
- case ACT2000_BUS_MCA:
- case ACT2000_BUS_PCMCIA:
- default:
- printk(KERN_WARNING
- "act2000: Invalid BUS type %d\n",
- card->bus);
- break;
- }
-}
-
-static int
-act2000_addcard(int bus, int port, int irq, char *id)
-{
- act2000_card *p;
- act2000_card *q = NULL;
- int initialized;
- int added = 0;
- int failed = 0;
- int i;
-
- if (!bus)
- bus = ACT2000_BUS_ISA;
- if (port != -1) {
- /* Port defined, do fixed setup */
- act2000_alloccard(bus, port, irq, id);
- } else {
- /* No port defined, perform autoprobing.
- * This may result in more than one card detected.
- */
- switch (bus) {
- case ACT2000_BUS_ISA:
- for (i = 0; i < ARRAY_SIZE(act2000_isa_ports); i++)
- if (act2000_isa_detect(act2000_isa_ports[i])) {
- printk(KERN_INFO "act2000: Detected "
- "ISA card at port 0x%x\n",
- act2000_isa_ports[i]);
- act2000_alloccard(bus,
- act2000_isa_ports[i], irq, id);
- }
- break;
- case ACT2000_BUS_MCA:
- case ACT2000_BUS_PCMCIA:
- default:
- printk(KERN_WARNING
- "act2000: addcard: Invalid BUS type %d\n", bus);
- }
- }
- if (!cards)
- return 1;
- p = cards;
- while (p) {
- initialized = 0;
- if (!p->interface.statcallb) {
- /* Not yet registered.
- * Try to register and activate it.
- */
- added++;
- switch (p->bus) {
- case ACT2000_BUS_ISA:
- if (act2000_isa_detect(p->port)) {
- if (act2000_registercard(p))
- break;
- if (act2000_isa_config_port(p, p->port)) {
- printk(KERN_WARNING
- "act2000: Could not request port 0x%04x\n",
- p->port);
- unregister_card(p);
- p->interface.statcallb = NULL;
- break;
- }
- if (act2000_isa_config_irq(p, p->irq)) {
- printk(KERN_INFO
- "act2000: No IRQ available, fallback to polling\n");
- /* Fall back to polled operation */
- p->irq = 0;
- }
- printk(KERN_INFO
- "act2000: ISA"
- "-type card at port "
- "0x%04x ",
- p->port);
- if (p->irq)
- printk("irq %d\n", p->irq);
- else
- printk("polled\n");
- initialized = 1;
- }
- break;
- case ACT2000_BUS_MCA:
- case ACT2000_BUS_PCMCIA:
- default:
- printk(KERN_WARNING
- "act2000: addcard: Invalid BUS type %d\n",
- p->bus);
- }
- } else
- /* Card already initialized */
- initialized = 1;
- if (initialized) {
- /* Init OK, next card ... */
- q = p;
- p = p->next;
- } else {
- /* Init failed, remove card from list, free memory */
- printk(KERN_WARNING
- "act2000: Initialization of %s failed\n",
- p->interface.id);
- if (q) {
- q->next = p->next;
- kfree(p);
- p = q->next;
- } else {
- cards = p->next;
- kfree(p);
- p = cards;
- }
- failed++;
- }
- }
- return added - failed;
-}
-
-#define DRIVERNAME "IBM Active 2000 ISDN driver"
-
-static int __init act2000_init(void)
-{
- printk(KERN_INFO "%s\n", DRIVERNAME);
- if (!cards)
- act2000_addcard(act_bus, act_port, act_irq, act_id);
- if (!cards)
- printk(KERN_INFO "act2000: No cards defined yet\n");
- return 0;
-}
-
-static void __exit act2000_exit(void)
-{
- act2000_card *card = cards;
- act2000_card *last;
-
- while (card) {
- unregister_card(card);
- del_timer_sync(&card->ptimer);
- card = card->next;
- }
- card = cards;
- while (card) {
- last = card;
- card = card->next;
- act2000_clear_msn(last);
- kfree(last);
- }
- printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
-}
-
-module_init(act2000_init);
-module_exit(act2000_exit);
diff --git a/drivers/staging/i4l/icn/Kconfig b/drivers/staging/i4l/icn/Kconfig
deleted file mode 100644
index 4534f21a1852..000000000000
--- a/drivers/staging/i4l/icn/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-config ISDN_DRV_ICN
- tristate "ICN 2B and 4B support"
- depends on ISA
- help
- This enables support for two kinds of ISDN-cards made by a German
- company called ICN. 2B is the standard version for a single ISDN
- line with two B-channels, 4B supports two ISDN lines. For running
- this card, additional firmware is necessary, which has to be
- downloaded into the card using a utility which is distributed
- separately. See <file:Documentation/isdn/README> and
- <file:Documentation/isdn/README.icn> for more
- information.
diff --git a/drivers/staging/i4l/icn/Makefile b/drivers/staging/i4l/icn/Makefile
deleted file mode 100644
index d9b476fcf384..000000000000
--- a/drivers/staging/i4l/icn/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Makefile for the icn ISDN device driver
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_ISDN_DRV_ICN) += icn.o
diff --git a/drivers/staging/i4l/icn/icn.c b/drivers/staging/i4l/icn/icn.c
deleted file mode 100644
index 3750ba38adc5..000000000000
--- a/drivers/staging/i4l/icn/icn.c
+++ /dev/null
@@ -1,1696 +0,0 @@
-/* $Id: icn.c,v 1.65.6.8 2001/09/23 22:24:55 kai Exp $
- *
- * ISDN low-level module for the ICN active ISDN-Card.
- *
- * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include "icn.h"
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-
-static int portbase = ICN_BASEADDR;
-static unsigned long membase = ICN_MEMADDR;
-static char *icn_id = "\0";
-static char *icn_id2 = "\0";
-
-MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card");
-MODULE_AUTHOR("Fritz Elfert");
-MODULE_LICENSE("GPL");
-module_param(portbase, int, 0);
-MODULE_PARM_DESC(portbase, "Port address of first card");
-module_param(membase, ulong, 0);
-MODULE_PARM_DESC(membase, "Shared memory address of all cards");
-module_param(icn_id, charp, 0);
-MODULE_PARM_DESC(icn_id, "ID-String of first card");
-module_param(icn_id2, charp, 0);
-MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");
-
-/*
- * Verbose bootcode- and protocol-downloading.
- */
-#undef BOOT_DEBUG
-
-/*
- * Verbose Shmem-Mapping.
- */
-#undef MAP_DEBUG
-
-static char
-*revision = "$Revision: 1.65.6.8 $";
-
-static int icn_addcard(int, char *, char *);
-
-/*
- * Free send-queue completely.
- * Parameter:
- * card = pointer to card struct
- * channel = channel number
- */
-static void
-icn_free_queue(icn_card *card, int channel)
-{
- struct sk_buff_head *queue = &card->spqueue[channel];
- struct sk_buff *skb;
-
- skb_queue_purge(queue);
- card->xlen[channel] = 0;
- card->sndcount[channel] = 0;
- skb = card->xskb[channel];
- if (skb) {
- card->xskb[channel] = NULL;
- dev_kfree_skb(skb);
- }
-}
-
-/* Put a value into a shift-register, highest bit first.
- * Parameters:
- * port = port for output (bit 0 is significant)
- * val = value to be output
- * firstbit = Bit-Number of highest bit
- * bitcount = Number of bits to output
- */
-static inline void
-icn_shiftout(unsigned short port,
- unsigned long val,
- int firstbit,
- int bitcount)
-{
- register u_char s;
- register u_char c;
-
- for (s = firstbit, c = bitcount; c > 0; s--, c--)
- OUTB_P((u_char)((val >> s) & 1) ? 0xff : 0, port);
-}
-
-/*
- * disable a cards shared memory
- */
-static inline void
-icn_disable_ram(icn_card *card)
-{
- OUTB_P(0, ICN_MAPRAM);
-}
-
-/*
- * enable a cards shared memory
- */
-static inline void
-icn_enable_ram(icn_card *card)
-{
- OUTB_P(0xff, ICN_MAPRAM);
-}
-
-/*
- * Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12)
- *
- * must called with holding the devlock
- */
-static inline void
-icn_map_channel(icn_card *card, int channel)
-{
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "icn_map_channel %d %d\n", dev.channel, channel);
-#endif
- if ((channel == dev.channel) && (card == dev.mcard))
- return;
- if (dev.mcard)
- icn_disable_ram(dev.mcard);
- icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4); /* Select Bank */
- icn_enable_ram(card);
- dev.mcard = card;
- dev.channel = channel;
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "icn_map_channel done\n");
-#endif
-}
-
-/*
- * Lock a cards channel.
- * Return 0 if requested card/channel is unmapped (failure).
- * Return 1 on success.
- *
- * must called with holding the devlock
- */
-static inline int
-icn_lock_channel(icn_card *card, int channel)
-{
- register int retval;
-
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "icn_lock_channel %d\n", channel);
-#endif
- if ((dev.channel == channel) && (card == dev.mcard)) {
- dev.chanlock++;
- retval = 1;
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "icn_lock_channel %d OK\n", channel);
-#endif
- } else {
- retval = 0;
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel);
-#endif
- }
- return retval;
-}
-
-/*
- * Release current card/channel lock
- *
- * must called with holding the devlock
- */
-static inline void
-__icn_release_channel(void)
-{
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock);
-#endif
- if (dev.chanlock > 0)
- dev.chanlock--;
-}
-
-/*
- * Release current card/channel lock
- */
-static inline void
-icn_release_channel(void)
-{
- ulong flags;
-
- spin_lock_irqsave(&dev.devlock, flags);
- __icn_release_channel();
- spin_unlock_irqrestore(&dev.devlock, flags);
-}
-
-/*
- * Try to map and lock a cards channel.
- * Return 1 on success, 0 on failure.
- */
-static inline int
-icn_trymaplock_channel(icn_card *card, int channel)
-{
- ulong flags;
-
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel,
- dev.chanlock);
-#endif
- spin_lock_irqsave(&dev.devlock, flags);
- if ((!dev.chanlock) ||
- ((dev.channel == channel) && (dev.mcard == card))) {
- dev.chanlock++;
- icn_map_channel(card, channel);
- spin_unlock_irqrestore(&dev.devlock, flags);
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "trymaplock %d OK\n", channel);
-#endif
- return 1;
- }
- spin_unlock_irqrestore(&dev.devlock, flags);
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "trymaplock %d FAILED\n", channel);
-#endif
- return 0;
-}
-
-/*
- * Release current card/channel lock,
- * then map same or other channel without locking.
- */
-static inline void
-icn_maprelease_channel(icn_card *card, int channel)
-{
- ulong flags;
-
-#ifdef MAP_DEBUG
- printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock);
-#endif
- spin_lock_irqsave(&dev.devlock, flags);
- if (dev.chanlock > 0)
- dev.chanlock--;
- if (!dev.chanlock)
- icn_map_channel(card, channel);
- spin_unlock_irqrestore(&dev.devlock, flags);
-}
-
-/* Get Data from the B-Channel, assemble fragmented packets and put them
- * into receive-queue. Wake up any B-Channel-reading processes.
- * This routine is called via timer-callback from icn_pollbchan().
- */
-
-static void
-icn_pollbchan_receive(int channel, icn_card *card)
-{
- int mch = channel + ((card->secondhalf) ? 2 : 0);
- int eflag;
- int cnt;
- struct sk_buff *skb;
-
- if (icn_trymaplock_channel(card, mch)) {
- while (rbavl) {
- cnt = readb(&rbuf_l);
- if ((card->rcvidx[channel] + cnt) > 4000) {
- printk(KERN_WARNING
- "icn: (%s) bogus packet on ch%d, dropping.\n",
- CID,
- channel + 1);
- card->rcvidx[channel] = 0;
- eflag = 0;
- } else {
- memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],
- &rbuf_d, cnt);
- card->rcvidx[channel] += cnt;
- eflag = readb(&rbuf_f);
- }
- rbnext;
- icn_maprelease_channel(card, mch & 2);
- if (!eflag) {
- cnt = card->rcvidx[channel];
- if (cnt) {
- skb = dev_alloc_skb(cnt);
- if (!skb) {
- printk(KERN_WARNING "icn: receive out of memory\n");
- break;
- }
- memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt);
- card->rcvidx[channel] = 0;
- card->interface.rcvcallb_skb(card->myid, channel, skb);
- }
- }
- if (!icn_trymaplock_channel(card, mch))
- break;
- }
- icn_maprelease_channel(card, mch & 2);
- }
-}
-
-/* Send data-packet to B-Channel, split it up into fragments of
- * ICN_FRAGSIZE length. If last fragment is sent out, signal
- * success to upper layers via statcallb with ISDN_STAT_BSENT argument.
- * This routine is called via timer-callback from icn_pollbchan() or
- * directly from icn_sendbuf().
- */
-
-static void
-icn_pollbchan_send(int channel, icn_card *card)
-{
- int mch = channel + ((card->secondhalf) ? 2 : 0);
- int cnt;
- unsigned long flags;
- struct sk_buff *skb;
- isdn_ctrl cmd;
-
- if (!(card->sndcount[channel] || card->xskb[channel] ||
- !skb_queue_empty(&card->spqueue[channel])))
- return;
- if (icn_trymaplock_channel(card, mch)) {
- while (sbfree &&
- (card->sndcount[channel] ||
- !skb_queue_empty(&card->spqueue[channel]) ||
- card->xskb[channel])) {
- spin_lock_irqsave(&card->lock, flags);
- if (card->xmit_lock[channel]) {
- spin_unlock_irqrestore(&card->lock, flags);
- break;
- }
- card->xmit_lock[channel]++;
- spin_unlock_irqrestore(&card->lock, flags);
- skb = card->xskb[channel];
- if (!skb) {
- skb = skb_dequeue(&card->spqueue[channel]);
- if (skb) {
- /* Pop ACK-flag off skb.
- * Store length to xlen.
- */
- if (*(skb_pull(skb, 1)))
- card->xlen[channel] = skb->len;
- else
- card->xlen[channel] = 0;
- }
- }
- if (!skb)
- break;
- if (skb->len > ICN_FRAGSIZE) {
- writeb(0xff, &sbuf_f);
- cnt = ICN_FRAGSIZE;
- } else {
- writeb(0x0, &sbuf_f);
- cnt = skb->len;
- }
- writeb(cnt, &sbuf_l);
- memcpy_toio(&sbuf_d, skb->data, cnt);
- skb_pull(skb, cnt);
- sbnext; /* switch to next buffer */
- icn_maprelease_channel(card, mch & 2);
- spin_lock_irqsave(&card->lock, flags);
- card->sndcount[channel] -= cnt;
- if (!skb->len) {
- if (card->xskb[channel])
- card->xskb[channel] = NULL;
- card->xmit_lock[channel] = 0;
- spin_unlock_irqrestore(&card->lock, flags);
- dev_kfree_skb(skb);
- if (card->xlen[channel]) {
- cmd.command = ISDN_STAT_BSENT;
- cmd.driver = card->myid;
- cmd.arg = channel;
- cmd.parm.length = card->xlen[channel];
- card->interface.statcallb(&cmd);
- }
- } else {
- card->xskb[channel] = skb;
- card->xmit_lock[channel] = 0;
- spin_unlock_irqrestore(&card->lock, flags);
- }
- if (!icn_trymaplock_channel(card, mch))
- break;
- }
- icn_maprelease_channel(card, mch & 2);
- }
-}
-
-/* Send/Receive Data to/from the B-Channel.
- * This routine is called via timer-callback.
- * It schedules itself while any B-Channel is open.
- */
-
-static void
-icn_pollbchan(unsigned long data)
-{
- icn_card *card = (icn_card *)data;
- unsigned long flags;
-
- if (card->flags & ICN_FLAGS_B1ACTIVE) {
- icn_pollbchan_receive(0, card);
- icn_pollbchan_send(0, card);
- }
- if (card->flags & ICN_FLAGS_B2ACTIVE) {
- icn_pollbchan_receive(1, card);
- icn_pollbchan_send(1, card);
- }
- if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
- /* schedule b-channel polling again */
- spin_lock_irqsave(&card->lock, flags);
- mod_timer(&card->rb_timer, jiffies + ICN_TIMER_BCREAD);
- card->flags |= ICN_FLAGS_RBTIMER;
- spin_unlock_irqrestore(&card->lock, flags);
- } else
- card->flags &= ~ICN_FLAGS_RBTIMER;
-}
-
-typedef struct icn_stat {
- char *statstr;
- int command;
- int action;
-} icn_stat;
-/* *INDENT-OFF* */
-static icn_stat icn_stat_table[] = {
- {"BCON_", ISDN_STAT_BCONN, 1}, /* B-Channel connected */
- {"BDIS_", ISDN_STAT_BHUP, 2}, /* B-Channel disconnected */
- /*
- ** add d-channel connect and disconnect support to link-level
- */
- {"DCON_", ISDN_STAT_DCONN, 10}, /* D-Channel connected */
- {"DDIS_", ISDN_STAT_DHUP, 11}, /* D-Channel disconnected */
- {"DCAL_I", ISDN_STAT_ICALL, 3}, /* Incoming call dialup-line */
- {"DSCA_I", ISDN_STAT_ICALL, 3}, /* Incoming call 1TR6-SPV */
- {"FCALL", ISDN_STAT_ICALL, 4}, /* Leased line connection up */
- {"CIF", ISDN_STAT_CINF, 5}, /* Charge-info, 1TR6-type */
- {"AOC", ISDN_STAT_CINF, 6}, /* Charge-info, DSS1-type */
- {"CAU", ISDN_STAT_CAUSE, 7}, /* Cause code */
- {"TEI OK", ISDN_STAT_RUN, 0}, /* Card connected to wallplug */
- {"E_L1: ACT FAIL", ISDN_STAT_BHUP, 8}, /* Layer-1 activation failed */
- {"E_L2: DATA LIN", ISDN_STAT_BHUP, 8}, /* Layer-2 data link lost */
- {"E_L1: ACTIVATION FAILED",
- ISDN_STAT_BHUP, 8}, /* Layer-1 activation failed */
- {NULL, 0, -1}
-};
-/* *INDENT-ON* */
-
-
-/*
- * Check Statusqueue-Pointer from isdn-cards.
- * If there are new status-replies from the interface, check
- * them against B-Channel-connects/disconnects and set flags accordingly.
- * Wake-Up any processes, who are reading the status-device.
- * If there are B-Channels open, initiate a timer-callback to
- * icn_pollbchan().
- * This routine is called periodically via timer.
- */
-
-static void
-icn_parse_status(u_char *status, int channel, icn_card *card)
-{
- icn_stat *s = icn_stat_table;
- int action = -1;
- unsigned long flags;
- isdn_ctrl cmd;
-
- while (s->statstr) {
- if (!strncmp(status, s->statstr, strlen(s->statstr))) {
- cmd.command = s->command;
- action = s->action;
- break;
- }
- s++;
- }
- if (action == -1)
- return;
- cmd.driver = card->myid;
- cmd.arg = channel;
- switch (action) {
- case 11:
- spin_lock_irqsave(&card->lock, flags);
- icn_free_queue(card, channel);
- card->rcvidx[channel] = 0;
-
- if (card->flags &
- ((channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE)) {
- isdn_ctrl ncmd;
-
- card->flags &= ~((channel) ?
- ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
-
- memset(&ncmd, 0, sizeof(ncmd));
-
- ncmd.driver = card->myid;
- ncmd.arg = channel;
- ncmd.command = ISDN_STAT_BHUP;
- spin_unlock_irqrestore(&card->lock, flags);
- card->interface.statcallb(&cmd);
- } else
- spin_unlock_irqrestore(&card->lock, flags);
- break;
- case 1:
- spin_lock_irqsave(&card->lock, flags);
- icn_free_queue(card, channel);
- card->flags |= (channel) ?
- ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE;
- spin_unlock_irqrestore(&card->lock, flags);
- break;
- case 2:
- spin_lock_irqsave(&card->lock, flags);
- card->flags &= ~((channel) ?
- ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
- icn_free_queue(card, channel);
- card->rcvidx[channel] = 0;
- spin_unlock_irqrestore(&card->lock, flags);
- break;
- case 3:
- {
- char *t = status + 6;
- char *s = strchr(t, ',');
-
- *s++ = '\0';
- strlcpy(cmd.parm.setup.phone, t,
- sizeof(cmd.parm.setup.phone));
- s = strchr(t = s, ',');
- *s++ = '\0';
- if (!strlen(t))
- cmd.parm.setup.si1 = 0;
- else
- cmd.parm.setup.si1 =
- simple_strtoul(t, NULL, 10);
- s = strchr(t = s, ',');
- *s++ = '\0';
- if (!strlen(t))
- cmd.parm.setup.si2 = 0;
- else
- cmd.parm.setup.si2 =
- simple_strtoul(t, NULL, 10);
- strlcpy(cmd.parm.setup.eazmsn, s,
- sizeof(cmd.parm.setup.eazmsn));
- }
- cmd.parm.setup.plan = 0;
- cmd.parm.setup.screen = 0;
- break;
- case 4:
- sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid);
- sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1);
- cmd.parm.setup.si1 = 7;
- cmd.parm.setup.si2 = 0;
- cmd.parm.setup.plan = 0;
- cmd.parm.setup.screen = 0;
- break;
- case 5:
- strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num));
- break;
- case 6:
- snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d",
- (int)simple_strtoul(status + 7, NULL, 16));
- break;
- case 7:
- status += 3;
- if (strlen(status) == 4)
- snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%s%c%c",
- status + 2, *status, *(status + 1));
- else
- strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num));
- break;
- case 8:
- spin_lock_irqsave(&card->lock, flags);
- card->flags &= ~ICN_FLAGS_B1ACTIVE;
- icn_free_queue(card, 0);
- card->rcvidx[0] = 0;
- spin_unlock_irqrestore(&card->lock, flags);
- cmd.arg = 0;
- cmd.driver = card->myid;
- card->interface.statcallb(&cmd);
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = 0;
- cmd.driver = card->myid;
- card->interface.statcallb(&cmd);
- cmd.command = ISDN_STAT_BHUP;
- spin_lock_irqsave(&card->lock, flags);
- card->flags &= ~ICN_FLAGS_B2ACTIVE;
- icn_free_queue(card, 1);
- card->rcvidx[1] = 0;
- spin_unlock_irqrestore(&card->lock, flags);
- cmd.arg = 1;
- cmd.driver = card->myid;
- card->interface.statcallb(&cmd);
- cmd.command = ISDN_STAT_DHUP;
- cmd.arg = 1;
- cmd.driver = card->myid;
- break;
- }
- card->interface.statcallb(&cmd);
- return;
-}
-
-static void
-icn_putmsg(icn_card *card, unsigned char c)
-{
- ulong flags;
-
- spin_lock_irqsave(&card->lock, flags);
- *card->msg_buf_write++ = (c == 0xff) ? '\n' : c;
- if (card->msg_buf_write == card->msg_buf_read) {
- if (++card->msg_buf_read > card->msg_buf_end)
- card->msg_buf_read = card->msg_buf;
- }
- if (card->msg_buf_write > card->msg_buf_end)
- card->msg_buf_write = card->msg_buf;
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static void
-icn_polldchan(unsigned long data)
-{
- icn_card *card = (icn_card *)data;
- int mch = card->secondhalf ? 2 : 0;
- int avail = 0;
- int left;
- u_char c;
- int ch;
- unsigned long flags;
- int i;
- u_char *p;
- isdn_ctrl cmd;
-
- if (icn_trymaplock_channel(card, mch)) {
- avail = msg_avail;
- for (left = avail, i = readb(&msg_o); left > 0; i++, left--) {
- c = readb(&dev.shmem->comm_buffers.iopc_buf[i & 0xff]);
- icn_putmsg(card, c);
- if (c == 0xff) {
- card->imsg[card->iptr] = 0;
- card->iptr = 0;
- if (card->imsg[0] == '0' && card->imsg[1] >= '0' &&
- card->imsg[1] <= '2' && card->imsg[2] == ';') {
- ch = (card->imsg[1] - '0') - 1;
- p = &card->imsg[3];
- icn_parse_status(p, ch, card);
- } else {
- p = card->imsg;
- if (!strncmp(p, "DRV1.", 5)) {
- u_char vstr[10];
- u_char *q = vstr;
-
- printk(KERN_INFO "icn: (%s) %s\n", CID, p);
- if (!strncmp(p + 7, "TC", 2)) {
- card->ptype = ISDN_PTYPE_1TR6;
- card->interface.features |= ISDN_FEATURE_P_1TR6;
- printk(KERN_INFO
- "icn: (%s) 1TR6-Protocol loaded and running\n", CID);
- }
- if (!strncmp(p + 7, "EC", 2)) {
- card->ptype = ISDN_PTYPE_EURO;
- card->interface.features |= ISDN_FEATURE_P_EURO;
- printk(KERN_INFO
- "icn: (%s) Euro-Protocol loaded and running\n", CID);
- }
- p = strstr(card->imsg, "BRV") + 3;
- while (*p) {
- if (*p >= '0' && *p <= '9')
- *q++ = *p;
- p++;
- }
- *q = '\0';
- strcat(vstr, "000");
- vstr[3] = '\0';
- card->fw_rev = (int)simple_strtoul(vstr, NULL, 10);
- continue;
- }
- }
- } else {
- card->imsg[card->iptr] = c;
- if (card->iptr < 59)
- card->iptr++;
- }
- }
- writeb((readb(&msg_o) + avail) & 0xff, &msg_o);
- icn_release_channel();
- }
- if (avail) {
- cmd.command = ISDN_STAT_STAVAIL;
- cmd.driver = card->myid;
- cmd.arg = avail;
- card->interface.statcallb(&cmd);
- }
- spin_lock_irqsave(&card->lock, flags);
- if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE))
- if (!(card->flags & ICN_FLAGS_RBTIMER)) {
- /* schedule b-channel polling */
- card->flags |= ICN_FLAGS_RBTIMER;
- del_timer(&card->rb_timer);
- card->rb_timer.function = icn_pollbchan;
- card->rb_timer.data = (unsigned long)card;
- card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
- add_timer(&card->rb_timer);
- }
- /* schedule again */
- mod_timer(&card->st_timer, jiffies + ICN_TIMER_DCREAD);
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-/* Append a packet to the transmit buffer-queue.
- * Parameters:
- * channel = Number of B-channel
- * skb = pointer to sk_buff
- * card = pointer to card-struct
- * Return:
- * Number of bytes transferred, -E??? on error
- */
-
-static int
-icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card *card)
-{
- int len = skb->len;
- unsigned long flags;
- struct sk_buff *nskb;
-
- if (len > 4000) {
- printk(KERN_WARNING
- "icn: Send packet too large\n");
- return -EINVAL;
- }
- if (len) {
- if (!(card->flags & (channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE))
- return 0;
- if (card->sndcount[channel] > ICN_MAX_SQUEUE)
- return 0;
- /* TODO test headroom or use skb->nb to flag ACK */
- nskb = skb_clone(skb, GFP_ATOMIC);
- if (nskb) {
- /* Push ACK flag as one
- * byte in front of data.
- */
- *(skb_push(nskb, 1)) = ack ? 1 : 0;
- skb_queue_tail(&card->spqueue[channel], nskb);
- dev_kfree_skb(skb);
- } else
- len = 0;
- spin_lock_irqsave(&card->lock, flags);
- card->sndcount[channel] += len;
- spin_unlock_irqrestore(&card->lock, flags);
- }
- return len;
-}
-
-/*
- * Check card's status after starting the bootstrap loader.
- * On entry, the card's shared memory has already to be mapped.
- * Return:
- * 0 on success (Boot loader ready)
- * -EIO on failure (timeout)
- */
-static int
-icn_check_loader(int cardnumber)
-{
- int timer = 0;
-
- while (1) {
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Loader %d ?\n", cardnumber);
-#endif
- if (readb(&dev.shmem->data_control.scns) ||
- readb(&dev.shmem->data_control.scnr)) {
- if (timer++ > 5) {
- printk(KERN_WARNING
- "icn: Boot-Loader %d timed out.\n",
- cardnumber);
- icn_release_channel();
- return -EIO;
- }
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Loader %d TO?\n", cardnumber);
-#endif
- msleep_interruptible(ICN_BOOT_TIMEOUT1);
- } else {
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Loader %d OK\n", cardnumber);
-#endif
- icn_release_channel();
- return 0;
- }
- }
-}
-
-/* Load the boot-code into the interface-card's memory and start it.
- * Always called from user-process.
- *
- * Parameters:
- * buffer = pointer to packet
- * Return:
- * 0 if successfully loaded
- */
-
-#ifdef BOOT_DEBUG
-#define SLEEP(sec) { \
- int slsec = sec; \
- printk(KERN_DEBUG "SLEEP(%d)\n", slsec); \
- while (slsec) { \
- msleep_interruptible(1000); \
- slsec--; \
- } \
- }
-#else
-#define SLEEP(sec)
-#endif
-
-static int
-icn_loadboot(u_char __user *buffer, icn_card *card)
-{
- int ret;
- u_char *codebuf;
- unsigned long flags;
-
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong)buffer);
-#endif
- codebuf = memdup_user(buffer, ICN_CODE_STAGE1);
- if (IS_ERR(codebuf))
- return PTR_ERR(codebuf);
-
- if (!card->rvalid) {
- if (!request_region(card->port, ICN_PORTLEN, card->regname)) {
- printk(KERN_WARNING
- "icn: (%s) ports 0x%03x-0x%03x in use.\n",
- CID,
- card->port,
- card->port + ICN_PORTLEN);
- ret = -EBUSY;
- goto out_kfree;
- }
- card->rvalid = 1;
- if (card->doubleS0)
- card->other->rvalid = 1;
- }
- if (!dev.mvalid) {
- if (!request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)")) {
- printk(KERN_WARNING
- "icn: memory at 0x%08lx in use.\n", dev.memaddr);
- ret = -EBUSY;
- goto out_kfree;
- }
- dev.shmem = ioremap(dev.memaddr, 0x4000);
- dev.mvalid = 1;
- }
- OUTB_P(0, ICN_RUN); /* Reset Controller */
- OUTB_P(0, ICN_MAPRAM); /* Disable RAM */
- icn_shiftout(ICN_CFG, 0x0f, 3, 4); /* Windowsize= 16k */
- icn_shiftout(ICN_CFG, dev.memaddr, 23, 10); /* Set RAM-Addr. */
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "shmem=%08lx\n", dev.memaddr);
-#endif
- SLEEP(1);
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Map Bank 0\n");
-#endif
- spin_lock_irqsave(&dev.devlock, flags);
- icn_map_channel(card, 0); /* Select Bank 0 */
- icn_lock_channel(card, 0); /* Lock Bank 0 */
- spin_unlock_irqrestore(&dev.devlock, flags);
- SLEEP(1);
- memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Bootloader transferred\n");
-#endif
- if (card->doubleS0) {
- SLEEP(1);
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Map Bank 8\n");
-#endif
- spin_lock_irqsave(&dev.devlock, flags);
- __icn_release_channel();
- icn_map_channel(card, 2); /* Select Bank 8 */
- icn_lock_channel(card, 2); /* Lock Bank 8 */
- spin_unlock_irqrestore(&dev.devlock, flags);
- SLEEP(1);
- memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code */
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Bootloader transferred\n");
-#endif
- }
- SLEEP(1);
- OUTB_P(0xff, ICN_RUN); /* Start Boot-Code */
- ret = icn_check_loader(card->doubleS0 ? 2 : 1);
- if (ret)
- goto out_kfree;
- if (!card->doubleS0) {
- ret = 0;
- goto out_kfree;
- }
- /* reached only, if we have a Double-S0-Card */
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Map Bank 0\n");
-#endif
- spin_lock_irqsave(&dev.devlock, flags);
- icn_map_channel(card, 0); /* Select Bank 0 */
- icn_lock_channel(card, 0); /* Lock Bank 0 */
- spin_unlock_irqrestore(&dev.devlock, flags);
- SLEEP(1);
- ret = (icn_check_loader(1));
-
-out_kfree:
- kfree(codebuf);
- return ret;
-}
-
-static int
-icn_loadproto(u_char __user *buffer, icn_card *card)
-{
- register u_char __user *p = buffer;
- u_char codebuf[256];
- uint left = ICN_CODE_STAGE2;
- uint cnt;
- int timer;
- unsigned long flags;
-
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "icn_loadproto called\n");
-#endif
- if (!access_ok(VERIFY_READ, buffer, ICN_CODE_STAGE2))
- return -EFAULT;
- timer = 0;
- spin_lock_irqsave(&dev.devlock, flags);
- if (card->secondhalf) {
- icn_map_channel(card, 2);
- icn_lock_channel(card, 2);
- } else {
- icn_map_channel(card, 0);
- icn_lock_channel(card, 0);
- }
- spin_unlock_irqrestore(&dev.devlock, flags);
- while (left) {
- if (sbfree) { /* If there is a free buffer... */
- cnt = left;
- if (cnt > 256)
- cnt = 256;
- if (copy_from_user(codebuf, p, cnt)) {
- icn_maprelease_channel(card, 0);
- return -EFAULT;
- }
- memcpy_toio(&sbuf_l, codebuf, cnt); /* copy data */
- sbnext; /* switch to next buffer */
- p += cnt;
- left -= cnt;
- timer = 0;
- } else {
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "boot 2 !sbfree\n");
-#endif
- if (timer++ > 5) {
- icn_maprelease_channel(card, 0);
- return -EIO;
- }
- schedule_timeout_interruptible(10);
- }
- }
- writeb(0x20, &sbuf_n);
- timer = 0;
- while (1) {
- if (readb(&cmd_o) || readb(&cmd_i)) {
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Proto?\n");
-#endif
- if (timer++ > 5) {
- printk(KERN_WARNING
- "icn: (%s) Protocol timed out.\n",
- CID);
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Proto TO!\n");
-#endif
- icn_maprelease_channel(card, 0);
- return -EIO;
- }
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Proto TO?\n");
-#endif
- msleep_interruptible(ICN_BOOT_TIMEOUT1);
- } else {
- if ((card->secondhalf) || (!card->doubleS0)) {
-#ifdef BOOT_DEBUG
- printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n",
- card->secondhalf);
-#endif
- spin_lock_irqsave(&card->lock, flags);
- setup_timer(&card->st_timer, icn_polldchan,
- (unsigned long)card);
- mod_timer(&card->st_timer,
- jiffies + ICN_TIMER_DCREAD);
- card->flags |= ICN_FLAGS_RUNNING;
- if (card->doubleS0) {
- setup_timer(&card->other->st_timer,
- icn_polldchan,
- (unsigned long)card->other);
- mod_timer(&card->other->st_timer,
- jiffies + ICN_TIMER_DCREAD);
- card->other->flags |= ICN_FLAGS_RUNNING;
- }
- spin_unlock_irqrestore(&card->lock, flags);
- }
- icn_maprelease_channel(card, 0);
- return 0;
- }
- }
-}
-
-/* Read the Status-replies from the Interface */
-static int
-icn_readstatus(u_char __user *buf, int len, icn_card *card)
-{
- int count;
- u_char __user *p;
-
- for (p = buf, count = 0; count < len; p++, count++) {
- if (card->msg_buf_read == card->msg_buf_write)
- return count;
- if (put_user(*card->msg_buf_read++, p))
- return -EFAULT;
- if (card->msg_buf_read > card->msg_buf_end)
- card->msg_buf_read = card->msg_buf;
- }
- return count;
-}
-
-/* Put command-strings into the command-queue of the Interface */
-static int
-icn_writecmd(const u_char __user *ubuf, const u_char *kbuf, int len,
- int user, icn_card *card)
-{
- int mch = card->secondhalf ? 2 : 0;
- int pp;
- int i;
- int count;
- int xcount;
- int ocount;
- int loop;
- unsigned long flags;
- int lastmap_channel;
- struct icn_card *lastmap_card;
- u_char *p;
- isdn_ctrl cmd;
- u_char msg[0x100];
-
- ocount = 1;
- xcount = loop = 0;
- while (len) {
- count = cmd_free;
- if (count > len)
- count = len;
- if (user) {
- if (copy_from_user(msg, ubuf, count))
- return -EFAULT;
- } else
- memcpy(msg, kbuf, count);
-
- spin_lock_irqsave(&dev.devlock, flags);
- lastmap_card = dev.mcard;
- lastmap_channel = dev.channel;
- icn_map_channel(card, mch);
-
- icn_putmsg(card, '>');
- for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp
- ++) {
- writeb((*p == '\n') ? 0xff : *p,
- &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]);
- len--;
- xcount++;
- icn_putmsg(card, *p);
- if ((*p == '\n') && (i > 1)) {
- icn_putmsg(card, '>');
- ocount++;
- }
- ocount++;
- }
- writeb((readb(&cmd_i) + count) & 0xff, &cmd_i);
- if (lastmap_card)
- icn_map_channel(lastmap_card, lastmap_channel);
- spin_unlock_irqrestore(&dev.devlock, flags);
- if (len) {
- mdelay(1);
- if (loop++ > 20)
- break;
- } else
- break;
- }
- if (len && (!user))
- printk(KERN_WARNING "icn: writemsg incomplete!\n");
- cmd.command = ISDN_STAT_STAVAIL;
- cmd.driver = card->myid;
- cmd.arg = ocount;
- card->interface.statcallb(&cmd);
- return xcount;
-}
-
-/*
- * Delete card's pending timers, send STOP to linklevel
- */
-static void
-icn_stopcard(icn_card *card)
-{
- unsigned long flags;
- isdn_ctrl cmd;
-
- spin_lock_irqsave(&card->lock, flags);
- if (card->flags & ICN_FLAGS_RUNNING) {
- card->flags &= ~ICN_FLAGS_RUNNING;
- del_timer(&card->st_timer);
- del_timer(&card->rb_timer);
- spin_unlock_irqrestore(&card->lock, flags);
- cmd.command = ISDN_STAT_STOP;
- cmd.driver = card->myid;
- card->interface.statcallb(&cmd);
- if (card->doubleS0)
- icn_stopcard(card->other);
- } else
- spin_unlock_irqrestore(&card->lock, flags);
-}
-
-static void
-icn_stopallcards(void)
-{
- icn_card *p = cards;
-
- while (p) {
- icn_stopcard(p);
- p = p->next;
- }
-}
-
-/*
- * Unmap all cards, because some of them may be mapped accidetly during
- * autoprobing of some network drivers (SMC-driver?)
- */
-static void
-icn_disable_cards(void)
-{
- icn_card *card = cards;
-
- while (card) {
- if (!request_region(card->port, ICN_PORTLEN, "icn-isdn")) {
- printk(KERN_WARNING
- "icn: (%s) ports 0x%03x-0x%03x in use.\n",
- CID,
- card->port,
- card->port + ICN_PORTLEN);
- } else {
- OUTB_P(0, ICN_RUN); /* Reset Controller */
- OUTB_P(0, ICN_MAPRAM); /* Disable RAM */
- release_region(card->port, ICN_PORTLEN);
- }
- card = card->next;
- }
-}
-
-static int
-icn_command(isdn_ctrl *c, icn_card *card)
-{
- ulong a;
- ulong flags;
- int i;
- char cbuf[80];
- isdn_ctrl cmd;
- icn_cdef cdef;
- char __user *arg;
-
- switch (c->command) {
- case ISDN_CMD_IOCTL:
- memcpy(&a, c->parm.num, sizeof(ulong));
- arg = (char __user *)a;
- switch (c->arg) {
- case ICN_IOCTL_SETMMIO:
- if (dev.memaddr != (a & 0x0ffc000)) {
- if (!request_mem_region(a & 0x0ffc000, 0x4000, "icn-isdn (all cards)")) {
- printk(KERN_WARNING
- "icn: memory at 0x%08lx in use.\n",
- a & 0x0ffc000);
- return -EINVAL;
- }
- release_mem_region(a & 0x0ffc000, 0x4000);
- icn_stopallcards();
- spin_lock_irqsave(&card->lock, flags);
- if (dev.mvalid) {
- iounmap(dev.shmem);
- release_mem_region(dev.memaddr, 0x4000);
- }
- dev.mvalid = 0;
- dev.memaddr = a & 0x0ffc000;
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_INFO
- "icn: (%s) mmio set to 0x%08lx\n",
- CID,
- dev.memaddr);
- }
- break;
- case ICN_IOCTL_GETMMIO:
- return (long)dev.memaddr;
- case ICN_IOCTL_SETPORT:
- if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
- || a == 0x340 || a == 0x350 || a == 0x360 ||
- a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
- || a == 0x348 || a == 0x358 || a == 0x368) {
- if (card->port != (unsigned short)a) {
- if (!request_region((unsigned short)a, ICN_PORTLEN, "icn-isdn")) {
- printk(KERN_WARNING
- "icn: (%s) ports 0x%03x-0x%03x in use.\n",
- CID, (int)a, (int)a + ICN_PORTLEN);
- return -EINVAL;
- }
- release_region((unsigned short)a, ICN_PORTLEN);
- icn_stopcard(card);
- spin_lock_irqsave(&card->lock, flags);
- if (card->rvalid)
- release_region(card->port, ICN_PORTLEN);
- card->port = (unsigned short)a;
- card->rvalid = 0;
- if (card->doubleS0) {
- card->other->port = (unsigned short)a;
- card->other->rvalid = 0;
- }
- spin_unlock_irqrestore(&card->lock, flags);
- printk(KERN_INFO
- "icn: (%s) port set to 0x%03x\n",
- CID, card->port);
- }
- } else
- return -EINVAL;
- break;
- case ICN_IOCTL_GETPORT:
- return (int)card->port;
- case ICN_IOCTL_GETDOUBLE:
- return (int)card->doubleS0;
- case ICN_IOCTL_DEBUGVAR:
- if (copy_to_user(arg,
- &card,
- sizeof(ulong)))
- return -EFAULT;
- a += sizeof(ulong);
- {
- ulong l = (ulong)&dev;
- if (copy_to_user(arg,
- &l,
- sizeof(ulong)))
- return -EFAULT;
- }
- return 0;
- case ICN_IOCTL_LOADBOOT:
- if (dev.firstload) {
- icn_disable_cards();
- dev.firstload = 0;
- }
- icn_stopcard(card);
- return icn_loadboot(arg, card);
- case ICN_IOCTL_LOADPROTO:
- icn_stopcard(card);
- i = (icn_loadproto(arg, card));
- if (i)
- return i;
- if (card->doubleS0)
- i = icn_loadproto(arg + ICN_CODE_STAGE2, card->other);
- return i;
- break;
- case ICN_IOCTL_ADDCARD:
- if (!dev.firstload)
- return -EBUSY;
- if (copy_from_user(&cdef,
- arg,
- sizeof(cdef)))
- return -EFAULT;
- return icn_addcard(cdef.port, cdef.id1, cdef.id2);
- break;
- case ICN_IOCTL_LEASEDCFG:
- if (a) {
- if (!card->leased) {
- card->leased = 1;
- while (card->ptype == ISDN_PTYPE_UNKNOWN)
- msleep_interruptible(ICN_BOOT_TIMEOUT1);
- msleep_interruptible(ICN_BOOT_TIMEOUT1);
- sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n",
- (a & 1) ? '1' : 'C', (a & 2) ? '2' : 'C');
- i = icn_writecmd(NULL, cbuf,
- strlen(cbuf),
- 0, card);
- printk(KERN_INFO
- "icn: (%s) Leased-line mode enabled\n",
- CID);
- cmd.command = ISDN_STAT_RUN;
- cmd.driver = card->myid;
- cmd.arg = 0;
- card->interface.statcallb(&cmd);
- }
- } else {
- if (card->leased) {
- card->leased = 0;
- sprintf(cbuf, "00;FV2OFF\n");
- i = icn_writecmd(NULL, cbuf,
- strlen(cbuf),
- 0, card);
- printk(KERN_INFO
- "icn: (%s) Leased-line mode disabled\n",
- CID);
- cmd.command = ISDN_STAT_RUN;
- cmd.driver = card->myid;
- cmd.arg = 0;
- card->interface.statcallb(&cmd);
- }
- }
- return 0;
- default:
- return -EINVAL;
- }
- break;
- case ISDN_CMD_DIAL:
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- if (card->leased)
- break;
- if ((c->arg & 255) < ICN_BCH) {
- char *p;
- char dcode[4];
-
- a = c->arg;
- p = c->parm.setup.phone;
- if (*p == 's' || *p == 'S') {
- /* Dial for SPV */
- p++;
- strcpy(dcode, "SCA");
- } else
- /* Normal Dial */
- strcpy(dcode, "CAL");
- snprintf(cbuf, sizeof(cbuf),
- "%02d;D%s_R%s,%02d,%02d,%s\n", (int)(a + 1),
- dcode, p, c->parm.setup.si1,
- c->parm.setup.si2, c->parm.setup.eazmsn);
- i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
- }
- break;
- case ISDN_CMD_ACCEPTD:
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- if (c->arg < ICN_BCH) {
- a = c->arg + 1;
- if (card->fw_rev >= 300) {
- switch (card->l2_proto[a - 1]) {
- case ISDN_PROTO_L2_X75I:
- sprintf(cbuf, "%02d;BX75\n", (int)a);
- break;
- case ISDN_PROTO_L2_HDLC:
- sprintf(cbuf, "%02d;BTRA\n", (int)a);
- break;
- }
- i = icn_writecmd(NULL, cbuf,
- strlen(cbuf), 0,
- card);
- }
- sprintf(cbuf, "%02d;DCON_R\n", (int)a);
- i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
- }
- break;
- case ISDN_CMD_ACCEPTB:
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- if (c->arg < ICN_BCH) {
- a = c->arg + 1;
- if (card->fw_rev >= 300)
- switch (card->l2_proto[a - 1]) {
- case ISDN_PROTO_L2_X75I:
- sprintf(cbuf, "%02d;BCON_R,BX75\n", (int)a);
- break;
- case ISDN_PROTO_L2_HDLC:
- sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int)a);
- break;
- } else
- sprintf(cbuf, "%02d;BCON_R\n", (int)a);
- i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
- }
- break;
- case ISDN_CMD_HANGUP:
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- if (c->arg < ICN_BCH) {
- a = c->arg + 1;
- sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int)a, (int)a);
- i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
- }
- break;
- case ISDN_CMD_SETEAZ:
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- if (card->leased)
- break;
- if (c->arg < ICN_BCH) {
- a = c->arg + 1;
- if (card->ptype == ISDN_PTYPE_EURO) {
- sprintf(cbuf, "%02d;MS%s%s\n", (int)a,
- c->parm.num[0] ? "N" : "ALL", c->parm.num);
- } else
- sprintf(cbuf, "%02d;EAZ%s\n", (int)a,
- c->parm.num[0] ? (char *)(c->parm.num) : "0123456789");
- i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
- }
- break;
- case ISDN_CMD_CLREAZ:
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- if (card->leased)
- break;
- if (c->arg < ICN_BCH) {
- a = c->arg + 1;
- if (card->ptype == ISDN_PTYPE_EURO)
- sprintf(cbuf, "%02d;MSNC\n", (int)a);
- else
- sprintf(cbuf, "%02d;EAZC\n", (int)a);
- i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
- }
- break;
- case ISDN_CMD_SETL2:
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- if ((c->arg & 255) < ICN_BCH) {
- a = c->arg;
- switch (a >> 8) {
- case ISDN_PROTO_L2_X75I:
- sprintf(cbuf, "%02d;BX75\n", (int)(a & 255) + 1);
- break;
- case ISDN_PROTO_L2_HDLC:
- sprintf(cbuf, "%02d;BTRA\n", (int)(a & 255) + 1);
- break;
- default:
- return -EINVAL;
- }
- i = icn_writecmd(NULL, cbuf, strlen(cbuf), 0, card);
- card->l2_proto[a & 255] = (a >> 8);
- }
- break;
- case ISDN_CMD_SETL3:
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- return 0;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * Find card with given driverId
- */
-static inline icn_card *
-icn_findcard(int driverid)
-{
- icn_card *p = cards;
-
- while (p) {
- if (p->myid == driverid)
- return p;
- p = p->next;
- }
- return (icn_card *)0;
-}
-
-/*
- * Wrapper functions for interface to linklevel
- */
-static int
-if_command(isdn_ctrl *c)
-{
- icn_card *card = icn_findcard(c->driver);
-
- if (card)
- return icn_command(c, card);
- printk(KERN_ERR
- "icn: if_command %d called with invalid driverId %d!\n",
- c->command, c->driver);
- return -ENODEV;
-}
-
-static int
-if_writecmd(const u_char __user *buf, int len, int id, int channel)
-{
- icn_card *card = icn_findcard(id);
-
- if (card) {
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- return icn_writecmd(buf, NULL, len, 1, card);
- }
- printk(KERN_ERR
- "icn: if_writecmd called with invalid driverId!\n");
- return -ENODEV;
-}
-
-static int
-if_readstatus(u_char __user *buf, int len, int id, int channel)
-{
- icn_card *card = icn_findcard(id);
-
- if (card) {
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- return icn_readstatus(buf, len, card);
- }
- printk(KERN_ERR
- "icn: if_readstatus called with invalid driverId!\n");
- return -ENODEV;
-}
-
-static int
-if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
-{
- icn_card *card = icn_findcard(id);
-
- if (card) {
- if (!(card->flags & ICN_FLAGS_RUNNING))
- return -ENODEV;
- return icn_sendbuf(channel, ack, skb, card);
- }
- printk(KERN_ERR
- "icn: if_sendbuf called with invalid driverId!\n");
- return -ENODEV;
-}
-
-/*
- * Allocate a new card-struct, initialize it
- * link it into cards-list and register it at linklevel.
- */
-static icn_card *
-icn_initcard(int port, char *id)
-{
- icn_card *card;
- int i;
-
- card = kzalloc(sizeof(icn_card), GFP_KERNEL);
- if (!card) {
- printk(KERN_WARNING
- "icn: (%s) Could not allocate card-struct.\n", id);
- return (icn_card *)0;
- }
- spin_lock_init(&card->lock);
- card->port = port;
- card->interface.owner = THIS_MODULE;
- card->interface.hl_hdrlen = 1;
- card->interface.channels = ICN_BCH;
- card->interface.maxbufsize = 4000;
- card->interface.command = if_command;
- card->interface.writebuf_skb = if_sendbuf;
- card->interface.writecmd = if_writecmd;
- card->interface.readstat = if_readstatus;
- card->interface.features = ISDN_FEATURE_L2_X75I |
- ISDN_FEATURE_L2_HDLC |
- ISDN_FEATURE_L3_TRANS |
- ISDN_FEATURE_P_UNKNOWN;
- card->ptype = ISDN_PTYPE_UNKNOWN;
- strlcpy(card->interface.id, id, sizeof(card->interface.id));
- card->msg_buf_write = card->msg_buf;
- card->msg_buf_read = card->msg_buf;
- card->msg_buf_end = &card->msg_buf[sizeof(card->msg_buf) - 1];
- for (i = 0; i < ICN_BCH; i++) {
- card->l2_proto[i] = ISDN_PROTO_L2_X75I;
- skb_queue_head_init(&card->spqueue[i]);
- }
- card->next = cards;
- cards = card;
- if (!register_isdn(&card->interface)) {
- cards = cards->next;
- printk(KERN_WARNING
- "icn: Unable to register %s\n", id);
- kfree(card);
- return (icn_card *)0;
- }
- card->myid = card->interface.channels;
- sprintf(card->regname, "icn-isdn (%s)", card->interface.id);
- return card;
-}
-
-static int
-icn_addcard(int port, char *id1, char *id2)
-{
- icn_card *card;
- icn_card *card2;
-
- card = icn_initcard(port, id1);
- if (!card)
- return -EIO;
- if (!strlen(id2)) {
- printk(KERN_INFO
- "icn: (%s) ICN-2B, port 0x%x added\n",
- card->interface.id, port);
- return 0;
- }
- card2 = icn_initcard(port, id2);
- if (!card2) {
- printk(KERN_INFO
- "icn: (%s) half ICN-4B, port 0x%x added\n", id2, port);
- return 0;
- }
- card->doubleS0 = 1;
- card->secondhalf = 0;
- card->other = card2;
- card2->doubleS0 = 1;
- card2->secondhalf = 1;
- card2->other = card;
- printk(KERN_INFO
- "icn: (%s and %s) ICN-4B, port 0x%x added\n",
- card->interface.id, card2->interface.id, port);
- return 0;
-}
-
-#ifndef MODULE
-static int __init
-icn_setup(char *line)
-{
- char *p, *str;
- int ints[3];
- static char sid[20];
- static char sid2[20];
-
- str = get_options(line, 2, ints);
- if (ints[0])
- portbase = ints[1];
- if (ints[0] > 1)
- membase = (unsigned long)ints[2];
- if (str && *str) {
- strlcpy(sid, str, sizeof(sid));
- icn_id = sid;
- p = strchr(sid, ',');
- if (p) {
- *p++ = 0;
- strcpy(sid2, p);
- icn_id2 = sid2;
- }
- }
- return 1;
-}
-__setup("icn=", icn_setup);
-#endif /* MODULE */
-
-static int __init icn_init(void)
-{
- char *p;
- char rev[21];
-
- memset(&dev, 0, sizeof(icn_dev));
- dev.memaddr = (membase & 0x0ffc000);
- dev.channel = -1;
- dev.mcard = NULL;
- dev.firstload = 1;
- spin_lock_init(&dev.devlock);
-
- p = strchr(revision, ':');
- if (p) {
- strncpy(rev, p + 1, 20);
- rev[20] = '\0';
- p = strchr(rev, '$');
- if (p)
- *p = 0;
- } else
- strcpy(rev, " ??? ");
- printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
- dev.memaddr);
- return icn_addcard(portbase, icn_id, icn_id2);
-}
-
-static void __exit icn_exit(void)
-{
- isdn_ctrl cmd;
- icn_card *card = cards;
- icn_card *last, *tmpcard;
- int i;
- unsigned long flags;
-
- icn_stopallcards();
- while (card) {
- cmd.command = ISDN_STAT_UNLOAD;
- cmd.driver = card->myid;
- card->interface.statcallb(&cmd);
- spin_lock_irqsave(&card->lock, flags);
- if (card->rvalid) {
- OUTB_P(0, ICN_RUN); /* Reset Controller */
- OUTB_P(0, ICN_MAPRAM); /* Disable RAM */
- if (card->secondhalf || (!card->doubleS0)) {
- release_region(card->port, ICN_PORTLEN);
- card->rvalid = 0;
- }
- for (i = 0; i < ICN_BCH; i++)
- icn_free_queue(card, i);
- }
- tmpcard = card->next;
- spin_unlock_irqrestore(&card->lock, flags);
- card = tmpcard;
- }
- card = cards;
- cards = NULL;
- while (card) {
- last = card;
- card = card->next;
- kfree(last);
- }
- if (dev.mvalid) {
- iounmap(dev.shmem);
- release_mem_region(dev.memaddr, 0x4000);
- }
- printk(KERN_NOTICE "ICN-ISDN-driver unloaded\n");
-}
-
-module_init(icn_init);
-module_exit(icn_exit);
diff --git a/drivers/staging/i4l/icn/icn.h b/drivers/staging/i4l/icn/icn.h
deleted file mode 100644
index 07e2e0196527..000000000000
--- a/drivers/staging/i4l/icn/icn.h
+++ /dev/null
@@ -1,252 +0,0 @@
-/* $Id: icn.h,v 1.30.6.5 2001/09/23 22:24:55 kai Exp $
- *
- * ISDN lowlevel-module for the ICN active ISDN-Card.
- *
- * Copyright 1994 by Fritz Elfert (fritz@isdn4linux.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef icn_h
-#define icn_h
-
-#define ICN_IOCTL_SETMMIO 0
-#define ICN_IOCTL_GETMMIO 1
-#define ICN_IOCTL_SETPORT 2
-#define ICN_IOCTL_GETPORT 3
-#define ICN_IOCTL_LOADBOOT 4
-#define ICN_IOCTL_LOADPROTO 5
-#define ICN_IOCTL_LEASEDCFG 6
-#define ICN_IOCTL_GETDOUBLE 7
-#define ICN_IOCTL_DEBUGVAR 8
-#define ICN_IOCTL_ADDCARD 9
-
-/* Struct for adding new cards */
-typedef struct icn_cdef {
- int port;
- char id1[10];
- char id2[10];
-} icn_cdef;
-
-#if defined(__KERNEL__) || defined(__DEBUGVAR__)
-
-#ifdef __KERNEL__
-/* Kernel includes */
-
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/major.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/wait.h>
-#include <linux/delay.h>
-#include <linux/isdnif.h>
-
-#endif /* __KERNEL__ */
-
-/* some useful macros for debugging */
-#ifdef ICN_DEBUG_PORT
-#define OUTB_P(v, p) {pr_debug("icn: outb_p(0x%02x,0x%03x)\n", v, p); outb_p(v, p);}
-#else
-#define OUTB_P outb
-#endif
-
-/* Defaults for Port-Address and shared-memory */
-#define ICN_BASEADDR 0x320
-#define ICN_PORTLEN (0x04)
-#define ICN_MEMADDR 0x0d0000
-
-#define ICN_FLAGS_B1ACTIVE 1 /* B-Channel-1 is open */
-#define ICN_FLAGS_B2ACTIVE 2 /* B-Channel-2 is open */
-#define ICN_FLAGS_RUNNING 4 /* Cards driver activated */
-#define ICN_FLAGS_RBTIMER 8 /* cyclic scheduling of B-Channel-poll */
-
-#define ICN_BOOT_TIMEOUT1 1000 /* Delay for Boot-download (msecs) */
-
-#define ICN_TIMER_BCREAD (HZ / 100) /* B-Channel poll-cycle */
-#define ICN_TIMER_DCREAD (HZ / 2) /* D-Channel poll-cycle */
-
-#define ICN_CODE_STAGE1 4096 /* Size of bootcode */
-#define ICN_CODE_STAGE2 65536 /* Size of protocol-code */
-
-#define ICN_MAX_SQUEUE 8000 /* Max. outstanding send-data (2* hw-buf.) */
-#define ICN_FRAGSIZE (250) /* Max. size of send-fragments */
-#define ICN_BCH 2 /* Number of supported channels per card */
-
-/* type-definitions for accessing the mmap-io-areas */
-
-#define SHM_DCTL_OFFSET (0) /* Offset to data-controlstructures in shm */
-#define SHM_CCTL_OFFSET (0x1d2) /* Offset to comm-controlstructures in shm */
-#define SHM_CBUF_OFFSET (0x200) /* Offset to comm-buffers in shm */
-#define SHM_DBUF_OFFSET (0x2000) /* Offset to data-buffers in shm */
-
-/*
- * Layout of card's data buffers
- */
-typedef struct {
- unsigned char length; /* Bytecount of fragment (max 250) */
- unsigned char endflag; /* 0=last frag., 0xff=frag. continued */
- unsigned char data[ICN_FRAGSIZE]; /* The data */
- /* Fill to 256 bytes */
- char unused[0x100 - ICN_FRAGSIZE - 2];
-} frag_buf;
-
-/*
- * Layout of card's shared memory
- */
-typedef union {
- struct {
- unsigned char scns; /* Index to free SendFrag. */
- unsigned char scnr; /* Index to active SendFrag READONLY */
- unsigned char ecns; /* Index to free RcvFrag. READONLY */
- unsigned char ecnr; /* Index to valid RcvFrag */
- char unused[6];
- unsigned short fuell1; /* Internal Buf Bytecount */
- } data_control;
- struct {
- char unused[SHM_CCTL_OFFSET];
- unsigned char iopc_i; /* Read-Ptr Status-Queue READONLY */
- unsigned char iopc_o; /* Write-Ptr Status-Queue */
- unsigned char pcio_i; /* Write-Ptr Command-Queue */
- unsigned char pcio_o; /* Read-Ptr Command Queue READONLY */
- } comm_control;
- struct {
- char unused[SHM_CBUF_OFFSET];
- unsigned char pcio_buf[0x100]; /* Ring-Buffer Command-Queue */
- unsigned char iopc_buf[0x100]; /* Ring-Buffer Status-Queue */
- } comm_buffers;
- struct {
- char unused[SHM_DBUF_OFFSET];
- frag_buf receive_buf[0x10];
- frag_buf send_buf[0x10];
- } data_buffers;
-} icn_shmem;
-
-/*
- * Per card driver data
- */
-typedef struct icn_card {
- struct icn_card *next; /* Pointer to next device struct */
- struct icn_card *other; /* Pointer to other card for ICN4B */
- unsigned short port; /* Base-port-address */
- int myid; /* Driver-Nr. assigned by linklevel */
- int rvalid; /* IO-portregion has been requested */
- int leased; /* Flag: This Adapter is connected */
- /* to a leased line */
- unsigned short flags; /* Statusflags */
- int doubleS0; /* Flag: ICN4B */
- int secondhalf; /* Flag: Second half of a doubleS0 */
- int fw_rev; /* Firmware revision loaded */
- int ptype; /* Protocol type (1TR6 or Euro) */
- struct timer_list st_timer; /* Timer for Status-Polls */
- struct timer_list rb_timer; /* Timer for B-Channel-Polls */
- u_char rcvbuf[ICN_BCH][4096]; /* B-Channel-Receive-Buffers */
- int rcvidx[ICN_BCH]; /* Index for above buffers */
- int l2_proto[ICN_BCH]; /* Current layer-2-protocol */
- isdn_if interface; /* Interface to upper layer */
- int iptr; /* Index to imsg-buffer */
- char imsg[60]; /* Internal buf for status-parsing */
- char msg_buf[2048]; /* Buffer for status-messages */
- char *msg_buf_write; /* Writepointer for statusbuffer */
- char *msg_buf_read; /* Readpointer for statusbuffer */
- char *msg_buf_end; /* Pointer to end of statusbuffer */
- int sndcount[ICN_BCH]; /* Byte-counters for B-Ch.-send */
- int xlen[ICN_BCH]; /* Byte-counters/Flags for sent-ACK */
- struct sk_buff *xskb[ICN_BCH]; /* Current transmitted skb */
- struct sk_buff_head spqueue[ICN_BCH]; /* Sendqueue */
- char regname[35]; /* Name used for request_region */
- u_char xmit_lock[ICN_BCH]; /* Semaphore for pollbchan_send()*/
- spinlock_t lock; /* protect critical operations */
-} icn_card;
-
-/*
- * Main driver data
- */
-typedef struct icn_dev {
- spinlock_t devlock; /* spinlock to protect this struct */
- unsigned long memaddr; /* Address of memory mapped buffers */
- icn_shmem __iomem *shmem; /* Pointer to memory-mapped-buffers */
- int mvalid; /* IO-shmem has been requested */
- int channel; /* Currently mapped channel */
- struct icn_card *mcard; /* Currently mapped card */
- int chanlock; /* Semaphore for channel-mapping */
- int firstload; /* Flag: firmware never loaded */
-} icn_dev;
-
-typedef icn_dev *icn_devptr;
-
-#ifdef __KERNEL__
-
-static icn_card *cards = (icn_card *) 0;
-static u_char chan2bank[] = {0, 4, 8, 12}; /* for icn_map_channel() */
-
-static icn_dev dev;
-
-#endif /* __KERNEL__ */
-
-/* Utility-Macros */
-
-/* Macros for accessing ports */
-#define ICN_CFG (card->port)
-#define ICN_MAPRAM (card->port + 1)
-#define ICN_RUN (card->port + 2)
-#define ICN_BANK (card->port + 3)
-
-/* Return true, if there is a free transmit-buffer */
-#define sbfree (((readb(&dev.shmem->data_control.scns) + 1) & 0xf) != \
- readb(&dev.shmem->data_control.scnr))
-
-/* Switch to next transmit-buffer */
-#define sbnext (writeb((readb(&dev.shmem->data_control.scns) + 1) & 0xf, \
- &dev.shmem->data_control.scns))
-
-/* Shortcuts for transmit-buffer-access */
-#define sbuf_n dev.shmem->data_control.scns
-#define sbuf_d dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].data
-#define sbuf_l dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].length
-#define sbuf_f dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].endflag
-
-/* Return true, if there is receive-data is available */
-#define rbavl (readb(&dev.shmem->data_control.ecnr) != \
- readb(&dev.shmem->data_control.ecns))
-
-/* Switch to next receive-buffer */
-#define rbnext (writeb((readb(&dev.shmem->data_control.ecnr) + 1) & 0xf, \
- &dev.shmem->data_control.ecnr))
-
-/* Shortcuts for receive-buffer-access */
-#define rbuf_n dev.shmem->data_control.ecnr
-#define rbuf_d dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].data
-#define rbuf_l dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].length
-#define rbuf_f dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].endflag
-
-/* Shortcuts for command-buffer-access */
-#define cmd_o (dev.shmem->comm_control.pcio_o)
-#define cmd_i (dev.shmem->comm_control.pcio_i)
-
-/* Return free space in command-buffer */
-#define cmd_free ((readb(&cmd_i) >= readb(&cmd_o)) ? \
- 0x100 - readb(&cmd_i) + readb(&cmd_o) : \
- readb(&cmd_o) - readb(&cmd_i))
-
-/* Shortcuts for message-buffer-access */
-#define msg_o (dev.shmem->comm_control.iopc_o)
-#define msg_i (dev.shmem->comm_control.iopc_i)
-
-/* Return length of Message, if avail. */
-#define msg_avail ((readb(&msg_o) > readb(&msg_i)) ? \
- 0x100 - readb(&msg_o) + readb(&msg_i) : \
- readb(&msg_i) - readb(&msg_o))
-
-#define CID (card->interface.id)
-
-#endif /* defined(__KERNEL__) || defined(__DEBUGVAR__) */
-#endif /* icn_h */
diff --git a/drivers/staging/i4l/pcbit/Kconfig b/drivers/staging/i4l/pcbit/Kconfig
deleted file mode 100644
index e9b2dd85d410..000000000000
--- a/drivers/staging/i4l/pcbit/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config ISDN_DRV_PCBIT
- tristate "PCBIT-D support"
- depends on ISA && (BROKEN || X86)
- help
- This enables support for the PCBIT ISDN-card. This card is
- manufactured in Portugal by Octal. For running this card,
- additional firmware is necessary, which has to be downloaded into
- the card using a utility which is distributed separately. See
- <file:Documentation/isdn/README> and
- <file:Documentation/isdn/README.pcbit> for more information.
diff --git a/drivers/staging/i4l/pcbit/Makefile b/drivers/staging/i4l/pcbit/Makefile
deleted file mode 100644
index 2d026c3242e8..000000000000
--- a/drivers/staging/i4l/pcbit/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Makefile for the pcbit ISDN device driver
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_ISDN_DRV_PCBIT) += pcbit.o
-
-# Multipart objects.
-
-pcbit-y := module.o edss1.o drv.o layer2.o capi.o callbacks.o
diff --git a/drivers/staging/i4l/pcbit/callbacks.c b/drivers/staging/i4l/pcbit/callbacks.c
deleted file mode 100644
index 212ab0b229d4..000000000000
--- a/drivers/staging/i4l/pcbit/callbacks.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Callbacks for the FSM
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-/*
- * Fix: 19981230 - Carlos Morgado <chbm@techie.com>
- * Port of Nelson Escravana's <nelson.escravana@usa.net> fix to CalledPN
- * NULL pointer dereference in cb_in_1 (originally fixed in 2.0)
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/skbuff.h>
-
-#include <linux/io.h>
-
-#include <linux/isdnif.h>
-
-#include "pcbit.h"
-#include "layer2.h"
-#include "edss1.h"
-#include "callbacks.h"
-#include "capi.h"
-
-ushort last_ref_num = 1;
-
-/*
- * send_conn_req
- *
- */
-
-void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *cbdata)
-{
- struct sk_buff *skb;
- int len;
- ushort refnum;
-
-
-#ifdef DEBUG
- printk(KERN_DEBUG "Called Party Number: %s\n",
- cbdata->data.setup.CalledPN);
-#endif
- /*
- * hdr - kmalloc in capi_conn_req
- * - kfree when msg has been sent
- */
-
- if ((len = capi_conn_req(cbdata->data.setup.CalledPN, &skb,
- chan->proto)) < 0)
- {
- printk("capi_conn_req failed\n");
- return;
- }
-
-
- refnum = last_ref_num++ & 0x7fffU;
-
- chan->callref = 0;
- chan->layer2link = 0;
- chan->snum = 0;
- chan->s_refnum = refnum;
-
- pcbit_l2_write(dev, MSG_CONN_REQ, refnum, skb, len);
-}
-
-/*
- * rcv CONNECT
- * will go into ACTIVE state
- * send CONN_ACTIVE_RESP
- * send Select protocol request
- */
-
-void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data)
-{
- isdn_ctrl ictl;
- struct sk_buff *skb;
- int len;
- ushort refnum;
-
- if ((len = capi_conn_active_resp(chan, &skb)) < 0)
- {
- printk("capi_conn_active_req failed\n");
- return;
- }
-
- refnum = last_ref_num++ & 0x7fffU;
- chan->s_refnum = refnum;
-
- pcbit_l2_write(dev, MSG_CONN_ACTV_RESP, refnum, skb, len);
-
-
- ictl.command = ISDN_STAT_DCONN;
- ictl.driver = dev->id;
- ictl.arg = chan->id;
- dev->dev_if->statcallb(&ictl);
-
- /* ACTIVE D-channel */
-
- /* Select protocol */
-
- if ((len = capi_select_proto_req(chan, &skb, 1 /*outgoing*/)) < 0) {
- printk("capi_select_proto_req failed\n");
- return;
- }
-
- refnum = last_ref_num++ & 0x7fffU;
- chan->s_refnum = refnum;
-
- pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
-}
-
-
-/*
- * Incoming call received
- * inform user
- */
-
-void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *cbdata)
-{
- isdn_ctrl ictl;
- unsigned short refnum;
- struct sk_buff *skb;
- int len;
-
-
- ictl.command = ISDN_STAT_ICALL;
- ictl.driver = dev->id;
- ictl.arg = chan->id;
-
- /*
- * ictl.num >= strlen() + strlen() + 5
- */
-
- if (cbdata->data.setup.CallingPN == NULL) {
- printk(KERN_DEBUG "NULL CallingPN to phone; using 0\n");
- strcpy(ictl.parm.setup.phone, "0");
- }
- else {
- strcpy(ictl.parm.setup.phone, cbdata->data.setup.CallingPN);
- }
- if (cbdata->data.setup.CalledPN == NULL) {
- printk(KERN_DEBUG "NULL CalledPN to eazmsn; using 0\n");
- strcpy(ictl.parm.setup.eazmsn, "0");
- }
- else {
- strcpy(ictl.parm.setup.eazmsn, cbdata->data.setup.CalledPN);
- }
- ictl.parm.setup.si1 = 7;
- ictl.parm.setup.si2 = 0;
- ictl.parm.setup.plan = 0;
- ictl.parm.setup.screen = 0;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "statstr: %s\n", ictl.num);
-#endif
-
- dev->dev_if->statcallb(&ictl);
-
-
- if ((len = capi_conn_resp(chan, &skb)) < 0) {
- printk(KERN_DEBUG "capi_conn_resp failed\n");
- return;
- }
-
- refnum = last_ref_num++ & 0x7fffU;
- chan->s_refnum = refnum;
-
- pcbit_l2_write(dev, MSG_CONN_RESP, refnum, skb, len);
-}
-
-/*
- * user has replied
- * open the channel
- * send CONNECT message CONNECT_ACTIVE_REQ in CAPI
- */
-
-void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data)
-{
- unsigned short refnum;
- struct sk_buff *skb;
- int len;
-
- if ((len = capi_conn_active_req(chan, &skb)) < 0) {
- printk(KERN_DEBUG "capi_conn_active_req failed\n");
- return;
- }
-
-
- refnum = last_ref_num++ & 0x7fffU;
- chan->s_refnum = refnum;
-
- printk(KERN_DEBUG "sending MSG_CONN_ACTV_REQ\n");
- pcbit_l2_write(dev, MSG_CONN_ACTV_REQ, refnum, skb, len);
-}
-
-/*
- * CONN_ACK arrived
- * start b-proto selection
- *
- */
-
-void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data)
-{
- unsigned short refnum;
- struct sk_buff *skb;
- int len;
-
- if ((len = capi_select_proto_req(chan, &skb, 0 /*incoming*/)) < 0)
- {
- printk("capi_select_proto_req failed\n");
- return;
- }
-
- refnum = last_ref_num++ & 0x7fffU;
- chan->s_refnum = refnum;
-
- pcbit_l2_write(dev, MSG_SELP_REQ, refnum, skb, len);
-
-}
-
-
-/*
- * Received disconnect ind on active state
- * send disconnect resp
- * send msg to user
- */
-void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data)
-{
- struct sk_buff *skb;
- int len;
- ushort refnum;
- isdn_ctrl ictl;
-
- if ((len = capi_disc_resp(chan, &skb)) < 0) {
- printk("capi_disc_resp failed\n");
- return;
- }
-
- refnum = last_ref_num++ & 0x7fffU;
- chan->s_refnum = refnum;
-
- pcbit_l2_write(dev, MSG_DISC_RESP, refnum, skb, len);
-
- ictl.command = ISDN_STAT_BHUP;
- ictl.driver = dev->id;
- ictl.arg = chan->id;
- dev->dev_if->statcallb(&ictl);
-}
-
-
-/*
- * User HANGUP on active/call proceeding state
- * send disc.req
- */
-void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data)
-{
- struct sk_buff *skb;
- int len;
- ushort refnum;
-
- if ((len = capi_disc_req(chan->callref, &skb, CAUSE_NORMAL)) < 0)
- {
- printk("capi_disc_req failed\n");
- return;
- }
-
- refnum = last_ref_num++ & 0x7fffU;
- chan->s_refnum = refnum;
-
- pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb, len);
-}
-
-/*
- * Disc confirm received send BHUP
- * Problem: when the HL driver sends the disc req itself
- * LL receives BHUP
- */
-void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data)
-{
- isdn_ctrl ictl;
-
- ictl.command = ISDN_STAT_BHUP;
- ictl.driver = dev->id;
- ictl.arg = chan->id;
- dev->dev_if->statcallb(&ictl);
-}
-
-void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data)
-{
-}
-
-/*
- * send activate b-chan protocol
- */
-void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data)
-{
- struct sk_buff *skb;
- int len;
- ushort refnum;
-
- if ((len = capi_activate_transp_req(chan, &skb)) < 0)
- {
- printk("capi_conn_activate_transp_req failed\n");
- return;
- }
-
- refnum = last_ref_num++ & 0x7fffU;
- chan->s_refnum = refnum;
-
- pcbit_l2_write(dev, MSG_ACT_TRANSP_REQ, refnum, skb, len);
-}
-
-/*
- * Inform User that the B-channel is available
- */
-void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data)
-{
- isdn_ctrl ictl;
-
- ictl.command = ISDN_STAT_BCONN;
- ictl.driver = dev->id;
- ictl.arg = chan->id;
- dev->dev_if->statcallb(&ictl);
-}
diff --git a/drivers/staging/i4l/pcbit/callbacks.h b/drivers/staging/i4l/pcbit/callbacks.h
deleted file mode 100644
index a036b4a7ffad..000000000000
--- a/drivers/staging/i4l/pcbit/callbacks.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Callbacks prototypes for FSM
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-#ifndef CALLBACKS_H
-#define CALLBACKS_H
-
-
-extern void cb_out_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-
-extern void cb_out_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-
-extern void cb_in_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-extern void cb_in_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-extern void cb_in_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-
-extern void cb_disc_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-extern void cb_disc_2(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-extern void cb_disc_3(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-
-extern void cb_notdone(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-
-extern void cb_selp_1(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-extern void cb_open(struct pcbit_dev *dev, struct pcbit_chan *chan,
- struct callb_data *data);
-
-#endif
diff --git a/drivers/staging/i4l/pcbit/capi.c b/drivers/staging/i4l/pcbit/capi.c
deleted file mode 100644
index a6c4e00dc726..000000000000
--- a/drivers/staging/i4l/pcbit/capi.c
+++ /dev/null
@@ -1,646 +0,0 @@
-/*
- * CAPI encoder/decoder for
- * Portugal Telecom CAPI 2.0
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- *
- * Not compatible with the AVM Gmbh. CAPI 2.0
- *
- */
-
-/*
- * Documentation:
- * - "Common ISDN API - Perfil Português - Versão 2.1",
- * Telecom Portugal, Fev 1992.
- * - "Common ISDN API - Especificação de protocolos para
- * acesso aos canais B", Inesc, Jan 1994.
- */
-
-/*
- * TODO: better decoding of Information Elements
- * for debug purposes mainly
- * encode our number in CallerPN and ConnectedPN
- */
-
-#include <linux/kernel.h>
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-
-#include <linux/skbuff.h>
-
-#include <linux/io.h>
-#include <linux/string.h>
-
-#include <linux/isdnif.h>
-
-#include "pcbit.h"
-#include "edss1.h"
-#include "capi.h"
-
-
-/*
- * Encoding of CAPI messages
- *
- */
-
-int capi_conn_req(const char *calledPN, struct sk_buff **skb, int proto)
-{
- ushort len;
-
- /*
- * length
- * AppInfoMask - 2
- * BC0 - 3
- * BC1 - 1
- * Chan - 2
- * Keypad - 1
- * CPN - 1
- * CPSA - 1
- * CalledPN - 2 + strlen
- * CalledPSA - 1
- * rest... - 4
- * ----------------
- * Total 18 + strlen
- */
-
- len = 18 + strlen(calledPN);
-
- if (proto == ISDN_PROTO_L2_TRANS)
- len++;
-
- if ((*skb = dev_alloc_skb(len)) == NULL) {
-
- printk(KERN_WARNING "capi_conn_req: alloc_skb failed\n");
- return -1;
- }
-
- /* InfoElmMask */
- *((ushort *)skb_put(*skb, 2)) = AppInfoMask;
-
- if (proto == ISDN_PROTO_L2_TRANS)
- {
- /* Bearer Capability - Mandatory*/
- *(skb_put(*skb, 1)) = 3; /* BC0.Length */
- *(skb_put(*skb, 1)) = 0x80; /* Speech */
- *(skb_put(*skb, 1)) = 0x10; /* Circuit Mode */
- *(skb_put(*skb, 1)) = 0x23; /* A-law */
- } else {
- /* Bearer Capability - Mandatory*/
- *(skb_put(*skb, 1)) = 2; /* BC0.Length */
- *(skb_put(*skb, 1)) = 0x88; /* Digital Information */
- *(skb_put(*skb, 1)) = 0x90; /* BC0.Octect4 */
- }
-
- /* Bearer Capability - Optional*/
- *(skb_put(*skb, 1)) = 0; /* BC1.Length = 0 */
-
- *(skb_put(*skb, 1)) = 1; /* ChannelID.Length = 1 */
- *(skb_put(*skb, 1)) = 0x83; /* Basic Interface - Any Channel */
-
- *(skb_put(*skb, 1)) = 0; /* Keypad.Length = 0 */
-
-
- *(skb_put(*skb, 1)) = 0; /* CallingPN.Length = 0 */
- *(skb_put(*skb, 1)) = 0; /* CallingPSA.Length = 0 */
-
- /* Called Party Number */
- *(skb_put(*skb, 1)) = strlen(calledPN) + 1;
- *(skb_put(*skb, 1)) = 0x81;
- memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN));
-
- /* '#' */
-
- *(skb_put(*skb, 1)) = 0; /* CalledPSA.Length = 0 */
-
- /* LLC.Length = 0; */
- /* HLC0.Length = 0; */
- /* HLC1.Length = 0; */
- /* UTUS.Length = 0; */
- memset(skb_put(*skb, 4), 0, 4);
-
- return len;
-}
-
-int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb)
-{
-
- if ((*skb = dev_alloc_skb(5)) == NULL) {
-
- printk(KERN_WARNING "capi_conn_resp: alloc_skb failed\n");
- return -1;
- }
-
- *((ushort *)skb_put(*skb, 2)) = chan->callref;
- *(skb_put(*skb, 1)) = 0x01; /* ACCEPT_CALL */
- *(skb_put(*skb, 1)) = 0;
- *(skb_put(*skb, 1)) = 0;
-
- return 5;
-}
-
-int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb)
-{
- /*
- * 8 bytes
- */
-
- if ((*skb = dev_alloc_skb(8)) == NULL) {
-
- printk(KERN_WARNING "capi_conn_active_req: alloc_skb failed\n");
- return -1;
- }
-
- *((ushort *)skb_put(*skb, 2)) = chan->callref;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
-#endif
-
- *(skb_put(*skb, 1)) = 0; /* BC.Length = 0; */
- *(skb_put(*skb, 1)) = 0; /* ConnectedPN.Length = 0 */
- *(skb_put(*skb, 1)) = 0; /* PSA.Length */
- *(skb_put(*skb, 1)) = 0; /* LLC.Length = 0; */
- *(skb_put(*skb, 1)) = 0; /* HLC.Length = 0; */
- *(skb_put(*skb, 1)) = 0; /* UTUS.Length = 0; */
-
- return 8;
-}
-
-int capi_conn_active_resp(struct pcbit_chan *chan, struct sk_buff **skb)
-{
- /*
- * 2 bytes
- */
-
- if ((*skb = dev_alloc_skb(2)) == NULL) {
-
- printk(KERN_WARNING "capi_conn_active_resp: alloc_skb failed\n");
- return -1;
- }
-
- *((ushort *)skb_put(*skb, 2)) = chan->callref;
-
- return 2;
-}
-
-
-int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb,
- int outgoing)
-{
-
- /*
- * 18 bytes
- */
-
- if ((*skb = dev_alloc_skb(18)) == NULL) {
-
- printk(KERN_WARNING "capi_select_proto_req: alloc_skb failed\n");
- return -1;
- }
-
- *((ushort *)skb_put(*skb, 2)) = chan->callref;
-
- /* Layer2 protocol */
-
- switch (chan->proto) {
- case ISDN_PROTO_L2_X75I:
- *(skb_put(*skb, 1)) = 0x05; /* LAPB */
- break;
- case ISDN_PROTO_L2_HDLC:
- *(skb_put(*skb, 1)) = 0x02;
- break;
- case ISDN_PROTO_L2_TRANS:
- /*
- * Voice (a-law)
- */
- *(skb_put(*skb, 1)) = 0x06;
- break;
- default:
-#ifdef DEBUG
- printk(KERN_DEBUG "Transparent\n");
-#endif
- *(skb_put(*skb, 1)) = 0x03;
- break;
- }
-
- *(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42); /* Don't ask */
- *(skb_put(*skb, 1)) = 0x00;
-
- *((ushort *) skb_put(*skb, 2)) = MRU;
-
-
- *(skb_put(*skb, 1)) = 0x08; /* Modulo */
- *(skb_put(*skb, 1)) = 0x07; /* Max Window */
-
- *(skb_put(*skb, 1)) = 0x01; /* No Layer3 Protocol */
-
- /*
- * 2 - layer3 MTU [10]
- * - Modulo [12]
- * - Window
- * - layer1 proto [14]
- * - bitrate
- * - sub-channel [16]
- * - layer1dataformat [17]
- */
-
- memset(skb_put(*skb, 8), 0, 8);
-
- return 18;
-}
-
-
-int capi_activate_transp_req(struct pcbit_chan *chan, struct sk_buff **skb)
-{
-
- if ((*skb = dev_alloc_skb(7)) == NULL) {
-
- printk(KERN_WARNING "capi_activate_transp_req: alloc_skb failed\n");
- return -1;
- }
-
- *((ushort *)skb_put(*skb, 2)) = chan->callref;
-
-
- *(skb_put(*skb, 1)) = chan->layer2link; /* Layer2 id */
- *(skb_put(*skb, 1)) = 0x00; /* Transmit by default */
-
- *((ushort *) skb_put(*skb, 2)) = MRU;
-
- *(skb_put(*skb, 1)) = 0x01; /* Enables reception*/
-
- return 7;
-}
-
-int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb)
-{
- ushort data_len;
-
-
- /*
- * callref - 2
- * layer2link - 1
- * wBlockLength - 2
- * data - 4
- * sernum - 1
- */
-
- data_len = skb->len;
-
- if (skb_headroom(skb) < 10)
- {
- printk(KERN_CRIT "No headspace (%u) on headroom %p for capi header\n", skb_headroom(skb), skb);
- }
- else
- {
- skb_push(skb, 10);
- }
-
- *((u16 *) (skb->data)) = chan->callref;
- skb->data[2] = chan->layer2link;
- *((u16 *) (skb->data + 3)) = data_len;
-
- chan->s_refnum = (chan->s_refnum + 1) % 8;
- *((u32 *) (skb->data + 5)) = chan->s_refnum;
-
- skb->data[9] = 0; /* HDLC frame number */
-
- return 10;
-}
-
-int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb)
-
-{
- if ((*skb = dev_alloc_skb(4)) == NULL) {
-
- printk(KERN_WARNING "capi_tdata_resp: alloc_skb failed\n");
- return -1;
- }
-
- *((ushort *)skb_put(*skb, 2)) = chan->callref;
-
- *(skb_put(*skb, 1)) = chan->layer2link;
- *(skb_put(*skb, 1)) = chan->r_refnum;
-
- return (*skb)->len;
-}
-
-int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause)
-{
-
- if ((*skb = dev_alloc_skb(6)) == NULL) {
-
- printk(KERN_WARNING "capi_disc_req: alloc_skb failed\n");
- return -1;
- }
-
- *((ushort *)skb_put(*skb, 2)) = callref;
-
- *(skb_put(*skb, 1)) = 2; /* Cause.Length = 2; */
- *(skb_put(*skb, 1)) = 0x80;
- *(skb_put(*skb, 1)) = 0x80 | cause;
-
- /*
- * Change it: we should send 'Sic transit gloria Mundi' here ;-)
- */
-
- *(skb_put(*skb, 1)) = 0; /* UTUS.Length = 0; */
-
- return 6;
-}
-
-int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb)
-{
- if ((*skb = dev_alloc_skb(2)) == NULL) {
-
- printk(KERN_WARNING "capi_disc_resp: alloc_skb failed\n");
- return -1;
- }
-
- *((ushort *)skb_put(*skb, 2)) = chan->callref;
-
- return 2;
-}
-
-
-/*
- * Decoding of CAPI messages
- *
- */
-
-int capi_decode_conn_ind(struct pcbit_chan *chan,
- struct sk_buff *skb,
- struct callb_data *info)
-{
- int CIlen, len;
-
- /* Call Reference [CAPI] */
- chan->callref = *((ushort *)skb->data);
- skb_pull(skb, 2);
-
-#ifdef DEBUG
- printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
-#endif
-
- /* Channel Identification */
-
- /* Expect
- Len = 1
- Octect 3 = 0100 10CC - [ 7 Basic, 4 , 2-1 chan ]
- */
-
- CIlen = skb->data[0];
-#ifdef DEBUG
- if (CIlen == 1) {
-
- if (((skb->data[1]) & 0xFC) == 0x48)
- printk(KERN_DEBUG "decode_conn_ind: chan ok\n");
- printk(KERN_DEBUG "phyChan = %d\n", skb->data[1] & 0x03);
- }
- else
- printk(KERN_DEBUG "conn_ind: CIlen = %d\n", CIlen);
-#endif
- skb_pull(skb, CIlen + 1);
-
- /* Calling Party Number */
- /* An "additional service" as far as Portugal Telecom is concerned */
-
- len = skb->data[0];
-
- if (len > 0) {
- int count = 1;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "CPN: Octect 3 %02x\n", skb->data[1]);
-#endif
- if ((skb->data[1] & 0x80) == 0)
- count = 2;
-
- if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC)))
- return -1;
-
- skb_copy_from_linear_data_offset(skb, count + 1,
- info->data.setup.CallingPN,
- len - count);
- info->data.setup.CallingPN[len - count] = 0;
-
- }
- else {
- info->data.setup.CallingPN = NULL;
- printk(KERN_DEBUG "NULL CallingPN\n");
- }
-
- skb_pull(skb, len + 1);
-
- /* Calling Party Subaddress */
- skb_pull(skb, skb->data[0] + 1);
-
- /* Called Party Number */
-
- len = skb->data[0];
-
- if (len > 0) {
- int count = 1;
-
- if ((skb->data[1] & 0x80) == 0)
- count = 2;
-
- if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC)))
- return -1;
-
- skb_copy_from_linear_data_offset(skb, count + 1,
- info->data.setup.CalledPN,
- len - count);
- info->data.setup.CalledPN[len - count] = 0;
-
- }
- else {
- info->data.setup.CalledPN = NULL;
- printk(KERN_DEBUG "NULL CalledPN\n");
- }
-
- skb_pull(skb, len + 1);
-
- /* Called Party Subaddress */
- skb_pull(skb, skb->data[0] + 1);
-
- /* LLC */
- skb_pull(skb, skb->data[0] + 1);
-
- /* HLC */
- skb_pull(skb, skb->data[0] + 1);
-
- /* U2U */
- skb_pull(skb, skb->data[0] + 1);
-
- return 0;
-}
-
-/*
- * returns errcode
- */
-
-int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb,
- int *complete)
-{
- int errcode;
-
- chan->callref = *((ushort *)skb->data); /* Update CallReference */
- skb_pull(skb, 2);
-
- errcode = *((ushort *) skb->data); /* read errcode */
- skb_pull(skb, 2);
-
- *complete = *(skb->data);
- skb_pull(skb, 1);
-
- /* FIX ME */
- /* This is actually a firmware bug */
- if (!*complete)
- {
- printk(KERN_DEBUG "complete=%02x\n", *complete);
- *complete = 1;
- }
-
-
- /* Optional Bearer Capability */
- skb_pull(skb, *(skb->data) + 1);
-
- /* Channel Identification */
- skb_pull(skb, *(skb->data) + 1);
-
- /* High Layer Compatibility follows */
- skb_pull(skb, *(skb->data) + 1);
-
- return errcode;
-}
-
-int capi_decode_conn_actv_ind(struct pcbit_chan *chan, struct sk_buff *skb)
-{
- ushort len;
-#ifdef DEBUG
- char str[32];
-#endif
-
- /* Yet Another Bearer Capability */
- skb_pull(skb, *(skb->data) + 1);
-
-
- /* Connected Party Number */
- len = *(skb->data);
-
-#ifdef DEBUG
- if (len > 1 && len < 31) {
- skb_copy_from_linear_data_offset(skb, 2, str, len - 1);
- str[len] = 0;
- printk(KERN_DEBUG "Connected Party Number: %s\n", str);
- }
- else
- printk(KERN_DEBUG "actv_ind CPN len = %d\n", len);
-#endif
-
- skb_pull(skb, len + 1);
-
- /* Connected Subaddress */
- skb_pull(skb, *(skb->data) + 1);
-
- /* Low Layer Capability */
- skb_pull(skb, *(skb->data) + 1);
-
- /* High Layer Capability */
- skb_pull(skb, *(skb->data) + 1);
-
- return 0;
-}
-
-int capi_decode_conn_actv_conf(struct pcbit_chan *chan, struct sk_buff *skb)
-{
- ushort errcode;
-
- errcode = *((ushort *)skb->data);
- skb_pull(skb, 2);
-
- /* Channel Identification
- skb_pull(skb, skb->data[0] + 1);
- */
- return errcode;
-}
-
-
-int capi_decode_sel_proto_conf(struct pcbit_chan *chan, struct sk_buff *skb)
-{
- ushort errcode;
-
- chan->layer2link = *(skb->data);
- skb_pull(skb, 1);
-
- errcode = *((ushort *)skb->data);
- skb_pull(skb, 2);
-
- return errcode;
-}
-
-int capi_decode_actv_trans_conf(struct pcbit_chan *chan, struct sk_buff *skb)
-{
- ushort errcode;
-
- if (chan->layer2link != *(skb->data))
- printk("capi_decode_actv_trans_conf: layer2link doesn't match\n");
-
- skb_pull(skb, 1);
-
- errcode = *((ushort *)skb->data);
- skb_pull(skb, 2);
-
- return errcode;
-}
-
-int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb)
-{
- ushort len;
-#ifdef DEBUG
- int i;
-#endif
- /* Cause */
-
- len = *(skb->data);
- skb_pull(skb, 1);
-
-#ifdef DEBUG
-
- for (i = 0; i < len; i++)
- printk(KERN_DEBUG "Cause Octect %d: %02x\n", i + 3,
- *(skb->data + i));
-#endif
-
- skb_pull(skb, len);
-
- return 0;
-}
-
-#ifdef DEBUG
-int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
-{
- char str[64];
- int len;
-
- len = hdr[0];
-
- if (len < 64 && len == hdrlen - 1) {
- memcpy(str, hdr + 1, hdrlen - 1);
- str[hdrlen - 1] = 0;
- printk("%s\n", str);
- }
- else
- printk("debug message incorrect\n");
-
- return 0;
-}
-#endif
diff --git a/drivers/staging/i4l/pcbit/capi.h b/drivers/staging/i4l/pcbit/capi.h
deleted file mode 100644
index 6f6f4dd0714e..000000000000
--- a/drivers/staging/i4l/pcbit/capi.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * CAPI encode/decode prototypes and defines
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-#ifndef CAPI_H
-#define CAPI_H
-
-
-#define REQ_CAUSE 0x01
-#define REQ_DISPLAY 0x04
-#define REQ_USER_TO_USER 0x08
-
-#define AppInfoMask (REQ_CAUSE | REQ_DISPLAY | REQ_USER_TO_USER)
-
-/* Connection Setup */
-extern int capi_conn_req(const char *calledPN, struct sk_buff **buf,
- int proto);
-extern int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb,
- int *complete);
-
-extern int capi_decode_conn_ind(struct pcbit_chan *chan, struct sk_buff *skb,
- struct callb_data *info);
-extern int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb);
-
-extern int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb);
-extern int capi_decode_conn_actv_conf(struct pcbit_chan *chan,
- struct sk_buff *skb);
-
-extern int capi_decode_conn_actv_ind(struct pcbit_chan *chan,
- struct sk_buff *skb);
-extern int capi_conn_active_resp(struct pcbit_chan *chan,
- struct sk_buff **skb);
-
-/* Data */
-extern int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb,
- int outgoing);
-extern int capi_decode_sel_proto_conf(struct pcbit_chan *chan,
- struct sk_buff *skb);
-
-extern int capi_activate_transp_req(struct pcbit_chan *chan,
- struct sk_buff **skb);
-extern int capi_decode_actv_trans_conf(struct pcbit_chan *chan,
- struct sk_buff *skb);
-
-extern int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb);
-extern int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb);
-
-/* Connection Termination */
-extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause);
-
-extern int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb);
-extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb);
-
-#ifdef DEBUG
-extern int capi_decode_debug_188(u_char *hdr, ushort hdrlen);
-#endif
-
-static inline struct pcbit_chan *
-capi_channel(struct pcbit_dev *dev, struct sk_buff *skb)
-{
- ushort callref;
-
- callref = *((ushort *)skb->data);
- skb_pull(skb, 2);
-
- if (dev->b1->callref == callref)
- return dev->b1;
- else if (dev->b2->callref == callref)
- return dev->b2;
-
- return NULL;
-}
-
-#endif
diff --git a/drivers/staging/i4l/pcbit/drv.c b/drivers/staging/i4l/pcbit/drv.c
deleted file mode 100644
index 89b0b5b94ce5..000000000000
--- a/drivers/staging/i4l/pcbit/drv.c
+++ /dev/null
@@ -1,1070 +0,0 @@
-/*
- * PCBIT-D interface with isdn4linux
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-/*
- * Fixes:
- *
- * Nuno Grilo <l38486@alfa.ist.utl.pt>
- * fixed msn_list NULL pointer dereference.
- *
- */
-
-#include <linux/module.h>
-
-
-#include <linux/kernel.h>
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/skbuff.h>
-
-#include <linux/isdnif.h>
-#include <linux/string.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-
-#include "pcbit.h"
-#include "edss1.h"
-#include "layer2.h"
-#include "capi.h"
-
-
-extern ushort last_ref_num;
-
-static int pcbit_ioctl(isdn_ctrl *ctl);
-
-static char *pcbit_devname[MAX_PCBIT_CARDS] = {
- "pcbit0",
- "pcbit1",
- "pcbit2",
- "pcbit3"
-};
-
-/*
- * prototypes
- */
-
-static int pcbit_command(isdn_ctrl *ctl);
-static int pcbit_stat(u_char __user *buf, int len, int, int);
-static int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
-static int pcbit_writecmd(const u_char __user *, int, int, int);
-
-static int set_protocol_running(struct pcbit_dev *dev);
-
-static void pcbit_clear_msn(struct pcbit_dev *dev);
-static void pcbit_set_msn(struct pcbit_dev *dev, char *list);
-static int pcbit_check_msn(struct pcbit_dev *dev, char *msn);
-
-
-int pcbit_init_dev(int board, int mem_base, int irq)
-{
- struct pcbit_dev *dev;
- isdn_if *dev_if;
-
- if ((dev = kzalloc(sizeof(struct pcbit_dev), GFP_KERNEL)) == NULL)
- {
- printk("pcbit_init: couldn't malloc pcbit_dev struct\n");
- return -ENOMEM;
- }
-
- dev_pcbit[board] = dev;
- init_waitqueue_head(&dev->set_running_wq);
- spin_lock_init(&dev->lock);
-
- if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF) {
- dev->ph_mem = mem_base;
- if (!request_mem_region(dev->ph_mem, 4096, "PCBIT mem")) {
- printk(KERN_WARNING
- "PCBIT: memory region %lx-%lx already in use\n",
- dev->ph_mem, dev->ph_mem + 4096);
- kfree(dev);
- dev_pcbit[board] = NULL;
- return -EACCES;
- }
- dev->sh_mem = ioremap(dev->ph_mem, 4096);
- }
- else
- {
- printk("memory address invalid");
- kfree(dev);
- dev_pcbit[board] = NULL;
- return -EACCES;
- }
-
- dev->b1 = kzalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
- if (!dev->b1) {
- printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
- iounmap(dev->sh_mem);
- release_mem_region(dev->ph_mem, 4096);
- kfree(dev);
- return -ENOMEM;
- }
-
- dev->b2 = kzalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
- if (!dev->b2) {
- printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
- kfree(dev->b1);
- iounmap(dev->sh_mem);
- release_mem_region(dev->ph_mem, 4096);
- kfree(dev);
- return -ENOMEM;
- }
-
- dev->b2->id = 1;
-
- INIT_WORK(&dev->qdelivery, pcbit_deliver);
-
- /*
- * interrupts
- */
-
- if (request_irq(irq, &pcbit_irq_handler, 0, pcbit_devname[board], dev) != 0)
- {
- kfree(dev->b1);
- kfree(dev->b2);
- iounmap(dev->sh_mem);
- release_mem_region(dev->ph_mem, 4096);
- kfree(dev);
- dev_pcbit[board] = NULL;
- return -EIO;
- }
-
- dev->irq = irq;
-
- /* next frame to be received */
- dev->rcv_seq = 0;
- dev->send_seq = 0;
- dev->unack_seq = 0;
-
- dev->hl_hdrlen = 16;
-
- dev_if = kmalloc(sizeof(isdn_if), GFP_KERNEL);
-
- if (!dev_if) {
- free_irq(irq, dev);
- kfree(dev->b1);
- kfree(dev->b2);
- iounmap(dev->sh_mem);
- release_mem_region(dev->ph_mem, 4096);
- kfree(dev);
- dev_pcbit[board] = NULL;
- return -EIO;
- }
-
- dev->dev_if = dev_if;
-
- dev_if->owner = THIS_MODULE;
-
- dev_if->channels = 2;
-
- dev_if->features = (ISDN_FEATURE_P_EURO | ISDN_FEATURE_L3_TRANS |
- ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L2_TRANS);
-
- dev_if->writebuf_skb = pcbit_xmit;
- dev_if->hl_hdrlen = 16;
-
- dev_if->maxbufsize = MAXBUFSIZE;
- dev_if->command = pcbit_command;
-
- dev_if->writecmd = pcbit_writecmd;
- dev_if->readstat = pcbit_stat;
-
-
- strcpy(dev_if->id, pcbit_devname[board]);
-
- if (!register_isdn(dev_if)) {
- free_irq(irq, dev);
- kfree(dev->b1);
- kfree(dev->b2);
- iounmap(dev->sh_mem);
- release_mem_region(dev->ph_mem, 4096);
- kfree(dev);
- dev_pcbit[board] = NULL;
- return -EIO;
- }
-
- dev->id = dev_if->channels;
-
-
- dev->l2_state = L2_DOWN;
- dev->free = 511;
-
- /*
- * set_protocol_running(dev);
- */
-
- return 0;
-}
-
-#ifdef MODULE
-void pcbit_terminate(int board)
-{
- struct pcbit_dev *dev;
-
- dev = dev_pcbit[board];
-
- if (dev) {
- /* unregister_isdn(dev->dev_if); */
- free_irq(dev->irq, dev);
- pcbit_clear_msn(dev);
- kfree(dev->dev_if);
- if (dev->b1->fsm_timer.function)
- del_timer(&dev->b1->fsm_timer);
- if (dev->b2->fsm_timer.function)
- del_timer(&dev->b2->fsm_timer);
- kfree(dev->b1);
- kfree(dev->b2);
- iounmap(dev->sh_mem);
- release_mem_region(dev->ph_mem, 4096);
- kfree(dev);
- }
-}
-#endif
-
-static int pcbit_command(isdn_ctrl *ctl)
-{
- struct pcbit_dev *dev;
- struct pcbit_chan *chan;
- struct callb_data info;
-
- dev = finddev(ctl->driver);
-
- if (!dev)
- {
- printk("pcbit_command: unknown device\n");
- return -1;
- }
-
- chan = (ctl->arg & 0x0F) ? dev->b2 : dev->b1;
-
-
- switch (ctl->command) {
- case ISDN_CMD_IOCTL:
- return pcbit_ioctl(ctl);
- break;
- case ISDN_CMD_DIAL:
- info.type = EV_USR_SETUP_REQ;
- info.data.setup.CalledPN = (char *) &ctl->parm.setup.phone;
- pcbit_fsm_event(dev, chan, EV_USR_SETUP_REQ, &info);
- break;
- case ISDN_CMD_ACCEPTD:
- pcbit_fsm_event(dev, chan, EV_USR_SETUP_RESP, NULL);
- break;
- case ISDN_CMD_ACCEPTB:
- printk("ISDN_CMD_ACCEPTB - not really needed\n");
- break;
- case ISDN_CMD_HANGUP:
- pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
- break;
- case ISDN_CMD_SETL2:
- chan->proto = (ctl->arg >> 8);
- break;
- case ISDN_CMD_CLREAZ:
- pcbit_clear_msn(dev);
- break;
- case ISDN_CMD_SETEAZ:
- pcbit_set_msn(dev, ctl->parm.num);
- break;
- case ISDN_CMD_SETL3:
- if ((ctl->arg >> 8) != ISDN_PROTO_L3_TRANS)
- printk(KERN_DEBUG "L3 protocol unknown\n");
- break;
- default:
- printk(KERN_DEBUG "pcbit_command: unknown command\n");
- break;
- }
-
- return 0;
-}
-
-/*
- * Another Hack :-(
- * on some conditions the board stops sending TDATA_CONFs
- * let's see if we can turn around the problem
- */
-
-#ifdef BLOCK_TIMER
-static void pcbit_block_timer(unsigned long data)
-{
- struct pcbit_chan *chan;
- struct pcbit_dev *dev;
- isdn_ctrl ictl;
-
- chan = (struct pcbit_chan *)data;
-
- dev = chan2dev(chan);
-
- if (dev == NULL) {
- printk(KERN_DEBUG "pcbit: chan2dev failed\n");
- return;
- }
-
- del_timer(&chan->block_timer);
- chan->block_timer.function = NULL;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "pcbit_block_timer\n");
-#endif
- chan->queued = 0;
- ictl.driver = dev->id;
- ictl.command = ISDN_STAT_BSENT;
- ictl.arg = chan->id;
- dev->dev_if->statcallb(&ictl);
-}
-#endif
-
-static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
-{
- ushort hdrlen;
- int refnum, len;
- struct pcbit_chan *chan;
- struct pcbit_dev *dev;
-
- dev = finddev(driver);
- if (dev == NULL)
- {
- printk("finddev returned NULL");
- return -1;
- }
-
- chan = chnum ? dev->b2 : dev->b1;
-
-
- if (chan->fsm_state != ST_ACTIVE)
- return -1;
-
- if (chan->queued >= MAX_QUEUED)
- {
-#ifdef DEBUG_QUEUE
- printk(KERN_DEBUG
- "pcbit: %d packets already in queue - write fails\n",
- chan->queued);
-#endif
- /*
- * packet stays on the head of the device queue
- * since dev_start_xmit will fail
- * see net/core/dev.c
- */
-#ifdef BLOCK_TIMER
- if (chan->block_timer.function == NULL) {
- setup_timer(&chan->block_timer, &pcbit_block_timer,
- (long)chan);
- mod_timer(&chan->block_timer, jiffies + 1 * HZ);
- }
-#endif
- return 0;
- }
-
-
- chan->queued++;
-
- len = skb->len;
-
- hdrlen = capi_tdata_req(chan, skb);
-
- refnum = last_ref_num++ & 0x7fffU;
- chan->s_refnum = refnum;
-
- pcbit_l2_write(dev, MSG_TDATA_REQ, refnum, skb, hdrlen);
-
- return len;
-}
-
-static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
-{
- struct pcbit_dev *dev;
- int i, j;
- const u_char *loadbuf;
- u_char *ptr = NULL;
- u_char *cbuf;
-
- int errstat;
-
- dev = finddev(driver);
-
- if (!dev)
- {
- printk("pcbit_writecmd: couldn't find device");
- return -ENODEV;
- }
-
- switch (dev->l2_state) {
- case L2_LWMODE:
- /* check (size <= rdp_size); write buf into board */
- if (len < 0 || len > BANK4 + 1 || len > 1024)
- {
- printk("pcbit_writecmd: invalid length %d\n", len);
- return -EINVAL;
- }
-
- cbuf = memdup_user(buf, len);
- if (IS_ERR(cbuf))
- return PTR_ERR(cbuf);
-
- memcpy_toio(dev->sh_mem, cbuf, len);
- kfree(cbuf);
- return len;
- case L2_FWMODE:
- /* this is the hard part */
- /* dumb board */
- /* get it into kernel space */
- if ((ptr = kmalloc(len, GFP_KERNEL)) == NULL)
- return -ENOMEM;
- if (copy_from_user(ptr, buf, len)) {
- kfree(ptr);
- return -EFAULT;
- }
- loadbuf = ptr;
-
- errstat = 0;
-
- for (i = 0; i < len; i++)
- {
- for (j = 0; j < LOAD_RETRY; j++)
- if (!(readb(dev->sh_mem + dev->loadptr)))
- break;
-
- if (j == LOAD_RETRY)
- {
- errstat = -ETIME;
- printk("TIMEOUT i=%d\n", i);
- break;
- }
- writeb(loadbuf[i], dev->sh_mem + dev->loadptr + 1);
- writeb(0x01, dev->sh_mem + dev->loadptr);
-
- dev->loadptr += 2;
- if (dev->loadptr > LOAD_ZONE_END)
- dev->loadptr = LOAD_ZONE_START;
- }
- kfree(ptr);
-
- return errstat ? errstat : len;
- default:
- return -EBUSY;
- }
-}
-
-/*
- * demultiplexing of messages
- *
- */
-
-void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg,
- struct sk_buff *skb,
- ushort hdr_len, ushort refnum)
-{
- struct pcbit_chan *chan;
- struct sk_buff *skb2;
- unsigned short len;
- struct callb_data cbdata;
- int complete, err;
- isdn_ctrl ictl;
-
- switch (msg) {
-
- case MSG_TDATA_IND:
- if (!(chan = capi_channel(dev, skb))) {
- printk(KERN_WARNING
- "CAPI header: unknown channel id\n");
- break;
- }
- chan->r_refnum = skb->data[7];
- skb_pull(skb, 8);
-
- dev->dev_if->rcvcallb_skb(dev->id, chan->id, skb);
-
- if (capi_tdata_resp(chan, &skb2) > 0)
- pcbit_l2_write(dev, MSG_TDATA_RESP, refnum,
- skb2, skb2->len);
- return;
- break;
- case MSG_TDATA_CONF:
- if (!(chan = capi_channel(dev, skb))) {
- printk(KERN_WARNING
- "CAPI header: unknown channel id\n");
- break;
- }
-
-#ifdef DEBUG
- if ((*((ushort *)(skb->data + 2))) != 0) {
- printk(KERN_DEBUG "TDATA_CONF error\n");
- }
-#endif
-#ifdef BLOCK_TIMER
- if (chan->queued == MAX_QUEUED) {
- del_timer(&chan->block_timer);
- chan->block_timer.function = NULL;
- }
-
-#endif
- chan->queued--;
-
- ictl.driver = dev->id;
- ictl.command = ISDN_STAT_BSENT;
- ictl.arg = chan->id;
- dev->dev_if->statcallb(&ictl);
- break;
-
- case MSG_CONN_IND:
- /*
- * channel: 1st not used will do
- * if both are used we're in trouble
- */
-
- if (!dev->b1->fsm_state)
- chan = dev->b1;
- else if (!dev->b2->fsm_state)
- chan = dev->b2;
- else {
- printk(KERN_INFO
- "Incoming connection: no channels available");
-
- if ((len = capi_disc_req(*(ushort *)(skb->data), &skb2, CAUSE_NOCHAN)) > 0)
- pcbit_l2_write(dev, MSG_DISC_REQ, refnum, skb2, len);
- break;
- }
-
- cbdata.data.setup.CalledPN = NULL;
- cbdata.data.setup.CallingPN = NULL;
-
- capi_decode_conn_ind(chan, skb, &cbdata);
- cbdata.type = EV_NET_SETUP;
-
- pcbit_fsm_event(dev, chan, EV_NET_SETUP, NULL);
-
- if (pcbit_check_msn(dev, cbdata.data.setup.CallingPN))
- pcbit_fsm_event(dev, chan, EV_USR_PROCED_REQ, &cbdata);
- else
- pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
-
- kfree(cbdata.data.setup.CalledPN);
- kfree(cbdata.data.setup.CallingPN);
- break;
-
- case MSG_CONN_CONF:
- /*
- * We should be able to find the channel by the message
- * reference number. The current version of the firmware
- * doesn't sent the ref number correctly.
- */
-#ifdef DEBUG
- printk(KERN_DEBUG "refnum=%04x b1=%04x b2=%04x\n", refnum,
- dev->b1->s_refnum,
- dev->b2->s_refnum);
-#endif
- /* We just try to find a channel in the right state */
-
- if (dev->b1->fsm_state == ST_CALL_INIT)
- chan = dev->b1;
- else {
- if (dev->b2->s_refnum == ST_CALL_INIT)
- chan = dev->b2;
- else {
- chan = NULL;
- printk(KERN_WARNING "Connection Confirm - no channel in Call Init state\n");
- break;
- }
- }
- if (capi_decode_conn_conf(chan, skb, &complete)) {
- printk(KERN_DEBUG "conn_conf indicates error\n");
- pcbit_fsm_event(dev, chan, EV_ERROR, NULL);
- }
- else
- if (complete)
- pcbit_fsm_event(dev, chan, EV_NET_CALL_PROC, NULL);
- else
- pcbit_fsm_event(dev, chan, EV_NET_SETUP_ACK, NULL);
- break;
- case MSG_CONN_ACTV_IND:
-
- if (!(chan = capi_channel(dev, skb))) {
- printk(KERN_WARNING
- "CAPI header: unknown channel id\n");
- break;
- }
-
- if (capi_decode_conn_actv_ind(chan, skb)) {
- printk("error in capi_decode_conn_actv_ind\n");
- /* pcbit_fsm_event(dev, chan, EV_ERROR, NULL); */
- break;
- }
- chan->r_refnum = refnum;
- pcbit_fsm_event(dev, chan, EV_NET_CONN, NULL);
- break;
- case MSG_CONN_ACTV_CONF:
-
- if (!(chan = capi_channel(dev, skb))) {
- printk(KERN_WARNING
- "CAPI header: unknown channel id\n");
- break;
- }
-
- if (capi_decode_conn_actv_conf(chan, skb) == 0)
- pcbit_fsm_event(dev, chan, EV_NET_CONN_ACK, NULL);
-
- else
- printk(KERN_DEBUG "decode_conn_actv_conf failed\n");
- break;
-
- case MSG_SELP_CONF:
-
- if (!(chan = capi_channel(dev, skb))) {
- printk(KERN_WARNING
- "CAPI header: unknown channel id\n");
- break;
- }
-
- if (!(err = capi_decode_sel_proto_conf(chan, skb)))
- pcbit_fsm_event(dev, chan, EV_NET_SELP_RESP, NULL);
- else {
- /* Error */
- printk("error %d - capi_decode_sel_proto_conf\n", err);
- }
- break;
- case MSG_ACT_TRANSP_CONF:
- if (!(chan = capi_channel(dev, skb))) {
- printk(KERN_WARNING
- "CAPI header: unknown channel id\n");
- break;
- }
-
- if (!capi_decode_actv_trans_conf(chan, skb))
- pcbit_fsm_event(dev, chan, EV_NET_ACTV_RESP, NULL);
- break;
-
- case MSG_DISC_IND:
-
- if (!(chan = capi_channel(dev, skb))) {
- printk(KERN_WARNING
- "CAPI header: unknown channel id\n");
- break;
- }
-
- if (!capi_decode_disc_ind(chan, skb))
- pcbit_fsm_event(dev, chan, EV_NET_DISC, NULL);
- else
- printk(KERN_WARNING "capi_decode_disc_ind - error\n");
- break;
- case MSG_DISC_CONF:
- if (!(chan = capi_channel(dev, skb))) {
- printk(KERN_WARNING
- "CAPI header: unknown channel id\n");
- break;
- }
-
- if (!capi_decode_disc_ind(chan, skb))
- pcbit_fsm_event(dev, chan, EV_NET_RELEASE, NULL);
- else
- printk(KERN_WARNING "capi_decode_disc_conf - error\n");
- break;
- case MSG_INFO_IND:
-#ifdef DEBUG
- printk(KERN_DEBUG "received Info Indication - discarded\n");
-#endif
- break;
-#ifdef DEBUG
- case MSG_DEBUG_188:
- capi_decode_debug_188(skb->data, skb->len);
- break;
-
- default:
- printk(KERN_DEBUG "pcbit_l3_receive: unknown message %08lx\n",
- msg);
- break;
-#endif
- }
-
- kfree_skb(skb);
-
-}
-
-/*
- * Single statbuf
- * should be a statbuf per device
- */
-
-static char statbuf[STATBUF_LEN];
-static int stat_st;
-static int stat_end;
-
-static int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
-{
- int stat_count;
- stat_count = stat_end - stat_st;
-
- if (stat_count < 0)
- stat_count = STATBUF_LEN - stat_st + stat_end;
-
- /* FIXME: should we sleep and wait for more cookies ? */
- if (len > stat_count)
- len = stat_count;
-
- if (stat_st < stat_end)
- {
- if (copy_to_user(buf, statbuf + stat_st, len))
- return -EFAULT;
- stat_st += len;
- }
- else
- {
- if (len > STATBUF_LEN - stat_st)
- {
- if (copy_to_user(buf, statbuf + stat_st,
- STATBUF_LEN - stat_st))
- return -EFAULT;
- if (copy_to_user(buf, statbuf,
- len - (STATBUF_LEN - stat_st)))
- return -EFAULT;
-
- stat_st = len - (STATBUF_LEN - stat_st);
- }
- else
- {
- if (copy_to_user(buf, statbuf + stat_st, len))
- return -EFAULT;
-
- stat_st += len;
-
- if (stat_st == STATBUF_LEN)
- stat_st = 0;
- }
- }
-
- if (stat_st == stat_end)
- stat_st = stat_end = 0;
-
- return len;
-}
-
-static void pcbit_logstat(struct pcbit_dev *dev, char *str)
-{
- int i;
- isdn_ctrl ictl;
-
- for (i = stat_end; i < strlen(str); i++)
- {
- statbuf[i] = str[i];
- stat_end = (stat_end + 1) % STATBUF_LEN;
- if (stat_end == stat_st)
- stat_st = (stat_st + 1) % STATBUF_LEN;
- }
-
- ictl.command = ISDN_STAT_STAVAIL;
- ictl.driver = dev->id;
- ictl.arg = strlen(str);
- dev->dev_if->statcallb(&ictl);
-}
-
-void pcbit_state_change(struct pcbit_dev *dev, struct pcbit_chan *chan,
- unsigned short i, unsigned short ev, unsigned short f)
-{
- char buf[256];
-
- sprintf(buf, "change on device: %d channel:%d\n%s -> %s -> %s\n",
- dev->id, chan->id,
- isdn_state_table[i], strisdnevent(ev), isdn_state_table[f]
- );
-
-#ifdef DEBUG
- printk("%s", buf);
-#endif
-
- pcbit_logstat(dev, buf);
-}
-
-static void set_running_timeout(unsigned long ptr)
-{
- struct pcbit_dev *dev;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "set_running_timeout\n");
-#endif
- dev = (struct pcbit_dev *) ptr;
-
- dev->l2_state = L2_DOWN;
- wake_up_interruptible(&dev->set_running_wq);
-}
-
-static int set_protocol_running(struct pcbit_dev *dev)
-{
- isdn_ctrl ctl;
-
- setup_timer(&dev->set_running_timer, &set_running_timeout, (ulong)dev);
-
- /* kick it */
-
- dev->l2_state = L2_STARTING;
-
- writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)),
- dev->sh_mem + BANK4);
-
- mod_timer(&dev->set_running_timer, jiffies + SET_RUN_TIMEOUT);
-
- wait_event(dev->set_running_wq, dev->l2_state == L2_RUNNING ||
- dev->l2_state == L2_DOWN);
-
- del_timer(&dev->set_running_timer);
-
- if (dev->l2_state == L2_RUNNING)
- {
- printk(KERN_DEBUG "pcbit: running\n");
-
- dev->unack_seq = dev->send_seq;
-
- dev->writeptr = dev->sh_mem;
- dev->readptr = dev->sh_mem + BANK2;
-
- /* tell the good news to the upper layer */
- ctl.driver = dev->id;
- ctl.command = ISDN_STAT_RUN;
-
- dev->dev_if->statcallb(&ctl);
- }
- else
- {
- printk(KERN_DEBUG "pcbit: initialization failed\n");
- printk(KERN_DEBUG "pcbit: firmware not loaded\n");
-
-#ifdef DEBUG
- printk(KERN_DEBUG "Bank3 = %02x\n",
- readb(dev->sh_mem + BANK3));
-#endif
- writeb(0x40, dev->sh_mem + BANK4);
-
- /* warn the upper layer */
- ctl.driver = dev->id;
- ctl.command = ISDN_STAT_STOP;
-
- dev->dev_if->statcallb(&ctl);
-
- return -EL2HLT; /* Level 2 halted */
- }
-
- return 0;
-}
-
-static int pcbit_ioctl(isdn_ctrl *ctl)
-{
- struct pcbit_dev *dev;
- struct pcbit_ioctl *cmd;
-
- dev = finddev(ctl->driver);
-
- if (!dev)
- {
- printk(KERN_DEBUG "pcbit_ioctl: unknown device\n");
- return -ENODEV;
- }
-
- cmd = (struct pcbit_ioctl *) ctl->parm.num;
-
- switch (ctl->arg) {
- case PCBIT_IOCTL_GETSTAT:
- cmd->info.l2_status = dev->l2_state;
- break;
-
- case PCBIT_IOCTL_STRLOAD:
- if (dev->l2_state == L2_RUNNING)
- return -EBUSY;
-
- dev->unack_seq = dev->send_seq = dev->rcv_seq = 0;
-
- dev->writeptr = dev->sh_mem;
- dev->readptr = dev->sh_mem + BANK2;
-
- dev->l2_state = L2_LOADING;
- break;
-
- case PCBIT_IOCTL_LWMODE:
- if (dev->l2_state != L2_LOADING)
- return -EINVAL;
-
- dev->l2_state = L2_LWMODE;
- break;
-
- case PCBIT_IOCTL_FWMODE:
- if (dev->l2_state == L2_RUNNING)
- return -EBUSY;
- dev->loadptr = LOAD_ZONE_START;
- dev->l2_state = L2_FWMODE;
-
- break;
- case PCBIT_IOCTL_ENDLOAD:
- if (dev->l2_state == L2_RUNNING)
- return -EBUSY;
- dev->l2_state = L2_DOWN;
- break;
-
- case PCBIT_IOCTL_SETBYTE:
- if (dev->l2_state == L2_RUNNING)
- return -EBUSY;
-
- /* check addr */
- if (cmd->info.rdp_byte.addr > BANK4)
- return -EFAULT;
-
- writeb(cmd->info.rdp_byte.value, dev->sh_mem + cmd->info.rdp_byte.addr);
- break;
- case PCBIT_IOCTL_GETBYTE:
- if (dev->l2_state == L2_RUNNING)
- return -EBUSY;
-
- /* check addr */
-
- if (cmd->info.rdp_byte.addr > BANK4)
- {
- printk("getbyte: invalid addr %04x\n", cmd->info.rdp_byte.addr);
- return -EFAULT;
- }
-
- cmd->info.rdp_byte.value = readb(dev->sh_mem + cmd->info.rdp_byte.addr);
- break;
- case PCBIT_IOCTL_RUNNING:
- if (dev->l2_state == L2_RUNNING)
- return -EBUSY;
- return set_protocol_running(dev);
- break;
- case PCBIT_IOCTL_WATCH188:
- if (dev->l2_state != L2_LOADING)
- return -EINVAL;
- pcbit_l2_write(dev, MSG_WATCH188, 0x0001, NULL, 0);
- break;
- case PCBIT_IOCTL_PING188:
- if (dev->l2_state != L2_LOADING)
- return -EINVAL;
- pcbit_l2_write(dev, MSG_PING188_REQ, 0x0001, NULL, 0);
- break;
- case PCBIT_IOCTL_APION:
- if (dev->l2_state != L2_LOADING)
- return -EINVAL;
- pcbit_l2_write(dev, MSG_API_ON, 0x0001, NULL, 0);
- break;
- case PCBIT_IOCTL_STOP:
- dev->l2_state = L2_DOWN;
- writeb(0x40, dev->sh_mem + BANK4);
- dev->rcv_seq = 0;
- dev->send_seq = 0;
- dev->unack_seq = 0;
- break;
- default:
- printk("error: unknown ioctl\n");
- break;
- }
- return 0;
-}
-
-/*
- * MSN list handling
- *
- * if null reject all calls
- * if first entry has null MSN accept all calls
- */
-
-static void pcbit_clear_msn(struct pcbit_dev *dev)
-{
- struct msn_entry *ptr, *back;
-
- for (ptr = dev->msn_list; ptr;)
- {
- back = ptr->next;
- kfree(ptr);
- ptr = back;
- }
-
- dev->msn_list = NULL;
-}
-
-static void pcbit_set_msn(struct pcbit_dev *dev, char *list)
-{
- struct msn_entry *ptr;
- struct msn_entry *back = NULL;
- char *cp, *sp;
- int len;
-
- if (strlen(list) == 0) {
- ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC);
- if (!ptr) {
- printk(KERN_WARNING "kmalloc failed\n");
- return;
- }
-
- ptr->msn = NULL;
-
- ptr->next = dev->msn_list;
- dev->msn_list = ptr;
-
- return;
- }
-
- if (dev->msn_list)
- for (back = dev->msn_list; back->next; back = back->next);
-
- sp = list;
-
- do {
- cp = strchr(sp, ',');
- if (cp)
- len = cp - sp;
- else
- len = strlen(sp);
-
- ptr = kmalloc(sizeof(struct msn_entry), GFP_ATOMIC);
-
- if (!ptr) {
- printk(KERN_WARNING "kmalloc failed\n");
- return;
- }
- ptr->next = NULL;
-
- ptr->msn = kmalloc(len + 1, GFP_ATOMIC);
- if (!ptr->msn) {
- printk(KERN_WARNING "kmalloc failed\n");
- kfree(ptr);
- return;
- }
-
- memcpy(ptr->msn, sp, len);
- ptr->msn[len] = 0;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "msn: %s\n", ptr->msn);
-#endif
- if (dev->msn_list == NULL)
- dev->msn_list = ptr;
- else
- back->next = ptr;
- back = ptr;
- sp += len;
- } while (cp);
-}
-
-/*
- * check if we do signal or reject an incoming call
- */
-static int pcbit_check_msn(struct pcbit_dev *dev, char *msn)
-{
- struct msn_entry *ptr;
-
- for (ptr = dev->msn_list; ptr; ptr = ptr->next) {
-
- if (ptr->msn == NULL)
- return 1;
-
- if (strcmp(ptr->msn, msn) == 0)
- return 1;
- }
-
- return 0;
-}
diff --git a/drivers/staging/i4l/pcbit/edss1.c b/drivers/staging/i4l/pcbit/edss1.c
deleted file mode 100644
index 5980d1b5da95..000000000000
--- a/drivers/staging/i4l/pcbit/edss1.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * DSS.1 Finite State Machine
- * base: ITU-T Rec Q.931
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-/*
- * TODO: complete the FSM
- * move state/event descriptions to a user space logger
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/skbuff.h>
-
-#include <linux/timer.h>
-#include <linux/io.h>
-
-#include <linux/isdnif.h>
-
-#include "pcbit.h"
-#include "edss1.h"
-#include "layer2.h"
-#include "callbacks.h"
-
-
-const char * const isdn_state_table[] = {
- "Closed",
- "Call initiated",
- "Overlap sending",
- "Outgoing call proceeding",
- "NOT DEFINED",
- "Call delivered",
- "Call present",
- "Call received",
- "Connect request",
- "Incoming call proceeding",
- "Active",
- "Disconnect request",
- "Disconnect indication",
- "NOT DEFINED",
- "NOT DEFINED",
- "Suspend request",
- "NOT DEFINED",
- "Resume request",
- "NOT DEFINED",
- "Release Request",
- "NOT DEFINED",
- "NOT DEFINED",
- "NOT DEFINED",
- "NOT DEFINED",
- "NOT DEFINED",
- "Overlap receiving",
- "Select protocol on B-Channel",
- "Activate B-channel protocol"
-};
-
-#ifdef DEBUG_ERRS
-static
-struct CauseValue {
- byte nr;
- char *descr;
-} cvlist[] = {
- {0x01, "Unallocated (unassigned) number"},
- {0x02, "No route to specified transit network"},
- {0x03, "No route to destination"},
- {0x04, "Send special information tone"},
- {0x05, "Misdialled trunk prefix"},
- {0x06, "Channel unacceptable"},
- {0x07, "Channel awarded and being delivered in an established channel"},
- {0x08, "Preemption"},
- {0x09, "Preemption - circuit reserved for reuse"},
- {0x10, "Normal call clearing"},
- {0x11, "User busy"},
- {0x12, "No user responding"},
- {0x13, "No answer from user (user alerted)"},
- {0x14, "Subscriber absent"},
- {0x15, "Call rejected"},
- {0x16, "Number changed"},
- {0x1a, "non-selected user clearing"},
- {0x1b, "Destination out of order"},
- {0x1c, "Invalid number format (address incomplete)"},
- {0x1d, "Facility rejected"},
- {0x1e, "Response to Status enquiry"},
- {0x1f, "Normal, unspecified"},
- {0x22, "No circuit/channel available"},
- {0x26, "Network out of order"},
- {0x27, "Permanent frame mode connection out-of-service"},
- {0x28, "Permanent frame mode connection operational"},
- {0x29, "Temporary failure"},
- {0x2a, "Switching equipment congestion"},
- {0x2b, "Access information discarded"},
- {0x2c, "Requested circuit/channel not available"},
- {0x2e, "Precedence call blocked"},
- {0x2f, "Resource unavailable, unspecified"},
- {0x31, "Quality of service unavailable"},
- {0x32, "Requested facility not subscribed"},
- {0x35, "Outgoing calls barred within CUG"},
- {0x37, "Incoming calls barred within CUG"},
- {0x39, "Bearer capability not authorized"},
- {0x3a, "Bearer capability not presently available"},
- {0x3e, "Inconsistency in designated outgoing access information and subscriber class"},
- {0x3f, "Service or option not available, unspecified"},
- {0x41, "Bearer capability not implemented"},
- {0x42, "Channel type not implemented"},
- {0x43, "Requested facility not implemented"},
- {0x44, "Only restricted digital information bearer capability is available"},
- {0x4f, "Service or option not implemented"},
- {0x51, "Invalid call reference value"},
- {0x52, "Identified channel does not exist"},
- {0x53, "A suspended call exists, but this call identity does not"},
- {0x54, "Call identity in use"},
- {0x55, "No call suspended"},
- {0x56, "Call having the requested call identity has been cleared"},
- {0x57, "User not member of CUG"},
- {0x58, "Incompatible destination"},
- {0x5a, "Non-existent CUG"},
- {0x5b, "Invalid transit network selection"},
- {0x5f, "Invalid message, unspecified"},
- {0x60, "Mandatory information element is missing"},
- {0x61, "Message type non-existent or not implemented"},
- {0x62, "Message not compatible with call state or message type non-existent or not implemented"},
- {0x63, "Information element/parameter non-existent or not implemented"},
- {0x64, "Invalid information element contents"},
- {0x65, "Message not compatible with call state"},
- {0x66, "Recovery on timer expiry"},
- {0x67, "Parameter non-existent or not implemented - passed on"},
- {0x6e, "Message with unrecognized parameter discarded"},
- {0x6f, "Protocol error, unspecified"},
- {0x7f, "Interworking, unspecified"}
-};
-
-#endif
-
-static struct isdn_event_desc {
- unsigned short ev;
- char *desc;
-} isdn_event_table[] = {
- {EV_USR_SETUP_REQ, "CC->L3: Setup Request"},
- {EV_USR_SETUP_RESP, "CC->L3: Setup Response"},
- {EV_USR_PROCED_REQ, "CC->L3: Proceeding Request"},
- {EV_USR_RELEASE_REQ, "CC->L3: Release Request"},
-
- {EV_NET_SETUP, "NET->TE: setup "},
- {EV_NET_CALL_PROC, "NET->TE: call proceeding"},
- {EV_NET_SETUP_ACK, "NET->TE: setup acknowledge (more info needed)"},
- {EV_NET_CONN, "NET->TE: connect"},
- {EV_NET_CONN_ACK, "NET->TE: connect acknowledge"},
- {EV_NET_DISC, "NET->TE: disconnect indication"},
- {EV_NET_RELEASE, "NET->TE: release"},
- {EV_NET_RELEASE_COMP, "NET->TE: release complete"},
- {EV_NET_SELP_RESP, "Board: Select B-channel protocol ack"},
- {EV_NET_ACTV_RESP, "Board: Activate B-channel protocol ack"},
- {EV_TIMER, "Timeout"},
- {0, "NULL"}
-};
-
-char *strisdnevent(ushort ev)
-{
- struct isdn_event_desc *entry;
-
- for (entry = isdn_event_table; entry->ev; entry++)
- if (entry->ev == ev)
- break;
-
- return entry->desc;
-}
-
-/*
- * Euro ISDN finite state machine
- */
-
-static struct fsm_timer_entry fsm_timers[] = {
- {ST_CALL_PROC, 10},
- {ST_DISC_REQ, 2},
- {ST_ACTIVE_SELP, 5},
- {ST_ACTIVE_ACTV, 5},
- {ST_INCM_PROC, 10},
- {ST_CONN_REQ, 2},
- {0xff, 0}
-};
-
-static struct fsm_entry fsm_table[] = {
-/* Connect Phase */
- /* Outgoing */
- {ST_NULL, ST_CALL_INIT, EV_USR_SETUP_REQ, cb_out_1},
-
- {ST_CALL_INIT, ST_OVER_SEND, EV_NET_SETUP_ACK, cb_notdone},
- {ST_CALL_INIT, ST_CALL_PROC, EV_NET_CALL_PROC, NULL},
- {ST_CALL_INIT, ST_NULL, EV_NET_DISC, cb_out_2},
-
- {ST_CALL_PROC, ST_ACTIVE_SELP, EV_NET_CONN, cb_out_2},
- {ST_CALL_PROC, ST_NULL, EV_NET_DISC, cb_disc_1},
- {ST_CALL_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
-
- /* Incoming */
- {ST_NULL, ST_CALL_PRES, EV_NET_SETUP, NULL},
-
- {ST_CALL_PRES, ST_INCM_PROC, EV_USR_PROCED_REQ, cb_in_1},
- {ST_CALL_PRES, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
-
- {ST_INCM_PROC, ST_CONN_REQ, EV_USR_SETUP_RESP, cb_in_2},
- {ST_INCM_PROC, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
-
- {ST_CONN_REQ, ST_ACTIVE_SELP, EV_NET_CONN_ACK, cb_in_3},
-
- /* Active */
- {ST_ACTIVE, ST_NULL, EV_NET_DISC, cb_disc_1},
- {ST_ACTIVE, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
- {ST_ACTIVE, ST_NULL, EV_NET_RELEASE, cb_disc_3},
-
- /* Disconnect */
-
- {ST_DISC_REQ, ST_NULL, EV_NET_DISC, cb_disc_1},
- {ST_DISC_REQ, ST_NULL, EV_NET_RELEASE, cb_disc_3},
-
- /* protocol selection */
- {ST_ACTIVE_SELP, ST_ACTIVE_ACTV, EV_NET_SELP_RESP, cb_selp_1},
- {ST_ACTIVE_SELP, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
-
- {ST_ACTIVE_ACTV, ST_ACTIVE, EV_NET_ACTV_RESP, cb_open},
- {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_USR_RELEASE_REQ, cb_disc_2},
-
- /* Timers */
- {ST_CALL_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2},
- {ST_DISC_REQ, ST_NULL, EV_TIMER, cb_disc_3},
- {ST_ACTIVE_SELP, ST_DISC_REQ, EV_TIMER, cb_disc_2},
- {ST_ACTIVE_ACTV, ST_DISC_REQ, EV_TIMER, cb_disc_2},
- {ST_INCM_PROC, ST_DISC_REQ, EV_TIMER, cb_disc_2},
- {ST_CONN_REQ, ST_CONN_REQ, EV_TIMER, cb_in_2},
-
- {0xff, 0, 0, NULL}
-};
-
-
-static void pcbit_fsm_timer(unsigned long data)
-{
- struct pcbit_dev *dev;
- struct pcbit_chan *chan;
-
- chan = (struct pcbit_chan *) data;
-
- del_timer(&chan->fsm_timer);
- chan->fsm_timer.function = NULL;
-
- dev = chan2dev(chan);
-
- if (!dev) {
- printk(KERN_WARNING "pcbit: timer for unknown device\n");
- return;
- }
-
- pcbit_fsm_event(dev, chan, EV_TIMER, NULL);
-}
-
-
-void pcbit_fsm_event(struct pcbit_dev *dev, struct pcbit_chan *chan,
- unsigned short event, struct callb_data *data)
-{
- struct fsm_entry *action;
- struct fsm_timer_entry *tentry;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->lock, flags);
-
- for (action = fsm_table; action->init != 0xff; action++)
- if (action->init == chan->fsm_state && action->event == event)
- break;
-
- if (action->init == 0xff) {
-
- spin_unlock_irqrestore(&dev->lock, flags);
- printk(KERN_DEBUG "fsm error: event %x on state %x\n",
- event, chan->fsm_state);
- return;
- }
-
- if (chan->fsm_timer.function) {
- del_timer(&chan->fsm_timer);
- chan->fsm_timer.function = NULL;
- }
-
- chan->fsm_state = action->final;
-
- pcbit_state_change(dev, chan, action->init, event, action->final);
-
- for (tentry = fsm_timers; tentry->init != 0xff; tentry++)
- if (tentry->init == chan->fsm_state)
- break;
-
- if (tentry->init != 0xff) {
- setup_timer(&chan->fsm_timer, &pcbit_fsm_timer, (ulong)chan);
- mod_timer(&chan->fsm_timer, jiffies + tentry->timeout * HZ);
- }
-
- spin_unlock_irqrestore(&dev->lock, flags);
-
- if (action->callb)
- action->callb(dev, chan, data);
-
-}
diff --git a/drivers/staging/i4l/pcbit/edss1.h b/drivers/staging/i4l/pcbit/edss1.h
deleted file mode 100644
index 2f6b3a8edfba..000000000000
--- a/drivers/staging/i4l/pcbit/edss1.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * DSS.1 module definitions
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-#ifndef EDSS1_H
-#define EDSS1_H
-
-/* ISDN states */
-
-#define ST_NULL 0
-#define ST_CALL_INIT 1 /* Call initiated */
-#define ST_OVER_SEND 2 /* Overlap sending - Requests More Info 4 call */
-#define ST_CALL_PROC 3 /* Call Proceeding */
-#define ST_CALL_DELV 4
-#define ST_CALL_PRES 6 /* Call Present - Received CONN.IND */
-#define ST_CALL_RECV 7 /* Alerting sent */
-#define ST_CONN_REQ 8 /* Answered - waiting 4 CONN.CONF */
-#define ST_INCM_PROC 9
-#define ST_ACTIVE 10
-#define ST_DISC_REQ 11
-#define ST_DISC_IND 12
-#define ST_SUSP_REQ 15
-#define ST_RESM_REQ 17
-#define ST_RELS_REQ 19
-#define ST_OVER_RECV 25
-
-#define ST_ACTIVE_SELP 26 /* Select protocol on B-Channel */
-#define ST_ACTIVE_ACTV 27 /* Activate B-channel protocol */
-
-#define MAX_STATE ST_ACTIVE_ACTV
-
-#define EV_NULL 0
-#define EV_USR_SETUP_REQ 1
-#define EV_USR_SETUP_RESP 2
-#define EV_USR_PROCED_REQ 3
-#define EV_USR_RELEASE_REQ 4
-#define EV_USR_REJECT_REQ 4
-
-#define EV_NET_SETUP 16
-#define EV_NET_CALL_PROC 17
-#define EV_NET_SETUP_ACK 18
-#define EV_NET_CONN 19
-#define EV_NET_CONN_ACK 20
-
-#define EV_NET_SELP_RESP 21
-#define EV_NET_ACTV_RESP 22
-
-#define EV_NET_DISC 23
-#define EV_NET_RELEASE 24
-#define EV_NET_RELEASE_COMP 25
-
-#define EV_TIMER 26
-#define EV_ERROR 32
-
-/*
- * Cause values
- * only the ones we use
- */
-
-#define CAUSE_NORMAL 0x10U
-#define CAUSE_NOCHAN 0x22U
-
-struct callb_data {
- unsigned short type;
- union {
- struct ConnInfo {
- char *CalledPN;
- char *CallingPN;
- } setup;
- unsigned short cause;
- } data;
-};
-
-struct fsm_entry {
- unsigned short init;
- unsigned short final;
- unsigned short event;
- void (*callb)(struct pcbit_dev *, struct pcbit_chan *, struct callb_data*);
-};
-
-struct fsm_timer_entry {
- unsigned short init;
- unsigned long timeout; /* in seconds */
-};
-
-extern const char * const isdn_state_table[];
-
-void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *,
- unsigned short event, struct callb_data *);
-char *strisdnevent(ushort ev);
-
-#endif
diff --git a/drivers/staging/i4l/pcbit/layer2.c b/drivers/staging/i4l/pcbit/layer2.c
deleted file mode 100644
index 0592bf6ee9c9..000000000000
--- a/drivers/staging/i4l/pcbit/layer2.c
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * PCBIT-D low-layer interface
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-/*
- * 19991203 - Fernando Carvalho - takion@superbofh.org
- * Hacked to compile with egcs and run with current version of isdn modules
- */
-
-/*
- * Based on documentation provided by Inesc:
- * - "Interface com bus do PC para o PCBIT e PCBIT-D", Inesc, Jan 93
- */
-
-/*
- * TODO: better handling of errors
- * re-write/remove debug printks
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/mm.h>
-#include <linux/skbuff.h>
-
-#include <linux/isdnif.h>
-
-#include <linux/io.h>
-
-
-#include "pcbit.h"
-#include "layer2.h"
-#include "edss1.h"
-
-#undef DEBUG_FRAG
-
-
-/*
- * Prototypes
- */
-
-static void pcbit_transmit(struct pcbit_dev *dev);
-
-static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack);
-
-static void pcbit_l2_error(struct pcbit_dev *dev);
-static void pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info);
-static void pcbit_l2_err_recover(unsigned long data);
-
-static void pcbit_firmware_bug(struct pcbit_dev *dev);
-
-static __inline__ void
-pcbit_sched_delivery(struct pcbit_dev *dev)
-{
- schedule_work(&dev->qdelivery);
-}
-
-
-/*
- * Called from layer3
- */
-
-int
-pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
- struct sk_buff *skb, unsigned short hdr_len)
-{
- struct frame_buf *frame,
- *ptr;
- unsigned long flags;
-
- if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
- dev_kfree_skb(skb);
- return -1;
- }
- if ((frame = kmalloc(sizeof(struct frame_buf),
- GFP_ATOMIC)) == NULL) {
- dev_kfree_skb(skb);
- return -1;
- }
- frame->msg = msg;
- frame->refnum = refnum;
- frame->copied = 0;
- frame->hdr_len = hdr_len;
-
- if (skb)
- frame->dt_len = skb->len - hdr_len;
- else
- frame->dt_len = 0;
-
- frame->skb = skb;
-
- frame->next = NULL;
-
- spin_lock_irqsave(&dev->lock, flags);
-
- if (dev->write_queue == NULL) {
- dev->write_queue = frame;
- spin_unlock_irqrestore(&dev->lock, flags);
- pcbit_transmit(dev);
- } else {
- for (ptr = dev->write_queue; ptr->next; ptr = ptr->next);
- ptr->next = frame;
-
- spin_unlock_irqrestore(&dev->lock, flags);
- }
- return 0;
-}
-
-static __inline__ void
-pcbit_tx_update(struct pcbit_dev *dev, ushort len)
-{
- u_char info;
-
- dev->send_seq = (dev->send_seq + 1) % 8;
-
- dev->fsize[dev->send_seq] = len;
- info = 0;
- info |= dev->rcv_seq << 3;
- info |= dev->send_seq;
-
- writeb(info, dev->sh_mem + BANK4);
-
-}
-
-/*
- * called by interrupt service routine or by write_2
- */
-
-static void
-pcbit_transmit(struct pcbit_dev *dev)
-{
- struct frame_buf *frame = NULL;
- unsigned char unacked;
- int flen; /* fragment frame length including all headers */
- int free;
- int count,
- cp_len;
- unsigned long flags;
- unsigned short tt;
-
- if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
- return;
-
- unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;
-
- spin_lock_irqsave(&dev->lock, flags);
-
- if (dev->free > 16 && dev->write_queue && unacked < 7) {
-
- if (!dev->w_busy)
- dev->w_busy = 1;
- else {
- spin_unlock_irqrestore(&dev->lock, flags);
- return;
- }
-
-
- frame = dev->write_queue;
- free = dev->free;
-
- spin_unlock_irqrestore(&dev->lock, flags);
-
- if (frame->copied == 0) {
-
- /* Type 0 frame */
-
- ulong msg;
-
- if (frame->skb)
- flen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
- else
- flen = FRAME_HDR_LEN + PREHDR_LEN;
-
- if (flen > free)
- flen = free;
-
- msg = frame->msg;
-
- /*
- * Board level 2 header
- */
-
- pcbit_writew(dev, flen - FRAME_HDR_LEN);
-
- pcbit_writeb(dev, GET_MSG_CPU(msg));
-
- pcbit_writeb(dev, GET_MSG_PROC(msg));
-
- /* TH */
- pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);
-
- /* TD */
- pcbit_writew(dev, frame->dt_len);
-
-
- /*
- * Board level 3 fixed-header
- */
-
- /* LEN = TH */
- pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);
-
- /* XX */
- pcbit_writew(dev, 0);
-
- /* C + S */
- pcbit_writeb(dev, GET_MSG_CMD(msg));
- pcbit_writeb(dev, GET_MSG_SCMD(msg));
-
- /* NUM */
- pcbit_writew(dev, frame->refnum);
-
- count = FRAME_HDR_LEN + PREHDR_LEN;
- } else {
- /* Type 1 frame */
-
- flen = 2 + (frame->skb->len - frame->copied);
-
- if (flen > free)
- flen = free;
-
- /* TT */
- tt = ((ushort) (flen - 2)) | 0x8000U; /* Type 1 */
- pcbit_writew(dev, tt);
-
- count = 2;
- }
-
- if (frame->skb) {
- cp_len = frame->skb->len - frame->copied;
- if (cp_len > flen - count)
- cp_len = flen - count;
-
- memcpy_topcbit(dev, frame->skb->data + frame->copied,
- cp_len);
- frame->copied += cp_len;
- }
- /* bookkeeping */
- dev->free -= flen;
- pcbit_tx_update(dev, flen);
-
- spin_lock_irqsave(&dev->lock, flags);
-
- if (frame->skb == NULL || frame->copied == frame->skb->len) {
-
- dev->write_queue = frame->next;
-
- if (frame->skb != NULL) {
- /* free frame */
- dev_kfree_skb(frame->skb);
- }
- kfree(frame);
- }
- dev->w_busy = 0;
- spin_unlock_irqrestore(&dev->lock, flags);
- } else {
- spin_unlock_irqrestore(&dev->lock, flags);
-#ifdef DEBUG
- printk(KERN_DEBUG "unacked %d free %d write_queue %s\n",
- unacked, dev->free, dev->write_queue ? "not empty" :
- "empty");
-#endif
- }
-}
-
-
-/*
- * deliver a queued frame to the upper layer
- */
-
-void
-pcbit_deliver(struct work_struct *work)
-{
- struct frame_buf *frame;
- unsigned long flags, msg;
- struct pcbit_dev *dev =
- container_of(work, struct pcbit_dev, qdelivery);
-
- spin_lock_irqsave(&dev->lock, flags);
-
- while ((frame = dev->read_queue)) {
- dev->read_queue = frame->next;
- spin_unlock_irqrestore(&dev->lock, flags);
-
- msg = 0;
- SET_MSG_CPU(msg, 0);
- SET_MSG_PROC(msg, 0);
- SET_MSG_CMD(msg, frame->skb->data[2]);
- SET_MSG_SCMD(msg, frame->skb->data[3]);
-
- frame->refnum = *((ushort *)frame->skb->data + 4);
- frame->msg = *((ulong *)&msg);
-
- skb_pull(frame->skb, 6);
-
- pcbit_l3_receive(dev, frame->msg, frame->skb, frame->hdr_len,
- frame->refnum);
-
- kfree(frame);
-
- spin_lock_irqsave(&dev->lock, flags);
- }
-
- spin_unlock_irqrestore(&dev->lock, flags);
-}
-
-/*
- * Reads BANK 2 & Reassembles
- */
-
-static void
-pcbit_receive(struct pcbit_dev *dev)
-{
- unsigned short tt;
- u_char cpu,
- proc;
- struct frame_buf *frame = NULL;
- unsigned long flags;
- u_char type1;
-
- if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
- return;
-
- tt = pcbit_readw(dev);
-
- if ((tt & 0x7fffU) > 511) {
- printk(KERN_INFO "pcbit: invalid frame length -> TT=%04x\n",
- tt);
- pcbit_l2_error(dev);
- return;
- }
- if (!(tt & 0x8000U)) { /* Type 0 */
- type1 = 0;
-
- if (dev->read_frame) {
- printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
- /* discard previous queued frame */
- kfree_skb(dev->read_frame->skb);
- kfree(dev->read_frame);
- dev->read_frame = NULL;
- }
- frame = kzalloc(sizeof(struct frame_buf), GFP_ATOMIC);
-
- if (frame == NULL) {
- printk(KERN_WARNING "kmalloc failed\n");
- return;
- }
-
- cpu = pcbit_readb(dev);
- proc = pcbit_readb(dev);
-
-
- if (cpu != 0x06 && cpu != 0x02) {
- printk(KERN_DEBUG "pcbit: invalid cpu value\n");
- kfree(frame);
- pcbit_l2_error(dev);
- return;
- }
- /*
- * we discard cpu & proc on receiving
- * but we read it to update the pointer
- */
-
- frame->hdr_len = pcbit_readw(dev);
- frame->dt_len = pcbit_readw(dev);
-
- /*
- * 0 sized packet
- * I don't know if they are an error or not...
- * But they are very frequent
- * Not documented
- */
-
- if (frame->hdr_len == 0) {
- kfree(frame);
-#ifdef DEBUG
- printk(KERN_DEBUG "0 sized frame\n");
-#endif
- pcbit_firmware_bug(dev);
- return;
- }
- /* sanity check the length values */
- if (frame->hdr_len > 1024 || frame->dt_len > 2048) {
-#ifdef DEBUG
- printk(KERN_DEBUG "length problem: ");
- printk(KERN_DEBUG "TH=%04x TD=%04x\n",
- frame->hdr_len,
- frame->dt_len);
-#endif
- pcbit_l2_error(dev);
- kfree(frame);
- return;
- }
- /* minimum frame read */
-
- frame->skb = dev_alloc_skb(frame->hdr_len + frame->dt_len +
- ((frame->hdr_len + 15) & ~15));
-
- if (!frame->skb) {
- printk(KERN_DEBUG "pcbit_receive: out of memory\n");
- kfree(frame);
- return;
- }
- /* 16 byte alignment for IP */
- if (frame->dt_len)
- skb_reserve(frame->skb, (frame->hdr_len + 15) & ~15);
-
- } else {
- /* Type 1 */
- type1 = 1;
- tt &= 0x7fffU;
-
- if (!(frame = dev->read_frame)) {
- printk("Type 1 frame and no frame queued\n");
- /* usually after an error: toss frame */
- dev->readptr += tt;
- if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN)
- dev->readptr -= BANKLEN;
- return;
-
- }
- }
-
- memcpy_frompcbit(dev, skb_put(frame->skb, tt), tt);
-
- frame->copied += tt;
- spin_lock_irqsave(&dev->lock, flags);
- if (frame->copied == frame->hdr_len + frame->dt_len) {
-
- if (type1) {
- dev->read_frame = NULL;
- }
- if (dev->read_queue) {
- struct frame_buf *ptr;
- for (ptr = dev->read_queue; ptr->next; ptr = ptr->next);
- ptr->next = frame;
- } else
- dev->read_queue = frame;
-
- } else {
- dev->read_frame = frame;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-}
-
-/*
- * The board sends 0 sized frames
- * They are TDATA_CONFs that get messed up somehow
- * gotta send a fake acknowledgment to the upper layer somehow
- */
-
-static __inline__ void
-pcbit_fake_conf(struct pcbit_dev *dev, struct pcbit_chan *chan)
-{
- isdn_ctrl ictl;
-
- if (chan->queued) {
- chan->queued--;
-
- ictl.driver = dev->id;
- ictl.command = ISDN_STAT_BSENT;
- ictl.arg = chan->id;
- dev->dev_if->statcallb(&ictl);
- }
-}
-
-static void
-pcbit_firmware_bug(struct pcbit_dev *dev)
-{
- struct pcbit_chan *chan;
-
- chan = dev->b1;
-
- if (chan->fsm_state == ST_ACTIVE) {
- pcbit_fake_conf(dev, chan);
- }
- chan = dev->b2;
-
- if (chan->fsm_state == ST_ACTIVE) {
- pcbit_fake_conf(dev, chan);
- }
-}
-
-irqreturn_t
-pcbit_irq_handler(int interrupt, void *devptr)
-{
- struct pcbit_dev *dev;
- u_char info,
- ack_seq,
- read_seq;
-
- dev = (struct pcbit_dev *) devptr;
-
- if (!dev) {
- printk(KERN_WARNING "pcbit_irq_handler: wrong device\n");
- return IRQ_NONE;
- }
- if (dev->interrupt) {
- printk(KERN_DEBUG "pcbit: reentering interrupt handler\n");
- return IRQ_HANDLED;
- }
- dev->interrupt = 1;
-
- info = readb(dev->sh_mem + BANK3);
-
- if (dev->l2_state == L2_STARTING || dev->l2_state == L2_ERROR) {
- pcbit_l2_active_conf(dev, info);
- dev->interrupt = 0;
- return IRQ_HANDLED;
- }
- if (info & 0x40U) { /* E bit set */
-#ifdef DEBUG
- printk(KERN_DEBUG "pcbit_irq_handler: E bit on\n");
-#endif
- pcbit_l2_error(dev);
- dev->interrupt = 0;
- return IRQ_HANDLED;
- }
- if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
- dev->interrupt = 0;
- return IRQ_HANDLED;
- }
- ack_seq = (info >> 3) & 0x07U;
- read_seq = (info & 0x07U);
-
- dev->interrupt = 0;
-
- if (read_seq != dev->rcv_seq) {
- while (read_seq != dev->rcv_seq) {
- pcbit_receive(dev);
- dev->rcv_seq = (dev->rcv_seq + 1) % 8;
- }
- pcbit_sched_delivery(dev);
- }
- if (ack_seq != dev->unack_seq) {
- pcbit_recv_ack(dev, ack_seq);
- }
- info = dev->rcv_seq << 3;
- info |= dev->send_seq;
-
- writeb(info, dev->sh_mem + BANK4);
- return IRQ_HANDLED;
-}
-
-
-static void
-pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info)
-{
- u_char state;
-
- state = dev->l2_state;
-
-#ifdef DEBUG
- printk(KERN_DEBUG "layer2_active_confirm\n");
-#endif
-
-
- if (info & 0x80U) {
- dev->rcv_seq = info & 0x07U;
- dev->l2_state = L2_RUNNING;
- } else
- dev->l2_state = L2_DOWN;
-
- if (state == L2_STARTING)
- wake_up_interruptible(&dev->set_running_wq);
-
- if (state == L2_ERROR && dev->l2_state == L2_RUNNING) {
- pcbit_transmit(dev);
- }
-}
-
-static void
-pcbit_l2_err_recover(unsigned long data)
-{
-
- struct pcbit_dev *dev;
- struct frame_buf *frame;
-
- dev = (struct pcbit_dev *) data;
-
- del_timer(&dev->error_recover_timer);
- if (dev->w_busy || dev->r_busy) {
- init_timer(&dev->error_recover_timer);
- dev->error_recover_timer.expires = jiffies + ERRTIME;
- add_timer(&dev->error_recover_timer);
- return;
- }
- dev->w_busy = dev->r_busy = 1;
-
- if (dev->read_frame) {
- kfree_skb(dev->read_frame->skb);
- kfree(dev->read_frame);
- dev->read_frame = NULL;
- }
- if (dev->write_queue) {
- frame = dev->write_queue;
-#ifdef FREE_ON_ERROR
- dev->write_queue = dev->write_queue->next;
-
- if (frame->skb) {
- dev_kfree_skb(frame->skb);
- }
- kfree(frame);
-#else
- frame->copied = 0;
-#endif
- }
- dev->rcv_seq = dev->send_seq = dev->unack_seq = 0;
- dev->free = 511;
- dev->l2_state = L2_ERROR;
-
- /* this is an hack... */
- pcbit_firmware_bug(dev);
-
- dev->writeptr = dev->sh_mem;
- dev->readptr = dev->sh_mem + BANK2;
-
- writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)),
- dev->sh_mem + BANK4);
- dev->w_busy = dev->r_busy = 0;
-
-}
-
-static void
-pcbit_l2_error(struct pcbit_dev *dev)
-{
- if (dev->l2_state == L2_RUNNING) {
-
- printk(KERN_INFO "pcbit: layer 2 error\n");
-
-#ifdef DEBUG
- log_state(dev);
-#endif
-
- dev->l2_state = L2_DOWN;
-
- setup_timer(&dev->error_recover_timer, &pcbit_l2_err_recover,
- (ulong)dev);
- mod_timer(&dev->error_recover_timer, jiffies + ERRTIME);
- }
-}
-
-/*
- * Description:
- * if board acks frames
- * update dev->free
- * call pcbit_transmit to write possible queued frames
- */
-
-static void
-pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack)
-{
- int i,
- count;
- int unacked;
-
- unacked = (dev->send_seq + (8 - dev->unack_seq)) & 0x07;
-
- /* dev->unack_seq < ack <= dev->send_seq; */
-
- if (unacked) {
-
- if (dev->send_seq > dev->unack_seq) {
- if (ack <= dev->unack_seq || ack > dev->send_seq) {
- printk(KERN_DEBUG
- "layer 2 ack unacceptable - dev %d",
- dev->id);
-
- pcbit_l2_error(dev);
- } else if (ack > dev->send_seq && ack <= dev->unack_seq) {
- printk(KERN_DEBUG
- "layer 2 ack unacceptable - dev %d",
- dev->id);
- pcbit_l2_error(dev);
- }
- }
- /* ack is acceptable */
-
-
- i = dev->unack_seq;
-
- do {
- dev->unack_seq = i = (i + 1) % 8;
- dev->free += dev->fsize[i];
- } while (i != ack);
-
- count = 0;
- while (count < 7 && dev->write_queue) {
- u8 lsend_seq = dev->send_seq;
-
- pcbit_transmit(dev);
-
- if (dev->send_seq == lsend_seq)
- break;
- count++;
- }
- } else
- printk(KERN_DEBUG "recv_ack: unacked = 0\n");
-}
diff --git a/drivers/staging/i4l/pcbit/layer2.h b/drivers/staging/i4l/pcbit/layer2.h
deleted file mode 100644
index 6b9063e388cd..000000000000
--- a/drivers/staging/i4l/pcbit/layer2.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * PCBIT-D low-layer interface definitions
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-/*
- * 19991203 - Fernando Carvalho - takion@superbofh.org
- * Hacked to compile with egcs and run with current version of isdn modules
- */
-
-#ifndef LAYER2_H
-#define LAYER2_H
-
-#include <linux/interrupt.h>
-
-#include <asm/byteorder.h>
-
-#define BANK1 0x0000U /* PC -> Board */
-#define BANK2 0x01ffU /* Board -> PC */
-#define BANK3 0x03feU /* Att Board */
-#define BANK4 0x03ffU /* Att PC */
-
-#define BANKLEN 0x01FFU
-
-#define LOAD_ZONE_START 0x03f8U
-#define LOAD_ZONE_END 0x03fdU
-
-#define LOAD_RETRY 18000000
-
-
-
-/* TAM - XX - C - S - NUM */
-#define PREHDR_LEN 8
-/* TT - M - I - TH - TD */
-#define FRAME_HDR_LEN 8
-
-#define MSG_CONN_REQ 0x08000100
-#define MSG_CONN_CONF 0x00000101
-#define MSG_CONN_IND 0x00000102
-#define MSG_CONN_RESP 0x08000103
-
-#define MSG_CONN_ACTV_REQ 0x08000300
-#define MSG_CONN_ACTV_CONF 0x00000301
-#define MSG_CONN_ACTV_IND 0x00000302
-#define MSG_CONN_ACTV_RESP 0x08000303
-
-#define MSG_DISC_REQ 0x08000400
-#define MSG_DISC_CONF 0x00000401
-#define MSG_DISC_IND 0x00000402
-#define MSG_DISC_RESP 0x08000403
-
-#define MSG_TDATA_REQ 0x0908E200
-#define MSG_TDATA_CONF 0x0000E201
-#define MSG_TDATA_IND 0x0000E202
-#define MSG_TDATA_RESP 0x0908E203
-
-#define MSG_SELP_REQ 0x09004000
-#define MSG_SELP_CONF 0x00004001
-
-#define MSG_ACT_TRANSP_REQ 0x0908E000
-#define MSG_ACT_TRANSP_CONF 0x0000E001
-
-#define MSG_STPROT_REQ 0x09004100
-#define MSG_STPROT_CONF 0x00004101
-
-#define MSG_PING188_REQ 0x09030500
-#define MSG_PING188_CONF 0x000005bc
-
-#define MSG_WATCH188 0x09030400
-
-#define MSG_API_ON 0x08020102
-#define MSG_POOL_PCBIT 0x08020400
-#define MSG_POOL_PCBIT_CONF 0x00000401
-
-#define MSG_INFO_IND 0x00002602
-#define MSG_INFO_RESP 0x08002603
-
-#define MSG_DEBUG_188 0x0000ff00
-
-/*
-
- long 4 3 2 1
- Intel 1 2 3 4
-*/
-
-#ifdef __LITTLE_ENDIAN
-#define SET_MSG_SCMD(msg, ch) (msg = (msg & 0xffffff00) | (((ch) & 0xff)))
-#define SET_MSG_CMD(msg, ch) (msg = (msg & 0xffff00ff) | (((ch) & 0xff) << 8))
-#define SET_MSG_PROC(msg, ch) (msg = (msg & 0xff00ffff) | (((ch) & 0xff) << 16))
-#define SET_MSG_CPU(msg, ch) (msg = (msg & 0x00ffffff) | (((ch) & 0xff) << 24))
-
-#define GET_MSG_SCMD(msg) ((msg) & 0xFF)
-#define GET_MSG_CMD(msg) ((msg) >> 8 & 0xFF)
-#define GET_MSG_PROC(msg) ((msg) >> 16 & 0xFF)
-#define GET_MSG_CPU(msg) ((msg) >> 24)
-
-#else
-#error "Non-Intel CPU"
-#endif
-
-#define MAX_QUEUED 7
-
-#define SCHED_READ 0x01
-#define SCHED_WRITE 0x02
-
-#define SET_RUN_TIMEOUT (2 * HZ) /* 2 seconds */
-
-struct frame_buf {
- ulong msg;
- unsigned int refnum;
- unsigned int dt_len;
- unsigned int hdr_len;
- struct sk_buff *skb;
- unsigned int copied;
- struct frame_buf *next;
-};
-
-extern int pcbit_l2_write(struct pcbit_dev *dev, ulong msg, ushort refnum,
- struct sk_buff *skb, unsigned short hdr_len);
-
-extern irqreturn_t pcbit_irq_handler(int interrupt, void *);
-
-extern struct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS];
-
-#ifdef DEBUG
-static __inline__ void log_state(struct pcbit_dev *dev) {
- printk(KERN_DEBUG "writeptr = %ld\n",
- (ulong) (dev->writeptr - dev->sh_mem));
- printk(KERN_DEBUG "readptr = %ld\n",
- (ulong) (dev->readptr - (dev->sh_mem + BANK2)));
- printk(KERN_DEBUG "{rcv_seq=%01x, send_seq=%01x, unack_seq=%01x}\n",
- dev->rcv_seq, dev->send_seq, dev->unack_seq);
-}
-#endif
-
-static __inline__ struct pcbit_dev *chan2dev(struct pcbit_chan *chan)
-{
- struct pcbit_dev *dev;
- int i;
-
-
- for (i = 0; i < MAX_PCBIT_CARDS; i++)
- if ((dev = dev_pcbit[i]))
- if (dev->b1 == chan || dev->b2 == chan)
- return dev;
- return NULL;
-
-}
-
-static __inline__ struct pcbit_dev *finddev(int id)
-{
- struct pcbit_dev *dev;
- int i;
-
- for (i = 0; i < MAX_PCBIT_CARDS; i++)
- if ((dev = dev_pcbit[i]))
- if (dev->id == id)
- return dev;
- return NULL;
-}
-
-
-/*
- * Support routines for reading and writing in the board
- */
-
-static __inline__ void pcbit_writeb(struct pcbit_dev *dev, unsigned char dt)
-{
- writeb(dt, dev->writeptr++);
- if (dev->writeptr == dev->sh_mem + BANKLEN)
- dev->writeptr = dev->sh_mem;
-}
-
-static __inline__ void pcbit_writew(struct pcbit_dev *dev, unsigned short dt)
-{
- int dist;
-
- dist = BANKLEN - (dev->writeptr - dev->sh_mem);
- switch (dist) {
- case 2:
- writew(dt, dev->writeptr);
- dev->writeptr = dev->sh_mem;
- break;
- case 1:
- writeb((u_char) (dt & 0x00ffU), dev->writeptr);
- dev->writeptr = dev->sh_mem;
- writeb((u_char) (dt >> 8), dev->writeptr++);
- break;
- default:
- writew(dt, dev->writeptr);
- dev->writeptr += 2;
- break;
- };
-}
-
-static __inline__ void memcpy_topcbit(struct pcbit_dev *dev, u_char *data,
- int len)
-{
- int diff;
-
- diff = len - (BANKLEN - (dev->writeptr - dev->sh_mem));
-
- if (diff > 0)
- {
- memcpy_toio(dev->writeptr, data, len - diff);
- memcpy_toio(dev->sh_mem, data + (len - diff), diff);
- dev->writeptr = dev->sh_mem + diff;
- }
- else
- {
- memcpy_toio(dev->writeptr, data, len);
-
- dev->writeptr += len;
- if (diff == 0)
- dev->writeptr = dev->sh_mem;
- }
-}
-
-static __inline__ unsigned char pcbit_readb(struct pcbit_dev *dev)
-{
- unsigned char val;
-
- val = readb(dev->readptr++);
- if (dev->readptr == dev->sh_mem + BANK2 + BANKLEN)
- dev->readptr = dev->sh_mem + BANK2;
-
- return val;
-}
-
-static __inline__ unsigned short pcbit_readw(struct pcbit_dev *dev)
-{
- int dist;
- unsigned short val;
-
- dist = BANKLEN - (dev->readptr - (dev->sh_mem + BANK2));
- switch (dist) {
- case 2:
- val = readw(dev->readptr);
- dev->readptr = dev->sh_mem + BANK2;
- break;
- case 1:
- val = readb(dev->readptr);
- dev->readptr = dev->sh_mem + BANK2;
- val = (readb(dev->readptr++) << 8) | val;
- break;
- default:
- val = readw(dev->readptr);
- dev->readptr += 2;
- break;
- };
- return val;
-}
-
-static __inline__ void memcpy_frompcbit(struct pcbit_dev *dev, u_char *data, int len)
-{
- int diff;
-
- diff = len - (BANKLEN - (dev->readptr - (dev->sh_mem + BANK2)));
- if (diff > 0)
- {
- memcpy_fromio(data, dev->readptr, len - diff);
- memcpy_fromio(data + (len - diff), dev->sh_mem + BANK2 , diff);
- dev->readptr = dev->sh_mem + BANK2 + diff;
- }
- else
- {
- memcpy_fromio(data, dev->readptr, len);
- dev->readptr += len;
- if (diff == 0)
- dev->readptr = dev->sh_mem + BANK2;
- }
-}
-
-
-#endif
diff --git a/drivers/staging/i4l/pcbit/module.c b/drivers/staging/i4l/pcbit/module.c
deleted file mode 100644
index 0a59bd0b8210..000000000000
--- a/drivers/staging/i4l/pcbit/module.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * PCBIT-D module support
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-
-#include <linux/isdnif.h>
-#include "pcbit.h"
-
-MODULE_DESCRIPTION("ISDN4Linux: Driver for PCBIT-T card");
-MODULE_AUTHOR("Pedro Roque Marques");
-MODULE_LICENSE("GPL");
-
-static int mem[MAX_PCBIT_CARDS];
-static int irq[MAX_PCBIT_CARDS];
-
-module_param_array(mem, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-
-static int num_boards;
-struct pcbit_dev *dev_pcbit[MAX_PCBIT_CARDS];
-
-static int __init pcbit_init(void)
-{
- int board;
-
- num_boards = 0;
-
- printk(KERN_NOTICE
- "PCBIT-D device driver v 0.5-fjpc0 19991204 - "
- "Copyright (C) 1996 Universidade de Lisboa\n");
-
- if (mem[0] || irq[0])
- {
- for (board = 0; board < MAX_PCBIT_CARDS && mem[board] && irq[board]; board++)
- {
- if (!mem[board])
- mem[board] = 0xD0000;
- if (!irq[board])
- irq[board] = 5;
-
- if (pcbit_init_dev(board, mem[board], irq[board]) == 0)
- num_boards++;
-
- else
- {
- printk(KERN_WARNING
- "pcbit_init failed for dev %d",
- board + 1);
- return -EIO;
- }
- }
- }
-
- /* Hardcoded default settings detection */
-
- if (!num_boards)
- {
- printk(KERN_INFO
- "Trying to detect board using default settings\n");
- if (pcbit_init_dev(0, 0xD0000, 5) == 0)
- num_boards++;
- else
- return -EIO;
- }
- return 0;
-}
-
-static void __exit pcbit_exit(void)
-{
-#ifdef MODULE
- int board;
-
- for (board = 0; board < num_boards; board++)
- pcbit_terminate(board);
- printk(KERN_NOTICE
- "PCBIT-D module unloaded\n");
-#endif
-}
-
-#ifndef MODULE
-#define MAX_PARA (MAX_PCBIT_CARDS * 2)
-static int __init pcbit_setup(char *line)
-{
- int i, j, argc;
- char *str;
- int ints[MAX_PARA + 1];
-
- str = get_options(line, MAX_PARA, ints);
- argc = ints[0];
- i = 0;
- j = 1;
-
- while (argc && (i < MAX_PCBIT_CARDS)) {
-
- if (argc) {
- mem[i] = ints[j];
- j++; argc--;
- }
-
- if (argc) {
- irq[i] = ints[j];
- j++; argc--;
- }
-
- i++;
- }
- return (1);
-}
-__setup("pcbit=", pcbit_setup);
-#endif
-
-module_init(pcbit_init);
-module_exit(pcbit_exit);
diff --git a/drivers/staging/i4l/pcbit/pcbit.h b/drivers/staging/i4l/pcbit/pcbit.h
deleted file mode 100644
index 0a5a99440a80..000000000000
--- a/drivers/staging/i4l/pcbit/pcbit.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * PCBIT-D device driver definitions
- *
- * Copyright (C) 1996 Universidade de Lisboa
- *
- * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License, incorporated herein by reference.
- */
-
-#ifndef PCBIT_H
-#define PCBIT_H
-
-#include <linux/workqueue.h>
-
-#define MAX_PCBIT_CARDS 4
-
-
-#define BLOCK_TIMER
-
-#ifdef __KERNEL__
-
-struct pcbit_chan {
- unsigned short id;
- unsigned short callref; /* Call Reference */
- unsigned char proto; /* layer2protocol */
- unsigned char queued; /* unacked data messages */
- unsigned char layer2link; /* used in TData */
- unsigned char snum; /* used in TData */
- unsigned short s_refnum;
- unsigned short r_refnum;
- unsigned short fsm_state;
- struct timer_list fsm_timer;
-#ifdef BLOCK_TIMER
- struct timer_list block_timer;
-#endif
-};
-
-struct msn_entry {
- char *msn;
- struct msn_entry *next;
-};
-
-struct pcbit_dev {
- /* board */
-
- volatile unsigned char __iomem *sh_mem; /* RDP address */
- unsigned long ph_mem;
- unsigned int irq;
- unsigned int id;
- unsigned int interrupt; /* set during interrupt
- processing */
- spinlock_t lock;
- /* isdn4linux */
-
- struct msn_entry *msn_list; /* ISDN address list */
-
- isdn_if *dev_if;
-
- ushort ll_hdrlen;
- ushort hl_hdrlen;
-
- /* link layer */
- unsigned char l2_state;
-
- struct frame_buf *read_queue;
- struct frame_buf *read_frame;
- struct frame_buf *write_queue;
-
- /* Protocol start */
- wait_queue_head_t set_running_wq;
- struct timer_list set_running_timer;
-
- struct timer_list error_recover_timer;
-
- struct work_struct qdelivery;
-
- u_char w_busy;
- u_char r_busy;
-
- volatile unsigned char __iomem *readptr;
- volatile unsigned char __iomem *writeptr;
-
- ushort loadptr;
-
- unsigned short fsize[8]; /* sent layer2 frames size */
-
- unsigned char send_seq;
- unsigned char rcv_seq;
- unsigned char unack_seq;
-
- unsigned short free;
-
- /* channels */
-
- struct pcbit_chan *b1;
- struct pcbit_chan *b2;
-};
-
-#define STATS_TIMER (10 * HZ)
-#define ERRTIME (HZ / 10)
-
-/* MRU */
-#define MAXBUFSIZE 1534
-#define MRU MAXBUFSIZE
-
-#define STATBUF_LEN 2048
-/*
- *
- */
-
-#endif /* __KERNEL__ */
-
-/* isdn_ctrl only allows a long sized argument */
-
-struct pcbit_ioctl {
- union {
- struct byte_op {
- ushort addr;
- ushort value;
- } rdp_byte;
- unsigned long l2_status;
- } info;
-};
-
-
-
-#define PCBIT_IOCTL_GETSTAT 0x01 /* layer2 status */
-#define PCBIT_IOCTL_LWMODE 0x02 /* linear write mode */
-#define PCBIT_IOCTL_STRLOAD 0x03 /* start load mode */
-#define PCBIT_IOCTL_ENDLOAD 0x04 /* end load mode */
-#define PCBIT_IOCTL_SETBYTE 0x05 /* set byte */
-#define PCBIT_IOCTL_GETBYTE 0x06 /* get byte */
-#define PCBIT_IOCTL_RUNNING 0x07 /* set protocol running */
-#define PCBIT_IOCTL_WATCH188 0x08 /* set watch 188 */
-#define PCBIT_IOCTL_PING188 0x09 /* ping 188 */
-#define PCBIT_IOCTL_FWMODE 0x0A /* firmware write mode */
-#define PCBIT_IOCTL_STOP 0x0B /* stop protocol */
-#define PCBIT_IOCTL_APION 0x0C /* issue API_ON */
-
-#ifndef __KERNEL__
-
-#define PCBIT_GETSTAT (PCBIT_IOCTL_GETSTAT + IIOCDRVCTL)
-#define PCBIT_LWMODE (PCBIT_IOCTL_LWMODE + IIOCDRVCTL)
-#define PCBIT_STRLOAD (PCBIT_IOCTL_STRLOAD + IIOCDRVCTL)
-#define PCBIT_ENDLOAD (PCBIT_IOCTL_ENDLOAD + IIOCDRVCTL)
-#define PCBIT_SETBYTE (PCBIT_IOCTL_SETBYTE + IIOCDRVCTL)
-#define PCBIT_GETBYTE (PCBIT_IOCTL_GETBYTE + IIOCDRVCTL)
-#define PCBIT_RUNNING (PCBIT_IOCTL_RUNNING + IIOCDRVCTL)
-#define PCBIT_WATCH188 (PCBIT_IOCTL_WATCH188 + IIOCDRVCTL)
-#define PCBIT_PING188 (PCBIT_IOCTL_PING188 + IIOCDRVCTL)
-#define PCBIT_FWMODE (PCBIT_IOCTL_FWMODE + IIOCDRVCTL)
-#define PCBIT_STOP (PCBIT_IOCTL_STOP + IIOCDRVCTL)
-#define PCBIT_APION (PCBIT_IOCTL_APION + IIOCDRVCTL)
-
-#define MAXSUPERLINE 3000
-
-#endif
-
-#define L2_DOWN 0
-#define L2_LOADING 1
-#define L2_LWMODE 2
-#define L2_FWMODE 3
-#define L2_STARTING 4
-#define L2_RUNNING 5
-#define L2_ERROR 6
-
-void pcbit_deliver(struct work_struct *work);
-int pcbit_init_dev(int board, int mem_base, int irq);
-void pcbit_terminate(int board);
-void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg, struct sk_buff *skb,
- ushort hdr_len, ushort refnum);
-void pcbit_state_change(struct pcbit_dev *dev, struct pcbit_chan *chan,
- unsigned short i, unsigned short ev, unsigned short f);
-
-#endif
diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c
index 6f3f8ff2a066..7963d4a83f84 100644
--- a/drivers/staging/iio/accel/adis16201_core.c
+++ b/drivers/staging/iio/accel/adis16201_core.c
@@ -1,5 +1,5 @@
/*
- * ADIS16201 Programmable Digital Vibration Sensor driver
+ * ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer
*
* Copyright 2010 Analog Devices Inc.
*
@@ -243,6 +243,6 @@ static struct spi_driver adis16201_driver = {
module_spi_driver(adis16201_driver);
MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16201 Programmable Digital Vibration Sensor driver");
+MODULE_DESCRIPTION("Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:adis16201");
diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c
index c70671778bae..bd8119a23339 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
+ * ADIS16203 Programmable 360 Degrees Inclinometer
*
- * Copyright 2030 Analog Devices Inc.
+ * Copyright 2010 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -211,6 +211,6 @@ static struct spi_driver adis16203_driver = {
module_spi_driver(adis16203_driver);
MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable Digital Vibration Sensor driver");
+MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:adis16203");
diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c
index 8dbad58628a1..a599e19303d3 100644
--- a/drivers/staging/iio/accel/adis16209_core.c
+++ b/drivers/staging/iio/accel/adis16209_core.c
@@ -1,5 +1,5 @@
/*
- * ADIS16209 Programmable Digital Vibration Sensor driver
+ * ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer
*
* Copyright 2010 Analog Devices Inc.
*
@@ -243,6 +243,6 @@ static struct spi_driver adis16209_driver = {
module_spi_driver(adis16209_driver);
MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16209 Digital Vibration Sensor driver");
+MODULE_DESCRIPTION("Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:adis16209");
diff --git a/drivers/staging/iio/adc/ad7606.c b/drivers/staging/iio/adc/ad7606.c
index 453190864b2f..9dbfa64b1e53 100644
--- a/drivers/staging/iio/adc/ad7606.c
+++ b/drivers/staging/iio/adc/ad7606.c
@@ -26,6 +26,11 @@
#include "ad7606.h"
+/* Scales are computed as 2.5/2**16 and 5/2**16 respectively */
+static const unsigned int scale_avail[2][2] = {
+ {0, 38147}, {0, 76294}
+};
+
static int ad7606_reset(struct ad7606_state *st)
{
if (st->gpio_reset) {
@@ -151,9 +156,9 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
*val = (short)ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = st->range * 2;
- *val2 = st->chip_info->channels[0].scan_type.realbits;
- return IIO_VAL_FRACTIONAL_LOG2;
+ *val = scale_avail[st->range][0];
+ *val2 = scale_avail[st->range][1];
+ return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
*val = st->oversampling;
return IIO_VAL_INT;
@@ -161,42 +166,22 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
return -EINVAL;
}
-static ssize_t ad7606_show_range(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7606_state *st = iio_priv(indio_dev);
-
- return sprintf(buf, "%u\n", st->range);
-}
-
-static ssize_t ad7606_store_range(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t in_voltage_scale_available_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct iio_dev *indio_dev = dev_to_iio_dev(dev);
- struct ad7606_state *st = iio_priv(indio_dev);
- unsigned long lval;
- int ret;
-
- ret = kstrtoul(buf, 10, &lval);
- if (ret)
- return ret;
+ int i, len = 0;
- if (!(lval == 5000 || lval == 10000))
- return -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(scale_avail); i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06u ",
+ scale_avail[i][0], scale_avail[i][1]);
- mutex_lock(&indio_dev->mlock);
- gpiod_set_value(st->gpio_range, lval == 10000);
- st->range = lval;
- mutex_unlock(&indio_dev->mlock);
+ buf[len - 1] = '\n';
- return count;
+ return len;
}
-static IIO_DEVICE_ATTR(in_voltage_range, S_IRUGO | S_IWUSR,
- ad7606_show_range, ad7606_store_range, 0);
-static IIO_CONST_ATTR(in_voltage_range_available, "5000 10000");
+static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0);
static int ad7606_oversampling_get_index(unsigned int val)
{
@@ -218,9 +203,23 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
{
struct ad7606_state *st = iio_priv(indio_dev);
int values[3];
- int ret;
+ int ret, i;
switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ ret = -EINVAL;
+ mutex_lock(&indio_dev->mlock);
+ for (i = 0; i < ARRAY_SIZE(scale_avail); i++)
+ if (val2 == scale_avail[i][1]) {
+ gpiod_set_value(st->gpio_range, i);
+ st->range = i;
+
+ ret = 0;
+ break;
+ }
+ mutex_unlock(&indio_dev->mlock);
+
+ return ret;
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
if (val2)
return -EINVAL;
@@ -247,8 +246,7 @@ static int ad7606_write_raw(struct iio_dev *indio_dev,
static IIO_CONST_ATTR(oversampling_ratio_available, "1 2 4 8 16 32 64");
static struct attribute *ad7606_attributes_os_and_range[] = {
- &iio_dev_attr_in_voltage_range.dev_attr.attr,
- &iio_const_attr_in_voltage_range_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
&iio_const_attr_oversampling_ratio_available.dev_attr.attr,
NULL,
};
@@ -267,8 +265,7 @@ static const struct attribute_group ad7606_attribute_group_os = {
};
static struct attribute *ad7606_attributes_range[] = {
- &iio_dev_attr_in_voltage_range.dev_attr.attr,
- &iio_const_attr_in_voltage_range_available.dev_attr.attr,
+ &iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
NULL,
};
@@ -397,6 +394,7 @@ static const struct iio_info ad7606_info_os = {
static const struct iio_info ad7606_info_range = {
.driver_module = THIS_MODULE,
.read_raw = &ad7606_read_raw,
+ .write_raw = &ad7606_write_raw,
.attrs = &ad7606_attribute_group_range,
};
@@ -417,7 +415,8 @@ int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
st->dev = dev;
st->bops = bops;
st->base_address = base_address;
- st->range = 5000;
+ /* tied to logic low, analog input range is +/- 5V */
+ st->range = 0;
st->oversampling = 1;
INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
@@ -525,7 +524,7 @@ static int ad7606_resume(struct device *dev)
struct ad7606_state *st = iio_priv(indio_dev);
if (st->gpio_standby) {
- gpiod_set_value(st->gpio_range, st->range == 10000);
+ gpiod_set_value(st->gpio_range, st->range);
gpiod_set_value(st->gpio_standby, 1);
ad7606_reset(st);
}
diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c
index 72551f827382..17d280581e24 100644
--- a/drivers/staging/iio/adc/ad7816.c
+++ b/drivers/staging/iio/adc/ad7816.c
@@ -139,7 +139,7 @@ static ssize_t ad7816_store_mode(struct device *dev,
return len;
}
-static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(mode, 0644,
ad7816_show_mode,
ad7816_store_mode,
0);
@@ -151,7 +151,7 @@ static ssize_t ad7816_show_available_modes(struct device *dev,
return sprintf(buf, "full\npower-save\n");
}
-static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes,
+static IIO_DEVICE_ATTR(available_modes, 0444, ad7816_show_available_modes,
NULL, 0);
static ssize_t ad7816_show_channel(struct device *dev,
@@ -197,7 +197,7 @@ static ssize_t ad7816_store_channel(struct device *dev,
return len;
}
-static IIO_DEVICE_ATTR(channel, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(channel, 0644,
ad7816_show_channel,
ad7816_store_channel,
0);
@@ -228,7 +228,7 @@ static ssize_t ad7816_show_value(struct device *dev,
return sprintf(buf, "%u\n", data);
}
-static IIO_DEVICE_ATTR(value, S_IRUGO, ad7816_show_value, NULL, 0);
+static IIO_DEVICE_ATTR(value, 0444, ad7816_show_value, NULL, 0);
static struct attribute *ad7816_attributes[] = {
&iio_dev_attr_available_modes.dev_attr.attr,
@@ -319,7 +319,7 @@ static inline ssize_t ad7816_set_oti(struct device *dev,
return len;
}
-static IIO_DEVICE_ATTR(oti, S_IRUGO | S_IWUSR,
+static IIO_DEVICE_ATTR(oti, 0644,
ad7816_show_oti, ad7816_set_oti, 0);
static struct attribute *ad7816_event_attributes[] = {
diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c
index 0ccf192b9a03..f66dd3ebbab1 100644
--- a/drivers/staging/iio/addac/adt7316-i2c.c
+++ b/drivers/staging/iio/addac/adt7316-i2c.c
@@ -93,7 +93,7 @@ static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data)
*/
static int adt7316_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct adt7316_bus bus = {
.client = client,
diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c
index a7d90c8bac5e..6054c7298fce 100644
--- a/drivers/staging/iio/addac/adt7316.c
+++ b/drivers/staging/iio/addac/adt7316.c
@@ -661,8 +661,9 @@ static ssize_t adt7316_store_da_high_resolution(struct device *dev,
chip->dac_bits = 12;
else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517)
chip->dac_bits = 10;
- } else
+ } else {
config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION);
+ }
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3);
if (ret)
diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c
index 6998c3ddfb6a..ca72af3e9d4b 100644
--- a/drivers/staging/iio/cdc/ad7150.c
+++ b/drivers/staging/iio/cdc/ad7150.c
@@ -274,7 +274,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
error_ret:
mutex_unlock(&chip->state_lock);
- return 0;
+ return ret;
}
static int ad7150_read_event_value(struct iio_dev *indio_dev,
@@ -414,7 +414,7 @@ error_ret:
#define AD7150_TIMEOUT(chan, type, dir, ev_type, ev_dir) \
IIO_DEVICE_ATTR(in_capacitance##chan##_##type##_##dir##_timeout, \
- S_IRUGO | S_IWUSR, \
+ 0644, \
&ad7150_show_timeout, \
&ad7150_store_timeout, \
IIO_UNMOD_EVENT_CODE(IIO_CAPACITANCE, \
@@ -610,27 +610,27 @@ static int ad7150_probe(struct i2c_client *client,
if (client->irq) {
ret = devm_request_threaded_irq(&client->dev, client->irq,
- NULL,
- &ad7150_event_handler,
- IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT,
- "ad7150_irq1",
- indio_dev);
+ NULL,
+ &ad7150_event_handler,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ "ad7150_irq1",
+ indio_dev);
if (ret)
return ret;
}
if (client->dev.platform_data) {
ret = devm_request_threaded_irq(&client->dev, *(unsigned int *)
- client->dev.platform_data,
- NULL,
- &ad7150_event_handler,
- IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT,
- "ad7150_irq2",
- indio_dev);
+ client->dev.platform_data,
+ NULL,
+ &ad7150_event_handler,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING |
+ IRQF_ONESHOT,
+ "ad7150_irq2",
+ indio_dev);
if (ret)
return ret;
}
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index 944789843938..5e96352fa4ac 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -23,8 +23,8 @@
#include <linux/iio/kfifo_buf.h>
/* AD5933/AD5934 Registers */
-#define AD5933_REG_CONTROL_HB 0x80 /* R/W, 2 bytes */
-#define AD5933_REG_CONTROL_LB 0x81 /* R/W, 2 bytes */
+#define AD5933_REG_CONTROL_HB 0x80 /* R/W, 1 byte */
+#define AD5933_REG_CONTROL_LB 0x81 /* R/W, 1 byte */
#define AD5933_REG_FREQ_START 0x82 /* R/W, 3 bytes */
#define AD5933_REG_FREQ_INC 0x85 /* R/W, 3 bytes */
#define AD5933_REG_INC_NUM 0x88 /* R/W, 2 bytes, 9 bit */
diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c
index aa413e5878b9..6bb6d37cc7d1 100644
--- a/drivers/staging/iio/light/isl29028.c
+++ b/drivers/staging/iio/light/isl29028.c
@@ -26,39 +26,42 @@
#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
+#include <linux/pm_runtime.h>
-#define ISL29028_CONV_TIME_MS 100
+#define ISL29028_CONV_TIME_MS 100
-#define ISL29028_REG_CONFIGURE 0x01
+#define ISL29028_REG_CONFIGURE 0x01
-#define ISL29028_CONF_ALS_IR_MODE_ALS 0
-#define ISL29028_CONF_ALS_IR_MODE_IR BIT(0)
-#define ISL29028_CONF_ALS_IR_MODE_MASK BIT(0)
+#define ISL29028_CONF_ALS_IR_MODE_ALS 0
+#define ISL29028_CONF_ALS_IR_MODE_IR BIT(0)
+#define ISL29028_CONF_ALS_IR_MODE_MASK BIT(0)
-#define ISL29028_CONF_ALS_RANGE_LOW_LUX 0
+#define ISL29028_CONF_ALS_RANGE_LOW_LUX 0
#define ISL29028_CONF_ALS_RANGE_HIGH_LUX BIT(1)
-#define ISL29028_CONF_ALS_RANGE_MASK BIT(1)
+#define ISL29028_CONF_ALS_RANGE_MASK BIT(1)
-#define ISL29028_CONF_ALS_DIS 0
-#define ISL29028_CONF_ALS_EN BIT(2)
-#define ISL29028_CONF_ALS_EN_MASK BIT(2)
+#define ISL29028_CONF_ALS_DIS 0
+#define ISL29028_CONF_ALS_EN BIT(2)
+#define ISL29028_CONF_ALS_EN_MASK BIT(2)
-#define ISL29028_CONF_PROX_SLP_SH 4
-#define ISL29028_CONF_PROX_SLP_MASK (7 << ISL29028_CONF_PROX_SLP_SH)
+#define ISL29028_CONF_PROX_SLP_SH 4
+#define ISL29028_CONF_PROX_SLP_MASK (7 << ISL29028_CONF_PROX_SLP_SH)
-#define ISL29028_CONF_PROX_EN BIT(7)
-#define ISL29028_CONF_PROX_EN_MASK BIT(7)
+#define ISL29028_CONF_PROX_EN BIT(7)
+#define ISL29028_CONF_PROX_EN_MASK BIT(7)
-#define ISL29028_REG_INTERRUPT 0x02
+#define ISL29028_REG_INTERRUPT 0x02
-#define ISL29028_REG_PROX_DATA 0x08
-#define ISL29028_REG_ALSIR_L 0x09
-#define ISL29028_REG_ALSIR_U 0x0A
+#define ISL29028_REG_PROX_DATA 0x08
+#define ISL29028_REG_ALSIR_L 0x09
+#define ISL29028_REG_ALSIR_U 0x0A
-#define ISL29028_REG_TEST1_MODE 0x0E
-#define ISL29028_REG_TEST2_MODE 0x0F
+#define ISL29028_REG_TEST1_MODE 0x0E
+#define ISL29028_REG_TEST2_MODE 0x0F
-#define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1)
+#define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1)
+
+#define ISL29028_POWER_OFF_DELAY_MS 2000
enum isl29028_als_ir_mode {
ISL29028_MODE_NONE = 0,
@@ -67,62 +70,93 @@ enum isl29028_als_ir_mode {
};
struct isl29028_chip {
- struct mutex lock;
- struct regmap *regmap;
-
- unsigned int prox_sampling;
- bool enable_prox;
-
- int lux_scale;
+ struct mutex lock;
+ struct regmap *regmap;
+ unsigned int prox_sampling;
+ bool enable_prox;
+ int lux_scale;
enum isl29028_als_ir_mode als_ir_mode;
};
static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
unsigned int sampling)
{
+ struct device *dev = regmap_get_device(chip->regmap);
static unsigned int prox_period[] = {800, 400, 200, 100, 75, 50, 12, 0};
- int sel;
unsigned int period = DIV_ROUND_UP(1000, sampling);
+ int sel, ret;
for (sel = 0; sel < ARRAY_SIZE(prox_period); ++sel) {
if (period >= prox_period[sel])
break;
}
- return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- ISL29028_CONF_PROX_SLP_MASK,
- sel << ISL29028_CONF_PROX_SLP_SH);
+
+ ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
+ ISL29028_CONF_PROX_SLP_MASK,
+ sel << ISL29028_CONF_PROX_SLP_SH);
+
+ if (ret < 0) {
+ dev_err(dev, "%s(): Error %d setting the proximity sampling\n",
+ __func__, ret);
+ return ret;
+ }
+
+ chip->prox_sampling = sampling;
+
+ return ret;
}
-static int isl29028_enable_proximity(struct isl29028_chip *chip, bool enable)
+static int isl29028_enable_proximity(struct isl29028_chip *chip)
{
int ret;
- int val = 0;
- if (enable)
- val = ISL29028_CONF_PROX_EN;
+ ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling);
+ if (ret < 0)
+ return ret;
+
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- ISL29028_CONF_PROX_EN_MASK, val);
+ ISL29028_CONF_PROX_EN_MASK,
+ ISL29028_CONF_PROX_EN);
if (ret < 0)
return ret;
/* Wait for conversion to be complete for first sample */
mdelay(DIV_ROUND_UP(1000, chip->prox_sampling));
+
return 0;
}
static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale)
{
+ struct device *dev = regmap_get_device(chip->regmap);
int val = (lux_scale == 2000) ? ISL29028_CONF_ALS_RANGE_HIGH_LUX :
ISL29028_CONF_ALS_RANGE_LOW_LUX;
+ int ret;
- return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- ISL29028_CONF_ALS_RANGE_MASK, val);
+ ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
+ ISL29028_CONF_ALS_RANGE_MASK, val);
+ if (ret < 0) {
+ dev_err(dev, "%s(): Error %d setting the ALS scale\n", __func__,
+ ret);
+ return ret;
+ }
+
+ chip->lux_scale = lux_scale;
+
+ return ret;
}
static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
enum isl29028_als_ir_mode mode)
{
- int ret = 0;
+ int ret;
+
+ if (chip->als_ir_mode == mode)
+ return 0;
+
+ ret = isl29028_set_als_scale(chip, chip->lux_scale);
+ if (ret < 0)
+ return ret;
switch (mode) {
case ISL29028_MODE_ALS:
@@ -136,16 +170,15 @@ static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
ISL29028_CONF_ALS_RANGE_MASK,
ISL29028_CONF_ALS_RANGE_HIGH_LUX);
break;
-
case ISL29028_MODE_IR:
ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
ISL29028_CONF_ALS_IR_MODE_MASK,
ISL29028_CONF_ALS_IR_MODE_IR);
break;
-
case ISL29028_MODE_NONE:
return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
- ISL29028_CONF_ALS_EN_MASK, ISL29028_CONF_ALS_DIS);
+ ISL29028_CONF_ALS_EN_MASK,
+ ISL29028_CONF_ALS_DIS);
}
if (ret < 0)
@@ -160,6 +193,9 @@ static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
/* Need to wait for conversion time if ALS/IR mode enabled */
mdelay(ISL29028_CONV_TIME_MS);
+
+ chip->als_ir_mode = mode;
+
return 0;
}
@@ -173,18 +209,21 @@ static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir)
ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb);
if (ret < 0) {
dev_err(dev,
- "Error in reading register ALSIR_L err %d\n", ret);
+ "%s(): Error %d reading register ALSIR_L\n",
+ __func__, ret);
return ret;
}
ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb);
if (ret < 0) {
dev_err(dev,
- "Error in reading register ALSIR_U err %d\n", ret);
+ "%s(): Error %d reading register ALSIR_U\n",
+ __func__, ret);
return ret;
}
*als_ir = ((msb & 0xF) << 8) | (lsb & 0xFF);
+
return 0;
}
@@ -194,27 +233,24 @@ static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox)
unsigned int data;
int ret;
+ if (!chip->enable_prox) {
+ ret = isl29028_enable_proximity(chip);
+ if (ret < 0)
+ return ret;
+
+ chip->enable_prox = true;
+ }
+
ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data);
if (ret < 0) {
- dev_err(dev, "Error in reading register %d, error %d\n",
- ISL29028_REG_PROX_DATA, ret);
+ dev_err(dev, "%s(): Error %d reading register PROX_DATA\n",
+ __func__, ret);
return ret;
}
- *prox = data;
- return 0;
-}
-static int isl29028_proxim_get(struct isl29028_chip *chip, int *prox_data)
-{
- int ret;
+ *prox = data;
- if (!chip->enable_prox) {
- ret = isl29028_enable_proximity(chip, true);
- if (ret < 0)
- return ret;
- chip->enable_prox = true;
- }
- return isl29028_read_proxim(chip, prox_data);
+ return 0;
}
static int isl29028_als_get(struct isl29028_chip *chip, int *als_data)
@@ -223,14 +259,11 @@ static int isl29028_als_get(struct isl29028_chip *chip, int *als_data)
int ret;
int als_ir_data;
- if (chip->als_ir_mode != ISL29028_MODE_ALS) {
- ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_ALS);
- if (ret < 0) {
- dev_err(dev,
- "Error in enabling ALS mode err %d\n", ret);
- return ret;
- }
- chip->als_ir_mode = ISL29028_MODE_ALS;
+ ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_ALS);
+ if (ret < 0) {
+ dev_err(dev, "%s(): Error %d enabling ALS mode\n", __func__,
+ ret);
+ return ret;
}
ret = isl29028_read_als_ir(chip, &als_ir_data);
@@ -248,6 +281,7 @@ static int isl29028_als_get(struct isl29028_chip *chip, int *als_data)
als_ir_data = (als_ir_data * 49) / 100;
*als_data = als_ir_data;
+
return 0;
}
@@ -256,18 +290,33 @@ static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data)
struct device *dev = regmap_get_device(chip->regmap);
int ret;
- if (chip->als_ir_mode != ISL29028_MODE_IR) {
- ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_IR);
- if (ret < 0) {
- dev_err(dev,
- "Error in enabling IR mode err %d\n", ret);
- return ret;
- }
- chip->als_ir_mode = ISL29028_MODE_IR;
+ ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_IR);
+ if (ret < 0) {
+ dev_err(dev, "%s(): Error %d enabling IR mode\n", __func__,
+ ret);
+ return ret;
}
+
return isl29028_read_als_ir(chip, ir_data);
}
+static int isl29028_set_pm_runtime_busy(struct isl29028_chip *chip, bool on)
+{
+ struct device *dev = regmap_get_device(chip->regmap);
+ int ret;
+
+ if (on) {
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ pm_runtime_put_noidle(dev);
+ } else {
+ pm_runtime_mark_last_busy(dev);
+ ret = pm_runtime_put_autosuspend(dev);
+ }
+
+ return ret;
+}
+
/* Channel IO */
static int isl29028_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
@@ -275,58 +324,65 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
{
struct isl29028_chip *chip = iio_priv(indio_dev);
struct device *dev = regmap_get_device(chip->regmap);
- int ret = -EINVAL;
+ int ret;
+
+ ret = isl29028_set_pm_runtime_busy(chip, true);
+ if (ret < 0)
+ return ret;
mutex_lock(&chip->lock);
+
+ ret = -EINVAL;
switch (chan->type) {
case IIO_PROXIMITY:
if (mask != IIO_CHAN_INFO_SAMP_FREQ) {
dev_err(dev,
- "proximity: mask value 0x%08lx not supported\n",
- mask);
+ "%s(): proximity: Mask value 0x%08lx is not supported\n",
+ __func__, mask);
break;
}
+
if (val < 1 || val > 100) {
dev_err(dev,
- "Samp_freq %d is not in range[1:100]\n", val);
+ "%s(): proximity: Sampling frequency %d is not in the range [1:100]\n",
+ __func__, val);
break;
}
+
ret = isl29028_set_proxim_sampling(chip, val);
- if (ret < 0) {
- dev_err(dev,
- "Setting proximity samp_freq fail, err %d\n",
- ret);
- break;
- }
- chip->prox_sampling = val;
break;
-
case IIO_LIGHT:
if (mask != IIO_CHAN_INFO_SCALE) {
dev_err(dev,
- "light: mask value 0x%08lx not supported\n",
- mask);
+ "%s(): light: Mask value 0x%08lx is not supported\n",
+ __func__, mask);
break;
}
- if ((val != 125) && (val != 2000)) {
+
+ if (val != 125 && val != 2000) {
dev_err(dev,
- "lux scale %d is invalid [125, 2000]\n", val);
+ "%s(): light: Lux scale %d is not in the set {125, 2000}\n",
+ __func__, val);
break;
}
+
ret = isl29028_set_als_scale(chip, val);
- if (ret < 0) {
- dev_err(dev,
- "Setting lux scale fail with error %d\n", ret);
- break;
- }
- chip->lux_scale = val;
break;
-
default:
- dev_err(dev, "Unsupported channel type\n");
+ dev_err(dev, "%s(): Unsupported channel type %x\n",
+ __func__, chan->type);
break;
}
+
mutex_unlock(&chip->lock);
+
+ if (ret < 0)
+ return ret;
+
+ ret = isl29028_set_pm_runtime_busy(chip, false);
+ if (ret < 0)
+ return ret;
+
return ret;
}
@@ -336,9 +392,15 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
{
struct isl29028_chip *chip = iio_priv(indio_dev);
struct device *dev = regmap_get_device(chip->regmap);
- int ret = -EINVAL;
+ int ret, pm_ret;
+
+ ret = isl29028_set_pm_runtime_busy(chip, true);
+ if (ret < 0)
+ return ret;
mutex_lock(&chip->lock);
+
+ ret = -EINVAL;
switch (mask) {
case IIO_CHAN_INFO_RAW:
case IIO_CHAN_INFO_PROCESSED:
@@ -350,35 +412,50 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
ret = isl29028_ir_get(chip, val);
break;
case IIO_PROXIMITY:
- ret = isl29028_proxim_get(chip, val);
+ ret = isl29028_read_proxim(chip, val);
break;
default:
break;
}
+
if (ret < 0)
break;
+
ret = IIO_VAL_INT;
break;
-
case IIO_CHAN_INFO_SAMP_FREQ:
if (chan->type != IIO_PROXIMITY)
break;
+
*val = chip->prox_sampling;
ret = IIO_VAL_INT;
break;
-
case IIO_CHAN_INFO_SCALE:
if (chan->type != IIO_LIGHT)
break;
*val = chip->lux_scale;
ret = IIO_VAL_INT;
break;
-
default:
- dev_err(dev, "mask value 0x%08lx not supported\n", mask);
+ dev_err(dev, "%s(): mask value 0x%08lx is not supported\n",
+ __func__, mask);
break;
}
+
mutex_unlock(&chip->lock);
+
+ if (ret < 0)
+ return ret;
+
+ /**
+ * Preserve the ret variable if the call to
+ * isl29028_set_pm_runtime_busy() is successful so the reading
+ * (if applicable) is returned to user space.
+ */
+ pm_ret = isl29028_set_pm_runtime_busy(chip, false);
+ if (pm_ret < 0)
+ return pm_ret;
+
return ret;
}
@@ -386,7 +463,6 @@ static IIO_CONST_ATTR(in_proximity_sampling_frequency_available,
"1 3 5 10 13 20 83 100");
static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000");
-#define ISL29028_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
static struct attribute *isl29028_attributes[] = {
ISL29028_CONST_ATTR(in_proximity_sampling_frequency_available),
@@ -420,45 +496,19 @@ static const struct iio_info isl29028_info = {
.write_raw = isl29028_write_raw,
};
-static int isl29028_chip_init(struct isl29028_chip *chip)
+static int isl29028_clear_configure_reg(struct isl29028_chip *chip)
{
struct device *dev = regmap_get_device(chip->regmap);
int ret;
- chip->enable_prox = false;
- chip->prox_sampling = 20;
- chip->lux_scale = 2000;
- chip->als_ir_mode = ISL29028_MODE_NONE;
-
- ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);
- if (ret < 0) {
- dev_err(dev, "%s(): write to reg %d failed, err = %d\n",
- __func__, ISL29028_REG_TEST1_MODE, ret);
- return ret;
- }
- ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0);
- if (ret < 0) {
- dev_err(dev, "%s(): write to reg %d failed, err = %d\n",
- __func__, ISL29028_REG_TEST2_MODE, ret);
- return ret;
- }
-
ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0);
- if (ret < 0) {
- dev_err(dev, "%s(): write to reg %d failed, err = %d\n",
- __func__, ISL29028_REG_CONFIGURE, ret);
- return ret;
- }
+ if (ret < 0)
+ dev_err(dev, "%s(): Error %d clearing the CONFIGURE register\n",
+ __func__, ret);
- ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling);
- if (ret < 0) {
- dev_err(dev, "setting the proximity, err = %d\n", ret);
- return ret;
- }
+ chip->als_ir_mode = ISL29028_MODE_NONE;
+ chip->enable_prox = false;
- ret = isl29028_set_als_scale(chip, chip->lux_scale);
- if (ret < 0)
- dev_err(dev, "setting als scale failed, err = %d\n", ret);
return ret;
}
@@ -492,10 +542,8 @@ static int isl29028_probe(struct i2c_client *client,
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
- if (!indio_dev) {
- dev_err(&client->dev, "iio allocation fails\n");
+ if (!indio_dev)
return -ENOMEM;
- }
chip = iio_priv(indio_dev);
@@ -505,33 +553,102 @@ static int isl29028_probe(struct i2c_client *client,
chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config);
if (IS_ERR(chip->regmap)) {
ret = PTR_ERR(chip->regmap);
- dev_err(&client->dev, "regmap initialization failed: %d\n",
- ret);
+ dev_err(&client->dev, "%s: Error %d initializing regmap\n",
+ __func__, ret);
return ret;
}
- ret = isl29028_chip_init(chip);
+ chip->enable_prox = false;
+ chip->prox_sampling = 20;
+ chip->lux_scale = 2000;
+
+ ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);
if (ret < 0) {
- dev_err(&client->dev, "chip initialization failed: %d\n", ret);
+ dev_err(&client->dev,
+ "%s(): Error %d writing to TEST1_MODE register\n",
+ __func__, ret);
return ret;
}
+ ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0);
+ if (ret < 0) {
+ dev_err(&client->dev,
+ "%s(): Error %d writing to TEST2_MODE register\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = isl29028_clear_configure_reg(chip);
+ if (ret < 0)
+ return ret;
+
indio_dev->info = &isl29028_info;
indio_dev->channels = isl29028_channels;
indio_dev->num_channels = ARRAY_SIZE(isl29028_channels);
indio_dev->name = id->name;
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
+
+ pm_runtime_enable(&client->dev);
+ pm_runtime_set_autosuspend_delay(&client->dev,
+ ISL29028_POWER_OFF_DELAY_MS);
+ pm_runtime_use_autosuspend(&client->dev);
+
ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
if (ret < 0) {
dev_err(&client->dev,
- "iio registration fails with error %d\n",
- ret);
+ "%s(): iio registration failed with error %d\n",
+ __func__, ret);
return ret;
}
+
return 0;
}
+static int isl29028_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+ struct isl29028_chip *chip = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
+
+ return isl29028_clear_configure_reg(chip);
+}
+
+static int __maybe_unused isl29028_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+ struct isl29028_chip *chip = iio_priv(indio_dev);
+ int ret;
+
+ mutex_lock(&chip->lock);
+
+ ret = isl29028_clear_configure_reg(chip);
+
+ mutex_unlock(&chip->lock);
+
+ return ret;
+}
+
+static int __maybe_unused isl29028_resume(struct device *dev)
+{
+ /**
+ * The specific component (ALS/IR or proximity) will enable itself as
+ * needed the next time that the user requests a reading. This is done
+ * above in isl29028_set_als_ir_mode() and isl29028_enable_proximity().
+ */
+ return 0;
+}
+
+static const struct dev_pm_ops isl29028_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(isl29028_suspend, isl29028_resume)
+ SET_RUNTIME_PM_OPS(isl29028_suspend, isl29028_resume, NULL)
+};
+
static const struct i2c_device_id isl29028_id[] = {
{"isl29028", 0},
{}
@@ -548,9 +665,11 @@ MODULE_DEVICE_TABLE(of, isl29028_of_match);
static struct i2c_driver isl29028_driver = {
.driver = {
.name = "isl29028",
+ .pm = &isl29028_pm_ops,
.of_match_table = isl29028_of_match,
},
.probe = isl29028_probe,
+ .remove = isl29028_remove,
.id_table = isl29028_id,
};
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c
index 4b5f05fdadcd..671dc9971610 100644
--- a/drivers/staging/iio/meter/ade7753.c
+++ b/drivers/staging/iio/meter/ade7753.c
@@ -377,7 +377,7 @@ static int ade7753_initial_setup(struct iio_dev *indio_dev)
}
ade7753_reset(dev);
- msleep(ADE7753_STARTUP_DELAY);
+ usleep_range(ADE7753_STARTUP_DELAY, ADE7753_STARTUP_DELAY + 100);
err_ret:
return ret;
diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h
index a9d93cc1c414..bfe749156bce 100644
--- a/drivers/staging/iio/meter/ade7753.h
+++ b/drivers/staging/iio/meter/ade7753.h
@@ -49,7 +49,7 @@
#define ADE7753_MAX_TX 4
#define ADE7753_MAX_RX 4
-#define ADE7753_STARTUP_DELAY 1
+#define ADE7753_STARTUP_DELAY 1000
#define ADE7753_SPI_SLOW (u32)(300 * 1000)
#define ADE7753_SPI_BURST (u32)(1000 * 1000)
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c
index 17309591ca57..024463a11c47 100644
--- a/drivers/staging/iio/meter/ade7754.c
+++ b/drivers/staging/iio/meter/ade7754.c
@@ -389,7 +389,7 @@ static int ade7754_initial_setup(struct iio_dev *indio_dev)
}
ade7754_reset(dev);
- msleep(ADE7754_STARTUP_DELAY);
+ usleep_range(ADE7754_STARTUP_DELAY, ADE7754_STARTUP_DELAY + 100);
err_ret:
return ret;
diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h
index e42ffc387a14..28f71c2cde0c 100644
--- a/drivers/staging/iio/meter/ade7754.h
+++ b/drivers/staging/iio/meter/ade7754.h
@@ -67,7 +67,7 @@
#define ADE7754_MAX_TX 4
#define ADE7754_MAX_RX 4
-#define ADE7754_STARTUP_DELAY 1
+#define ADE7754_STARTUP_DELAY 1000
#define ADE7754_SPI_SLOW (u32)(300 * 1000)
#define ADE7754_SPI_BURST (u32)(1000 * 1000)
diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h
index 1d04ec9524c8..6ae78d8aa24f 100644
--- a/drivers/staging/iio/meter/ade7758.h
+++ b/drivers/staging/iio/meter/ade7758.h
@@ -89,7 +89,7 @@
#define ADE7758_MAX_TX 8
#define ADE7758_MAX_RX 4
-#define ADE7758_STARTUP_DELAY 1
+#define ADE7758_STARTUP_DELAY 1000
#define AD7758_NUM_WAVSEL 5
#define AD7758_NUM_PHSEL 3
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index 3af8f77b8e41..99c89e606c8d 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -459,7 +459,7 @@ static int ade7758_initial_setup(struct iio_dev *indio_dev)
}
ade7758_reset(dev);
- msleep(ADE7758_STARTUP_DELAY);
+ usleep_range(ADE7758_STARTUP_DELAY, ADE7758_STARTUP_DELAY + 100);
err_ret:
return ret;
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 57c213dfadcc..6d7444d6e880 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -13,6 +13,7 @@
#include <asm/unaligned.h>
#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger_consumer.h>
#include "ade7758.h"
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index 80144d40d9ca..944ee3401029 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -338,7 +338,7 @@ static int ade7759_initial_setup(struct iio_dev *indio_dev)
}
ade7759_reset(dev);
- msleep(ADE7759_STARTUP_DELAY);
+ usleep_range(ADE7759_STARTUP_DELAY, ADE7759_STARTUP_DELAY + 100);
err_ret:
return ret;
diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h
index f9ff1f8e7372..f0716d2fdf8e 100644
--- a/drivers/staging/iio/meter/ade7759.h
+++ b/drivers/staging/iio/meter/ade7759.h
@@ -30,7 +30,7 @@
#define ADE7759_MAX_TX 6
#define ADE7759_MAX_RX 6
-#define ADE7759_STARTUP_DELAY 1
+#define ADE7759_STARTUP_DELAY 1000
#define ADE7759_SPI_SLOW (u32)(300 * 1000)
#define ADE7759_SPI_BURST (u32)(1000 * 1000)
diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c
index 24edbc39ab4e..e8007f0c5186 100644
--- a/drivers/staging/iio/meter/ade7854.c
+++ b/drivers/staging/iio/meter/ade7854.c
@@ -444,7 +444,7 @@ static int ade7854_initial_setup(struct iio_dev *indio_dev)
}
ade7854_reset(dev);
- msleep(ADE7854_STARTUP_DELAY);
+ usleep_range(ADE7854_STARTUP_DELAY, ADE7854_STARTUP_DELAY + 100);
err_ret:
return ret;
diff --git a/drivers/staging/iio/meter/ade7854.h b/drivers/staging/iio/meter/ade7854.h
index 52f4195cf6f4..dbd97def9cd8 100644
--- a/drivers/staging/iio/meter/ade7854.h
+++ b/drivers/staging/iio/meter/ade7854.h
@@ -136,7 +136,7 @@
#define ADE7854_MAX_TX 7
#define ADE7854_MAX_RX 7
-#define ADE7854_STARTUP_DELAY 1
+#define ADE7854_STARTUP_DELAY 1000
#define ADE7854_SPI_SLOW (u32)(300 * 1000)
#define ADE7854_SPI_BURST (u32)(1000 * 1000)
diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
index 38dca69a06eb..4e0b4eedb53d 100644
--- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
+++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
@@ -133,7 +133,7 @@ static ssize_t iio_bfin_tmr_frequency_show(struct device *dev,
return sprintf(buf, "%lu\n", val);
}
-static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_bfin_tmr_frequency_show,
+static DEVICE_ATTR(frequency, 0644, iio_bfin_tmr_frequency_show,
iio_bfin_tmr_frequency_store);
static struct attribute *iio_bfin_tmr_trigger_attrs[] = {
@@ -260,7 +260,7 @@ out_free_irq:
out1:
iio_trigger_unregister(st->trig);
out:
- iio_trigger_put(st->trig);
+ iio_trigger_free(st->trig);
return ret;
}
@@ -273,7 +273,7 @@ static int iio_bfin_tmr_trigger_remove(struct platform_device *pdev)
peripheral_free(st->t->pin);
free_irq(st->irq, st);
iio_trigger_unregister(st->trig);
- iio_trigger_put(st->trig);
+ iio_trigger_free(st->trig);
return 0;
}
diff --git a/drivers/staging/ks7010/ks7010_sdio.h b/drivers/staging/ks7010/ks7010_sdio.h
index 0f5fd848e23d..0165994605ac 100644
--- a/drivers/staging/ks7010/ks7010_sdio.h
+++ b/drivers/staging/ks7010/ks7010_sdio.h
@@ -81,11 +81,11 @@
/* AHB Data Window 0x010000-0x01FFFF */
#define DATA_WINDOW 0x010000
-#define WINDOW_SIZE 64*1024
+#define WINDOW_SIZE (64 * 1024)
#define KS7010_IRAM_ADDRESS 0x06000000
-/*
+/*
* struct define
*/
struct hw_info_t {
diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c
index e5d04adaeb1a..8c55428b71c7 100644
--- a/drivers/staging/ks7010/ks_wlan_net.c
+++ b/drivers/staging/ks7010/ks_wlan_net.c
@@ -3400,8 +3400,9 @@ int ks_wlan_close(struct net_device *dev)
/* Operational parameters that usually are not changed. */
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (3*HZ)
-static const unsigned char dummy_addr[] =
- { 0x00, 0x0b, 0xe3, 0x00, 0x00, 0x00 };
+static const unsigned char dummy_addr[] = {
+ 0x00, 0x0b, 0xe3, 0x00, 0x00, 0x00
+};
static const struct net_device_ops ks_wlan_netdev_ops = {
.ndo_start_xmit = ks_wlan_start_xmit,
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
index a59c5e99cbd3..3d19402ba728 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
@@ -78,7 +78,7 @@ static inline int lnet_is_route_alive(lnet_route_t *route)
return route->lr_downis == 0;
}
-static inline int lnet_is_wire_handle_none(lnet_handle_wire_t *wh)
+static inline int lnet_is_wire_handle_none(struct lnet_handle_wire *wh)
{
return (wh->wh_interface_cookie == LNET_WIRE_HANDLE_COOKIE_NONE &&
wh->wh_object_cookie == LNET_WIRE_HANDLE_COOKIE_NONE);
@@ -323,7 +323,7 @@ lnet_handle2md(lnet_handle_md_t *handle)
}
static inline lnet_libmd_t *
-lnet_wire_handle2md(lnet_handle_wire_t *wh)
+lnet_wire_handle2md(struct lnet_handle_wire *wh)
{
/* ALWAYS called with resource lock held */
lnet_libhandle_t *lh;
@@ -552,7 +552,7 @@ int lnet_portals_create(void);
void lnet_portals_destroy(void);
/* message functions */
-int lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr,
+int lnet_parse(lnet_ni_t *ni, struct lnet_hdr *hdr,
lnet_nid_t fromnid, void *private, int rdma_req);
int lnet_parse_local(lnet_ni_t *ni, lnet_msg_t *msg);
int lnet_parse_forward_locked(lnet_ni_t *ni, lnet_msg_t *msg);
@@ -579,7 +579,7 @@ void lnet_msg_containers_destroy(void);
int lnet_msg_containers_create(void);
char *lnet_msgtyp2str(int type);
-void lnet_print_hdr(lnet_hdr_t *hdr);
+void lnet_print_hdr(struct lnet_hdr *hdr);
int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold);
/** \addtogroup lnet_fault_simulation @{ */
@@ -588,7 +588,7 @@ int lnet_fault_ctl(int cmd, struct libcfs_ioctl_data *data);
int lnet_fault_init(void);
void lnet_fault_fini(void);
-bool lnet_drop_rule_match(lnet_hdr_t *hdr);
+bool lnet_drop_rule_match(struct lnet_hdr *hdr);
int lnet_delay_rule_add(struct lnet_fault_attr *attr);
int lnet_delay_rule_del(lnet_nid_t src, lnet_nid_t dst, bool shutdown);
@@ -596,7 +596,7 @@ int lnet_delay_rule_list(int pos, struct lnet_fault_attr *attr,
struct lnet_fault_stat *stat);
void lnet_delay_rule_reset(void);
void lnet_delay_rule_check(void);
-bool lnet_delay_rule_match_locked(lnet_hdr_t *hdr, struct lnet_msg *msg);
+bool lnet_delay_rule_match_locked(struct lnet_hdr *hdr, struct lnet_msg *msg);
/** @} lnet_fault_simulation */
@@ -664,7 +664,7 @@ int lnet_peer_buffer_credits(lnet_ni_t *ni);
int lnet_router_checker_start(void);
void lnet_router_checker_stop(void);
void lnet_router_ni_update_locked(lnet_peer_t *gw, __u32 net);
-void lnet_swap_pinginfo(lnet_ping_info_t *info);
+void lnet_swap_pinginfo(struct lnet_ping_info *info);
int lnet_parse_ip2nets(char **networksp, char *ip2nets);
int lnet_parse_routes(char *route_str, int *im_a_router);
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h
index b84a5bb9186c..9850398bf29a 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-types.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h
@@ -105,7 +105,7 @@ typedef struct lnet_msg {
lnet_kiov_t *msg_kiov;
lnet_event_t msg_ev;
- lnet_hdr_t msg_hdr;
+ struct lnet_hdr msg_hdr;
} lnet_msg_t;
typedef struct lnet_libhandle {
@@ -270,7 +270,7 @@ typedef struct lnet_ni {
struct lnet_tx_queue **ni_tx_queues; /* percpt TX queues */
int **ni_refs; /* percpt reference count */
time64_t ni_last_alive;/* when I was last alive */
- lnet_ni_status_t *ni_status; /* my health status */
+ struct lnet_ni_status *ni_status; /* my health status */
/* per NI LND tunables */
struct lnet_ioctl_config_lnd_tunables *ni_lnd_tunables;
/* equivalent interfaces to use */
@@ -295,13 +295,13 @@ typedef struct lnet_ni {
/* router checker data, per router */
#define LNET_MAX_RTR_NIS 16
-#define LNET_PINGINFO_SIZE offsetof(lnet_ping_info_t, pi_ni[LNET_MAX_RTR_NIS])
+#define LNET_PINGINFO_SIZE offsetof(struct lnet_ping_info, pi_ni[LNET_MAX_RTR_NIS])
typedef struct {
/* chain on the_lnet.ln_zombie_rcd or ln_deathrow_rcd */
struct list_head rcd_list;
lnet_handle_md_t rcd_mdh; /* ping buffer MD */
struct lnet_peer *rcd_gateway; /* reference to gateway */
- lnet_ping_info_t *rcd_pinginfo; /* ping buffer */
+ struct lnet_ping_info *rcd_pinginfo; /* ping buffer */
} lnet_rc_data_t;
typedef struct lnet_peer {
@@ -599,7 +599,7 @@ typedef struct {
lnet_handle_md_t ln_ping_target_md;
lnet_handle_eq_t ln_ping_target_eq;
- lnet_ping_info_t *ln_ping_info;
+ struct lnet_ping_info *ln_ping_info;
/* router checker startup/shutdown state */
int ln_rc_state;
diff --git a/drivers/staging/lustre/include/linux/lnet/lnetst.h b/drivers/staging/lustre/include/linux/lnet/lnetst.h
index 8a84888635ff..c81c246ef221 100644
--- a/drivers/staging/lustre/include/linux/lnet/lnetst.h
+++ b/drivers/staging/lustre/include/linux/lnet/lnetst.h
@@ -68,16 +68,16 @@
#define LSTIO_BATCH_QUERY 0xC27 /* query batch status */
#define LSTIO_STAT_QUERY 0xC30 /* get stats */
-typedef struct {
+struct lst_sid {
lnet_nid_t ses_nid; /* nid of console node */
__u64 ses_stamp; /* time stamp */
-} lst_sid_t; /*** session id */
+}; /*** session id */
-extern lst_sid_t LST_INVALID_SID;
+extern struct lst_sid LST_INVALID_SID;
-typedef struct {
+struct lst_bid {
__u64 bat_id; /* unique id in session */
-} lst_bid_t; /*** batch id (group of tests) */
+}; /*** batch id (group of tests) */
/* Status of test node */
#define LST_NODE_ACTIVE 0x1 /* node in this session */
@@ -85,59 +85,59 @@ typedef struct {
#define LST_NODE_DOWN 0x4 /* node is down */
#define LST_NODE_UNKNOWN 0x8 /* node not in session */
-typedef struct {
+struct lstcon_node_ent {
lnet_process_id_t nde_id; /* id of node */
int nde_state; /* state of node */
-} lstcon_node_ent_t; /*** node entry, for list_group command */
+}; /*** node entry, for list_group command */
-typedef struct {
+struct lstcon_ndlist_ent {
int nle_nnode; /* # of nodes */
int nle_nactive; /* # of active nodes */
int nle_nbusy; /* # of busy nodes */
int nle_ndown; /* # of down nodes */
int nle_nunknown; /* # of unknown nodes */
-} lstcon_ndlist_ent_t; /*** node_list entry, for list_batch command */
+}; /*** node_list entry, for list_batch command */
-typedef struct {
+struct lstcon_test_ent {
int tse_type; /* test type */
int tse_loop; /* loop count */
int tse_concur; /* concurrency of test */
-} lstcon_test_ent_t; /*** test summary entry, for
+}; /*** test summary entry, for
*** list_batch command */
-typedef struct {
+struct lstcon_batch_ent {
int bae_state; /* batch status */
int bae_timeout; /* batch timeout */
int bae_ntest; /* # of tests in the batch */
-} lstcon_batch_ent_t; /*** batch summary entry, for
+}; /*** batch summary entry, for
*** list_batch command */
-typedef struct {
- lstcon_ndlist_ent_t tbe_cli_nle; /* client (group) node_list
+struct lstcon_test_batch_ent {
+ struct lstcon_ndlist_ent tbe_cli_nle; /* client (group) node_list
* entry */
- lstcon_ndlist_ent_t tbe_srv_nle; /* server (group) node_list
+ struct lstcon_ndlist_ent tbe_srv_nle; /* server (group) node_list
* entry */
union {
- lstcon_test_ent_t tbe_test; /* test entry */
- lstcon_batch_ent_t tbe_batch; /* batch entry */
+ struct lstcon_test_ent tbe_test; /* test entry */
+ struct lstcon_batch_ent tbe_batch;/* batch entry */
} u;
-} lstcon_test_batch_ent_t; /*** test/batch verbose information entry,
+}; /*** test/batch verbose information entry,
*** for list_batch command */
-typedef struct {
+struct lstcon_rpc_ent {
struct list_head rpe_link; /* link chain */
lnet_process_id_t rpe_peer; /* peer's id */
struct timeval rpe_stamp; /* time stamp of RPC */
int rpe_state; /* peer's state */
int rpe_rpc_errno; /* RPC errno */
- lst_sid_t rpe_sid; /* peer's session id */
+ struct lst_sid rpe_sid; /* peer's session id */
int rpe_fwk_errno; /* framework errno */
int rpe_priv[4]; /* private data */
char rpe_payload[0]; /* private reply payload */
-} lstcon_rpc_ent_t;
+};
-typedef struct {
+struct lstcon_trans_stat {
int trs_rpc_stat[4]; /* RPCs stat (0: total
1: failed
2: finished
@@ -146,125 +146,125 @@ typedef struct {
int trs_fwk_stat[8]; /* framework stat */
int trs_fwk_errno; /* errno of the first remote error */
void *trs_fwk_private; /* private framework stat */
-} lstcon_trans_stat_t;
+};
static inline int
-lstcon_rpc_stat_total(lstcon_trans_stat_t *stat, int inc)
+lstcon_rpc_stat_total(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_rpc_stat[0] : stat->trs_rpc_stat[0];
}
static inline int
-lstcon_rpc_stat_success(lstcon_trans_stat_t *stat, int inc)
+lstcon_rpc_stat_success(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_rpc_stat[1] : stat->trs_rpc_stat[1];
}
static inline int
-lstcon_rpc_stat_failure(lstcon_trans_stat_t *stat, int inc)
+lstcon_rpc_stat_failure(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_rpc_stat[2] : stat->trs_rpc_stat[2];
}
static inline int
-lstcon_sesop_stat_success(lstcon_trans_stat_t *stat, int inc)
+lstcon_sesop_stat_success(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
}
static inline int
-lstcon_sesop_stat_failure(lstcon_trans_stat_t *stat, int inc)
+lstcon_sesop_stat_failure(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
}
static inline int
-lstcon_sesqry_stat_active(lstcon_trans_stat_t *stat, int inc)
+lstcon_sesqry_stat_active(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
}
static inline int
-lstcon_sesqry_stat_busy(lstcon_trans_stat_t *stat, int inc)
+lstcon_sesqry_stat_busy(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
}
static inline int
-lstcon_sesqry_stat_unknown(lstcon_trans_stat_t *stat, int inc)
+lstcon_sesqry_stat_unknown(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[2] : stat->trs_fwk_stat[2];
}
static inline int
-lstcon_tsbop_stat_success(lstcon_trans_stat_t *stat, int inc)
+lstcon_tsbop_stat_success(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
}
static inline int
-lstcon_tsbop_stat_failure(lstcon_trans_stat_t *stat, int inc)
+lstcon_tsbop_stat_failure(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
}
static inline int
-lstcon_tsbqry_stat_idle(lstcon_trans_stat_t *stat, int inc)
+lstcon_tsbqry_stat_idle(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
}
static inline int
-lstcon_tsbqry_stat_run(lstcon_trans_stat_t *stat, int inc)
+lstcon_tsbqry_stat_run(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
}
static inline int
-lstcon_tsbqry_stat_failure(lstcon_trans_stat_t *stat, int inc)
+lstcon_tsbqry_stat_failure(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[2] : stat->trs_fwk_stat[2];
}
static inline int
-lstcon_statqry_stat_success(lstcon_trans_stat_t *stat, int inc)
+lstcon_statqry_stat_success(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[0] : stat->trs_fwk_stat[0];
}
static inline int
-lstcon_statqry_stat_failure(lstcon_trans_stat_t *stat, int inc)
+lstcon_statqry_stat_failure(struct lstcon_trans_stat *stat, int inc)
{
return inc ? ++stat->trs_fwk_stat[1] : stat->trs_fwk_stat[1];
}
/* create a session */
-typedef struct {
+struct lstio_session_new_args {
int lstio_ses_key; /* IN: local key */
int lstio_ses_timeout; /* IN: session timeout */
int lstio_ses_force; /* IN: force create ? */
/** IN: session features */
unsigned int lstio_ses_feats;
- lst_sid_t __user *lstio_ses_idp; /* OUT: session id */
+ struct lst_sid __user *lstio_ses_idp; /* OUT: session id */
int lstio_ses_nmlen; /* IN: name length */
char __user *lstio_ses_namep; /* IN: session name */
-} lstio_session_new_args_t;
+};
/* query current session */
-typedef struct {
- lst_sid_t __user *lstio_ses_idp; /* OUT: session id */
+struct lstio_session_info_args {
+ struct lst_sid __user *lstio_ses_idp; /* OUT: session id */
int __user *lstio_ses_keyp; /* OUT: local key */
/** OUT: session features */
unsigned int __user *lstio_ses_featp;
- lstcon_ndlist_ent_t __user *lstio_ses_ndinfo; /* OUT: */
+ struct lstcon_ndlist_ent __user *lstio_ses_ndinfo;/* OUT: */
int lstio_ses_nmlen; /* IN: name length */
char __user *lstio_ses_namep; /* OUT: session name */
-} lstio_session_info_args_t;
+};
/* delete a session */
-typedef struct {
+struct lstio_session_end_args {
int lstio_ses_key; /* IN: session key */
-} lstio_session_end_args_t;
+};
#define LST_OPC_SESSION 1
#define LST_OPC_GROUP 2
@@ -272,7 +272,7 @@ typedef struct {
#define LST_OPC_BATCHCLI 4
#define LST_OPC_BATCHSRV 5
-typedef struct {
+struct lstio_debug_args {
int lstio_dbg_key; /* IN: session key */
int lstio_dbg_type; /* IN: debug
session|batch|
@@ -291,26 +291,26 @@ typedef struct {
nodes */
struct list_head __user *lstio_dbg_resultp; /* OUT: list head of
result buffer */
-} lstio_debug_args_t;
+};
-typedef struct {
+struct lstio_group_add_args {
int lstio_grp_key; /* IN: session key */
int lstio_grp_nmlen; /* IN: name length */
char __user *lstio_grp_namep; /* IN: group name */
-} lstio_group_add_args_t;
+};
-typedef struct {
+struct lstio_group_del_args {
int lstio_grp_key; /* IN: session key */
int lstio_grp_nmlen; /* IN: name length */
char __user *lstio_grp_namep; /* IN: group name */
-} lstio_group_del_args_t;
+};
#define LST_GROUP_CLEAN 1 /* remove inactive nodes in the group */
#define LST_GROUP_REFRESH 2 /* refresh inactive nodes
* in the group */
#define LST_GROUP_RMND 3 /* delete nodes from the group */
-typedef struct {
+struct lstio_group_update_args {
int lstio_grp_key; /* IN: session key */
int lstio_grp_opc; /* IN: OPC */
int lstio_grp_args; /* IN: arguments */
@@ -320,9 +320,9 @@ typedef struct {
lnet_process_id_t __user *lstio_grp_idsp; /* IN: array of nodes */
struct list_head __user *lstio_grp_resultp; /* OUT: list head of
result buffer */
-} lstio_group_update_args_t;
+};
-typedef struct {
+struct lstio_group_nodes_args {
int lstio_grp_key; /* IN: session key */
int lstio_grp_nmlen; /* IN: name length */
char __user *lstio_grp_namep; /* IN: group name */
@@ -332,41 +332,41 @@ typedef struct {
lnet_process_id_t __user *lstio_grp_idsp; /* IN: nodes */
struct list_head __user *lstio_grp_resultp; /* OUT: list head of
result buffer */
-} lstio_group_nodes_args_t;
+};
-typedef struct {
+struct lstio_group_list_args {
int lstio_grp_key; /* IN: session key */
int lstio_grp_idx; /* IN: group idx */
int lstio_grp_nmlen; /* IN: name len */
char __user *lstio_grp_namep; /* OUT: name */
-} lstio_group_list_args_t;
+};
-typedef struct {
+struct lstio_group_info_args {
int lstio_grp_key; /* IN: session key */
int lstio_grp_nmlen; /* IN: name len */
char __user *lstio_grp_namep; /* IN: name */
- lstcon_ndlist_ent_t __user *lstio_grp_entp; /* OUT: description of
- group */
+ struct lstcon_ndlist_ent __user *lstio_grp_entp;/* OUT: description of
+ group */
int __user *lstio_grp_idxp; /* IN/OUT: node index */
int __user *lstio_grp_ndentp; /* IN/OUT: # of nodent */
- lstcon_node_ent_t __user *lstio_grp_dentsp; /* OUT: nodent array */
-} lstio_group_info_args_t;
+ struct lstcon_node_ent __user *lstio_grp_dentsp;/* OUT: nodent array */
+};
#define LST_DEFAULT_BATCH "batch" /* default batch name */
-typedef struct {
+struct lstio_batch_add_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_nmlen; /* IN: name length */
char __user *lstio_bat_namep; /* IN: batch name */
-} lstio_batch_add_args_t;
+};
-typedef struct {
+struct lstio_batch_del_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_nmlen; /* IN: name length */
char __user *lstio_bat_namep; /* IN: batch name */
-} lstio_batch_del_args_t;
+};
-typedef struct {
+struct lstio_batch_run_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_timeout; /* IN: timeout for
the batch */
@@ -374,9 +374,9 @@ typedef struct {
char __user *lstio_bat_namep; /* IN: batch name */
struct list_head __user *lstio_bat_resultp; /* OUT: list head of
result buffer */
-} lstio_batch_run_args_t;
+};
-typedef struct {
+struct lstio_batch_stop_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_force; /* IN: abort unfinished
test RPC */
@@ -384,9 +384,9 @@ typedef struct {
char __user *lstio_bat_namep; /* IN: batch name */
struct list_head __user *lstio_bat_resultp; /* OUT: list head of
result buffer */
-} lstio_batch_stop_args_t;
+};
-typedef struct {
+struct lstio_batch_query_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_testidx; /* IN: test index */
int lstio_bat_client; /* IN: we testing
@@ -397,31 +397,31 @@ typedef struct {
char __user *lstio_bat_namep; /* IN: batch name */
struct list_head __user *lstio_bat_resultp; /* OUT: list head of
result buffer */
-} lstio_batch_query_args_t;
+};
-typedef struct {
+struct lstio_batch_list_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_idx; /* IN: index */
int lstio_bat_nmlen; /* IN: name length */
char __user *lstio_bat_namep; /* IN: batch name */
-} lstio_batch_list_args_t;
+};
-typedef struct {
+struct lstio_batch_info_args {
int lstio_bat_key; /* IN: session key */
int lstio_bat_nmlen; /* IN: name length */
char __user *lstio_bat_namep; /* IN: name */
int lstio_bat_server; /* IN: query server
or not */
int lstio_bat_testidx; /* IN: test index */
- lstcon_test_batch_ent_t __user *lstio_bat_entp; /* OUT: batch ent */
+ struct lstcon_test_batch_ent __user *lstio_bat_entp;/* OUT: batch ent */
int __user *lstio_bat_idxp; /* IN/OUT: index of node */
int __user *lstio_bat_ndentp; /* IN/OUT: # of nodent */
- lstcon_node_ent_t __user *lstio_bat_dentsp; /* array of nodent */
-} lstio_batch_info_args_t;
+ struct lstcon_node_ent __user *lstio_bat_dentsp;/* array of nodent */
+};
/* add stat in session */
-typedef struct {
+struct lstio_stat_args {
int lstio_sta_key; /* IN: session key */
int lstio_sta_timeout; /* IN: timeout for
stat request */
@@ -432,17 +432,17 @@ typedef struct {
lnet_process_id_t __user *lstio_sta_idsp; /* IN: pid */
struct list_head __user *lstio_sta_resultp; /* OUT: list head of
result buffer */
-} lstio_stat_args_t;
+};
-typedef enum {
+enum lst_test_type {
LST_TEST_BULK = 1,
LST_TEST_PING = 2
-} lst_test_type_t;
+};
/* create a test in a batch */
#define LST_MAX_CONCUR 1024 /* Max concurrency of test */
-typedef struct {
+struct lstio_test_args {
int lstio_tes_key; /* IN: session key */
int lstio_tes_bat_nmlen; /* IN: batch name len */
char __user *lstio_tes_bat_name; /* IN: batch name */
@@ -472,36 +472,36 @@ typedef struct {
value */
struct list_head __user *lstio_tes_resultp;/* OUT: list head of
result buffer */
-} lstio_test_args_t;
+};
-typedef enum {
+enum lst_brw_type {
LST_BRW_READ = 1,
LST_BRW_WRITE = 2
-} lst_brw_type_t;
+};
-typedef enum {
+enum lst_brw_flags {
LST_BRW_CHECK_NONE = 1,
LST_BRW_CHECK_SIMPLE = 2,
LST_BRW_CHECK_FULL = 3
-} lst_brw_flags_t;
+};
-typedef struct {
+struct lst_test_bulk_param {
int blk_opc; /* bulk operation code */
int blk_size; /* size (bytes) */
int blk_time; /* time of running the test*/
int blk_flags; /* reserved flags */
int blk_cli_off; /* bulk offset on client */
int blk_srv_off; /* reserved: bulk offset on server */
-} lst_test_bulk_param_t;
+};
-typedef struct {
+struct lst_test_ping_param {
int png_size; /* size of ping message */
int png_time; /* time */
int png_loop; /* loop */
int png_flags; /* reserved flags */
-} lst_test_ping_param_t;
+};
-typedef struct {
+struct srpc_counters {
__u32 errors;
__u32 rpcs_sent;
__u32 rpcs_rcvd;
@@ -509,15 +509,15 @@ typedef struct {
__u32 rpcs_expired;
__u64 bulk_get;
__u64 bulk_put;
-} WIRE_ATTR srpc_counters_t;
+} WIRE_ATTR;
-typedef struct {
+struct sfw_counters {
/** milliseconds since current session started */
__u32 running_ms;
__u32 active_batches;
__u32 zombie_sessions;
__u32 brw_errors;
__u32 ping_errors;
-} WIRE_ATTR sfw_counters_t;
+} WIRE_ATTR;
#endif
diff --git a/drivers/staging/lustre/include/linux/lnet/socklnd.h b/drivers/staging/lustre/include/linux/lnet/socklnd.h
index bc32403f4a08..7d24a9132e09 100644
--- a/drivers/staging/lustre/include/linux/lnet/socklnd.h
+++ b/drivers/staging/lustre/include/linux/lnet/socklnd.h
@@ -60,7 +60,7 @@ typedef struct {
} WIRE_ATTR ksock_hello_msg_t;
typedef struct {
- lnet_hdr_t ksnm_hdr; /* lnet hdr */
+ struct lnet_hdr ksnm_hdr; /* lnet hdr */
/*
* ksnm_payload is removed because of winnt compiler's limitation:
diff --git a/drivers/staging/lustre/include/linux/lnet/types.h b/drivers/staging/lustre/include/linux/lnet/types.h
index 8ca1e9d0cfe2..1c8de72e6d6b 100644
--- a/drivers/staging/lustre/include/linux/lnet/types.h
+++ b/drivers/staging/lustre/include/linux/lnet/types.h
@@ -115,11 +115,11 @@ static inline __u32 LNET_MKNET(__u32 type, __u32 num)
#define WIRE_ATTR __packed
/* Packed version of lnet_process_id_t to transfer via network */
-typedef struct {
+struct lnet_process_id_packed {
/* node id / process id */
lnet_nid_t nid;
lnet_pid_t pid;
-} WIRE_ATTR lnet_process_id_packed_t;
+} WIRE_ATTR;
/*
* The wire handle's interface cookie only matches one network interface in
@@ -127,10 +127,10 @@ typedef struct {
* reboots). The object cookie only matches one object on that interface
* during that object's lifetime (i.e. no cookie re-use).
*/
-typedef struct {
+struct lnet_handle_wire {
__u64 wh_interface_cookie;
__u64 wh_object_cookie;
-} WIRE_ATTR lnet_handle_wire_t;
+} WIRE_ATTR;
typedef enum {
LNET_MSG_ACK = 0,
@@ -146,38 +146,38 @@ typedef enum {
* wire structs MUST be fixed size and the smaller types are placed at the
* end.
*/
-typedef struct lnet_ack {
- lnet_handle_wire_t dst_wmd;
+struct lnet_ack {
+ struct lnet_handle_wire dst_wmd;
__u64 match_bits;
__u32 mlength;
-} WIRE_ATTR lnet_ack_t;
+} WIRE_ATTR;
-typedef struct lnet_put {
- lnet_handle_wire_t ack_wmd;
+struct lnet_put {
+ struct lnet_handle_wire ack_wmd;
__u64 match_bits;
__u64 hdr_data;
__u32 ptl_index;
__u32 offset;
-} WIRE_ATTR lnet_put_t;
+} WIRE_ATTR;
-typedef struct lnet_get {
- lnet_handle_wire_t return_wmd;
+struct lnet_get {
+ struct lnet_handle_wire return_wmd;
__u64 match_bits;
__u32 ptl_index;
__u32 src_offset;
__u32 sink_length;
-} WIRE_ATTR lnet_get_t;
+} WIRE_ATTR;
-typedef struct lnet_reply {
- lnet_handle_wire_t dst_wmd;
-} WIRE_ATTR lnet_reply_t;
+struct lnet_reply {
+ struct lnet_handle_wire dst_wmd;
+} WIRE_ATTR;
-typedef struct lnet_hello {
+struct lnet_hello {
__u64 incarnation;
__u32 type;
-} WIRE_ATTR lnet_hello_t;
+} WIRE_ATTR;
-typedef struct {
+struct lnet_hdr {
lnet_nid_t dest_nid;
lnet_nid_t src_nid;
lnet_pid_t dest_pid;
@@ -186,13 +186,13 @@ typedef struct {
__u32 payload_length; /* payload data to follow */
/*<------__u64 aligned------->*/
union {
- lnet_ack_t ack;
- lnet_put_t put;
- lnet_get_t get;
- lnet_reply_t reply;
- lnet_hello_t hello;
+ struct lnet_ack ack;
+ struct lnet_put put;
+ struct lnet_get get;
+ struct lnet_reply reply;
+ struct lnet_hello hello;
} msg;
-} WIRE_ATTR lnet_hdr_t;
+} WIRE_ATTR;
/*
* A HELLO message contains a magic number and protocol version
@@ -202,13 +202,13 @@ typedef struct {
* This is for use by byte-stream LNDs (e.g. TCP/IP) to check the peer is
* running the same protocol and to find out its NID. These LNDs should
* exchange HELLO messages when a connection is first established. Individual
- * LNDs can put whatever else they fancy in lnet_hdr_t::msg.
+ * LNDs can put whatever else they fancy in struct lnet_hdr::msg.
*/
-typedef struct {
+struct lnet_magicversion {
__u32 magic; /* LNET_PROTO_TCP_MAGIC */
__u16 version_major; /* increment on incompatible change */
__u16 version_minor; /* increment on compatible change */
-} WIRE_ATTR lnet_magicversion_t;
+} WIRE_ATTR;
/* PROTO MAGIC for LNDs */
#define LNET_PROTO_IB_MAGIC 0x0be91b91
@@ -228,27 +228,27 @@ typedef struct {
#define LNET_PROTO_TCP_VERSION_MINOR 0
/* Acceptor connection request */
-typedef struct {
+struct lnet_acceptor_connreq {
__u32 acr_magic; /* PTL_ACCEPTOR_PROTO_MAGIC */
__u32 acr_version; /* protocol version */
__u64 acr_nid; /* target NID */
-} WIRE_ATTR lnet_acceptor_connreq_t;
+} WIRE_ATTR;
#define LNET_PROTO_ACCEPTOR_VERSION 1
-typedef struct {
+struct lnet_ni_status {
lnet_nid_t ns_nid;
__u32 ns_status;
__u32 ns_unused;
-} WIRE_ATTR lnet_ni_status_t;
+} WIRE_ATTR;
-typedef struct {
+struct lnet_ping_info {
__u32 pi_magic;
__u32 pi_features;
lnet_pid_t pi_pid;
__u32 pi_nnis;
- lnet_ni_status_t pi_ni[0];
-} WIRE_ATTR lnet_ping_info_t;
+ struct lnet_ni_status pi_ni[0];
+} WIRE_ATTR;
typedef struct lnet_counters {
__u32 msgs_alloc;
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
index 14576977200f..2cb429830681 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
@@ -364,7 +364,7 @@ struct kib_connparams {
} WIRE_ATTR;
struct kib_immediate_msg {
- lnet_hdr_t ibim_hdr; /* portals header */
+ struct lnet_hdr ibim_hdr; /* portals header */
char ibim_payload[0]; /* piggy-backed payload */
} WIRE_ATTR;
@@ -380,7 +380,7 @@ struct kib_rdma_desc {
} WIRE_ATTR;
struct kib_putreq_msg {
- lnet_hdr_t ibprm_hdr; /* portals header */
+ struct lnet_hdr ibprm_hdr; /* portals header */
__u64 ibprm_cookie; /* opaque completion cookie */
} WIRE_ATTR;
@@ -391,7 +391,7 @@ struct kib_putack_msg {
} WIRE_ATTR;
struct kib_get_msg {
- lnet_hdr_t ibgm_hdr; /* portals header */
+ struct lnet_hdr ibgm_hdr; /* portals header */
__u64 ibgm_cookie; /* opaque completion cookie */
struct kib_rdma_desc ibgm_rd; /* rdma descriptor */
} WIRE_ATTR;
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index c7917abf9944..14dbc530f62b 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -1490,7 +1490,7 @@ kiblnd_launch_tx(lnet_ni_t *ni, struct kib_tx *tx, lnet_nid_t nid)
int
kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
{
- lnet_hdr_t *hdr = &lntmsg->msg_hdr;
+ struct lnet_hdr *hdr = &lntmsg->msg_hdr;
int type = lntmsg->msg_type;
lnet_process_id_t target = lntmsg->msg_target;
int target_is_router = lntmsg->msg_target_is_router;
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
index b74cf635faee..2181c67a95e8 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
@@ -1108,12 +1108,12 @@ ksocknal_create_conn(lnet_ni_t *ni, struct ksock_route *route,
write_unlock_bh(global_lock);
if (!conn->ksnc_proto) {
- conn->ksnc_proto = &ksocknal_protocol_v3x;
+ conn->ksnc_proto = &ksocknal_protocol_v3x;
#if SOCKNAL_VERSION_DEBUG
- if (*ksocknal_tunables.ksnd_protocol == 2)
- conn->ksnc_proto = &ksocknal_protocol_v2x;
- else if (*ksocknal_tunables.ksnd_protocol == 1)
- conn->ksnc_proto = &ksocknal_protocol_v1x;
+ if (*ksocknal_tunables.ksnd_protocol == 2)
+ conn->ksnc_proto = &ksocknal_protocol_v2x;
+ else if (*ksocknal_tunables.ksnd_protocol == 1)
+ conn->ksnc_proto = &ksocknal_protocol_v1x;
#endif
}
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
index 842c45393b38..9e86563b8c70 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
@@ -373,7 +373,7 @@ struct ksock_conn {
* V2.x message takes the
* whole struct
* V1.x message is a bare
- * lnet_hdr_t, it's stored in
+ * struct lnet_hdr, it's stored in
* ksnc_msg.ksm_u.lnetmsg
*/
/* WRITER */
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
index 972f6094be75..3531e7d99349 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
@@ -1073,14 +1073,14 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
break;
case KSOCK_PROTO_V1:
- /* Receiving bare lnet_hdr_t */
+ /* Receiving bare struct lnet_hdr */
conn->ksnc_rx_state = SOCKNAL_RX_LNET_HEADER;
- conn->ksnc_rx_nob_wanted = sizeof(lnet_hdr_t);
- conn->ksnc_rx_nob_left = sizeof(lnet_hdr_t);
+ conn->ksnc_rx_nob_wanted = sizeof(struct lnet_hdr);
+ conn->ksnc_rx_nob_left = sizeof(struct lnet_hdr);
conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg.ksm_u.lnetmsg;
- conn->ksnc_rx_iov[0].iov_len = sizeof(lnet_hdr_t);
+ conn->ksnc_rx_iov[0].iov_len = sizeof(struct lnet_hdr);
break;
default:
@@ -1126,7 +1126,7 @@ ksocknal_new_packet(struct ksock_conn *conn, int nob_to_skip)
static int
ksocknal_process_receive(struct ksock_conn *conn)
{
- lnet_hdr_t *lhdr;
+ struct lnet_hdr *lhdr;
lnet_process_id_t *id;
int rc;
@@ -1656,9 +1656,9 @@ ksocknal_parse_proto_version(ksock_hello_msg_t *hello)
}
if (hello->kshm_magic == le32_to_cpu(LNET_PROTO_TCP_MAGIC)) {
- lnet_magicversion_t *hmv = (lnet_magicversion_t *)hello;
+ struct lnet_magicversion *hmv = (struct lnet_magicversion *)hello;
- CLASSERT(sizeof(lnet_magicversion_t) ==
+ CLASSERT(sizeof(struct lnet_magicversion) ==
offsetof(ksock_hello_msg_t, kshm_src_nid));
if (hmv->version_major == cpu_to_le16(KSOCK_PROTO_V1_MAJOR) &&
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
index 8f0ff6ca1f39..b36f181db08e 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
@@ -291,7 +291,7 @@ ksocknal_match_tx(struct ksock_conn *conn, struct ksock_tx *tx, int nonblk)
} else {
nob = tx->tx_lnetmsg->msg_len +
((conn->ksnc_proto == &ksocknal_protocol_v1x) ?
- sizeof(lnet_hdr_t) : sizeof(ksock_msg_t));
+ sizeof(struct lnet_hdr) : sizeof(ksock_msg_t));
}
/* default checking for typed connection */
@@ -459,23 +459,23 @@ static int
ksocknal_send_hello_v1(struct ksock_conn *conn, ksock_hello_msg_t *hello)
{
struct socket *sock = conn->ksnc_sock;
- lnet_hdr_t *hdr;
- lnet_magicversion_t *hmv;
+ struct lnet_hdr *hdr;
+ struct lnet_magicversion *hmv;
int rc;
int i;
- CLASSERT(sizeof(lnet_magicversion_t) == offsetof(lnet_hdr_t, src_nid));
+ CLASSERT(sizeof(struct lnet_magicversion) == offsetof(struct lnet_hdr, src_nid));
LIBCFS_ALLOC(hdr, sizeof(*hdr));
if (!hdr) {
- CERROR("Can't allocate lnet_hdr_t\n");
+ CERROR("Can't allocate struct lnet_hdr\n");
return -ENOMEM;
}
- hmv = (lnet_magicversion_t *)&hdr->dest_nid;
+ hmv = (struct lnet_magicversion *)&hdr->dest_nid;
/*
- * Re-organize V2.x message header to V1.x (lnet_hdr_t)
+ * Re-organize V2.x message header to V1.x (struct lnet_hdr)
* header and send out
*/
hmv->magic = cpu_to_le32(LNET_PROTO_TCP_MAGIC);
@@ -577,18 +577,18 @@ ksocknal_recv_hello_v1(struct ksock_conn *conn, ksock_hello_msg_t *hello,
int timeout)
{
struct socket *sock = conn->ksnc_sock;
- lnet_hdr_t *hdr;
+ struct lnet_hdr *hdr;
int rc;
int i;
LIBCFS_ALLOC(hdr, sizeof(*hdr));
if (!hdr) {
- CERROR("Can't allocate lnet_hdr_t\n");
+ CERROR("Can't allocate struct lnet_hdr\n");
return -ENOMEM;
}
rc = lnet_sock_read(sock, &hdr->src_nid,
- sizeof(*hdr) - offsetof(lnet_hdr_t, src_nid),
+ sizeof(*hdr) - offsetof(struct lnet_hdr, src_nid),
timeout);
if (rc) {
CERROR("Error %d reading rest of HELLO hdr from %pI4h\n",
@@ -723,10 +723,10 @@ ksocknal_pack_msg_v1(struct ksock_tx *tx)
LASSERT(tx->tx_lnetmsg);
tx->tx_iov[0].iov_base = &tx->tx_lnetmsg->msg_hdr;
- tx->tx_iov[0].iov_len = sizeof(lnet_hdr_t);
+ tx->tx_iov[0].iov_len = sizeof(struct lnet_hdr);
- tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t);
- tx->tx_resid = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t);
+ tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(struct lnet_hdr);
+ tx->tx_resid = tx->tx_lnetmsg->msg_len + sizeof(struct lnet_hdr);
}
static void
diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c
index 161e04226521..c388550c2d10 100644
--- a/drivers/staging/lustre/lnet/libcfs/module.c
+++ b/drivers/staging/lustre/lnet/libcfs/module.c
@@ -488,10 +488,10 @@ static const struct file_operations lnet_debugfs_file_operations_wo = {
static const struct file_operations *lnet_debugfs_fops_select(umode_t mode)
{
- if (!(mode & S_IWUGO))
+ if (!(mode & 0222))
return &lnet_debugfs_file_operations_ro;
- if (!(mode & S_IRUGO))
+ if (!(mode & 0444))
return &lnet_debugfs_file_operations_wo;
return &lnet_debugfs_file_operations_rw;
diff --git a/drivers/staging/lustre/lnet/lnet/acceptor.c b/drivers/staging/lustre/lnet/lnet/acceptor.c
index 8c50c99d82d5..a55c6cd6ff37 100644
--- a/drivers/staging/lustre/lnet/lnet/acceptor.c
+++ b/drivers/staging/lustre/lnet/lnet/acceptor.c
@@ -143,7 +143,7 @@ int
lnet_connect(struct socket **sockp, lnet_nid_t peer_nid,
__u32 local_ip, __u32 peer_ip, int peer_port)
{
- lnet_acceptor_connreq_t cr;
+ struct lnet_acceptor_connreq cr;
struct socket *sock;
int rc;
int port;
@@ -206,7 +206,7 @@ EXPORT_SYMBOL(lnet_connect);
static int
lnet_accept(struct socket *sock, __u32 magic)
{
- lnet_acceptor_connreq_t cr;
+ struct lnet_acceptor_connreq cr;
__u32 peer_ip;
int peer_port;
int rc;
@@ -284,7 +284,7 @@ lnet_accept(struct socket *sock, __u32 magic)
rc = lnet_sock_read(sock, &cr.acr_nid,
sizeof(cr) -
- offsetof(lnet_acceptor_connreq_t, acr_nid),
+ offsetof(struct lnet_acceptor_connreq, acr_nid),
accept_timeout);
if (rc) {
CERROR("Error %d reading connection request from %pI4h\n",
diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c
index b2ba10d59f84..79f8534d1056 100644
--- a/drivers/staging/lustre/lnet/lnet/api-ni.c
+++ b/drivers/staging/lustre/lnet/lnet/api-ni.c
@@ -190,79 +190,79 @@ static void lnet_assert_wire_constants(void)
CLASSERT(LNET_MSG_HELLO == 4);
/* Checks for struct ptl_handle_wire_t */
- CLASSERT((int)sizeof(lnet_handle_wire_t) == 16);
- CLASSERT((int)offsetof(lnet_handle_wire_t, wh_interface_cookie) == 0);
- CLASSERT((int)sizeof(((lnet_handle_wire_t *)0)->wh_interface_cookie) == 8);
- CLASSERT((int)offsetof(lnet_handle_wire_t, wh_object_cookie) == 8);
- CLASSERT((int)sizeof(((lnet_handle_wire_t *)0)->wh_object_cookie) == 8);
-
- /* Checks for struct lnet_magicversion_t */
- CLASSERT((int)sizeof(lnet_magicversion_t) == 8);
- CLASSERT((int)offsetof(lnet_magicversion_t, magic) == 0);
- CLASSERT((int)sizeof(((lnet_magicversion_t *)0)->magic) == 4);
- CLASSERT((int)offsetof(lnet_magicversion_t, version_major) == 4);
- CLASSERT((int)sizeof(((lnet_magicversion_t *)0)->version_major) == 2);
- CLASSERT((int)offsetof(lnet_magicversion_t, version_minor) == 6);
- CLASSERT((int)sizeof(((lnet_magicversion_t *)0)->version_minor) == 2);
-
- /* Checks for struct lnet_hdr_t */
- CLASSERT((int)sizeof(lnet_hdr_t) == 72);
- CLASSERT((int)offsetof(lnet_hdr_t, dest_nid) == 0);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->dest_nid) == 8);
- CLASSERT((int)offsetof(lnet_hdr_t, src_nid) == 8);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->src_nid) == 8);
- CLASSERT((int)offsetof(lnet_hdr_t, dest_pid) == 16);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->dest_pid) == 4);
- CLASSERT((int)offsetof(lnet_hdr_t, src_pid) == 20);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->src_pid) == 4);
- CLASSERT((int)offsetof(lnet_hdr_t, type) == 24);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->type) == 4);
- CLASSERT((int)offsetof(lnet_hdr_t, payload_length) == 28);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->payload_length) == 4);
- CLASSERT((int)offsetof(lnet_hdr_t, msg) == 32);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg) == 40);
+ CLASSERT((int)sizeof(struct lnet_handle_wire) == 16);
+ CLASSERT((int)offsetof(struct lnet_handle_wire, wh_interface_cookie) == 0);
+ CLASSERT((int)sizeof(((struct lnet_handle_wire *)0)->wh_interface_cookie) == 8);
+ CLASSERT((int)offsetof(struct lnet_handle_wire, wh_object_cookie) == 8);
+ CLASSERT((int)sizeof(((struct lnet_handle_wire *)0)->wh_object_cookie) == 8);
+
+ /* Checks for struct struct lnet_magicversion */
+ CLASSERT((int)sizeof(struct lnet_magicversion) == 8);
+ CLASSERT((int)offsetof(struct lnet_magicversion, magic) == 0);
+ CLASSERT((int)sizeof(((struct lnet_magicversion *)0)->magic) == 4);
+ CLASSERT((int)offsetof(struct lnet_magicversion, version_major) == 4);
+ CLASSERT((int)sizeof(((struct lnet_magicversion *)0)->version_major) == 2);
+ CLASSERT((int)offsetof(struct lnet_magicversion, version_minor) == 6);
+ CLASSERT((int)sizeof(((struct lnet_magicversion *)0)->version_minor) == 2);
+
+ /* Checks for struct struct lnet_hdr */
+ CLASSERT((int)sizeof(struct lnet_hdr) == 72);
+ CLASSERT((int)offsetof(struct lnet_hdr, dest_nid) == 0);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->dest_nid) == 8);
+ CLASSERT((int)offsetof(struct lnet_hdr, src_nid) == 8);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->src_nid) == 8);
+ CLASSERT((int)offsetof(struct lnet_hdr, dest_pid) == 16);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->dest_pid) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, src_pid) == 20);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->src_pid) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, type) == 24);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->type) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, payload_length) == 28);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->payload_length) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg) == 32);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg) == 40);
/* Ack */
- CLASSERT((int)offsetof(lnet_hdr_t, msg.ack.dst_wmd) == 32);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.ack.dst_wmd) == 16);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.ack.match_bits) == 48);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.ack.match_bits) == 8);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.ack.mlength) == 56);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.ack.mlength) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.ack.dst_wmd) == 32);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.ack.dst_wmd) == 16);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.ack.match_bits) == 48);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.ack.match_bits) == 8);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.ack.mlength) == 56);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.ack.mlength) == 4);
/* Put */
- CLASSERT((int)offsetof(lnet_hdr_t, msg.put.ack_wmd) == 32);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.ack_wmd) == 16);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.put.match_bits) == 48);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.match_bits) == 8);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.put.hdr_data) == 56);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.hdr_data) == 8);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.put.ptl_index) == 64);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.ptl_index) == 4);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.put.offset) == 68);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.put.offset) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.put.ack_wmd) == 32);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.put.ack_wmd) == 16);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.put.match_bits) == 48);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.put.match_bits) == 8);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.put.hdr_data) == 56);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.put.hdr_data) == 8);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.put.ptl_index) == 64);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.put.ptl_index) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.put.offset) == 68);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.put.offset) == 4);
/* Get */
- CLASSERT((int)offsetof(lnet_hdr_t, msg.get.return_wmd) == 32);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.return_wmd) == 16);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.get.match_bits) == 48);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.match_bits) == 8);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.get.ptl_index) == 56);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.ptl_index) == 4);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.get.src_offset) == 60);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.src_offset) == 4);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.get.sink_length) == 64);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.get.sink_length) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.get.return_wmd) == 32);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.get.return_wmd) == 16);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.get.match_bits) == 48);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.get.match_bits) == 8);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.get.ptl_index) == 56);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.get.ptl_index) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.get.src_offset) == 60);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.get.src_offset) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.get.sink_length) == 64);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.get.sink_length) == 4);
/* Reply */
- CLASSERT((int)offsetof(lnet_hdr_t, msg.reply.dst_wmd) == 32);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.reply.dst_wmd) == 16);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.reply.dst_wmd) == 32);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.reply.dst_wmd) == 16);
/* Hello */
- CLASSERT((int)offsetof(lnet_hdr_t, msg.hello.incarnation) == 32);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.hello.incarnation) == 8);
- CLASSERT((int)offsetof(lnet_hdr_t, msg.hello.type) == 40);
- CLASSERT((int)sizeof(((lnet_hdr_t *)0)->msg.hello.type) == 4);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.hello.incarnation) == 32);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.hello.incarnation) == 8);
+ CLASSERT((int)offsetof(struct lnet_hdr, msg.hello.type) == 40);
+ CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.hello.type) == 4);
}
static lnd_t *
@@ -822,13 +822,13 @@ lnet_count_acceptor_nis(void)
return count;
}
-static lnet_ping_info_t *
+static struct lnet_ping_info *
lnet_ping_info_create(int num_ni)
{
- lnet_ping_info_t *ping_info;
+ struct lnet_ping_info *ping_info;
unsigned int infosz;
- infosz = offsetof(lnet_ping_info_t, pi_ni[num_ni]);
+ infosz = offsetof(struct lnet_ping_info, pi_ni[num_ni]);
LIBCFS_ALLOC(ping_info, infosz);
if (!ping_info) {
CERROR("Can't allocate ping info[%d]\n", num_ni);
@@ -860,10 +860,10 @@ lnet_get_ni_count(void)
}
static inline void
-lnet_ping_info_free(lnet_ping_info_t *pinfo)
+lnet_ping_info_free(struct lnet_ping_info *pinfo)
{
LIBCFS_FREE(pinfo,
- offsetof(lnet_ping_info_t,
+ offsetof(struct lnet_ping_info,
pi_ni[pinfo->pi_nnis]));
}
@@ -889,14 +889,14 @@ lnet_ping_info_destroy(void)
static void
lnet_ping_event_handler(lnet_event_t *event)
{
- lnet_ping_info_t *pinfo = event->md.user_ptr;
+ struct lnet_ping_info *pinfo = event->md.user_ptr;
if (event->unlinked)
pinfo->pi_features = LNET_PING_FEAT_INVAL;
}
static int
-lnet_ping_info_setup(lnet_ping_info_t **ppinfo, lnet_handle_md_t *md_handle,
+lnet_ping_info_setup(struct lnet_ping_info **ppinfo, lnet_handle_md_t *md_handle,
int ni_count, bool set_eq)
{
lnet_process_id_t id = {LNET_NID_ANY, LNET_PID_ANY};
@@ -930,7 +930,7 @@ lnet_ping_info_setup(lnet_ping_info_t **ppinfo, lnet_handle_md_t *md_handle,
/* initialize md content */
md.start = *ppinfo;
- md.length = offsetof(lnet_ping_info_t,
+ md.length = offsetof(struct lnet_ping_info,
pi_ni[(*ppinfo)->pi_nnis]);
md.threshold = LNET_MD_THRESH_INF;
md.max_size = 0;
@@ -961,7 +961,7 @@ failed_0:
}
static void
-lnet_ping_md_unlink(lnet_ping_info_t *pinfo, lnet_handle_md_t *md_handle)
+lnet_ping_md_unlink(struct lnet_ping_info *pinfo, lnet_handle_md_t *md_handle)
{
sigset_t blocked = cfs_block_allsigs();
@@ -979,9 +979,9 @@ lnet_ping_md_unlink(lnet_ping_info_t *pinfo, lnet_handle_md_t *md_handle)
}
static void
-lnet_ping_info_install_locked(lnet_ping_info_t *ping_info)
+lnet_ping_info_install_locked(struct lnet_ping_info *ping_info)
{
- lnet_ni_status_t *ns;
+ struct lnet_ni_status *ns;
lnet_ni_t *ni;
int i = 0;
@@ -1003,9 +1003,9 @@ lnet_ping_info_install_locked(lnet_ping_info_t *ping_info)
}
static void
-lnet_ping_target_update(lnet_ping_info_t *pinfo, lnet_handle_md_t md_handle)
+lnet_ping_target_update(struct lnet_ping_info *pinfo, lnet_handle_md_t md_handle)
{
- lnet_ping_info_t *old_pinfo = NULL;
+ struct lnet_ping_info *old_pinfo = NULL;
lnet_handle_md_t old_md;
/* switch the NIs to point to the new ping info created */
@@ -1496,7 +1496,7 @@ LNetNIInit(lnet_pid_t requested_pid)
int im_a_router = 0;
int rc;
int ni_count;
- lnet_ping_info_t *pinfo;
+ struct lnet_ping_info *pinfo;
lnet_handle_md_t md_handle;
struct list_head net_head;
@@ -1754,7 +1754,7 @@ int
lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf)
{
char *nets = conf->cfg_config_u.cfg_net.net_intf;
- lnet_ping_info_t *pinfo;
+ struct lnet_ping_info *pinfo;
lnet_handle_md_t md_handle;
struct lnet_ni *ni;
struct list_head net_head;
@@ -1834,7 +1834,7 @@ int
lnet_dyn_del_ni(__u32 net)
{
lnet_ni_t *ni;
- lnet_ping_info_t *pinfo;
+ struct lnet_ping_info *pinfo;
lnet_handle_md_t md_handle;
int rc;
@@ -2147,7 +2147,7 @@ static int lnet_ping(lnet_process_id_t id, int timeout_ms,
int replied = 0;
const int a_long_time = 60000; /* mS */
int infosz;
- lnet_ping_info_t *info;
+ struct lnet_ping_info *info;
lnet_process_id_t tmpid;
int i;
int nob;
@@ -2155,7 +2155,7 @@ static int lnet_ping(lnet_process_id_t id, int timeout_ms,
int rc2;
sigset_t blocked;
- infosz = offsetof(lnet_ping_info_t, pi_ni[n_ids]);
+ infosz = offsetof(struct lnet_ping_info, pi_ni[n_ids]);
if (n_ids <= 0 ||
id.nid == LNET_NID_ANY ||
@@ -2283,18 +2283,18 @@ static int lnet_ping(lnet_process_id_t id, int timeout_ms,
goto out_1;
}
- if (nob < offsetof(lnet_ping_info_t, pi_ni[0])) {
+ if (nob < offsetof(struct lnet_ping_info, pi_ni[0])) {
CERROR("%s: Short reply %d(%d min)\n", libcfs_id2str(id),
- nob, (int)offsetof(lnet_ping_info_t, pi_ni[0]));
+ nob, (int)offsetof(struct lnet_ping_info, pi_ni[0]));
goto out_1;
}
if (info->pi_nnis < n_ids)
n_ids = info->pi_nnis;
- if (nob < offsetof(lnet_ping_info_t, pi_ni[n_ids])) {
+ if (nob < offsetof(struct lnet_ping_info, pi_ni[n_ids])) {
CERROR("%s: Short reply %d(%d expected)\n", libcfs_id2str(id),
- nob, (int)offsetof(lnet_ping_info_t, pi_ni[n_ids]));
+ nob, (int)offsetof(struct lnet_ping_info, pi_ni[n_ids]));
goto out_1;
}
diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
index f3dd6e42f4d4..6b0be6c23fff 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-move.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
@@ -641,7 +641,7 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send)
!list_empty(&lp->lp_txq));
msg->msg_peertxcredit = 1;
- lp->lp_txqnob += msg->msg_len + sizeof(lnet_hdr_t);
+ lp->lp_txqnob += msg->msg_len + sizeof(struct lnet_hdr);
lp->lp_txcredits--;
if (lp->lp_txcredits < lp->lp_mintxcredits)
@@ -811,7 +811,7 @@ lnet_return_tx_credits_locked(lnet_msg_t *msg)
LASSERT((txpeer->lp_txcredits < 0) ==
!list_empty(&txpeer->lp_txq));
- txpeer->lp_txqnob -= msg->msg_len + sizeof(lnet_hdr_t);
+ txpeer->lp_txqnob -= msg->msg_len + sizeof(struct lnet_hdr);
LASSERT(txpeer->lp_txqnob >= 0);
txpeer->lp_txcredits++;
@@ -1245,7 +1245,7 @@ lnet_drop_message(lnet_ni_t *ni, int cpt, void *private, unsigned int nob)
static void
lnet_recv_put(lnet_ni_t *ni, lnet_msg_t *msg)
{
- lnet_hdr_t *hdr = &msg->msg_hdr;
+ struct lnet_hdr *hdr = &msg->msg_hdr;
if (msg->msg_wanted)
lnet_setpayloadbuffer(msg);
@@ -1266,7 +1266,7 @@ lnet_recv_put(lnet_ni_t *ni, lnet_msg_t *msg)
static int
lnet_parse_put(lnet_ni_t *ni, lnet_msg_t *msg)
{
- lnet_hdr_t *hdr = &msg->msg_hdr;
+ struct lnet_hdr *hdr = &msg->msg_hdr;
struct lnet_match_info info;
bool ready_delay;
int rc;
@@ -1325,8 +1325,8 @@ static int
lnet_parse_get(lnet_ni_t *ni, lnet_msg_t *msg, int rdma_get)
{
struct lnet_match_info info;
- lnet_hdr_t *hdr = &msg->msg_hdr;
- lnet_handle_wire_t reply_wmd;
+ struct lnet_hdr *hdr = &msg->msg_hdr;
+ struct lnet_handle_wire reply_wmd;
int rc;
/* Convert get fields to host byte order */
@@ -1389,7 +1389,7 @@ static int
lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
{
void *private = msg->msg_private;
- lnet_hdr_t *hdr = &msg->msg_hdr;
+ struct lnet_hdr *hdr = &msg->msg_hdr;
lnet_process_id_t src = {0};
lnet_libmd_t *md;
int rlength;
@@ -1453,7 +1453,7 @@ lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
static int
lnet_parse_ack(lnet_ni_t *ni, lnet_msg_t *msg)
{
- lnet_hdr_t *hdr = &msg->msg_hdr;
+ struct lnet_hdr *hdr = &msg->msg_hdr;
lnet_process_id_t src = {0};
lnet_libmd_t *md;
int cpt;
@@ -1576,7 +1576,7 @@ lnet_msgtyp2str(int type)
}
void
-lnet_print_hdr(lnet_hdr_t *hdr)
+lnet_print_hdr(struct lnet_hdr *hdr)
{
lnet_process_id_t src = {0};
lnet_process_id_t dst = {0};
@@ -1634,7 +1634,7 @@ lnet_print_hdr(lnet_hdr_t *hdr)
}
int
-lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
+lnet_parse(lnet_ni_t *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid,
void *private, int rdma_req)
{
int rc = 0;
diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c
index 0897e588bd54..7ee164e67fbe 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-msg.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c
@@ -56,7 +56,7 @@ lnet_build_unlink_event(lnet_libmd_t *md, lnet_event_t *ev)
void
lnet_build_msg_event(lnet_msg_t *msg, lnet_event_kind_t ev_type)
{
- lnet_hdr_t *hdr = &msg->msg_hdr;
+ struct lnet_hdr *hdr = &msg->msg_hdr;
lnet_event_t *ev = &msg->msg_ev;
LASSERT(!msg->msg_routing);
@@ -361,7 +361,7 @@ lnet_msg_detach_md(lnet_msg_t *msg, int status)
static int
lnet_complete_msg_locked(lnet_msg_t *msg, int cpt)
{
- lnet_handle_wire_t ack_wmd;
+ struct lnet_handle_wire ack_wmd;
int rc;
int status = msg->msg_ev.status;
diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
index 3947e8b711c0..fa515af2ac1d 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
@@ -680,7 +680,7 @@ lnet_ptl_attach_md(lnet_me_t *me, lnet_libmd_t *md,
again:
list_for_each_entry_safe(msg, tmp, head, msg_list) {
struct lnet_match_info info;
- lnet_hdr_t *hdr;
+ struct lnet_hdr *hdr;
int rc;
LASSERT(msg->msg_rx_delayed || head == &ptl->ptl_msg_stealing);
diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c
index e4aceb71c4ec..bb6e4576a119 100644
--- a/drivers/staging/lustre/lnet/lnet/net_fault.c
+++ b/drivers/staging/lustre/lnet/lnet/net_fault.c
@@ -349,7 +349,7 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src,
* Check if message from \a src to \a dst can match any existed drop rule
*/
bool
-lnet_drop_rule_match(lnet_hdr_t *hdr)
+lnet_drop_rule_match(struct lnet_hdr *hdr)
{
struct lnet_drop_rule *rule;
lnet_nid_t src = le64_to_cpu(hdr->src_nid);
@@ -530,7 +530,7 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src,
* will be delayed if there is a match.
*/
bool
-lnet_delay_rule_match_locked(lnet_hdr_t *hdr, struct lnet_msg *msg)
+lnet_delay_rule_match_locked(struct lnet_hdr *hdr, struct lnet_msg *msg)
{
struct lnet_delay_rule *rule;
lnet_nid_t src = le64_to_cpu(hdr->src_nid);
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index 8afa0abf15cd..cf22525d7129 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -621,10 +621,10 @@ lnet_get_route(int idx, __u32 *net, __u32 *hops,
}
void
-lnet_swap_pinginfo(lnet_ping_info_t *info)
+lnet_swap_pinginfo(struct lnet_ping_info *info)
{
int i;
- lnet_ni_status_t *stat;
+ struct lnet_ni_status *stat;
__swab32s(&info->pi_magic);
__swab32s(&info->pi_features);
@@ -644,7 +644,7 @@ lnet_swap_pinginfo(lnet_ping_info_t *info)
static void
lnet_parse_rc_info(lnet_rc_data_t *rcd)
{
- lnet_ping_info_t *info = rcd->rcd_pinginfo;
+ struct lnet_ping_info *info = rcd->rcd_pinginfo;
struct lnet_peer *gw = rcd->rcd_gateway;
lnet_route_t *rte;
@@ -683,7 +683,7 @@ lnet_parse_rc_info(lnet_rc_data_t *rcd)
}
for (i = 0; i < info->pi_nnis && i < LNET_MAX_RTR_NIS; i++) {
- lnet_ni_status_t *stat = &info->pi_ni[i];
+ struct lnet_ni_status *stat = &info->pi_ni[i];
lnet_nid_t nid = stat->ns_nid;
if (nid == LNET_NID_ANY) {
@@ -902,7 +902,7 @@ static lnet_rc_data_t *
lnet_create_rc_data_locked(lnet_peer_t *gateway)
{
lnet_rc_data_t *rcd = NULL;
- lnet_ping_info_t *pi;
+ struct lnet_ping_info *pi;
lnet_md_t md;
int rc;
int i;
diff --git a/drivers/staging/lustre/lnet/selftest/brw_test.c b/drivers/staging/lustre/lnet/selftest/brw_test.c
index 67b460f41d6e..b9ac34ecbd53 100644
--- a/drivers/staging/lustre/lnet/selftest/brw_test.c
+++ b/drivers/staging/lustre/lnet/selftest/brw_test.c
@@ -136,7 +136,7 @@ brw_client_init(struct sfw_test_instance *tsi)
return 0;
}
-int brw_inject_one_error(void)
+static int brw_inject_one_error(void)
{
struct timespec64 ts;
diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c
index 94383023c1be..6ca7192b03b7 100644
--- a/drivers/staging/lustre/lnet/selftest/conctl.c
+++ b/drivers/staging/lustre/lnet/selftest/conctl.c
@@ -42,7 +42,7 @@
#include "console.h"
static int
-lst_session_new_ioctl(lstio_session_new_args_t *args)
+lst_session_new_ioctl(struct lstio_session_new_args *args)
{
char *name;
int rc;
@@ -78,7 +78,7 @@ lst_session_new_ioctl(lstio_session_new_args_t *args)
}
static int
-lst_session_end_ioctl(lstio_session_end_args_t *args)
+lst_session_end_ioctl(struct lstio_session_end_args *args)
{
if (args->lstio_ses_key != console_session.ses_key)
return -EACCES;
@@ -87,7 +87,7 @@ lst_session_end_ioctl(lstio_session_end_args_t *args)
}
static int
-lst_session_info_ioctl(lstio_session_info_args_t *args)
+lst_session_info_ioctl(struct lstio_session_info_args *args)
{
/* no checking of key */
@@ -109,7 +109,7 @@ lst_session_info_ioctl(lstio_session_info_args_t *args)
}
static int
-lst_debug_ioctl(lstio_debug_args_t *args)
+lst_debug_ioctl(struct lstio_debug_args *args)
{
char *name = NULL;
int client = 1;
@@ -190,7 +190,7 @@ out:
}
static int
-lst_group_add_ioctl(lstio_group_add_args_t *args)
+lst_group_add_ioctl(struct lstio_group_add_args *args)
{
char *name;
int rc;
@@ -223,7 +223,7 @@ lst_group_add_ioctl(lstio_group_add_args_t *args)
}
static int
-lst_group_del_ioctl(lstio_group_del_args_t *args)
+lst_group_del_ioctl(struct lstio_group_del_args *args)
{
int rc;
char *name;
@@ -256,7 +256,7 @@ lst_group_del_ioctl(lstio_group_del_args_t *args)
}
static int
-lst_group_update_ioctl(lstio_group_update_args_t *args)
+lst_group_update_ioctl(struct lstio_group_update_args *args)
{
int rc;
char *name;
@@ -313,7 +313,7 @@ lst_group_update_ioctl(lstio_group_update_args_t *args)
}
static int
-lst_nodes_add_ioctl(lstio_group_nodes_args_t *args)
+lst_nodes_add_ioctl(struct lstio_group_nodes_args *args)
{
unsigned int feats;
int rc;
@@ -358,7 +358,7 @@ lst_nodes_add_ioctl(lstio_group_nodes_args_t *args)
}
static int
-lst_group_list_ioctl(lstio_group_list_args_t *args)
+lst_group_list_ioctl(struct lstio_group_list_args *args)
{
if (args->lstio_grp_key != console_session.ses_key)
return -EACCES;
@@ -375,7 +375,7 @@ lst_group_list_ioctl(lstio_group_list_args_t *args)
}
static int
-lst_group_info_ioctl(lstio_group_info_args_t *args)
+lst_group_info_ioctl(struct lstio_group_info_args *args)
{
char *name;
int ndent;
@@ -438,7 +438,7 @@ lst_group_info_ioctl(lstio_group_info_args_t *args)
}
static int
-lst_batch_add_ioctl(lstio_batch_add_args_t *args)
+lst_batch_add_ioctl(struct lstio_batch_add_args *args)
{
int rc;
char *name;
@@ -471,7 +471,7 @@ lst_batch_add_ioctl(lstio_batch_add_args_t *args)
}
static int
-lst_batch_run_ioctl(lstio_batch_run_args_t *args)
+lst_batch_run_ioctl(struct lstio_batch_run_args *args)
{
int rc;
char *name;
@@ -505,7 +505,7 @@ lst_batch_run_ioctl(lstio_batch_run_args_t *args)
}
static int
-lst_batch_stop_ioctl(lstio_batch_stop_args_t *args)
+lst_batch_stop_ioctl(struct lstio_batch_stop_args *args)
{
int rc;
char *name;
@@ -540,7 +540,7 @@ lst_batch_stop_ioctl(lstio_batch_stop_args_t *args)
}
static int
-lst_batch_query_ioctl(lstio_batch_query_args_t *args)
+lst_batch_query_ioctl(struct lstio_batch_query_args *args)
{
char *name;
int rc;
@@ -581,7 +581,7 @@ lst_batch_query_ioctl(lstio_batch_query_args_t *args)
}
static int
-lst_batch_list_ioctl(lstio_batch_list_args_t *args)
+lst_batch_list_ioctl(struct lstio_batch_list_args *args)
{
if (args->lstio_bat_key != console_session.ses_key)
return -EACCES;
@@ -598,7 +598,7 @@ lst_batch_list_ioctl(lstio_batch_list_args_t *args)
}
static int
-lst_batch_info_ioctl(lstio_batch_info_args_t *args)
+lst_batch_info_ioctl(struct lstio_batch_info_args *args)
{
char *name;
int rc;
@@ -662,7 +662,7 @@ lst_batch_info_ioctl(lstio_batch_info_args_t *args)
}
static int
-lst_stat_query_ioctl(lstio_stat_args_t *args)
+lst_stat_query_ioctl(struct lstio_stat_args *args)
{
int rc;
char *name = NULL;
@@ -707,7 +707,7 @@ lst_stat_query_ioctl(lstio_stat_args_t *args)
return rc;
}
-static int lst_test_add_ioctl(lstio_test_args_t *args)
+static int lst_test_add_ioctl(struct lstio_test_args *args)
{
char *batch_name;
char *src_name = NULL;
@@ -851,69 +851,69 @@ lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
goto out;
}
- memset(&console_session.ses_trans_stat, 0, sizeof(lstcon_trans_stat_t));
+ memset(&console_session.ses_trans_stat, 0, sizeof(struct lstcon_trans_stat));
switch (opc) {
case LSTIO_SESSION_NEW:
- rc = lst_session_new_ioctl((lstio_session_new_args_t *)buf);
+ rc = lst_session_new_ioctl((struct lstio_session_new_args *)buf);
break;
case LSTIO_SESSION_END:
- rc = lst_session_end_ioctl((lstio_session_end_args_t *)buf);
+ rc = lst_session_end_ioctl((struct lstio_session_end_args *)buf);
break;
case LSTIO_SESSION_INFO:
- rc = lst_session_info_ioctl((lstio_session_info_args_t *)buf);
+ rc = lst_session_info_ioctl((struct lstio_session_info_args *)buf);
break;
case LSTIO_DEBUG:
- rc = lst_debug_ioctl((lstio_debug_args_t *)buf);
+ rc = lst_debug_ioctl((struct lstio_debug_args *)buf);
break;
case LSTIO_GROUP_ADD:
- rc = lst_group_add_ioctl((lstio_group_add_args_t *)buf);
+ rc = lst_group_add_ioctl((struct lstio_group_add_args *)buf);
break;
case LSTIO_GROUP_DEL:
- rc = lst_group_del_ioctl((lstio_group_del_args_t *)buf);
+ rc = lst_group_del_ioctl((struct lstio_group_del_args *)buf);
break;
case LSTIO_GROUP_UPDATE:
- rc = lst_group_update_ioctl((lstio_group_update_args_t *)buf);
+ rc = lst_group_update_ioctl((struct lstio_group_update_args *)buf);
break;
case LSTIO_NODES_ADD:
- rc = lst_nodes_add_ioctl((lstio_group_nodes_args_t *)buf);
+ rc = lst_nodes_add_ioctl((struct lstio_group_nodes_args *)buf);
break;
case LSTIO_GROUP_LIST:
- rc = lst_group_list_ioctl((lstio_group_list_args_t *)buf);
+ rc = lst_group_list_ioctl((struct lstio_group_list_args *)buf);
break;
case LSTIO_GROUP_INFO:
- rc = lst_group_info_ioctl((lstio_group_info_args_t *)buf);
+ rc = lst_group_info_ioctl((struct lstio_group_info_args *)buf);
break;
case LSTIO_BATCH_ADD:
- rc = lst_batch_add_ioctl((lstio_batch_add_args_t *)buf);
+ rc = lst_batch_add_ioctl((struct lstio_batch_add_args *)buf);
break;
case LSTIO_BATCH_START:
- rc = lst_batch_run_ioctl((lstio_batch_run_args_t *)buf);
+ rc = lst_batch_run_ioctl((struct lstio_batch_run_args *)buf);
break;
case LSTIO_BATCH_STOP:
- rc = lst_batch_stop_ioctl((lstio_batch_stop_args_t *)buf);
+ rc = lst_batch_stop_ioctl((struct lstio_batch_stop_args *)buf);
break;
case LSTIO_BATCH_QUERY:
- rc = lst_batch_query_ioctl((lstio_batch_query_args_t *)buf);
+ rc = lst_batch_query_ioctl((struct lstio_batch_query_args *)buf);
break;
case LSTIO_BATCH_LIST:
- rc = lst_batch_list_ioctl((lstio_batch_list_args_t *)buf);
+ rc = lst_batch_list_ioctl((struct lstio_batch_list_args *)buf);
break;
case LSTIO_BATCH_INFO:
- rc = lst_batch_info_ioctl((lstio_batch_info_args_t *)buf);
+ rc = lst_batch_info_ioctl((struct lstio_batch_info_args *)buf);
break;
case LSTIO_TEST_ADD:
- rc = lst_test_add_ioctl((lstio_test_args_t *)buf);
+ rc = lst_test_add_ioctl((struct lstio_test_args *)buf);
break;
case LSTIO_STAT_QUERY:
- rc = lst_stat_query_ioctl((lstio_stat_args_t *)buf);
+ rc = lst_stat_query_ioctl((struct lstio_stat_args *)buf);
break;
default:
rc = -EINVAL;
}
if (copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat,
- sizeof(lstcon_trans_stat_t)))
+ sizeof(struct lstcon_trans_stat)))
rc = -EFAULT;
out:
mutex_unlock(&console_session.ses_mutex);
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
index 994422c62487..c6a683bda75e 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.c
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
@@ -43,7 +43,7 @@
#include "console.h"
void lstcon_rpc_stat_reply(struct lstcon_rpc_trans *, struct srpc_msg *,
- struct lstcon_node *, lstcon_trans_stat_t *);
+ struct lstcon_node *, struct lstcon_trans_stat *);
static void
lstcon_rpc_done(struct srpc_client_rpc *rpc)
@@ -420,7 +420,7 @@ lstcon_rpc_get_reply(struct lstcon_rpc *crpc, struct srpc_msg **msgpp)
}
void
-lstcon_rpc_trans_stat(struct lstcon_rpc_trans *trans, lstcon_trans_stat_t *stat)
+lstcon_rpc_trans_stat(struct lstcon_rpc_trans *trans, struct lstcon_trans_stat *stat)
{
struct lstcon_rpc *crpc;
struct srpc_msg *rep;
@@ -469,7 +469,7 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans,
{
struct list_head tmp;
struct list_head __user *next;
- lstcon_rpc_ent_t *ent;
+ struct lstcon_rpc_ent *ent;
struct srpc_generic_reply *rep;
struct lstcon_rpc *crpc;
struct srpc_msg *msg;
@@ -492,7 +492,7 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans,
next = tmp.next;
- ent = list_entry(next, lstcon_rpc_ent_t, rpe_link);
+ ent = list_entry(next, struct lstcon_rpc_ent, rpe_link);
LASSERT(crpc->crp_stamp);
@@ -519,7 +519,7 @@ lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans,
/* RPC is done */
rep = (struct srpc_generic_reply *)&msg->msg_body.reply;
- if (copy_to_user(&ent->rpe_sid, &rep->sid, sizeof(lst_sid_t)) ||
+ if (copy_to_user(&ent->rpe_sid, &rep->sid, sizeof(rep->sid)) ||
copy_to_user(&ent->rpe_fwk_errno, &rep->status,
sizeof(rep->status)))
return -EFAULT;
@@ -698,17 +698,17 @@ lstcon_statrpc_prep(struct lstcon_node *nd, unsigned int feats,
return 0;
}
-static lnet_process_id_packed_t *
+static struct lnet_process_id_packed *
lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov)
{
- lnet_process_id_packed_t *pid;
+ struct lnet_process_id_packed *pid;
int i;
i = idx / SFW_ID_PER_PAGE;
LASSERT(i < nkiov);
- pid = (lnet_process_id_packed_t *)page_address(kiov[i].bv_page);
+ pid = (struct lnet_process_id_packed *)page_address(kiov[i].bv_page);
return &pid[idx % SFW_ID_PER_PAGE];
}
@@ -717,7 +717,7 @@ static int
lstcon_dstnodes_prep(struct lstcon_group *grp, int idx,
int dist, int span, int nkiov, lnet_kiov_t *kiov)
{
- lnet_process_id_packed_t *pid;
+ struct lnet_process_id_packed *pid;
struct lstcon_ndlink *ndl;
struct lstcon_node *nd;
int start;
@@ -768,7 +768,7 @@ lstcon_dstnodes_prep(struct lstcon_group *grp, int idx,
}
static int
-lstcon_pingrpc_prep(lst_test_ping_param_t *param, struct srpc_test_reqst *req)
+lstcon_pingrpc_prep(struct lst_test_ping_param *param, struct srpc_test_reqst *req)
{
struct test_ping_req *prq = &req->tsr_u.ping;
@@ -779,7 +779,7 @@ lstcon_pingrpc_prep(lst_test_ping_param_t *param, struct srpc_test_reqst *req)
}
static int
-lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param,
+lstcon_bulkrpc_v0_prep(struct lst_test_bulk_param *param,
struct srpc_test_reqst *req)
{
struct test_bulk_req *brq = &req->tsr_u.bulk_v0;
@@ -793,7 +793,7 @@ lstcon_bulkrpc_v0_prep(lst_test_bulk_param_t *param,
}
static int
-lstcon_bulkrpc_v1_prep(lst_test_bulk_param_t *param, bool is_client,
+lstcon_bulkrpc_v1_prep(struct lst_test_bulk_param *param, bool is_client,
struct srpc_test_reqst *req)
{
struct test_bulk_req_v1 *brq = &req->tsr_u.bulk_v1;
@@ -823,7 +823,7 @@ lstcon_testrpc_prep(struct lstcon_node *nd, int transop, unsigned int feats,
npg = sfw_id_pages(test->tes_span);
nob = !(feats & LST_FEAT_BULK_LEN) ?
npg * PAGE_SIZE :
- sizeof(lnet_process_id_packed_t) * test->tes_span;
+ sizeof(struct lnet_process_id_packed) * test->tes_span;
}
rc = lstcon_rpc_prep(nd, SRPC_SERVICE_TEST, feats, npg, nob, crpc);
@@ -891,17 +891,17 @@ lstcon_testrpc_prep(struct lstcon_node *nd, int transop, unsigned int feats,
switch (test->tes_type) {
case LST_TEST_PING:
trq->tsr_service = SRPC_SERVICE_PING;
- rc = lstcon_pingrpc_prep((lst_test_ping_param_t *)
+ rc = lstcon_pingrpc_prep((struct lst_test_ping_param *)
&test->tes_param[0], trq);
break;
case LST_TEST_BULK:
trq->tsr_service = SRPC_SERVICE_BRW;
if (!(feats & LST_FEAT_BULK_LEN)) {
- rc = lstcon_bulkrpc_v0_prep((lst_test_bulk_param_t *)
+ rc = lstcon_bulkrpc_v0_prep((struct lst_test_bulk_param *)
&test->tes_param[0], trq);
} else {
- rc = lstcon_bulkrpc_v1_prep((lst_test_bulk_param_t *)
+ rc = lstcon_bulkrpc_v1_prep((struct lst_test_bulk_param *)
&test->tes_param[0],
trq->tsr_is_client, trq);
}
@@ -964,7 +964,7 @@ lstcon_sesnew_stat_reply(struct lstcon_rpc_trans *trans,
void
lstcon_rpc_stat_reply(struct lstcon_rpc_trans *trans, struct srpc_msg *msg,
- struct lstcon_node *nd, lstcon_trans_stat_t *stat)
+ struct lstcon_node *nd, struct lstcon_trans_stat *stat)
{
struct srpc_rmsn_reply *rmsn_rep;
struct srpc_debug_reply *dbg_rep;
@@ -1320,7 +1320,7 @@ lstcon_rpc_pinger_stop(void)
lstcon_rpc_trans_stat(console_session.ses_ping, lstcon_trans_stat());
lstcon_rpc_trans_destroy(console_session.ses_ping);
- memset(lstcon_trans_stat(), 0, sizeof(lstcon_trans_stat_t));
+ memset(lstcon_trans_stat(), 0, sizeof(struct lstcon_trans_stat));
console_session.ses_ping = NULL;
}
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.h b/drivers/staging/lustre/lnet/selftest/conrpc.h
index e629e87c461c..7141d2c902a5 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.h
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.h
@@ -103,7 +103,7 @@ struct lstcon_rpc_trans {
typedef int (*lstcon_rpc_cond_func_t)(int, struct lstcon_node *, void *);
typedef int (*lstcon_rpc_readent_func_t)(int, struct srpc_msg *,
- lstcon_rpc_ent_t __user *);
+ struct lstcon_rpc_ent __user *);
int lstcon_sesrpc_prep(struct lstcon_node *nd, int transop,
unsigned int version, struct lstcon_rpc **crpc);
@@ -125,7 +125,7 @@ int lstcon_rpc_trans_ndlist(struct list_head *ndlist,
void *arg, lstcon_rpc_cond_func_t condition,
struct lstcon_rpc_trans **transpp);
void lstcon_rpc_trans_stat(struct lstcon_rpc_trans *trans,
- lstcon_trans_stat_t *stat);
+ struct lstcon_trans_stat *stat);
int lstcon_rpc_trans_interpreter(struct lstcon_rpc_trans *trans,
struct list_head __user *head_up,
lstcon_rpc_readent_func_t readent);
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
index 1456d2395cc9..4e7e5c862c64 100644
--- a/drivers/staging/lustre/lnet/selftest/console.c
+++ b/drivers/staging/lustre/lnet/selftest/console.c
@@ -368,7 +368,7 @@ lstcon_sesrpc_condition(int transop, struct lstcon_node *nd, void *arg)
static int
lstcon_sesrpc_readent(int transop, struct srpc_msg *msg,
- lstcon_rpc_ent_t __user *ent_up)
+ struct lstcon_rpc_ent __user *ent_up)
{
struct srpc_debug_reply *rep;
@@ -741,7 +741,7 @@ lstcon_group_list(int index, int len, char __user *name_up)
static int
lstcon_nodes_getent(struct list_head *head, int *index_p,
- int *count_p, lstcon_node_ent_t __user *dents_up)
+ int *count_p, struct lstcon_node_ent __user *dents_up)
{
struct lstcon_ndlink *ndl;
struct lstcon_node *nd;
@@ -780,11 +780,11 @@ lstcon_nodes_getent(struct list_head *head, int *index_p,
}
int
-lstcon_group_info(char *name, lstcon_ndlist_ent_t __user *gents_p,
+lstcon_group_info(char *name, struct lstcon_ndlist_ent __user *gents_p,
int *index_p, int *count_p,
- lstcon_node_ent_t __user *dents_up)
+ struct lstcon_node_ent __user *dents_up)
{
- lstcon_ndlist_ent_t *gentp;
+ struct lstcon_ndlist_ent *gentp;
struct lstcon_group *grp;
struct lstcon_ndlink *ndl;
int rc;
@@ -805,7 +805,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t __user *gents_p,
}
/* non-verbose query */
- LIBCFS_ALLOC(gentp, sizeof(lstcon_ndlist_ent_t));
+ LIBCFS_ALLOC(gentp, sizeof(struct lstcon_ndlist_ent));
if (!gentp) {
CERROR("Can't allocate ndlist_ent\n");
lstcon_group_decref(grp);
@@ -817,9 +817,9 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t __user *gents_p,
LST_NODE_STATE_COUNTER(ndl->ndl_node, gentp);
rc = copy_to_user(gents_p, gentp,
- sizeof(lstcon_ndlist_ent_t)) ? -EFAULT : 0;
+ sizeof(struct lstcon_ndlist_ent)) ? -EFAULT : 0;
- LIBCFS_FREE(gentp, sizeof(lstcon_ndlist_ent_t));
+ LIBCFS_FREE(gentp, sizeof(struct lstcon_ndlist_ent));
lstcon_group_decref(grp);
@@ -926,11 +926,11 @@ lstcon_batch_list(int index, int len, char __user *name_up)
}
int
-lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up,
+lstcon_batch_info(char *name, struct lstcon_test_batch_ent __user *ent_up,
int server, int testidx, int *index_p, int *ndent_p,
- lstcon_node_ent_t __user *dents_up)
+ struct lstcon_node_ent __user *dents_up)
{
- lstcon_test_batch_ent_t *entp;
+ struct lstcon_test_batch_ent *entp;
struct list_head *clilst;
struct list_head *srvlst;
struct lstcon_test *test = NULL;
@@ -969,7 +969,7 @@ lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up,
}
/* non-verbose query */
- LIBCFS_ALLOC(entp, sizeof(lstcon_test_batch_ent_t));
+ LIBCFS_ALLOC(entp, sizeof(struct lstcon_test_batch_ent));
if (!entp)
return -ENOMEM;
@@ -989,9 +989,9 @@ lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up,
LST_NODE_STATE_COUNTER(ndl->ndl_node, &entp->tbe_srv_nle);
rc = copy_to_user(ent_up, entp,
- sizeof(lstcon_test_batch_ent_t)) ? -EFAULT : 0;
+ sizeof(struct lstcon_test_batch_ent)) ? -EFAULT : 0;
- LIBCFS_FREE(entp, sizeof(lstcon_test_batch_ent_t));
+ LIBCFS_FREE(entp, sizeof(struct lstcon_test_batch_ent));
return rc;
}
@@ -1385,7 +1385,7 @@ lstcon_test_find(struct lstcon_batch *batch, int idx,
static int
lstcon_tsbrpc_readent(int transop, struct srpc_msg *msg,
- lstcon_rpc_ent_t __user *ent_up)
+ struct lstcon_rpc_ent __user *ent_up)
{
struct srpc_batch_reply *rep = &msg->msg_body.bat_reply;
@@ -1464,18 +1464,18 @@ lstcon_test_batch_query(char *name, int testidx, int client,
static int
lstcon_statrpc_readent(int transop, struct srpc_msg *msg,
- lstcon_rpc_ent_t __user *ent_up)
+ struct lstcon_rpc_ent __user *ent_up)
{
struct srpc_stat_reply *rep = &msg->msg_body.stat_reply;
- sfw_counters_t __user *sfwk_stat;
- srpc_counters_t __user *srpc_stat;
+ struct sfw_counters __user *sfwk_stat;
+ struct srpc_counters __user *srpc_stat;
lnet_counters_t __user *lnet_stat;
if (rep->str_status)
return 0;
- sfwk_stat = (sfw_counters_t __user *)&ent_up->rpe_payload[0];
- srpc_stat = (srpc_counters_t __user *)(sfwk_stat + 1);
+ sfwk_stat = (struct sfw_counters __user *)&ent_up->rpe_payload[0];
+ srpc_stat = (struct srpc_counters __user *)(sfwk_stat + 1);
lnet_stat = (lnet_counters_t __user *)(srpc_stat + 1);
if (copy_to_user(sfwk_stat, &rep->str_fw, sizeof(*sfwk_stat)) ||
@@ -1688,14 +1688,14 @@ lstcon_nodes_debug(int timeout,
}
int
-lstcon_session_match(lst_sid_t sid)
+lstcon_session_match(struct lst_sid sid)
{
return (console_session.ses_id.ses_nid == sid.ses_nid &&
console_session.ses_id.ses_stamp == sid.ses_stamp) ? 1 : 0;
}
static void
-lstcon_new_session_id(lst_sid_t *sid)
+lstcon_new_session_id(struct lst_sid *sid)
{
lnet_process_id_t id;
@@ -1708,7 +1708,7 @@ lstcon_new_session_id(lst_sid_t *sid)
int
lstcon_session_new(char *name, int key, unsigned int feats,
- int timeout, int force, lst_sid_t __user *sid_up)
+ int timeout, int force, struct lst_sid __user *sid_up)
{
int rc = 0;
int i;
@@ -1767,7 +1767,7 @@ lstcon_session_new(char *name, int key, unsigned int feats,
}
if (!copy_to_user(sid_up, &console_session.ses_id,
- sizeof(lst_sid_t)))
+ sizeof(struct lst_sid)))
return rc;
lstcon_session_end();
@@ -1776,12 +1776,12 @@ lstcon_session_new(char *name, int key, unsigned int feats,
}
int
-lstcon_session_info(lst_sid_t __user *sid_up, int __user *key_up,
+lstcon_session_info(struct lst_sid __user *sid_up, int __user *key_up,
unsigned __user *featp,
- lstcon_ndlist_ent_t __user *ndinfo_up,
+ struct lstcon_ndlist_ent __user *ndinfo_up,
char __user *name_up, int len)
{
- lstcon_ndlist_ent_t *entp;
+ struct lstcon_ndlist_ent *entp;
struct lstcon_ndlink *ndl;
int rc = 0;
@@ -1796,7 +1796,7 @@ lstcon_session_info(lst_sid_t __user *sid_up, int __user *key_up,
LST_NODE_STATE_COUNTER(ndl->ndl_node, entp);
if (copy_to_user(sid_up, &console_session.ses_id,
- sizeof(lst_sid_t)) ||
+ sizeof(*sid_up)) ||
copy_to_user(key_up, &console_session.ses_key,
sizeof(*key_up)) ||
copy_to_user(featp, &console_session.ses_features,
diff --git a/drivers/staging/lustre/lnet/selftest/console.h b/drivers/staging/lustre/lnet/selftest/console.h
index 5dc1de48a10e..05b4b7013d2e 100644
--- a/drivers/staging/lustre/lnet/selftest/console.h
+++ b/drivers/staging/lustre/lnet/selftest/console.h
@@ -81,7 +81,7 @@ struct lstcon_group {
#define LST_BATCH_RUNNING 0xB1 /* running batch */
struct lstcon_tsb_hdr {
- lst_bid_t tsb_id; /* batch ID */
+ struct lst_bid tsb_id; /* batch ID */
int tsb_index; /* test index */
};
@@ -140,7 +140,7 @@ struct lstcon_test {
struct lstcon_session {
struct mutex ses_mutex; /* only 1 thread in session */
- lst_sid_t ses_id; /* global session id */
+ struct lst_sid ses_id; /* global session id */
int ses_key; /* local session key */
int ses_state; /* state of session */
int ses_timeout; /* timeout in seconds */
@@ -158,7 +158,7 @@ struct lstcon_session {
char ses_name[LST_NAME_SIZE];/* session name */
struct lstcon_rpc_trans *ses_ping; /* session pinger */
struct stt_timer ses_ping_timer; /* timer for pinger */
- lstcon_trans_stat_t ses_trans_stat; /* transaction stats */
+ struct lstcon_trans_stat ses_trans_stat; /* transaction stats */
struct list_head ses_trans_list; /* global list of transaction */
struct list_head ses_grp_list; /* global list of groups */
@@ -173,7 +173,7 @@ struct lstcon_session {
extern struct lstcon_session console_session;
-static inline lstcon_trans_stat_t *
+static inline struct lstcon_trans_stat *
lstcon_trans_stat(void)
{
return &console_session.ses_trans_stat;
@@ -190,11 +190,11 @@ lstcon_id2hash(lnet_process_id_t id, struct list_head *hash)
int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr);
int lstcon_console_init(void);
int lstcon_console_fini(void);
-int lstcon_session_match(lst_sid_t sid);
+int lstcon_session_match(struct lst_sid sid);
int lstcon_session_new(char *name, int key, unsigned int version,
- int timeout, int flags, lst_sid_t __user *sid_up);
-int lstcon_session_info(lst_sid_t __user *sid_up, int __user *key,
- unsigned __user *verp, lstcon_ndlist_ent_t __user *entp,
+ int timeout, int flags, struct lst_sid __user *sid_up);
+int lstcon_session_info(struct lst_sid __user *sid_up, int __user *key,
+ unsigned __user *verp, struct lstcon_ndlist_ent __user *entp,
char __user *name_up, int len);
int lstcon_session_end(void);
int lstcon_session_debug(int timeout, struct list_head __user *result_up);
@@ -213,9 +213,9 @@ int lstcon_nodes_add(char *name, int nnd, lnet_process_id_t __user *nds_up,
unsigned int *featp, struct list_head __user *result_up);
int lstcon_nodes_remove(char *name, int nnd, lnet_process_id_t __user *nds_up,
struct list_head __user *result_up);
-int lstcon_group_info(char *name, lstcon_ndlist_ent_t __user *gent_up,
+int lstcon_group_info(char *name, struct lstcon_ndlist_ent __user *gent_up,
int *index_p, int *ndent_p,
- lstcon_node_ent_t __user *ndents_up);
+ struct lstcon_node_ent __user *ndents_up);
int lstcon_group_list(int idx, int len, char __user *name_up);
int lstcon_batch_add(char *name);
int lstcon_batch_run(char *name, int timeout,
@@ -227,9 +227,9 @@ int lstcon_test_batch_query(char *name, int testidx,
struct list_head __user *result_up);
int lstcon_batch_del(char *name);
int lstcon_batch_list(int idx, int namelen, char __user *name_up);
-int lstcon_batch_info(char *name, lstcon_test_batch_ent_t __user *ent_up,
+int lstcon_batch_info(char *name, struct lstcon_test_batch_ent __user *ent_up,
int server, int testidx, int *index_p,
- int *ndent_p, lstcon_node_ent_t __user *dents_up);
+ int *ndent_p, struct lstcon_node_ent __user *dents_up);
int lstcon_group_stat(char *grp_name, int timeout,
struct list_head __user *result_up);
int lstcon_nodes_stat(int count, lnet_process_id_t __user *ids_up,
diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c
index 48dcc330dc9b..9dd4e1a70329 100644
--- a/drivers/staging/lustre/lnet/selftest/framework.c
+++ b/drivers/staging/lustre/lnet/selftest/framework.c
@@ -39,7 +39,7 @@
#include "selftest.h"
-lst_sid_t LST_INVALID_SID = {LNET_NID_ANY, -1};
+struct lst_sid LST_INVALID_SID = {LNET_NID_ANY, -1};
static int session_timeout = 100;
module_param(session_timeout, int, 0444);
@@ -254,7 +254,7 @@ sfw_session_expired(void *data)
}
static inline void
-sfw_init_session(struct sfw_session *sn, lst_sid_t sid,
+sfw_init_session(struct sfw_session *sn, struct lst_sid sid,
unsigned int features, const char *name)
{
struct stt_timer *timer = &sn->sn_timer;
@@ -316,7 +316,7 @@ sfw_client_rpc_fini(struct srpc_client_rpc *rpc)
}
static struct sfw_batch *
-sfw_find_batch(lst_bid_t bid)
+sfw_find_batch(struct lst_bid bid)
{
struct sfw_session *sn = sfw_data.fw_session;
struct sfw_batch *bat;
@@ -332,7 +332,7 @@ sfw_find_batch(lst_bid_t bid)
}
static struct sfw_batch *
-sfw_bid2batch(lst_bid_t bid)
+sfw_bid2batch(struct lst_bid bid)
{
struct sfw_session *sn = sfw_data.fw_session;
struct sfw_batch *bat;
@@ -361,7 +361,7 @@ static int
sfw_get_stats(struct srpc_stat_reqst *request, struct srpc_stat_reply *reply)
{
struct sfw_session *sn = sfw_data.fw_session;
- sfw_counters_t *cnt = &reply->str_fw;
+ struct sfw_counters *cnt = &reply->str_fw;
struct sfw_batch *bat;
reply->str_sid = !sn ? LST_INVALID_SID : sn->sn_id;
@@ -777,14 +777,14 @@ sfw_add_test_instance(struct sfw_batch *tsb, struct srpc_server_rpc *rpc)
LASSERT(bk);
LASSERT(bk->bk_niov * SFW_ID_PER_PAGE >= (unsigned int)ndest);
LASSERT((unsigned int)bk->bk_len >=
- sizeof(lnet_process_id_packed_t) * ndest);
+ sizeof(struct lnet_process_id_packed) * ndest);
sfw_unpack_addtest_req(msg);
memcpy(&tsi->tsi_u, &req->tsr_u, sizeof(tsi->tsi_u));
for (i = 0; i < ndest; i++) {
- lnet_process_id_packed_t *dests;
- lnet_process_id_packed_t id;
+ struct lnet_process_id_packed *dests;
+ struct lnet_process_id_packed id;
int j;
dests = page_address(bk->bk_iovs[i / SFW_ID_PER_PAGE].bv_page);
@@ -1164,7 +1164,7 @@ sfw_add_test(struct srpc_server_rpc *rpc)
len = npg * PAGE_SIZE;
} else {
- len = sizeof(lnet_process_id_packed_t) *
+ len = sizeof(struct lnet_process_id_packed) *
request->tsr_ndest;
}
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
index ce9de8c9be57..92cd4113cf75 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.c
+++ b/drivers/staging/lustre/lnet/selftest/rpc.c
@@ -55,7 +55,7 @@ static struct smoketest_rpc {
struct srpc_service *rpc_services[SRPC_SERVICE_MAX_ID + 1];
lnet_handle_eq_t rpc_lnet_eq; /* _the_ LNet event queue */
enum srpc_state rpc_state;
- srpc_counters_t rpc_counters;
+ struct srpc_counters rpc_counters;
__u64 rpc_matchbits; /* matchbits counter */
} srpc_data;
@@ -69,14 +69,14 @@ srpc_serv_portal(int svc_id)
/* forward ref's */
int srpc_handle_rpc(struct swi_workitem *wi);
-void srpc_get_counters(srpc_counters_t *cnt)
+void srpc_get_counters(struct srpc_counters *cnt)
{
spin_lock(&srpc_data.rpc_glock);
*cnt = srpc_data.rpc_counters;
spin_unlock(&srpc_data.rpc_glock);
}
-void srpc_set_counters(const srpc_counters_t *cnt)
+void srpc_set_counters(const struct srpc_counters *cnt)
{
spin_lock(&srpc_data.rpc_glock);
srpc_data.rpc_counters = *cnt;
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.h b/drivers/staging/lustre/lnet/selftest/rpc.h
index f353a634cc8e..418c9c96abe6 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.h
+++ b/drivers/staging/lustre/lnet/selftest/rpc.h
@@ -75,43 +75,43 @@ struct srpc_generic_reqst {
struct srpc_generic_reply {
__u32 status;
- lst_sid_t sid;
+ struct lst_sid sid;
} WIRE_ATTR;
/* FRAMEWORK RPCs */
struct srpc_mksn_reqst {
__u64 mksn_rpyid; /* reply buffer matchbits */
- lst_sid_t mksn_sid; /* session id */
+ struct lst_sid mksn_sid; /* session id */
__u32 mksn_force; /* use brute force */
char mksn_name[LST_NAME_SIZE];
} WIRE_ATTR; /* make session request */
struct srpc_mksn_reply {
__u32 mksn_status; /* session status */
- lst_sid_t mksn_sid; /* session id */
+ struct lst_sid mksn_sid; /* session id */
__u32 mksn_timeout; /* session timeout */
char mksn_name[LST_NAME_SIZE];
} WIRE_ATTR; /* make session reply */
struct srpc_rmsn_reqst {
__u64 rmsn_rpyid; /* reply buffer matchbits */
- lst_sid_t rmsn_sid; /* session id */
+ struct lst_sid rmsn_sid; /* session id */
} WIRE_ATTR; /* remove session request */
struct srpc_rmsn_reply {
__u32 rmsn_status;
- lst_sid_t rmsn_sid; /* session id */
+ struct lst_sid rmsn_sid; /* session id */
} WIRE_ATTR; /* remove session reply */
struct srpc_join_reqst {
__u64 join_rpyid; /* reply buffer matchbits */
- lst_sid_t join_sid; /* session id to join */
+ struct lst_sid join_sid; /* session id to join */
char join_group[LST_NAME_SIZE]; /* group name */
} WIRE_ATTR;
struct srpc_join_reply {
__u32 join_status; /* returned status */
- lst_sid_t join_sid; /* session id */
+ struct lst_sid join_sid; /* session id */
__u32 join_timeout; /* # seconds' inactivity to
* expire
*/
@@ -120,13 +120,13 @@ struct srpc_join_reply {
struct srpc_debug_reqst {
__u64 dbg_rpyid; /* reply buffer matchbits */
- lst_sid_t dbg_sid; /* session id */
+ struct lst_sid dbg_sid; /* session id */
__u32 dbg_flags; /* bitmap of debug */
} WIRE_ATTR;
struct srpc_debug_reply {
__u32 dbg_status; /* returned code */
- lst_sid_t dbg_sid; /* session id */
+ struct lst_sid dbg_sid; /* session id */
__u32 dbg_timeout; /* session timeout */
__u32 dbg_nbatch; /* # of batches in the node */
char dbg_name[LST_NAME_SIZE]; /* session name */
@@ -138,8 +138,8 @@ struct srpc_debug_reply {
struct srpc_batch_reqst {
__u64 bar_rpyid; /* reply buffer matchbits */
- lst_sid_t bar_sid; /* session id */
- lst_bid_t bar_bid; /* batch id */
+ struct lst_sid bar_sid; /* session id */
+ struct lst_bid bar_bid; /* batch id */
__u32 bar_opc; /* create/start/stop batch */
__u32 bar_testidx; /* index of test */
__u32 bar_arg; /* parameters */
@@ -147,22 +147,22 @@ struct srpc_batch_reqst {
struct srpc_batch_reply {
__u32 bar_status; /* status of request */
- lst_sid_t bar_sid; /* session id */
+ struct lst_sid bar_sid; /* session id */
__u32 bar_active; /* # of active tests in batch/test */
__u32 bar_time; /* remained time */
} WIRE_ATTR;
struct srpc_stat_reqst {
__u64 str_rpyid; /* reply buffer matchbits */
- lst_sid_t str_sid; /* session id */
+ struct lst_sid str_sid; /* session id */
__u32 str_type; /* type of stat */
} WIRE_ATTR;
struct srpc_stat_reply {
__u32 str_status;
- lst_sid_t str_sid;
- sfw_counters_t str_fw;
- srpc_counters_t str_rpc;
+ struct lst_sid str_sid;
+ struct sfw_counters str_fw;
+ struct srpc_counters str_rpc;
lnet_counters_t str_lnet;
} WIRE_ATTR;
@@ -187,8 +187,8 @@ struct test_ping_req {
struct srpc_test_reqst {
__u64 tsr_rpyid; /* reply buffer matchbits */
__u64 tsr_bulkid; /* bulk buffer matchbits */
- lst_sid_t tsr_sid; /* session id */
- lst_bid_t tsr_bid; /* batch id */
+ struct lst_sid tsr_sid; /* session id */
+ struct lst_bid tsr_bid; /* batch id */
__u32 tsr_service; /* test type: bulk|ping|... */
__u32 tsr_loop; /* test client loop count or
* # server buffers needed
@@ -207,7 +207,7 @@ struct srpc_test_reqst {
struct srpc_test_reply {
__u32 tsr_status; /* returned code */
- lst_sid_t tsr_sid;
+ struct lst_sid tsr_sid;
} WIRE_ATTR;
/* TEST RPCs */
diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h
index c8833a016b6d..f25948087ee0 100644
--- a/drivers/staging/lustre/lnet/selftest/selftest.h
+++ b/drivers/staging/lustre/lnet/selftest/selftest.h
@@ -322,7 +322,7 @@ struct srpc_service {
struct sfw_session {
struct list_head sn_list; /* chain on fw_zombie_sessions */
- lst_sid_t sn_id; /* unique identifier */
+ struct lst_sid sn_id; /* unique identifier */
unsigned int sn_timeout; /* # seconds' inactivity to expire */
int sn_timer_active;
unsigned int sn_features;
@@ -340,7 +340,7 @@ struct sfw_session {
struct sfw_batch {
struct list_head bat_list; /* chain on sn_batches */
- lst_bid_t bat_id; /* batch id */
+ struct lst_bid bat_id; /* batch id */
int bat_error; /* error code of batch */
struct sfw_session *bat_session; /* batch's session */
atomic_t bat_nactive; /* # of active tests */
@@ -396,7 +396,7 @@ struct sfw_test_instance {
* pages are not used
*/
#define SFW_MAX_CONCUR LST_MAX_CONCUR
-#define SFW_ID_PER_PAGE (PAGE_SIZE / sizeof(lnet_process_id_packed_t))
+#define SFW_ID_PER_PAGE (PAGE_SIZE / sizeof(struct lnet_process_id_packed))
#define SFW_MAX_NDESTS (LNET_MAX_IOV * SFW_ID_PER_PAGE)
#define sfw_id_pages(n) (((n) + SFW_ID_PER_PAGE - 1) / SFW_ID_PER_PAGE)
@@ -453,8 +453,8 @@ void srpc_abort_service(struct srpc_service *sv);
int srpc_finish_service(struct srpc_service *sv);
int srpc_service_add_buffers(struct srpc_service *sv, int nbuffer);
void srpc_service_remove_buffers(struct srpc_service *sv, int nbuffer);
-void srpc_get_counters(srpc_counters_t *cnt);
-void srpc_set_counters(const srpc_counters_t *cnt);
+void srpc_get_counters(struct srpc_counters *cnt);
+void srpc_set_counters(const struct srpc_counters *cnt);
extern struct cfs_wi_sched *lst_sched_serial;
extern struct cfs_wi_sched **lst_sched_test;
diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h
index 260643ee0d48..69b281252db0 100644
--- a/drivers/staging/lustre/lustre/include/lu_object.h
+++ b/drivers/staging/lustre/lustre/include/lu_object.h
@@ -1326,5 +1326,8 @@ void lu_buf_realloc(struct lu_buf *buf, size_t size);
int lu_buf_check_and_grow(struct lu_buf *buf, size_t len);
struct lu_buf *lu_buf_check_and_alloc(struct lu_buf *buf, size_t len);
+extern __u32 lu_context_tags_default;
+extern __u32 lu_session_tags_default;
+
/** @} lu */
#endif /* __LUSTRE_LU_OBJECT_H */
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
index 65ce503ad595..b0eb80d70c23 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
@@ -3130,52 +3130,6 @@ struct obdo {
#define o_cksum o_nlink
#define o_grant_used o_data_version
-static inline void lustre_set_wire_obdo(const struct obd_connect_data *ocd,
- struct obdo *wobdo,
- const struct obdo *lobdo)
-{
- *wobdo = *lobdo;
- wobdo->o_flags &= ~OBD_FL_LOCAL_MASK;
- if (!ocd)
- return;
-
- if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) &&
- fid_seq_is_echo(ostid_seq(&lobdo->o_oi))) {
- /* Currently OBD_FL_OSTID will only be used when 2.4 echo
- * client communicate with pre-2.4 server
- */
- wobdo->o_oi.oi.oi_id = fid_oid(&lobdo->o_oi.oi_fid);
- wobdo->o_oi.oi.oi_seq = fid_seq(&lobdo->o_oi.oi_fid);
- }
-}
-
-static inline void lustre_get_wire_obdo(const struct obd_connect_data *ocd,
- struct obdo *lobdo,
- const struct obdo *wobdo)
-{
- __u32 local_flags = 0;
-
- if (lobdo->o_valid & OBD_MD_FLFLAGS)
- local_flags = lobdo->o_flags & OBD_FL_LOCAL_MASK;
-
- *lobdo = *wobdo;
- if (local_flags != 0) {
- lobdo->o_valid |= OBD_MD_FLFLAGS;
- lobdo->o_flags &= ~OBD_FL_LOCAL_MASK;
- lobdo->o_flags |= local_flags;
- }
- if (!ocd)
- return;
-
- if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) &&
- fid_seq_is_echo(wobdo->o_oi.oi.oi_seq)) {
- /* see above */
- lobdo->o_oi.oi_fid.f_seq = wobdo->o_oi.oi.oi_seq;
- lobdo->o_oi.oi_fid.f_oid = wobdo->o_oi.oi.oi_id;
- lobdo->o_oi.oi_fid.f_ver = 0;
- }
-}
-
/* request structure for OST's */
struct ost_body {
struct obdo oa;
diff --git a/drivers/staging/lustre/lustre/include/lustre_obdo.h b/drivers/staging/lustre/lustre/include/lustre_obdo.h
new file mode 100644
index 000000000000..1e12f8c0f157
--- /dev/null
+++ b/drivers/staging/lustre/lustre/include/lustre_obdo.h
@@ -0,0 +1,54 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2014, Intel Corporation.
+ *
+ * Copyright 2015 Cray Inc, all rights reserved.
+ * Author: Ben Evans.
+ *
+ * Define obdo associated functions
+ * obdo: OBject Device o...
+ */
+
+#ifndef _LUSTRE_OBDO_H_
+#define _LUSTRE_OBDO_H_
+
+#include "lustre/lustre_idl.h"
+
+/**
+ * Create an obdo to send over the wire
+ */
+void lustre_set_wire_obdo(const struct obd_connect_data *ocd,
+ struct obdo *wobdo,
+ const struct obdo *lobdo);
+
+/**
+ * Create a local obdo from a wire based odbo
+ */
+void lustre_get_wire_obdo(const struct obd_connect_data *ocd,
+ struct obdo *lobdo,
+ const struct obdo *wobdo);
+
+#endif
diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
index 0f48e9c3d9e3..6f0f5dd1f617 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -43,6 +43,7 @@
#include "lustre_fld.h"
#include "lustre_handles.h"
#include "lustre_intent.h"
+#include "cl_object.h"
#define MAX_OBD_DEVICES 8192
@@ -76,6 +77,8 @@ static inline void loi_init(struct lov_oinfo *loi)
struct lov_stripe_md;
struct obd_info;
+int lov_read_and_clear_async_rc(struct cl_object *clob);
+
typedef int (*obd_enqueue_update_f)(void *cookie, int rc);
/* obd info for a particular level (lov, osc). */
@@ -889,7 +892,7 @@ struct obd_client_handle {
struct md_open_data *och_mod;
struct lustre_handle och_lease_handle; /* open lock for lease */
__u32 och_magic;
- int och_flags;
+ fmode_t och_flags;
};
#define OBD_CLIENT_HANDLE_MAGIC 0xd15ea5ed
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index 722160784f83..f815827532dc 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -143,7 +143,7 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req, __u64 *flags,
int added = (mode == LCK_NL);
int overlaps = 0;
int splitted = 0;
- const struct ldlm_callback_suite null_cbs = { NULL };
+ const struct ldlm_callback_suite null_cbs = { };
CDEBUG(D_DLMTRACE,
"flags %#llx owner %llu pid %u mode %u start %llu end %llu\n",
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
index a4a291acb659..afef5a27cd1d 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
@@ -1131,8 +1131,7 @@ static int lock_matches(struct ldlm_lock *lock, struct lock_match_data *data)
if (!data->lmd_unref && LDLM_HAVE_MASK(lock, GONE))
return INTERVAL_ITER_CONT;
- if ((data->lmd_flags & LDLM_FL_LOCAL_ONLY) &&
- !ldlm_is_local(lock))
+ if (!equi(data->lmd_flags & LDLM_FL_LOCAL_ONLY, ldlm_is_local(lock)))
return INTERVAL_ITER_CONT;
if (data->lmd_flags & LDLM_FL_TEST_LOCK) {
@@ -1148,7 +1147,7 @@ static int lock_matches(struct ldlm_lock *lock, struct lock_match_data *data)
return INTERVAL_ITER_STOP;
}
-static unsigned int itree_overlap_cb(struct interval_node *in, void *args)
+static enum interval_iter itree_overlap_cb(struct interval_node *in, void *args)
{
struct ldlm_interval *node = to_ldlm_interval(in);
struct lock_match_data *data = args;
diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
index ea5d247a3f70..526fea266926 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -432,7 +432,7 @@ static int ll_dir_setdirstripe(struct inode *parent, struct lmv_user_md *lump,
if (!IS_POSIXACL(parent) || !exp_connect_umask(ll_i2mdexp(parent)))
mode &= ~current_umask();
- mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+ mode = (mode & (0777 | S_ISVTX)) | S_IFDIR;
op_data = ll_prep_md_op_data(NULL, parent, NULL, dirname,
strlen(dirname), mode, LUSTRE_OPC_MKDIR,
lump);
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index f634c11216e6..a17118876555 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -1016,7 +1016,7 @@ static bool file_is_noatime(const struct file *file)
return false;
}
-void ll_io_init(struct cl_io *io, const struct file *file, int write)
+static void ll_io_init(struct cl_io *io, const struct file *file, int write)
{
struct inode *inode = file_inode(file);
@@ -1883,7 +1883,7 @@ static int ll_hsm_import(struct inode *inode, struct file *file,
goto free_hss;
}
- attr->ia_mode = hui->hui_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ attr->ia_mode = hui->hui_mode & 0777;
attr->ia_mode |= S_IFREG;
attr->ia_uid = make_kuid(&init_user_ns, hui->hui_uid);
attr->ia_gid = make_kgid(&init_user_ns, hui->hui_gid);
diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c
index 25f5aed97f63..9cb4909e3b86 100644
--- a/drivers/staging/lustre/lustre/llite/llite_lib.c
+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c
@@ -1599,7 +1599,7 @@ int ll_setattr(struct dentry *de, struct iattr *attr)
if (((attr->ia_valid & (ATTR_MODE | ATTR_FORCE | ATTR_SIZE)) ==
(ATTR_SIZE | ATTR_MODE)) &&
(((mode & S_ISUID) && !(attr->ia_mode & S_ISUID)) ||
- (((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) &&
+ (((mode & (S_ISGID | 0010)) == (S_ISGID | 0010)) &&
!(attr->ia_mode & S_ISGID))))
attr->ia_valid |= ATTR_FORCE;
@@ -1610,7 +1610,7 @@ int ll_setattr(struct dentry *de, struct iattr *attr)
attr->ia_valid |= ATTR_KILL_SUID;
if ((attr->ia_valid & ATTR_MODE) &&
- ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) &&
+ ((mode & (S_ISGID | 0010)) == (S_ISGID | 0010)) &&
!(attr->ia_mode & S_ISGID) &&
!(attr->ia_valid & ATTR_KILL_SGID))
attr->ia_valid |= ATTR_KILL_SGID;
diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
index 03682c10fc9e..f3ee584157e0 100644
--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
+++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
@@ -924,27 +924,29 @@ static ssize_t ll_unstable_stats_seq_write(struct file *file,
}
LPROC_SEQ_FOPS(ll_unstable_stats);
-static ssize_t root_squash_show(struct kobject *kobj, struct attribute *attr,
- char *buf)
+static int ll_root_squash_seq_show(struct seq_file *m, void *v)
{
- struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
- ll_kobj);
+ struct super_block *sb = m->private;
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
struct root_squash_info *squash = &sbi->ll_squash;
- return sprintf(buf, "%u:%u\n", squash->rsi_uid, squash->rsi_gid);
+ seq_printf(m, "%u:%u\n", squash->rsi_uid, squash->rsi_gid);
+ return 0;
}
-static ssize_t root_squash_store(struct kobject *kobj, struct attribute *attr,
- const char *buffer, size_t count)
+static ssize_t ll_root_squash_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
{
- struct ll_sb_info *sbi = container_of(kobj, struct ll_sb_info,
- ll_kobj);
+ struct seq_file *m = file->private_data;
+ struct super_block *sb = m->private;
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
struct root_squash_info *squash = &sbi->ll_squash;
return lprocfs_wr_root_squash(buffer, count, squash,
- ll_get_fsname(sbi->ll_sb, NULL, 0));
+ ll_get_fsname(sb, NULL, 0));
}
-LUSTRE_RW_ATTR(root_squash);
+LPROC_SEQ_FOPS(ll_root_squash);
static int ll_nosquash_nids_seq_show(struct seq_file *m, void *v)
{
@@ -997,6 +999,8 @@ static struct lprocfs_vars lprocfs_llite_obd_vars[] = {
{ "statahead_stats", &ll_statahead_stats_fops, NULL, 0 },
{ "unstable_stats", &ll_unstable_stats_fops, NULL },
{ "sbi_flags", &ll_sbi_flags_fops, NULL, 0 },
+ { .name = "root_squash",
+ .fops = &ll_root_squash_fops },
{ .name = "nosquash_nids",
.fops = &ll_nosquash_nids_fops },
{ NULL }
@@ -1027,7 +1031,6 @@ static struct attribute *llite_attrs[] = {
&lustre_attr_max_easize.attr,
&lustre_attr_default_easize.attr,
&lustre_attr_xattr_cache.attr,
- &lustre_attr_root_squash.attr,
NULL,
};
diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c
index a8f4e7fb0a46..f925656f11c9 100644
--- a/drivers/staging/lustre/lustre/llite/namei.c
+++ b/drivers/staging/lustre/lustre/llite/namei.c
@@ -1041,7 +1041,7 @@ static int ll_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
if (!IS_POSIXACL(dir) || !exp_connect_umask(ll_i2mdexp(dir)))
mode &= ~current_umask();
- mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+ mode = (mode & (0777 | S_ISVTX)) | S_IFDIR;
err = ll_new_node(dir, dentry, NULL, mode, 0, LUSTRE_OPC_MKDIR);
if (!err)
@@ -1089,7 +1089,7 @@ static int ll_symlink(struct inode *dir, struct dentry *dentry,
CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, dir="DFID"(%p),target=%.*s\n",
dentry, PFID(ll_inode2fid(dir)), dir, 3000, oldname);
- err = ll_new_node(dir, dentry, oldname, S_IFLNK | S_IRWXUGO,
+ err = ll_new_node(dir, dentry, oldname, S_IFLNK | 0777,
0, LUSTRE_OPC_SYMLINK);
if (!err)
diff --git a/drivers/staging/lustre/lustre/llite/vvp_internal.h b/drivers/staging/lustre/lustre/llite/vvp_internal.h
index c60d0414ac25..f40fd7f115d1 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_internal.h
+++ b/drivers/staging/lustre/lustre/llite/vvp_internal.h
@@ -301,8 +301,6 @@ static inline struct vvp_lock *cl2vvp_lock(const struct cl_lock_slice *slice)
# define CLOBINVRNT(env, clob, expr) \
((void)sizeof(env), (void)sizeof(clob), (void)sizeof(!!(expr)))
-int lov_read_and_clear_async_rc(struct cl_object *clob);
-
int vvp_io_init(const struct lu_env *env, struct cl_object *obj,
struct cl_io *io);
int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io);
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index f124f6c05ea4..76a0306df5a6 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -771,7 +771,6 @@ static int lmv_hsm_ct_unregister(struct lmv_obd *lmv, unsigned int cmd, int len,
struct lustre_kernelcomm *lk,
void __user *uarg)
{
- int rc = 0;
__u32 i;
/* unregister request (call from llapi_hsm_copytool_fini) */
@@ -791,9 +790,7 @@ static int lmv_hsm_ct_unregister(struct lmv_obd *lmv, unsigned int cmd, int len,
* Unreached coordinators will get EPIPE on next requests
* and will unregister automatically.
*/
- rc = libcfs_kkuc_group_rem(lk->lk_uid, lk->lk_group);
-
- return rc;
+ return libcfs_kkuc_group_rem(lk->lk_uid, lk->lk_group);
}
static int lmv_hsm_ct_register(struct lmv_obd *lmv, unsigned int cmd, int len,
@@ -1425,8 +1422,7 @@ static int lmv_getstatus(struct obd_export *exp,
if (rc)
return rc;
- rc = md_getstatus(lmv->tgts[0]->ltd_exp, fid);
- return rc;
+ return md_getstatus(lmv->tgts[0]->ltd_exp, fid);
}
static int lmv_getxattr(struct obd_export *exp, const struct lu_fid *fid,
@@ -1447,10 +1443,8 @@ static int lmv_getxattr(struct obd_export *exp, const struct lu_fid *fid,
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- rc = md_getxattr(tgt->ltd_exp, fid, valid, name, input,
+ return md_getxattr(tgt->ltd_exp, fid, valid, name, input,
input_size, output_size, flags, request);
-
- return rc;
}
static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid,
@@ -1472,11 +1466,9 @@ static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid,
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- rc = md_setxattr(tgt->ltd_exp, fid, valid, name, input,
+ return md_setxattr(tgt->ltd_exp, fid, valid, name, input,
input_size, output_size, flags, suppgid,
request);
-
- return rc;
}
static int lmv_getattr(struct obd_export *exp, struct md_op_data *op_data,
@@ -1500,9 +1492,7 @@ static int lmv_getattr(struct obd_export *exp, struct md_op_data *op_data,
return 0;
}
- rc = md_getattr(tgt->ltd_exp, op_data, request);
-
- return rc;
+ return md_getattr(tgt->ltd_exp, op_data, request);
}
static int lmv_null_inode(struct obd_export *exp, const struct lu_fid *fid)
@@ -1549,8 +1539,7 @@ static int lmv_close(struct obd_export *exp, struct md_op_data *op_data,
return PTR_ERR(tgt);
CDEBUG(D_INODE, "CLOSE "DFID"\n", PFID(&op_data->op_fid1));
- rc = md_close(tgt->ltd_exp, op_data, mod, request);
- return rc;
+ return md_close(tgt->ltd_exp, op_data, mod, request);
}
/**
@@ -1743,10 +1732,8 @@ lmv_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
CDEBUG(D_INODE, "ENQUEUE '%s' on " DFID " -> mds #%u\n",
LL_IT2STR(it), PFID(&op_data->op_fid1), tgt->ltd_idx);
- rc = md_enqueue(tgt->ltd_exp, einfo, policy, it, op_data, lockh,
+ return md_enqueue(tgt->ltd_exp, einfo, policy, it, op_data, lockh,
extra_lock_flags);
-
- return rc;
}
static int
@@ -1894,9 +1881,7 @@ static int lmv_link(struct obd_export *exp, struct md_op_data *op_data,
if (rc != 0)
return rc;
- rc = md_link(tgt->ltd_exp, op_data, request);
-
- return rc;
+ return md_link(tgt->ltd_exp, op_data, request);
}
static int lmv_rename(struct obd_export *exp, struct md_op_data *op_data,
@@ -2109,8 +2094,7 @@ static int lmv_sync(struct obd_export *exp, const struct lu_fid *fid,
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- rc = md_sync(tgt->ltd_exp, fid, request);
- return rc;
+ return md_sync(tgt->ltd_exp, fid, request);
}
/**
@@ -2428,17 +2412,14 @@ static int lmv_read_page(struct obd_export *exp, struct md_op_data *op_data,
return rc;
if (unlikely(lsm)) {
- rc = lmv_read_striped_page(exp, op_data, cb_op, offset, ppage);
- return rc;
+ return lmv_read_striped_page(exp, op_data, cb_op, offset, ppage);
}
tgt = lmv_find_target(lmv, &op_data->op_fid1);
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- rc = md_read_page(tgt->ltd_exp, op_data, cb_op, offset, ppage);
-
- return rc;
+ return md_read_page(tgt->ltd_exp, op_data, cb_op, offset, ppage);
}
/**
@@ -2922,13 +2903,11 @@ static int lmv_set_lock_data(struct obd_export *exp,
{
struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
struct lmv_tgt_desc *tgt = lmv->tgts[0];
- int rc;
if (!tgt || !tgt->ltd_exp)
return -EINVAL;
- rc = md_set_lock_data(tgt->ltd_exp, lockh, data, bits);
- return rc;
+ return md_set_lock_data(tgt->ltd_exp, lockh, data, bits);
}
static enum ldlm_mode lmv_lock_match(struct obd_export *exp, __u64 flags,
@@ -3050,8 +3029,7 @@ static int lmv_intent_getattr_async(struct obd_export *exp,
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- rc = md_intent_getattr_async(tgt->ltd_exp, minfo, einfo);
- return rc;
+ return md_intent_getattr_async(tgt->ltd_exp, minfo, einfo);
}
static int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
@@ -3070,8 +3048,7 @@ static int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
if (IS_ERR(tgt))
return PTR_ERR(tgt);
- rc = md_revalidate_lock(tgt->ltd_exp, it, fid, bits);
- return rc;
+ return md_revalidate_lock(tgt->ltd_exp, it, fid, bits);
}
static int
@@ -3113,8 +3090,7 @@ static int lmv_quotactl(struct obd_device *unused, struct obd_export *exp,
}
if (oqctl->qc_cmd != Q_GETOQUOTA) {
- rc = obd_quotactl(tgt->ltd_exp, oqctl);
- return rc;
+ return obd_quotactl(tgt->ltd_exp, oqctl);
}
for (i = 0; i < lmv->desc.ld_tgt_count; i++) {
@@ -3234,13 +3210,11 @@ static struct md_ops lmv_md_ops = {
static int __init lmv_init(void)
{
struct lprocfs_static_vars lvars;
- int rc;
lprocfs_lmv_init_vars(&lvars);
- rc = class_register_type(&lmv_obd_ops, &lmv_md_ops,
+ return class_register_type(&lmv_obd_ops, &lmv_md_ops,
LUSTRE_LMV_NAME, NULL);
- return rc;
}
static void lmv_exit(void)
diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c
index 6c93d180aef7..68fa2de7a6ff 100644
--- a/drivers/staging/lustre/lustre/lov/lov_pack.c
+++ b/drivers/staging/lustre/lustre/lov/lov_pack.c
@@ -198,7 +198,8 @@ static int lov_verify_lmm(void *lmm, int lmm_bytes, __u16 *stripe_count)
return rc;
}
-struct lov_stripe_md *lov_lsm_alloc(u16 stripe_count, u32 pattern, u32 magic)
+static struct lov_stripe_md *lov_lsm_alloc(u16 stripe_count, u32 pattern,
+ u32 magic)
{
struct lov_stripe_md *lsm;
unsigned int i;
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c
index 3f42457b0d7d..ee7d67761191 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_io.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c
@@ -1119,9 +1119,9 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_sync_io *anchor,
LASSERT(atomic_read(&anchor->csi_sync_nr) == 0);
/* wait until cl_sync_io_note() has done wakeup */
- while (unlikely(atomic_read(&anchor->csi_barrier) != 0)) {
+ while (unlikely(atomic_read(&anchor->csi_barrier) != 0))
cpu_relax();
- }
+
return rc;
}
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index f5d4e23c64b7..703cb67ce42e 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -54,6 +54,7 @@
#include <linux/list.h>
#include "../../include/linux/libcfs/libcfs_hash.h" /* for cfs_hash stuff */
#include "../include/cl_object.h"
+#include "../include/lu_object.h"
#include "cl_internal.h"
static struct kmem_cache *cl_env_kmem;
@@ -61,8 +62,6 @@ static struct kmem_cache *cl_env_kmem;
/** Lock class of cl_object_header::coh_attr_guard */
static struct lock_class_key cl_attr_guard_class;
-extern __u32 lu_context_tags_default;
-extern __u32 lu_session_tags_default;
/**
* Initialize cl_object_header.
*/
diff --git a/drivers/staging/lustre/lustre/obdclass/obdo.c b/drivers/staging/lustre/lustre/obdclass/obdo.c
index c52b9e07d7dd..b1dfa1622ae7 100644
--- a/drivers/staging/lustre/lustre/obdclass/obdo.c
+++ b/drivers/staging/lustre/lustre/obdclass/obdo.c
@@ -40,6 +40,7 @@
#include "../include/obd_class.h"
#include "../include/lustre/lustre_idl.h"
+#include "../include/lustre_obdo.h"
void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent)
{
@@ -124,3 +125,56 @@ void obdo_to_ioobj(const struct obdo *oa, struct obd_ioobj *ioobj)
ioobj->ioo_max_brw = 0;
}
EXPORT_SYMBOL(obdo_to_ioobj);
+
+/**
+ * Create an obdo to send over the wire
+ */
+void lustre_set_wire_obdo(const struct obd_connect_data *ocd,
+ struct obdo *wobdo, const struct obdo *lobdo)
+{
+ *wobdo = *lobdo;
+ wobdo->o_flags &= ~OBD_FL_LOCAL_MASK;
+ if (!ocd)
+ return;
+
+ if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) &&
+ fid_seq_is_echo(ostid_seq(&lobdo->o_oi))) {
+ /*
+ * Currently OBD_FL_OSTID will only be used when 2.4 echo
+ * client communicate with pre-2.4 server
+ */
+ wobdo->o_oi.oi.oi_id = fid_oid(&lobdo->o_oi.oi_fid);
+ wobdo->o_oi.oi.oi_seq = fid_seq(&lobdo->o_oi.oi_fid);
+ }
+}
+EXPORT_SYMBOL(lustre_set_wire_obdo);
+
+/**
+ * Create a local obdo from a wire based odbo
+ */
+void lustre_get_wire_obdo(const struct obd_connect_data *ocd,
+ struct obdo *lobdo, const struct obdo *wobdo)
+{
+ u32 local_flags = 0;
+
+ if (lobdo->o_valid & OBD_MD_FLFLAGS)
+ local_flags = lobdo->o_flags & OBD_FL_LOCAL_MASK;
+
+ *lobdo = *wobdo;
+ if (local_flags) {
+ lobdo->o_valid |= OBD_MD_FLFLAGS;
+ lobdo->o_flags &= ~OBD_FL_LOCAL_MASK;
+ lobdo->o_flags |= local_flags;
+ }
+ if (!ocd)
+ return;
+
+ if (unlikely(!(ocd->ocd_connect_flags & OBD_CONNECT_FID)) &&
+ fid_seq_is_echo(wobdo->o_oi.oi.oi_seq)) {
+ /* see above */
+ lobdo->o_oi.oi_fid.f_seq = wobdo->o_oi.oi.oi_seq;
+ lobdo->o_oi.oi_fid.f_oid = wobdo->o_oi.oi.oi_id;
+ lobdo->o_oi.oi_fid.f_ver = 0;
+ }
+}
+EXPORT_SYMBOL(lustre_get_wire_obdo);
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index b0f030c6c9c9..5ac0e1439c2b 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -142,10 +142,7 @@ static const char *oes_strings[] = {
static inline struct osc_extent *rb_extent(struct rb_node *n)
{
- if (!n)
- return NULL;
-
- return container_of(n, struct osc_extent, oe_node);
+ return rb_entry_safe(n, struct osc_extent, oe_node);
}
static inline struct osc_extent *next_extent(struct osc_extent *ext)
@@ -247,7 +244,7 @@ static int osc_extent_sanity_check0(struct osc_extent *ext,
goto out;
}
- if (ext->oe_dlmlock) {
+ if (ext->oe_dlmlock && !ldlm_is_failed(ext->oe_dlmlock)) {
struct ldlm_extent *extent;
extent = &ext->oe_dlmlock->l_policy_data.l_extent;
@@ -2710,8 +2707,8 @@ int osc_queue_sync_pages(const struct lu_env *env, struct osc_object *obj,
/**
* Called by osc_io_setattr_start() to freeze and destroy covering extents.
*/
-int osc_cache_truncate_start(const struct lu_env *env, struct osc_io *oio,
- struct osc_object *obj, __u64 size)
+int osc_cache_truncate_start(const struct lu_env *env, struct osc_object *obj,
+ u64 size, struct osc_extent **extp)
{
struct client_obd *cli = osc_cli(obj);
struct osc_extent *ext;
@@ -2808,9 +2805,11 @@ again:
/* we need to hold this extent in OES_TRUNC state so
* that no writeback will happen. This is to avoid
* BUG 17397.
+ * Only partial truncate can reach here, if @size is
+ * not zero, the caller should provide a valid @extp.
*/
- LASSERT(!oio->oi_trunc);
- oio->oi_trunc = osc_extent_get(ext);
+ LASSERT(!*extp);
+ *extp = osc_extent_get(ext);
OSC_EXTENT_DUMP(D_CACHE, ext,
"trunc at %llu\n", size);
}
@@ -2836,13 +2835,10 @@ again:
/**
* Called after osc_io_setattr_end to add oio->oi_trunc back to cache.
*/
-void osc_cache_truncate_end(const struct lu_env *env, struct osc_io *oio,
- struct osc_object *obj)
+void osc_cache_truncate_end(const struct lu_env *env, struct osc_extent *ext)
{
- struct osc_extent *ext = oio->oi_trunc;
-
- oio->oi_trunc = NULL;
if (ext) {
+ struct osc_object *obj = ext->oe_obj;
bool unplug = false;
EASSERT(ext->oe_nr_pages > 0, ext);
@@ -3183,8 +3179,10 @@ static int discard_cb(const struct lu_env *env, struct cl_io *io,
/* page is top page. */
info->oti_next_index = osc_index(ops) + 1;
if (cl_page_own(env, io, page) == 0) {
- KLASSERT(ergo(page->cp_type == CPT_CACHEABLE,
- !PageDirty(cl_page_vmpage(page))));
+ if (page->cp_type == CPT_CACHEABLE &&
+ PageDirty(cl_page_vmpage(page)))
+ CL_PAGE_DEBUG(D_ERROR, env, page,
+ "discard dirty page?\n");
/* discard the page */
cl_page_discard(env, io, page);
diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
index cce55a9689f0..c09ab97d64ae 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h
@@ -159,6 +159,10 @@ struct osc_object {
/* Protect osc_lock this osc_object has */
spinlock_t oo_ol_spin;
struct list_head oo_ol_list;
+
+ /** number of active IOs of this object */
+ atomic_t oo_nr_ios;
+ wait_queue_head_t oo_io_waitq;
};
static inline void osc_object_lock(struct osc_object *obj)
@@ -399,10 +403,9 @@ int osc_flush_async_page(const struct lu_env *env, struct cl_io *io,
struct osc_page *ops);
int osc_queue_sync_pages(const struct lu_env *env, struct osc_object *obj,
struct list_head *list, int cmd, int brw_flags);
-int osc_cache_truncate_start(const struct lu_env *env, struct osc_io *oio,
- struct osc_object *obj, __u64 size);
-void osc_cache_truncate_end(const struct lu_env *env, struct osc_io *oio,
- struct osc_object *obj);
+int osc_cache_truncate_start(const struct lu_env *env, struct osc_object *obj,
+ u64 size, struct osc_extent **extp);
+void osc_cache_truncate_end(const struct lu_env *env, struct osc_extent *ext);
int osc_cache_writeback_range(const struct lu_env *env, struct osc_object *obj,
pgoff_t start, pgoff_t end, int hp, int discard);
int osc_cache_wait_range(const struct lu_env *env, struct osc_object *obj,
diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h
index 688783dcc1e4..ff7c9ec8f672 100644
--- a/drivers/staging/lustre/lustre/osc/osc_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_internal.h
@@ -181,6 +181,8 @@ static inline struct osc_device *obd2osc_dev(const struct obd_device *d)
return container_of0(d->obd_lu_dev, struct osc_device, od_cl.cd_lu_dev);
}
+extern struct lu_kmem_descr osc_caches[];
+
extern struct kmem_cache *osc_quota_kmem;
struct osc_quota_info {
/** linkage for quota hash table */
@@ -218,4 +220,6 @@ struct ldlm_lock *osc_dlmlock_at_pgoff(const struct lu_env *env,
struct osc_object *obj, pgoff_t index,
enum osc_dap_flags flags);
+int osc_object_invalidate(const struct lu_env *env, struct osc_object *osc);
+
#endif /* OSC_INTERNAL_H */
diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c
index 228a97c098fe..9402dfc01668 100644
--- a/drivers/staging/lustre/lustre/osc/osc_io.c
+++ b/drivers/staging/lustre/lustre/osc/osc_io.c
@@ -37,6 +37,8 @@
#define DEBUG_SUBSYSTEM S_OSC
+#include "../include/lustre_obdo.h"
+
#include "osc_cl_internal.h"
/** \addtogroup osc
@@ -330,8 +332,25 @@ static int osc_io_commit_async(const struct lu_env *env,
return result;
}
-static int osc_io_rw_iter_init(const struct lu_env *env,
- const struct cl_io_slice *ios)
+static int osc_io_iter_init(const struct lu_env *env,
+ const struct cl_io_slice *ios)
+{
+ struct osc_object *osc = cl2osc(ios->cis_obj);
+ struct obd_import *imp = osc_cli(osc)->cl_import;
+ int rc = -EIO;
+
+ spin_lock(&imp->imp_lock);
+ if (likely(!imp->imp_invalid)) {
+ atomic_inc(&osc->oo_nr_ios);
+ rc = 0;
+ }
+ spin_unlock(&imp->imp_lock);
+
+ return rc;
+}
+
+static int osc_io_write_iter_init(const struct lu_env *env,
+ const struct cl_io_slice *ios)
{
struct cl_io *io = ios->cis_io;
struct osc_io *oio = osc_env_io(env);
@@ -342,7 +361,7 @@ static int osc_io_rw_iter_init(const struct lu_env *env,
unsigned long max_pages;
if (cl_io_is_append(io))
- return 0;
+ return osc_io_iter_init(env, ios);
npages = io->u.ci_rw.crw_count >> PAGE_SHIFT;
if (io->u.ci_rw.crw_pos & ~PAGE_MASK)
@@ -374,11 +393,21 @@ static int osc_io_rw_iter_init(const struct lu_env *env,
(void)ptlrpcd_queue_work(cli->cl_lru_work);
}
- return 0;
+ return osc_io_iter_init(env, ios);
+}
+
+static void osc_io_iter_fini(const struct lu_env *env,
+ const struct cl_io_slice *ios)
+{
+ struct osc_object *osc = cl2osc(ios->cis_obj);
+
+ LASSERT(atomic_read(&osc->oo_nr_ios) > 0);
+ if (atomic_dec_and_test(&osc->oo_nr_ios))
+ wake_up_all(&osc->oo_io_waitq);
}
-static void osc_io_rw_iter_fini(const struct lu_env *env,
- const struct cl_io_slice *ios)
+static void osc_io_write_iter_fini(const struct lu_env *env,
+ const struct cl_io_slice *ios)
{
struct osc_io *oio = osc_env_io(env);
struct osc_object *osc = cl2osc(ios->cis_obj);
@@ -389,6 +418,8 @@ static void osc_io_rw_iter_fini(const struct lu_env *env,
oio->oi_lru_reserved = 0;
}
oio->oi_write_osclock = NULL;
+
+ osc_io_iter_fini(env, ios);
}
static int osc_io_fault_start(const struct lu_env *env,
@@ -479,7 +510,8 @@ static int osc_io_setattr_start(const struct lu_env *env,
/* truncate cache dirty pages first */
if (cl_io_is_trunc(io))
- result = osc_cache_truncate_start(env, oio, cl2osc(obj), size);
+ result = osc_cache_truncate_start(env, cl2osc(obj), size,
+ &oio->oi_trunc);
if (result == 0 && oio->oi_lockless == 0) {
cl_object_attr_lock(obj);
@@ -589,10 +621,8 @@ static void osc_io_setattr_end(const struct lu_env *env,
__u64 size = io->u.ci_setattr.sa_attr.lvb_size;
osc_trunc_check(env, io, oio, size);
- if (oio->oi_trunc) {
- osc_cache_truncate_end(env, oio, cl2osc(obj));
- oio->oi_trunc = NULL;
- }
+ osc_cache_truncate_end(env, oio->oi_trunc);
+ oio->oi_trunc = NULL;
}
}
@@ -832,17 +862,21 @@ static void osc_io_end(const struct lu_env *env,
static const struct cl_io_operations osc_io_ops = {
.op = {
[CIT_READ] = {
+ .cio_iter_init = osc_io_iter_init,
+ .cio_iter_fini = osc_io_iter_fini,
.cio_start = osc_io_read_start,
.cio_fini = osc_io_fini
},
[CIT_WRITE] = {
- .cio_iter_init = osc_io_rw_iter_init,
- .cio_iter_fini = osc_io_rw_iter_fini,
+ .cio_iter_init = osc_io_write_iter_init,
+ .cio_iter_fini = osc_io_write_iter_fini,
.cio_start = osc_io_write_start,
.cio_end = osc_io_end,
.cio_fini = osc_io_fini
},
[CIT_SETATTR] = {
+ .cio_iter_init = osc_io_iter_init,
+ .cio_iter_fini = osc_io_iter_fini,
.cio_start = osc_io_setattr_start,
.cio_end = osc_io_setattr_end
},
@@ -851,6 +885,8 @@ static const struct cl_io_operations osc_io_ops = {
.cio_end = osc_io_data_version_end,
},
[CIT_FAULT] = {
+ .cio_iter_init = osc_io_iter_init,
+ .cio_iter_fini = osc_io_iter_fini,
.cio_start = osc_io_fault_start,
.cio_end = osc_io_end,
.cio_fini = osc_io_fini
diff --git a/drivers/staging/lustre/lustre/osc/osc_object.c b/drivers/staging/lustre/lustre/osc/osc_object.c
index e0c3324857dd..d3e5ca7db7b2 100644
--- a/drivers/staging/lustre/lustre/osc/osc_object.c
+++ b/drivers/staging/lustre/lustre/osc/osc_object.c
@@ -78,6 +78,9 @@ static int osc_object_init(const struct lu_env *env, struct lu_object *obj,
INIT_LIST_HEAD(&osc->oo_write_item);
INIT_LIST_HEAD(&osc->oo_read_item);
+ atomic_set(&osc->oo_nr_ios, 0);
+ init_waitqueue_head(&osc->oo_io_waitq);
+
osc->oo_root.rb_node = NULL;
INIT_LIST_HEAD(&osc->oo_hp_exts);
INIT_LIST_HEAD(&osc->oo_urgent_exts);
@@ -112,6 +115,7 @@ static void osc_object_free(const struct lu_env *env, struct lu_object *obj)
LASSERT(atomic_read(&osc->oo_nr_reads) == 0);
LASSERT(atomic_read(&osc->oo_nr_writes) == 0);
LASSERT(list_empty(&osc->oo_ol_list));
+ LASSERT(!atomic_read(&osc->oo_nr_ios));
lu_object_fini(obj);
kmem_cache_free(osc_object_kmem, osc);
@@ -444,4 +448,19 @@ struct lu_object *osc_object_alloc(const struct lu_env *env,
return obj;
}
+int osc_object_invalidate(const struct lu_env *env, struct osc_object *osc)
+{
+ struct l_wait_info lwi = { 0 };
+
+ CDEBUG(D_INODE, "Invalidate osc object: %p, # of active IOs: %d\n",
+ osc, atomic_read(&osc->oo_nr_ios));
+
+ l_wait_event(osc->oo_io_waitq, !atomic_read(&osc->oo_nr_ios), &lwi);
+
+ /* Discard all pages of this object. */
+ osc_cache_truncate_start(env, osc, 0, NULL);
+
+ return 0;
+}
+
/** @} osc */
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index 7143564ae7e7..3efae759bdfa 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -43,6 +43,7 @@
#include "../include/lprocfs_status.h"
#include "../include/lustre/lustre_ioctl.h"
#include "../include/lustre_debug.h"
+#include "../include/lustre_obdo.h"
#include "../include/lustre_param.h"
#include "../include/lustre_fid.h"
#include "../include/obd_class.h"
@@ -2479,6 +2480,33 @@ static int osc_disconnect(struct obd_export *exp)
return rc;
}
+static int osc_ldlm_resource_invalidate(struct cfs_hash *hs,
+ struct cfs_hash_bd *bd,
+ struct hlist_node *hnode, void *arg)
+{
+ struct ldlm_resource *res = cfs_hash_object(hs, hnode);
+ struct osc_object *osc = NULL;
+ struct lu_env *env = arg;
+ struct ldlm_lock *lock;
+
+ lock_res(res);
+ list_for_each_entry(lock, &res->lr_granted, l_res_link) {
+ if (lock->l_ast_data && !osc) {
+ osc = lock->l_ast_data;
+ cl_object_get(osc2cl(osc));
+ }
+ lock->l_ast_data = NULL;
+ }
+ unlock_res(res);
+
+ if (osc) {
+ osc_object_invalidate(env, osc);
+ cl_object_put(env, osc2cl(osc));
+ }
+
+ return 0;
+}
+
static int osc_import_event(struct obd_device *obd,
struct obd_import *imp,
enum obd_import_event event)
@@ -2506,17 +2534,18 @@ static int osc_import_event(struct obd_device *obd,
struct lu_env *env;
int refcheck;
+ ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY);
+
env = cl_env_get(&refcheck);
if (!IS_ERR(env)) {
- /* Reset grants */
- cli = &obd->u.cli;
- /* all pages go to failing rpcs due to the invalid
- * import
- */
- osc_io_unplug(env, cli, NULL);
+ osc_io_unplug(env, &obd->u.cli, NULL);
- ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY);
+ cfs_hash_for_each_nolock(ns->ns_rs_hash,
+ osc_ldlm_resource_invalidate,
+ env, 0);
cl_env_put(env, &refcheck);
+
+ ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY);
} else {
rc = PTR_ERR(env);
}
@@ -2766,8 +2795,6 @@ static struct obd_ops osc_obd_ops = {
.quotactl = osc_quotactl,
};
-extern struct lu_kmem_descr osc_caches[];
-
static int __init osc_init(void)
{
struct lprocfs_static_vars lvars = { NULL };
diff --git a/drivers/staging/lustre/lustre/ptlrpc/events.c b/drivers/staging/lustre/lustre/ptlrpc/events.c
index 49f3e6368415..ae1650dda573 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/events.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/events.c
@@ -277,7 +277,7 @@ static void ptlrpc_req_add_history(struct ptlrpc_service_part *svcpt,
* then we hope there will be less RPCs per bucket at some
* point, and sequence will catch up again
*/
- svcpt->scp_hist_seq += (1U << REQS_SEQ_SHIFT(svcpt));
+ svcpt->scp_hist_seq += (1ULL << REQS_SEQ_SHIFT(svcpt));
new_seq = svcpt->scp_hist_seq;
}
diff --git a/drivers/staging/lustre/lustre/ptlrpc/nrs.c b/drivers/staging/lustre/lustre/ptlrpc/nrs.c
index 7b6ffb195834..ef19dbe2ea5c 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/nrs.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/nrs.c
@@ -1559,9 +1559,6 @@ out:
return rc;
}
-/* ptlrpc/nrs_fifo.c */
-extern struct ptlrpc_nrs_pol_conf nrs_conf_fifo;
-
/**
* Adds all policies that ship with the ptlrpc module, to NRS core's list of
* policies \e nrs_core.nrs_policies.
diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
index 13f00b7cbbe5..b1170277fd84 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c
@@ -469,6 +469,7 @@ int lustre_shrink_msg(struct lustre_msg *msg, int segment,
default:
LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic);
}
+ return 0;
}
EXPORT_SYMBOL(lustre_shrink_msg);
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
index e0f859ca6223..8e6a805487ec 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpc_internal.h
@@ -226,6 +226,9 @@ struct ptlrpc_nrs_policy *nrs_request_policy(struct ptlrpc_nrs_request *nrq)
sizeof(NRS_LPROCFS_QUANTUM_NAME_REG __stringify(LPROCFS_NRS_QUANTUM_MAX) " " \
NRS_LPROCFS_QUANTUM_NAME_HP __stringify(LPROCFS_NRS_QUANTUM_MAX))
+/* ptlrpc/nrs_fifo.c */
+extern struct ptlrpc_nrs_pol_conf nrs_conf_fifo;
+
/* recovd_thread.c */
int ptlrpc_expire_one_request(struct ptlrpc_request *req, int async_unlink);
diff --git a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
index bf077f8342f6..32109cdd73a6 100644
--- a/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
+++ b/drivers/staging/media/davinci_vpfe/vpfe_mc_capture.c
@@ -74,7 +74,7 @@
static bool debug;
static bool interface;
-module_param(interface, bool, S_IRUGO);
+module_param(interface, bool, 0444);
module_param(debug, bool, 0644);
/**
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index bfb76a45bfbf..0a43bac2b162 100644
--- a/drivers/staging/media/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
@@ -626,41 +626,26 @@ static void kf(void *handle)
/*** module initialization and cleanup ***/
-static int __init lirc_parallel_init(void)
+static void lirc_parallel_attach(struct parport *port)
{
- int result;
-
- result = platform_driver_register(&lirc_parallel_driver);
- if (result) {
- pr_notice("platform_driver_register returned %d\n", result);
- return result;
- }
+ struct pardev_cb lirc_parallel_cb;
- lirc_parallel_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
- if (!lirc_parallel_dev) {
- result = -ENOMEM;
- goto exit_driver_unregister;
- }
+ if (port->base != io)
+ return;
- result = platform_device_add(lirc_parallel_dev);
- if (result)
- goto exit_device_put;
+ pport = port;
+ memset(&lirc_parallel_cb, 0, sizeof(lirc_parallel_cb));
+ lirc_parallel_cb.preempt = pf;
+ lirc_parallel_cb.wakeup = kf;
+ lirc_parallel_cb.irq_func = lirc_lirc_irq_handler;
- pport = parport_find_base(io);
- if (!pport) {
- pr_notice("no port at %x found\n", io);
- result = -ENXIO;
- goto exit_device_del;
- }
- ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME,
- pf, kf, lirc_lirc_irq_handler, 0,
- NULL);
- parport_put_port(pport);
+ ppdevice = parport_register_dev_model(port, LIRC_DRIVER_NAME,
+ &lirc_parallel_cb, 0);
if (!ppdevice) {
pr_notice("parport_register_device() failed\n");
- result = -ENXIO;
- goto exit_device_del;
+ return;
}
+
if (parport_claim(ppdevice) != 0)
goto skip_init;
is_claimed = 1;
@@ -688,18 +673,64 @@ static int __init lirc_parallel_init(void)
is_claimed = 0;
parport_release(ppdevice);
+
skip_init:
+ return;
+}
+
+static void lirc_parallel_detach(struct parport *port)
+{
+ if (port->base != io)
+ return;
+
+ parport_unregister_device(ppdevice);
+}
+
+static struct parport_driver lirc_parport_driver = {
+ .name = LIRC_DRIVER_NAME,
+ .match_port = lirc_parallel_attach,
+ .detach = lirc_parallel_detach,
+ .devmodel = true,
+};
+
+static int __init lirc_parallel_init(void)
+{
+ int result;
+
+ result = platform_driver_register(&lirc_parallel_driver);
+ if (result) {
+ pr_notice("platform_driver_register returned %d\n", result);
+ return result;
+ }
+
+ lirc_parallel_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
+ if (!lirc_parallel_dev) {
+ result = -ENOMEM;
+ goto exit_driver_unregister;
+ }
+
+ result = platform_device_add(lirc_parallel_dev);
+ if (result)
+ goto exit_device_put;
+
+ result = parport_register_driver(&lirc_parport_driver);
+ if (result) {
+ pr_notice("parport_register_driver returned %d\n", result);
+ goto exit_device_del;
+ }
+
driver.dev = &lirc_parallel_dev->dev;
driver.minor = lirc_register_driver(&driver);
if (driver.minor < 0) {
pr_notice("register_chrdev() failed\n");
- parport_unregister_device(ppdevice);
result = -EIO;
- goto exit_device_del;
+ goto exit_unregister;
}
pr_info("installed using port 0x%04x irq %d\n", io, irq);
return 0;
+exit_unregister:
+ parport_unregister_driver(&lirc_parport_driver);
exit_device_del:
platform_device_del(lirc_parallel_dev);
exit_device_put:
@@ -711,9 +742,9 @@ exit_driver_unregister:
static void __exit lirc_parallel_exit(void)
{
- parport_unregister_device(ppdevice);
lirc_unregister_driver(driver.minor);
+ parport_unregister_driver(&lirc_parport_driver);
platform_device_unregister(lirc_parallel_dev);
platform_driver_unregister(&lirc_parallel_driver);
}
diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c
index d6db0bd65be0..65211d1824b7 100644
--- a/drivers/staging/most/hdm-usb/hdm_usb.c
+++ b/drivers/staging/most/hdm-usb/hdm_usb.c
@@ -145,7 +145,7 @@ static void wq_netinfo(struct work_struct *wq_obj);
static inline int drci_rd_reg(struct usb_device *dev, u16 reg, u16 *buf)
{
int retval;
- u16 *dma_buf = kzalloc(sizeof(u16), GFP_KERNEL);
+ __le16 *dma_buf = kzalloc(sizeof(*dma_buf), GFP_KERNEL);
u8 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
if (!dma_buf)
@@ -154,7 +154,7 @@ static inline int drci_rd_reg(struct usb_device *dev, u16 reg, u16 *buf)
retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
DRCI_READ_REQ, req_type,
0x0000,
- reg, dma_buf, sizeof(u16), 5 * HZ);
+ reg, dma_buf, sizeof(*dma_buf), 5 * HZ);
*buf = le16_to_cpu(*dma_buf);
kfree(dma_buf);
@@ -846,15 +846,15 @@ static struct usb_device_id usbid[] = {
#define MOST_DCI_RO_ATTR(_name) \
struct most_dci_attribute most_dci_attr_##_name = \
- __ATTR(_name, S_IRUGO, show_value, NULL)
+ __ATTR(_name, 0444, show_value, NULL)
#define MOST_DCI_ATTR(_name) \
struct most_dci_attribute most_dci_attr_##_name = \
- __ATTR(_name, S_IRUGO | S_IWUSR, show_value, store_value)
+ __ATTR(_name, 0644, show_value, store_value)
#define MOST_DCI_WO_ATTR(_name) \
struct most_dci_attribute most_dci_attr_##_name = \
- __ATTR(_name, S_IWUSR, NULL, store_value)
+ __ATTR(_name, 0200, NULL, store_value)
/**
* struct most_dci_attribute - to access the attributes of a dci object
diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c
index fcbb0fa03765..3b144a9ea055 100644
--- a/drivers/staging/nvec/nvec_power.c
+++ b/drivers/staging/nvec/nvec_power.c
@@ -442,7 +442,7 @@ static struct platform_driver nvec_power_driver = {
.remove = nvec_power_remove,
.driver = {
.name = "nvec-power",
- }
+ }
};
module_platform_driver(nvec_power_driver);
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index 8130dfe89745..4971aa54756a 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -770,6 +770,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
/* Initialize the device private structure. */
struct octeon_ethernet *priv = netdev_priv(dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
dev->netdev_ops = &cvm_oct_pow_netdev_ops;
priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
priv->port = CVMX_PIP_NUM_INPUT_PORTS;
@@ -816,6 +817,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
}
/* Initialize the device private structure. */
+ SET_NETDEV_DEV(dev, &pdev->dev);
priv = netdev_priv(dev);
priv->netdev = dev;
priv->of_node = cvm_oct_node_for_port(pip, interface,
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
index f45b2ef05f48..684815c98789 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon.c
@@ -81,7 +81,7 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init)
if (ver < 0xdc02) {
dev_err(&dcon->client->dev,
- "DCON v1 is unsupported, giving up..\n");
+ "DCON v1 is unsupported, giving up..\n");
rc = -ENODEV;
goto err;
}
@@ -90,7 +90,7 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init)
dcon_write(dcon, 0x3a, 0xc040);
dcon_write(dcon, DCON_REG_MEM_OPT_A, 0x0000); /* clear option bits */
dcon_write(dcon, DCON_REG_MEM_OPT_A,
- MEM_DLL_CLOCK_DELAY | MEM_POWER_DOWN);
+ MEM_DLL_CLOCK_DELAY | MEM_POWER_DOWN);
dcon_write(dcon, DCON_REG_MEM_OPT_B, MEM_SOFT_RESET);
/* Colour swizzle, AA, no passthrough, backlight */
@@ -261,14 +261,14 @@ static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank)
dcon->ignore_fb_events = true;
err = fb_blank(dcon->fbinfo,
- blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
+ blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
dcon->ignore_fb_events = false;
unlock_fb_info(dcon->fbinfo);
console_unlock();
if (err) {
dev_err(&dcon->client->dev, "couldn't %sblank framebuffer\n",
- blank ? "" : "un");
+ blank ? "" : "un");
return false;
}
return true;
@@ -293,7 +293,7 @@ static void dcon_source_switch(struct work_struct *work)
pr_info("dcon_source_switch to CPU\n");
/* Enable the scanline interrupt bit */
if (dcon_write(dcon, DCON_REG_MODE,
- dcon->disp_mode | MODE_SCAN_INT))
+ dcon->disp_mode | MODE_SCAN_INT))
pr_err("couldn't enable scanline interrupt!\n");
else
/* Wait up to one second for the scanline interrupt */
@@ -336,7 +336,7 @@ static void dcon_source_switch(struct work_struct *work)
pdata->set_dconload(0);
dcon->load_time = ktime_get();
- wait_event_timeout(dcon->waitq, dcon->switched, HZ/2);
+ wait_event_timeout(dcon->waitq, dcon->switched, HZ / 2);
if (!dcon->switched) {
pr_err("Timeout entering DCON mode; expect a screen glitch.\n");
@@ -646,7 +646,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id)
dcon, &dcon_bl_ops, &dcon_bl_props);
if (IS_ERR(dcon->bl_dev)) {
dev_err(&client->dev, "cannot register backlight dev (%ld)\n",
- PTR_ERR(dcon->bl_dev));
+ PTR_ERR(dcon->bl_dev));
dcon->bl_dev = NULL;
}
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 1e23ef15b263..75c3c2fe9560 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
@@ -53,9 +53,8 @@ static int dcon_was_irq(void)
/* irq status will appear in PMIO_Rx50[6] on gpio12 */
tmp = inb(VX855_GPI_STATUS_CHG);
- return !!(tmp & BIT_GPIO12);
- return 0;
+ return !!(tmp & BIT_GPIO12);
}
static int dcon_init_xo_1_5(struct dcon_priv *dcon)
@@ -108,7 +107,6 @@ static void set_i2c_line(int sda, int scl)
outb(tmp, 0x3c5);
}
-
static void dcon_wiggle_xo_1_5(void)
{
int x;
diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c
index 553e8d50352f..1c8fa3a1f5bb 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ap.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ap.c
@@ -26,7 +26,7 @@
void init_mlme_ap_info(struct adapter *padapter)
{
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct sta_priv *pstapriv = &padapter->stapriv;
struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
@@ -43,7 +43,7 @@ void free_mlme_ap_info(struct adapter *padapter)
{
struct sta_info *psta = NULL;
struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
@@ -59,17 +59,17 @@ void free_mlme_ap_info(struct adapter *padapter)
/* free bc/mc sta_info */
psta = rtw_get_bcmc_stainfo(padapter);
- spin_lock_bh(&(pstapriv->sta_hash_lock));
+ spin_lock_bh(&pstapriv->sta_hash_lock);
rtw_free_stainfo(padapter, psta);
- spin_unlock_bh(&(pstapriv->sta_hash_lock));
+ spin_unlock_bh(&pstapriv->sta_hash_lock);
}
static void update_BCNTIM(struct adapter *padapter)
{
struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
unsigned char *pie = pnetwork_mlmeext->IEs;
u8 *p, *dst_ie, *premainder_ie = NULL;
u8 *pbackup_remainder_ie = NULL;
@@ -94,10 +94,9 @@ static void update_BCNTIM(struct adapter *padapter)
offset += pnetwork_mlmeext->Ssid.SsidLength + 2;
/* get supported rates len */
- p = rtw_get_ie(pie + _BEACON_IE_OFFSET_,
- _SUPPORTEDRATES_IE_, &tmp_len,
- (pnetwork_mlmeext->IELength -
- _BEACON_IE_OFFSET_));
+ p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_,
+ &tmp_len, (pnetwork_mlmeext->IELength -
+ _BEACON_IE_OFFSET_));
if (p)
offset += tmp_len+2;
@@ -116,13 +115,12 @@ static void update_BCNTIM(struct adapter *padapter)
if (remainder_ielen > 0) {
pbackup_remainder_ie = rtw_malloc(remainder_ielen);
if (pbackup_remainder_ie && premainder_ie)
- memcpy(pbackup_remainder_ie,
- premainder_ie, remainder_ielen);
+ memcpy(pbackup_remainder_ie, premainder_ie,
+ remainder_ielen);
}
*dst_ie++ = _TIM_IE_;
- if ((pstapriv->tim_bitmap&0xff00) &&
- (pstapriv->tim_bitmap&0x00fc))
+ if ((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc))
tim_ielen = 5;
else
tim_ielen = 4;
@@ -157,7 +155,7 @@ static void update_BCNTIM(struct adapter *padapter)
}
void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
- u8 index, u8 *data, u8 len)
+ u8 index, u8 *data, u8 len)
{
struct ndis_802_11_var_ie *pIE;
u8 bmatch = false;
@@ -201,8 +199,8 @@ void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
if (remainder_ielen > 0) {
pbackup_remainder_ie = rtw_malloc(remainder_ielen);
if (pbackup_remainder_ie && premainder_ie)
- memcpy(pbackup_remainder_ie,
- premainder_ie, remainder_ielen);
+ memcpy(pbackup_remainder_ie, premainder_ie,
+ remainder_ielen);
}
*dst_ie++ = index;
@@ -223,7 +221,7 @@ void rtw_add_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
}
void rtw_remove_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
- u8 index)
+ u8 index)
{
u8 *p, *dst_ie = NULL, *premainder_ie = NULL;
u8 *pbackup_remainder_ie = NULL;
@@ -247,8 +245,8 @@ void rtw_remove_bcn_ie(struct adapter *padapter, struct wlan_bssid_ex *pnetwork,
if (remainder_ielen > 0) {
pbackup_remainder_ie = rtw_malloc(remainder_ielen);
if (pbackup_remainder_ie && premainder_ie)
- memcpy(pbackup_remainder_ie,
- premainder_ie, remainder_ielen);
+ memcpy(pbackup_remainder_ie, premainder_ie,
+ remainder_ielen);
}
/* copy remainder IE */
@@ -310,9 +308,9 @@ void expire_timeout_chk(struct adapter *padapter)
spin_unlock_bh(&pstapriv->auth_list_lock);
- spin_lock_bh(&(pstapriv->sta_hash_lock));
+ spin_lock_bh(&pstapriv->sta_hash_lock);
rtw_free_stainfo(padapter, psta);
- spin_unlock_bh(&(pstapriv->sta_hash_lock));
+ spin_unlock_bh(&pstapriv->sta_hash_lock);
spin_lock_bh(&pstapriv->auth_list_lock);
}
@@ -361,8 +359,8 @@ void expire_timeout_chk(struct adapter *padapter)
* for this station
*/
pstapriv->tim_bitmap |= BIT(psta->aid);
- update_beacon(padapter, _TIM_IE_,
- NULL, false);
+ update_beacon(padapter, _TIM_IE_, NULL,
+ false);
if (!pmlmeext->active_keep_alive_check)
continue;
@@ -456,7 +454,7 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
unsigned char limit;
unsigned int tx_ra_bitmap = 0;
struct ht_priv *psta_ht = NULL;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
if (psta)
@@ -548,7 +546,7 @@ static void update_bmc_sta(struct adapter *padapter)
unsigned char network_type, raid;
int i, supportRateNum = 0;
unsigned int tx_ra_bitmap = 0;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
@@ -630,9 +628,9 @@ static void update_bmc_sta(struct adapter *padapter)
void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta)
{
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
struct ht_priv *phtpriv_sta = &psta->htpriv;
@@ -700,7 +698,7 @@ static void update_hw_ht_param(struct adapter *padapter)
unsigned char max_AMPDU_len;
unsigned char min_MPDU_spacing;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
DBG_88E("%s\n", __func__);
@@ -733,12 +731,12 @@ static void start_bss_network(struct adapter *padapter, u8 *pbuf)
u32 acparm;
int ie_len;
struct registry_priv *pregpriv = &padapter->registrypriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct security_priv *psecuritypriv = &(padapter->securitypriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct wlan_bssid_ex *pnetwork_mlmeext = &(pmlmeinfo->network);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct wlan_bssid_ex *pnetwork_mlmeext = &pmlmeinfo->network;
struct HT_info_element *pht_info = NULL;
bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
@@ -869,7 +867,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
struct registry_priv *pregistrypriv = &padapter->registrypriv;
struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct wlan_bssid_ex *pbss_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network;
u8 *ie = pbss_network->IEs;
@@ -905,7 +903,7 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len)
pbss_network->Rssi = 0;
- ether_addr_copy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)));
+ ether_addr_copy(pbss_network->MacAddress, myid(&padapter->eeprompriv));
/* beacon interval */
p = rtw_get_beacon_interval_from_ie(ie);/* 8: TimeStamp, 2: Beacon Interval 2:Capability */
@@ -1150,7 +1148,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
if ((NUM_ACL - 1) < pacl_list->num)
return -1;
- spin_lock_bh(&(pacl_node_q->lock));
+ spin_lock_bh(&pacl_node_q->lock);
phead = get_list_head(pacl_node_q);
plist = phead->next;
@@ -1168,12 +1166,12 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
}
}
- spin_unlock_bh(&(pacl_node_q->lock));
+ spin_unlock_bh(&pacl_node_q->lock);
if (added)
return ret;
- spin_lock_bh(&(pacl_node_q->lock));
+ spin_lock_bh(&pacl_node_q->lock);
for (i = 0; i < NUM_ACL; i++) {
paclnode = &pacl_list->aclnode[i];
@@ -1195,7 +1193,7 @@ int rtw_acl_add_sta(struct adapter *padapter, u8 *addr)
DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num);
- spin_unlock_bh(&(pacl_node_q->lock));
+ spin_unlock_bh(&pacl_node_q->lock);
return ret;
}
@@ -1210,7 +1208,7 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
DBG_88E("%s(acl_num =%d) =%pM\n", __func__, pacl_list->num, (addr));
- spin_lock_bh(&(pacl_node_q->lock));
+ spin_lock_bh(&pacl_node_q->lock);
phead = get_list_head(pacl_node_q);
plist = phead->next;
@@ -1230,7 +1228,7 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
}
}
- spin_unlock_bh(&(pacl_node_q->lock));
+ spin_unlock_bh(&pacl_node_q->lock);
DBG_88E("%s, acl_num =%d\n", __func__, pacl_list->num);
return 0;
@@ -1238,10 +1236,10 @@ int rtw_acl_remove_sta(struct adapter *padapter, u8 *addr)
static void update_bcn_erpinfo_ie(struct adapter *padapter)
{
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
unsigned char *p, *ie = pnetwork->IEs;
u32 len = 0;
@@ -1275,10 +1273,10 @@ static void update_bcn_wps_ie(struct adapter *padapter)
u8 *pwps_ie = NULL, *pwps_ie_src;
u8 *premainder_ie, *pbackup_remainder_ie = NULL;
uint wps_ielen = 0, wps_offset, remainder_ielen;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
unsigned char *ie = pnetwork->IEs;
u32 ielen = pnetwork->IELength;
@@ -1338,8 +1336,8 @@ void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
if (!padapter)
return;
- pmlmepriv = &(padapter->mlmepriv);
- pmlmeext = &(padapter->mlmeextpriv);
+ pmlmepriv = &padapter->mlmepriv;
+ pmlmeext = &padapter->mlmeextpriv;
if (!pmlmeext->bstart_bss)
return;
@@ -1384,7 +1382,7 @@ static int rtw_ht_operation_update(struct adapter *padapter)
{
u16 cur_op_mode, new_op_mode;
int op_mode_changes = 0;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
if (pmlmepriv->htpriv.ht_option)
@@ -1477,8 +1475,8 @@ void associated_clients_update(struct adapter *padapter, u8 updated)
void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
{
u8 beacon_updated = false;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
if (!(psta->flags & WLAN_STA_SHORT_PREAMBLE)) {
if (!psta->no_short_preamble_set) {
@@ -1573,8 +1571,8 @@ void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
pmlmepriv->num_sta_ht_no_gf++;
}
DBG_88E("%s STA %pM - no greenfield, num of non-gf stations %d\n",
- __func__, (psta->hwaddr),
- pmlmepriv->num_sta_ht_no_gf);
+ __func__, (psta->hwaddr),
+ pmlmepriv->num_sta_ht_no_gf);
}
if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
@@ -1583,8 +1581,8 @@ void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
pmlmepriv->num_sta_ht_20mhz++;
}
DBG_88E("%s STA %pM - 20 MHz HT, num of 20MHz HT STAs %d\n",
- __func__, (psta->hwaddr),
- pmlmepriv->num_sta_ht_20mhz);
+ __func__, (psta->hwaddr),
+ pmlmepriv->num_sta_ht_20mhz);
}
} else {
if (!psta->no_ht_set) {
@@ -1612,8 +1610,8 @@ void bss_cap_update_on_sta_join(struct adapter *padapter, struct sta_info *psta)
u8 bss_cap_update_on_sta_leave(struct adapter *padapter, struct sta_info *psta)
{
u8 beacon_updated = false;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
if (!psta)
return beacon_updated;
@@ -1708,9 +1706,9 @@ u8 ap_free_sta(struct adapter *padapter, struct sta_info *psta,
beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
- spin_lock_bh(&(pstapriv->sta_hash_lock));
+ spin_lock_bh(&pstapriv->sta_hash_lock);
rtw_free_stainfo(padapter, psta);
- spin_unlock_bh(&(pstapriv->sta_hash_lock));
+ spin_unlock_bh(&pstapriv->sta_hash_lock);
return beacon_updated;
}
@@ -1721,7 +1719,7 @@ int rtw_sta_flush(struct adapter *padapter)
struct sta_info *psta = NULL;
struct sta_priv *pstapriv = &padapter->stapriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
DBG_88E(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
@@ -1758,7 +1756,7 @@ int rtw_sta_flush(struct adapter *padapter)
void sta_info_update(struct adapter *padapter, struct sta_info *psta)
{
int flags = psta->flags;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
/* update wmm cap. */
if (WLAN_STA_WME&flags)
@@ -1795,7 +1793,7 @@ void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta)
void start_ap_mode(struct adapter *padapter)
{
int i;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct sta_priv *pstapriv = &padapter->stapriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
@@ -1828,7 +1826,7 @@ void start_ap_mode(struct adapter *padapter)
pmlmepriv->wps_assoc_resp_ie = NULL;
/* for ACL */
- INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue));
+ INIT_LIST_HEAD(&pacl_list->acl_node_q.queue);
pacl_list->num = 0;
pacl_list->mode = 0;
for (i = 0; i < NUM_ACL; i++) {
@@ -1843,7 +1841,7 @@ void stop_ap_mode(struct adapter *padapter)
struct rtw_wlan_acl_node *paclnode;
struct sta_info *psta = NULL;
struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
struct __queue *pacl_node_q = &pacl_list->acl_node_q;
@@ -1857,7 +1855,7 @@ void stop_ap_mode(struct adapter *padapter)
padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
/* for ACL */
- spin_lock_bh(&(pacl_node_q->lock));
+ spin_lock_bh(&pacl_node_q->lock);
phead = get_list_head(pacl_node_q);
plist = phead->next;
while (phead != plist) {
@@ -1872,7 +1870,7 @@ void stop_ap_mode(struct adapter *padapter)
pacl_list->num--;
}
}
- spin_unlock_bh(&(pacl_node_q->lock));
+ spin_unlock_bh(&pacl_node_q->lock);
DBG_88E("%s, free acl_node_queue, num =%d\n", __func__, pacl_list->num);
@@ -1882,9 +1880,9 @@ void stop_ap_mode(struct adapter *padapter)
rtw_free_all_stainfo(padapter);
psta = rtw_get_bcmc_stainfo(padapter);
- spin_lock_bh(&(pstapriv->sta_hash_lock));
+ spin_lock_bh(&pstapriv->sta_hash_lock);
rtw_free_stainfo(padapter, psta);
- spin_unlock_bh(&(pstapriv->sta_hash_lock));
+ spin_unlock_bh(&pstapriv->sta_hash_lock);
rtw_init_bcmc_stainfo(padapter);
diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c
index 36109cec8706..14979666dadd 100644
--- a/drivers/staging/rtl8188eu/core/rtw_cmd.c
+++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c
@@ -1321,9 +1321,6 @@ void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *
spin_lock_bh(&pmlmepriv->lock);
- if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true))
- _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
-
set_fwstate(pmlmepriv, _FW_LINKED);
spin_unlock_bh(&pmlmepriv->lock);
diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c
index 16cc7706a1e6..b9bdff0490ca 100644
--- a/drivers/staging/rtl8188eu/core/rtw_efuse.c
+++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c
@@ -253,6 +253,7 @@ static void efuse_read_phymap_from_txpktbuf(
u8 lenc[2];
u16 lenbak, aaabak;
u16 aaa;
+
lenc[0] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L);
lenc[1] = usb_read8(adapter, REG_PKTBUF_DBG_DATA_L+1);
@@ -562,13 +563,14 @@ static bool hal_EfusePgPacketWrite2ByteHeader(struct adapter *pAdapter, u8 efuse
}
if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */
- if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
+ if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
return false;
- }
+
efuse_addr++;
continue;
} else if (pg_header != tmp_header) { /* offset PG fail */
struct pgpkt fixPkt;
+
fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
fixPkt.word_en = tmp_header & 0x0F;
fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
@@ -611,6 +613,7 @@ static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuse
bRet = true;
} else {
struct pgpkt fixPkt;
+
fixPkt.offset = (tmp_header>>4) & 0x0F;
fixPkt.word_en = tmp_header & 0x0F;
fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
@@ -819,6 +822,7 @@ bool Efuse_PgPacketWrite(struct adapter *pAdapter, u8 offset, u8 word_en, u8 *pD
u8 Efuse_CalculateWordCnts(u8 word_en)
{
u8 word_cnts = 0;
+
if (!(word_en & BIT(0)))
word_cnts++; /* 0 : write enable */
if (!(word_en & BIT(1)))
diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
index 914c4923421b..d1cd34011602 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
@@ -71,8 +71,8 @@ int rtw_get_bit_value_from_ieee_value(u8 val)
unsigned char dot11_rate_table[] = {
2, 4, 11, 22, 12, 18, 24, 36, 48,
72, 96, 108, 0}; /* last element must be zero!! */
-
int i = 0;
+
while (dot11_rate_table[i] != 0) {
if (dot11_rate_table[i] == val)
return BIT(i);
@@ -162,6 +162,7 @@ u8 *rtw_get_ie(u8 *pbuf, int index, int *len, int limit)
{
int tmp, i;
u8 *p;
+
if (limit < 1)
return NULL;
@@ -211,6 +212,7 @@ void rtw_set_supported_rate(u8 *SupportedRates, uint mode)
uint rtw_get_rateset_len(u8 *rateset)
{
uint i = 0;
+
while (1) {
if ((rateset[i]) == 0)
break;
@@ -998,10 +1000,11 @@ int ieee80211_get_hdrlen(u16 fc)
static int rtw_get_cipher_info(struct wlan_network *pnetwork)
{
- u32 wpa_ielen;
+ int wpa_ielen;
unsigned char *pbuf;
int group_cipher = 0, pairwise_cipher = 0, is8021x = 0;
int ret = _FAIL;
+
pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
if (pbuf && (wpa_ielen > 0)) {
@@ -1042,7 +1045,7 @@ void rtw_get_bcn_info(struct wlan_network *pnetwork)
__le16 le_tmp;
u16 wpa_len = 0, rsn_len = 0;
struct HT_info_element *pht_info = NULL;
- unsigned int len;
+ int len;
unsigned char *p;
memcpy(&le_tmp, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
index 6ed23f4db38c..67508a6cf0e5 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c
@@ -573,11 +573,6 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter)
u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0;
u32 ht_ielen = 0;
- if (adapter->registrypriv.mp_mode == 1) {
- if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
- return 0;
- }
-
if ((!check_fwstate(pmlmepriv, _FW_LINKED)) &&
(!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)))
return 0;
diff --git a/drivers/staging/rtl8188eu/core/rtw_led.c b/drivers/staging/rtl8188eu/core/rtw_led.c
index c1478cff5854..8e3721c797c3 100644
--- a/drivers/staging/rtl8188eu/core/rtw_led.c
+++ b/drivers/staging/rtl8188eu/core/rtw_led.c
@@ -40,6 +40,7 @@ void BlinkTimerCallback(unsigned long data)
void BlinkWorkItemCallback(struct work_struct *work)
{
struct LED_871x *pLed = container_of(work, struct LED_871x, BlinkWorkItem);
+
BlinkHandler(pLed);
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c
index 032f783b0d83..a71928952eca 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c
@@ -659,6 +659,7 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf)
}
} else {
int s_ret;
+
set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
pmlmepriv->to_join = false;
s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
@@ -1256,6 +1257,7 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf)
if (mac_id >= 0) {
u16 media_status;
+
media_status = (mac_id<<8)|0; /* MACID|OPMODE:0 means disconnect */
/* for STA, AP, ADHOC mode, report disconnect stauts to FW */
rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
@@ -1542,6 +1544,7 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(supp_ant_div));
if (supp_ant_div) {
u8 cur_ant;
+
rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(cur_ant));
DBG_88E("#### Opt_Ant_(%s), cur_Ant(%s)\n",
(2 == candidate->network.PhyInfo.Optimum_antenna) ? "A" : "B",
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index d9c114776cab..29334794333c 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -147,6 +147,7 @@ static const struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {
int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch)
{
int i;
+
for (i = 0; ch_set[i].ChannelNum != 0; i++) {
if (ch == ch_set[i].ChannelNum)
break;
@@ -274,9 +275,8 @@ static s32 dump_mgntframe_and_wait_ack(struct adapter *padapter,
pxmitpriv->ack_tx = true;
pmgntframe->ack_report = 1;
- if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
+ if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
- }
pxmitpriv->ack_tx = false;
mutex_unlock(&pxmitpriv->ack_tx_mutex);
@@ -371,6 +371,7 @@ static void issue_beacon(struct adapter *padapter, int timeout_ms)
u8 *wps_ie;
uint wps_ielen;
u8 sr = 0;
+
memcpy(pframe, cur_network->IEs, cur_network->IELength);
len_diff = update_hidden_ssid(
pframe+_BEACON_IE_OFFSET_
@@ -829,6 +830,7 @@ static void issue_auth(struct adapter *padapter, struct sta_info *psta,
} else {
__le32 le_tmp32;
__le16 le_tmp16;
+
ether_addr_copy(pwlanhdr->addr1, pnetwork->MacAddress);
ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
ether_addr_copy(pwlanhdr->addr3, pnetwork->MacAddress);
@@ -1963,6 +1965,7 @@ static void site_survey(struct adapter *padapter)
if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */
int i;
+
for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
/* todo: to issue two probe req??? */
@@ -2155,6 +2158,7 @@ static u8 collect_bss_info(struct adapter *padapter,
p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
if (p) {
struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
+
bssid->Configuration.DSConfig = HT_info->primary_channel;
} else { /* use current channel */
bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
@@ -2192,6 +2196,7 @@ static u8 collect_bss_info(struct adapter *padapter,
/* 20/40 BSS Coexistence check */
if ((pregistrypriv->wifi_spec == 1) && (!pmlmeinfo->bwmode_updated)) {
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
if (p && len > 0) {
struct ieee80211_ht_cap *pHT_caps =
@@ -2218,6 +2223,7 @@ static void start_create_ibss(struct adapter *padapter)
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network));
+
pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
@@ -3453,11 +3459,10 @@ static unsigned int OnAssocRsp(struct adapter *padapter,
UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
report_assoc_result:
- if (res > 0) {
+ if (res > 0)
rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
- } else {
+ else
rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
- }
report_join_res(padapter, res);
@@ -3747,8 +3752,8 @@ static unsigned int on_action_public_p2p(struct recv_frame *precv_frame)
u8 *pframe = precv_frame->rx_data;
u8 *frame_body;
u8 dialogToken = 0;
- frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
+ frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr));
dialogToken = frame_body[7];
if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
@@ -4002,9 +4007,8 @@ static void init_channel_list(struct adapter *padapter, struct rt_channel_info *
struct p2p_reg_class *reg = NULL;
for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
- if (!has_channel(channel_set, chanset_size, ch)) {
+ if (!has_channel(channel_set, chanset_size, ch))
continue;
- }
if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
continue;
@@ -4664,23 +4668,6 @@ void mlmeext_sta_del_event_callback(struct adapter *padapter)
Following are the functions for the timer handlers
*****************************************************************************/
-void _linked_rx_signal_strehgth_display(struct adapter *padapter);
-void _linked_rx_signal_strehgth_display(struct adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- u8 mac_id;
- int UndecoratedSmoothedPWDB;
- if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
- mac_id = 0;
- else if ((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
- mac_id = 2;
-
- rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &mac_id);
-
- rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
- DBG_88E("UndecoratedSmoothedPWDB:%d\n", UndecoratedSmoothedPWDB);
-}
static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta)
{
@@ -4707,9 +4694,6 @@ void linked_status_chk(struct adapter *padapter)
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
struct sta_priv *pstapriv = &padapter->stapriv;
- if (padapter->bRxRSSIDisplay)
- _linked_rx_signal_strehgth_display(padapter);
-
if (is_client_associated_to_ap(padapter)) {
/* linked infrastructure client mode */
@@ -4767,9 +4751,8 @@ void linked_status_chk(struct adapter *padapter)
}
}
- if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) {
+ if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf)
tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0);
- }
}
if (rx_chk == _FAIL) {
diff --git a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
index 4032121a06f3..f86c9cebf09a 100644
--- a/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
+++ b/drivers/staging/rtl8188eu/core/rtw_pwrctrl.c
@@ -180,9 +180,9 @@ int ips_leave(struct adapter *padapter)
DBG_88E("==>ips_leave cnts:%d\n", pwrpriv->ips_leave_cnts);
result = rtw_ips_pwr_up(padapter);
- if (result == _SUCCESS) {
+ if (result == _SUCCESS)
pwrpriv->rf_pwrstate = rf_on;
- }
+
DBG_88E_LEVEL(_drv_info_, "nolinked power save leave\n");
if ((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) || (_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm)) {
@@ -279,6 +279,7 @@ exit:
static void pwr_state_check_handler(unsigned long data)
{
struct adapter *padapter = (struct adapter *)data;
+
rtw_ps_cmd(padapter);
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c
index 3e6edb63d36b..f2021fed704c 100644
--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
+++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
@@ -211,6 +211,7 @@ u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter)
{
u32 cnt = 0;
struct recv_frame *pending_frame;
+
while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
DBG_88E("%s: dequeue uc_swdec_pending_queue\n", __func__);
@@ -296,6 +297,7 @@ static int recvframe_chkmic(struct adapter *adapter,
*(pframemic-10), *(pframemic-9)));
{
uint i;
+
RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
("\n ======demp packet (len=%d)======\n",
precvframe->len));
@@ -373,6 +375,7 @@ static struct recv_frame *decryptor(struct adapter *padapter,
if (prxattrib->encrypt > 0) {
u8 *iv = precv_frame->rx_data+prxattrib->hdrlen;
+
prxattrib->key_index = (((iv[3])>>6)&0x3);
if (prxattrib->key_index > WEP_KEYS) {
@@ -647,7 +650,6 @@ int sta2sta_data_frame(
int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame,
struct sta_info **psta)
{
- u8 *ptr = precv_frame->rx_data;
int ret = _SUCCESS;
struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
struct sta_priv *pstapriv = &adapter->stapriv;
@@ -703,14 +705,6 @@ int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame,
sta_addr = pattrib->src;
}
- } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
- memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
- memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- sta_addr = mybssid;
} else {
ret = _FAIL;
}
@@ -799,23 +793,6 @@ static int ap2sta_data_frame(
ret = RTW_RX_HANDLED;
goto exit;
}
- } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) &&
- (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
- memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
- memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
- memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- /* */
- memcpy(pattrib->bssid, mybssid, ETH_ALEN);
-
- *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */
- if (*psta == NULL) {
- RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under MP_MODE ; drop pkt\n"));
- ret = _FAIL;
- goto exit;
- }
} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
/* Special case */
ret = RTW_RX_HANDLED;
@@ -880,6 +857,7 @@ static int sta2ap_data_frame(struct adapter *adapter,
}
} else {
u8 *myhwaddr = myid(&adapter->eeprompriv);
+
if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
ret = RTW_RX_HANDLED;
goto exit;
@@ -1115,11 +1093,10 @@ static int validate_recv_data_frame(struct adapter *adapter,
break;
}
- if (ret == _FAIL) {
+ if (ret == _FAIL)
goto exit;
- } else if (ret == RTW_RX_HANDLED) {
+ else if (ret == RTW_RX_HANDLED)
goto exit;
- }
if (psta == NULL) {
RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" after to_fr_ds_chk; psta==NULL\n"));
@@ -1197,6 +1174,7 @@ static int validate_recv_frame(struct adapter *adapter,
if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter));
+
if (ch_set_idx >= 0)
pmlmeext->channel_set[ch_set_idx].rx_count++;
}
@@ -1265,6 +1243,7 @@ static int validate_recv_frame(struct adapter *adapter,
retval = validate_recv_data_frame(adapter, precv_frame);
if (retval == _FAIL) {
struct recv_priv *precvpriv = &adapter->recvpriv;
+
precvpriv->rx_drop++;
}
break;
@@ -1303,8 +1282,6 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe)
u8 *psnap_type;
struct ieee80211_snap_hdr *psnap;
- struct adapter *adapter = precvframe->adapter;
- struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
u8 *ptr = precvframe->rx_data;
struct rx_pkt_attrib *pattrib = &precvframe->attrib;
@@ -1335,19 +1312,9 @@ static int wlanhdr_to_ethhdr(struct recv_frame *precvframe)
eth_type = ntohs(be_tmp); /* pattrib->ether_type */
pattrib->eth_type = eth_type;
- if ((check_fwstate(pmlmepriv, WIFI_MP_STATE))) {
- ptr += rmv_len;
- *ptr = 0x87;
- *(ptr+1) = 0x12;
-
- eth_type = 0x8712;
- /* append rx status for mp test packets */
- ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24);
- memcpy(ptr, get_rxmem(precvframe), 24);
- ptr += 24;
- } else {
- ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
- }
+ ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
+ if (!ptr)
+ return _FAIL;
memcpy(ptr, pattrib->dst, ETH_ALEN);
memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
@@ -1466,6 +1433,7 @@ struct recv_frame *recvframe_chk_defrag(struct adapter *padapter,
psta = rtw_get_stainfo(pstapriv, psta_addr);
if (psta == NULL) {
u8 type = GetFrameType(pfhdr->rx_data);
+
if (type != WIFI_DATA_TYPE) {
psta = rtw_get_bcmc_stainfo(padapter);
pdefrag_q = &psta->sta_recvpriv.defrag_q;
@@ -1548,8 +1516,8 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe)
struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT];
struct recv_priv *precvpriv = &padapter->recvpriv;
struct __queue *pfree_recv_queue = &(precvpriv->free_recv_queue);
- nr_subframes = 0;
+ nr_subframes = 0;
pattrib = &prframe->attrib;
recvframe_pull(prframe, prframe->attrib.hdrlen);
@@ -1606,9 +1574,9 @@ static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe)
if (padding_len == 4)
padding_len = 0;
- if (a_len < padding_len) {
+ if (a_len < padding_len)
goto exit;
- }
+
pdata += padding_len;
a_len -= padding_len;
}
@@ -2064,45 +2032,48 @@ static void rtw_signal_stat_timer_hdl(unsigned long data)
u8 avg_signal_qual = 0;
u8 _alpha = 3; /* this value is based on converging_constant = 5000 and sampling_interval = 1000 */
- if (adapter->recvpriv.is_signal_dbg) {
- /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */
- adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg;
- adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
- } else {
- if (recvpriv->signal_strength_data.update_req == 0) {/* update_req is clear, means we got rx */
- avg_signal_strength = recvpriv->signal_strength_data.avg_val;
- /* after avg_vals are acquired, we can re-stat the signal values */
- recvpriv->signal_strength_data.update_req = 1;
- }
-
- if (recvpriv->signal_qual_data.update_req == 0) {/* update_req is clear, means we got rx */
- avg_signal_qual = recvpriv->signal_qual_data.avg_val;
- /* after avg_vals are acquired, we can re-stat the signal values */
- recvpriv->signal_qual_data.update_req = 1;
- }
+ if (recvpriv->signal_strength_data.update_req == 0) {
+ /* update_req is clear, means we got rx */
+ avg_signal_strength = recvpriv->signal_strength_data.avg_val;
+ /* after avg_vals are acquired, we can re-stat the signal
+ * values
+ */
+ recvpriv->signal_strength_data.update_req = 1;
+ }
- /* update value of signal_strength, rssi, signal_qual */
- if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == false) {
- tmp_s = avg_signal_strength+(_alpha-1)*recvpriv->signal_strength;
- if (tmp_s % _alpha)
- tmp_s = tmp_s/_alpha + 1;
- else
- tmp_s = tmp_s/_alpha;
- if (tmp_s > 100)
- tmp_s = 100;
+ if (recvpriv->signal_qual_data.update_req == 0) {
+ /* update_req is clear, means we got rx */
+ avg_signal_qual = recvpriv->signal_qual_data.avg_val;
+ /* after avg_vals are acquired, we can re-stat the signal
+ * values
+ */
+ recvpriv->signal_qual_data.update_req = 1;
+ }
- tmp_q = avg_signal_qual+(_alpha-1)*recvpriv->signal_qual;
- if (tmp_q % _alpha)
- tmp_q = tmp_q/_alpha + 1;
- else
- tmp_q = tmp_q/_alpha;
- if (tmp_q > 100)
- tmp_q = 100;
+ /* update value of signal_strength, rssi, signal_qual */
+ if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == false) {
+ tmp_s = avg_signal_strength +
+ (_alpha - 1) * recvpriv->signal_strength;
+ if (tmp_s % _alpha)
+ tmp_s = tmp_s / _alpha + 1;
+ else
+ tmp_s = tmp_s / _alpha;
+ if (tmp_s > 100)
+ tmp_s = 100;
+
+ tmp_q = avg_signal_qual +
+ (_alpha - 1) * recvpriv->signal_qual;
+ if (tmp_q % _alpha)
+ tmp_q = tmp_q / _alpha + 1;
+ else
+ tmp_q = tmp_q / _alpha;
+ if (tmp_q > 100)
+ tmp_q = 100;
- recvpriv->signal_strength = tmp_s;
- recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
- recvpriv->signal_qual = tmp_q;
- }
+ recvpriv->signal_strength = tmp_s;
+ recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
+ recvpriv->signal_qual = tmp_q;
}
+
rtw_set_signal_stat_timer(recvpriv);
}
diff --git a/drivers/staging/rtl8188eu/core/rtw_security.c b/drivers/staging/rtl8188eu/core/rtw_security.c
index 85bb441a7214..34b265dda601 100644
--- a/drivers/staging/rtl8188eu/core/rtw_security.c
+++ b/drivers/staging/rtl8188eu/core/rtw_security.c
@@ -36,6 +36,7 @@ static void arcfour_init(struct arc4context *parc4ctx, u8 *key, u32 key_len)
u32 stateindex;
u8 *state;
u32 counter;
+
state = parc4ctx->state;
parc4ctx->x = 0;
parc4ctx->y = 0;
@@ -60,6 +61,7 @@ static u32 arcfour_byte(struct arc4context *parc4ctx)
u32 y;
u32 sx, sy;
u8 *state;
+
state = parc4ctx->state;
x = (parc4ctx->x + 1) & 0xff;
sx = state[x];
@@ -75,6 +77,7 @@ static u32 arcfour_byte(struct arc4context *parc4ctx)
static void arcfour_encrypt(struct arc4context *parc4ctx, u8 *dest, u8 *src, u32 len)
{
u32 i;
+
for (i = 0; i < len; i++)
dest[i] = src[i] ^ (unsigned char)arcfour_byte(parc4ctx);
}
@@ -120,6 +123,7 @@ static __le32 getcrc32(u8 *buf, int len)
{
u8 *p;
u32 crc;
+
if (bcrc32initialized == 0)
crc32_init();
@@ -242,6 +246,7 @@ static u32 secmicgetuint32(u8 *p)
{
s32 i;
u32 res = 0;
+
for (i = 0; i < 4; i++)
res |= ((u32)(*p++)) << (8*i);
return res;
@@ -251,6 +256,7 @@ static void secmicputuint32(u8 *p, u32 val)
/* Convert from Us3232 to Byte[] in a portable way */
{
long i;
+
for (i = 0; i < 4; i++) {
*p++ = (u8)(val & 0xff);
val >>= 8;
@@ -328,6 +334,7 @@ void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_cod
{
struct mic_data micdata;
u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
+
rtw_secmicsetkey(&micdata, key);
priority[0] = pri;
@@ -378,73 +385,73 @@ void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_cod
/* 2-unsigned char by 2-unsigned char subset of the full AES S-box table */
static const unsigned short Sbox1[2][256] = { /* Sbox for hash (can be in ROM) */
{
- 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
- 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
- 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
- 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
- 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
- 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
- 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
- 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
- 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
- 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
- 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
- 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
- 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
- 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
- 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
- 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
- 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
- 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
- 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
- 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
- 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
- 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
- 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
- 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
- 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
- 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
- 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
- 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
- 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
- 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
- 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
- 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
+ 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
+ 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
+ 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
+ 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
+ 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
+ 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
+ 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
+ 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
+ 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
+ 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
+ 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
+ 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
+ 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
+ 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
+ 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
+ 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
+ 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
+ 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
+ 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
+ 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
+ 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
+ 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
+ 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
+ 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
+ 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
+ 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
+ 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
+ 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
+ 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
+ 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
+ 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
+ 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
},
{ /* second half of table is unsigned char-reversed version of first! */
- 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
- 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
- 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
- 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
- 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
- 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
- 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
- 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
- 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
- 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
- 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
- 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
- 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
- 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
- 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
- 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
- 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
- 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
- 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
- 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
- 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
- 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
- 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
- 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
- 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
- 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
- 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
- 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
- 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
- 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
- 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
- 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
+ 0xA5C6, 0x84F8, 0x99EE, 0x8DF6, 0x0DFF, 0xBDD6, 0xB1DE, 0x5491,
+ 0x5060, 0x0302, 0xA9CE, 0x7D56, 0x19E7, 0x62B5, 0xE64D, 0x9AEC,
+ 0x458F, 0x9D1F, 0x4089, 0x87FA, 0x15EF, 0xEBB2, 0xC98E, 0x0BFB,
+ 0xEC41, 0x67B3, 0xFD5F, 0xEA45, 0xBF23, 0xF753, 0x96E4, 0x5B9B,
+ 0xC275, 0x1CE1, 0xAE3D, 0x6A4C, 0x5A6C, 0x417E, 0x02F5, 0x4F83,
+ 0x5C68, 0xF451, 0x34D1, 0x08F9, 0x93E2, 0x73AB, 0x5362, 0x3F2A,
+ 0x0C08, 0x5295, 0x6546, 0x5E9D, 0x2830, 0xA137, 0x0F0A, 0xB52F,
+ 0x090E, 0x3624, 0x9B1B, 0x3DDF, 0x26CD, 0x694E, 0xCD7F, 0x9FEA,
+ 0x1B12, 0x9E1D, 0x7458, 0x2E34, 0x2D36, 0xB2DC, 0xEEB4, 0xFB5B,
+ 0xF6A4, 0x4D76, 0x61B7, 0xCE7D, 0x7B52, 0x3EDD, 0x715E, 0x9713,
+ 0xF5A6, 0x68B9, 0x0000, 0x2CC1, 0x6040, 0x1FE3, 0xC879, 0xEDB6,
+ 0xBED4, 0x468D, 0xD967, 0x4B72, 0xDE94, 0xD498, 0xE8B0, 0x4A85,
+ 0x6BBB, 0x2AC5, 0xE54F, 0x16ED, 0xC586, 0xD79A, 0x5566, 0x9411,
+ 0xCF8A, 0x10E9, 0x0604, 0x81FE, 0xF0A0, 0x4478, 0xBA25, 0xE34B,
+ 0xF3A2, 0xFE5D, 0xC080, 0x8A05, 0xAD3F, 0xBC21, 0x4870, 0x04F1,
+ 0xDF63, 0xC177, 0x75AF, 0x6342, 0x3020, 0x1AE5, 0x0EFD, 0x6DBF,
+ 0x4C81, 0x1418, 0x3526, 0x2FC3, 0xE1BE, 0xA235, 0xCC88, 0x392E,
+ 0x5793, 0xF255, 0x82FC, 0x477A, 0xACC8, 0xE7BA, 0x2B32, 0x95E6,
+ 0xA0C0, 0x9819, 0xD19E, 0x7FA3, 0x6644, 0x7E54, 0xAB3B, 0x830B,
+ 0xCA8C, 0x29C7, 0xD36B, 0x3C28, 0x79A7, 0xE2BC, 0x1D16, 0x76AD,
+ 0x3BDB, 0x5664, 0x4E74, 0x1E14, 0xDB92, 0x0A0C, 0x6C48, 0xE4B8,
+ 0x5D9F, 0x6EBD, 0xEF43, 0xA6C4, 0xA839, 0xA431, 0x37D3, 0x8BF2,
+ 0x32D5, 0x438B, 0x596E, 0xB7DA, 0x8C01, 0x64B1, 0xD29C, 0xE049,
+ 0xB4D8, 0xFAAC, 0x07F3, 0x25CF, 0xAFCA, 0x8EF4, 0xE947, 0x1810,
+ 0xD56F, 0x88F0, 0x6F4A, 0x725C, 0x2438, 0xF157, 0xC773, 0x5197,
+ 0x23CB, 0x7CA1, 0x9CE8, 0x213E, 0xDD96, 0xDC61, 0x860D, 0x850F,
+ 0x90E0, 0x427C, 0xC471, 0xAACC, 0xD890, 0x0506, 0x01F7, 0x121C,
+ 0xA3C2, 0x5F6A, 0xF9AE, 0xD069, 0x9117, 0x5899, 0x273A, 0xB927,
+ 0x38D9, 0x13EB, 0xB32B, 0x3322, 0xBBD2, 0x70A9, 0x8907, 0xA733,
+ 0xB62D, 0x223C, 0x9215, 0x20C9, 0x4987, 0xFFAA, 0x7850, 0x7AA5,
+ 0x8F03, 0xF859, 0x8009, 0x171A, 0xDA65, 0x31D7, 0xC684, 0xB8D0,
+ 0xC382, 0xB029, 0x775A, 0x111E, 0xCB7B, 0xFCA8, 0xD66D, 0x3A2C,
}
};
@@ -776,6 +783,7 @@ static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext);
static void xor_128(u8 *a, u8 *b, u8 *out)
{
int i;
+
for (i = 0; i < 16; i++)
out[i] = a[i] ^ b[i];
}
@@ -783,6 +791,7 @@ static void xor_128(u8 *a, u8 *b, u8 *out)
static void xor_32(u8 *a, u8 *b, u8 *out)
{
int i;
+
for (i = 0; i < 4; i++)
out[i] = a[i] ^ b[i];
}
@@ -800,6 +809,7 @@ static void next_key(u8 *key, int round)
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0x1b, 0x36, 0x36, 0x36
};
+
sbox_key[0] = sbox(key[13]);
sbox_key[1] = sbox(key[14]);
sbox_key[2] = sbox(key[15]);
@@ -853,6 +863,7 @@ static void mix_column(u8 *in, u8 *out)
u8 rotr[4];
u8 temp[4];
u8 tempb[4];
+
for (i = 0 ; i < 4; i++) {
if ((in[i] & 0x80) == 0x80)
add1b[i] = 0x1b;
@@ -905,6 +916,7 @@ static void aes128k128d(u8 *key, u8 *data, u8 *ciphertext)
u8 intermediatea[16];
u8 intermediateb[16];
u8 round_key[16];
+
for (i = 0; i < 16; i++)
round_key[i] = key[i];
for (round = 0; round < 11; round++) {
@@ -936,6 +948,7 @@ static void construct_mic_iv(u8 *mic_iv, int qc_exists, int a4_exists, u8 *mpdu,
uint payload_length, u8 *pn_vector)
{
int i;
+
mic_iv[0] = 0x59;
if (qc_exists && a4_exists)
mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
@@ -984,6 +997,7 @@ static void construct_mic_header1(u8 *mic_header1, int header_length, u8 *mpdu)
static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int qc_exists)
{
int i;
+
for (i = 0; i < 16; i++)
mic_header2[i] = 0x00;
@@ -1025,6 +1039,7 @@ static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, int a4_exists, int
static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists, u8 *mpdu, u8 *pn_vector, int c)
{
int i;
+
for (i = 0; i < 16; i++)
ctr_preload[i] = 0x00;
i = 0;
@@ -1050,6 +1065,7 @@ static void construct_ctr_preload(u8 *ctr_preload, int a4_exists, int qc_exists,
static void bitwise_xor(u8 *ina, u8 *inb, u8 *out)
{
int i;
+
for (i = 0; i < 16; i++)
out[i] = ina[i] ^ inb[i];
}
@@ -1256,6 +1272,7 @@ static int aes_decipher(u8 *key, uint hdrlen,
uint qc_exists, a4_exists, i, j, payload_remainder,
num_blocks, payload_index;
int res = _SUCCESS;
+
u8 pn_vector[6];
u8 mic_iv[16];
u8 mic_header1[16];
@@ -1452,6 +1469,7 @@ u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe)
struct rx_pkt_attrib *prxattrib = &((struct recv_frame *)precvframe)->attrib;
struct security_priv *psecuritypriv = &padapter->securitypriv;
u32 res = _SUCCESS;
+
pframe = (unsigned char *)((struct recv_frame *)precvframe)->rx_data;
/* 4 start to encrypt each fragment */
if (prxattrib->encrypt == _AES_) {
diff --git a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
index 941d1a069d20..2ecfb117bf3f 100644
--- a/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
+++ b/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
@@ -154,6 +154,7 @@ u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
while (phead != plist) {
int i;
+
psta = container_of(plist, struct sta_info,
hash_list);
plist = plist->next;
diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
index 2a65ac702129..f6f1b09466a8 100644
--- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
@@ -379,6 +379,7 @@ int get_bsstype(unsigned short capability)
u16 get_beacon_interval(struct wlan_bssid_ex *bss)
{
__le16 val;
+
memcpy((unsigned char *)&val, rtw_get_beacon_interval_from_ie(bss->IEs), 2);
return le16_to_cpu(val);
@@ -1306,6 +1307,7 @@ void set_sta_rate(struct adapter *padapter, struct sta_info *psta)
void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode)
{
unsigned char supported_rates[NDIS_802_11_LENGTH_RATES_EX];
+
memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
@@ -1330,6 +1332,7 @@ unsigned char check_assoc_AP(u8 *pframe, uint len)
struct ndis_802_11_var_ie *pIE;
u8 epigram_vendor_flag;
u8 ralink_vendor_flag;
+
epigram_vendor_flag = 0;
ralink_vendor_flag = 0;
diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c
index b60b126b860e..630fdc33d58a 100644
--- a/drivers/staging/rtl8188eu/core/rtw_xmit.c
+++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c
@@ -246,8 +246,7 @@ void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
pxmitbuf++;
}
- if (pxmitpriv->pallocated_xmit_extbuf)
- vfree(pxmitpriv->pallocated_xmit_extbuf);
+ vfree(pxmitpriv->pallocated_xmit_extbuf);
rtw_free_hwxmits(padapter);
@@ -304,6 +303,7 @@ static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *
/* check HT op mode */
if (pattrib->ht_en) {
u8 htopmode = pmlmeinfo->HT_protection;
+
if ((pmlmeext->cur_bwmode && (htopmode == 2 || htopmode == 3)) ||
(!pmlmeext->cur_bwmode && htopmode == 3)) {
pattrib->vcs_mode = RTS_CTS;
@@ -454,6 +454,7 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
/* The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */
/* to prevent DHCP protocol fail */
u8 tmp[24];
+
_rtw_pktfile_read(&pktfile, &tmp[0], 24);
pattrib->dhcp_pkt = 0;
if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */
@@ -530,7 +531,7 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p
pattrib->encrypt = 0;
- if ((pattrib->ether_type != ETH_P_PAE) && !check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
+ if (pattrib->ether_type != ETH_P_PAE) {
RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("\npsta->ieee8021x_blocked == true, pattrib->ether_type(%.4x) != ETH_P_PAE\n", pattrib->ether_type));
res = _FAIL;
goto exit;
@@ -1605,6 +1606,7 @@ void rtw_free_hwxmits(struct adapter *padapter)
void rtw_init_hwxmits(struct hw_xmit *phwxmit, int entry)
{
int i;
+
for (i = 0; i < entry; i++, phwxmit++)
phwxmit->accnt = 0;
}
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
index 85650b2663ec..53e312aaefb5 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
@@ -635,7 +635,7 @@ s32 rtw_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe)
if (res == _SUCCESS) {
rtw_dump_xframe(adapt, pxmitframe);
} else {
- DBG_88E("==> %s xmitframe_coalsece failed\n", __func__);
+ DBG_88E("==> %s xmitframe_coalesce failed\n", __func__);
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
rtw_free_xmitframe(pxmitpriv, pxmitframe);
}
diff --git a/drivers/staging/rtl8188eu/include/drv_types.h b/drivers/staging/rtl8188eu/include/drv_types.h
index e86419e525d8..0fd2a2d9be20 100644
--- a/drivers/staging/rtl8188eu/include/drv_types.h
+++ b/drivers/staging/rtl8188eu/include/drv_types.h
@@ -168,7 +168,6 @@ struct adapter {
u8 bFWReady;
u8 bReadPortCancel;
u8 bWritePortCancel;
- u8 bRxRSSIDisplay;
struct mutex hw_init_mutex;
};
diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h
index 9047b6dec9ed..ee3f5ee06529 100644
--- a/drivers/staging/rtl8188eu/include/osdep_service.h
+++ b/drivers/staging/rtl8188eu/include/osdep_service.h
@@ -69,9 +69,6 @@ static inline int rtw_netif_queue_stopped(struct net_device *pnetdev)
netif_tx_queue_stopped(netdev_get_tx_queue(pnetdev, 3));
}
-int RTW_STATUS_CODE(int error_code);
-
-#define rtw_update_mem_stat(flag, sz) do {} while (0)
u8 *_rtw_malloc(u32 sz);
#define rtw_malloc(sz) _rtw_malloc((sz))
@@ -88,10 +85,6 @@ struct net_device *rtw_alloc_etherdev_with_old_priv(void *old_priv);
(((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv)
void rtw_free_netdev(struct net_device *netdev);
-#define NDEV_FMT "%s"
-#define NDEV_ARG(ndev) ndev->name
-#define ADPT_FMT "%s"
-#define ADPT_ARG(adapter) adapter->pnetdev->name
#define FUNC_NDEV_FMT "%s(%s)"
#define FUNC_NDEV_ARG(ndev) __func__, ndev->name
#define FUNC_ADPT_FMT "%s(%s)"
diff --git a/drivers/staging/rtl8188eu/include/rtw_debug.h b/drivers/staging/rtl8188eu/include/rtw_debug.h
index 95590a1a7b1b..9cc4b8c7c166 100644
--- a/drivers/staging/rtl8188eu/include/rtw_debug.h
+++ b/drivers/staging/rtl8188eu/include/rtw_debug.h
@@ -70,7 +70,7 @@ extern u32 GlobalDebugLevel;
#define DBG_88E_LEVEL(_level, fmt, arg...) \
do { \
if (_level <= GlobalDebugLevel) \
- pr_info(DRIVER_PREFIX"ERROR " fmt, ##arg); \
+ pr_info(DRIVER_PREFIX fmt, ##arg); \
} while (0)
#define DBG_88E(...) \
diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme.h b/drivers/staging/rtl8188eu/include/rtw_mlme.h
index 18fb7e7b2273..7324a95bb162 100644
--- a/drivers/staging/rtl8188eu/include/rtw_mlme.h
+++ b/drivers/staging/rtl8188eu/include/rtw_mlme.h
@@ -47,14 +47,6 @@
#define WIFI_STA_ALIVE_CHK_STATE 0x00000400
#define WIFI_SITE_MONITOR 0x00000800 /* to indicate the station is under site surveying */
-#define WIFI_MP_STATE 0x00010000
-#define WIFI_MP_CTX_BACKGROUND 0x00020000 /* in continuous tx background */
-#define WIFI_MP_CTX_ST 0x00040000 /* in continuous tx with single-tone */
-#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in continuous tx background due to out of skb */
-#define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx */
-#define WIFI_MP_CTX_CCK_CS 0x00200000 /* in continuous tx with carrier suppression */
-#define WIFI_MP_LPBK_STATE 0x00400000
-
#define _FW_UNDER_LINKING WIFI_UNDER_LINKING
#define _FW_LINKED WIFI_ASOC_STATE
#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR
@@ -115,183 +107,6 @@ struct rt_link_detect {
* to Tx traffic. */
};
-struct profile_info {
- u8 ssidlen;
- u8 ssid[WLAN_SSID_MAXLEN];
- u8 peermac[ETH_ALEN];
-};
-
-struct tx_invite_req_info {
- u8 token;
- u8 benable;
- u8 go_ssid[WLAN_SSID_MAXLEN];
- u8 ssidlen;
- u8 go_bssid[ETH_ALEN];
- u8 peer_macaddr[ETH_ALEN];
- u8 operating_ch; /* This information will be set by using the
- * p2p_set op_ch=x */
- u8 peer_ch; /* The listen channel for peer P2P device */
-};
-
-struct tx_invite_resp_info {
- u8 token; /* Used to record the dialog token of p2p invitation
- * request frame. */
-};
-
-struct tx_provdisc_req_info {
- u16 wps_config_method_request; /* Used when sending the
- * provisioning request frame*/
- u16 peer_channel_num[2]; /* The channel number which the
- * receiver stands. */
- struct ndis_802_11_ssid ssid;
- u8 peerDevAddr[ETH_ALEN]; /* Peer device address */
- u8 peerIFAddr[ETH_ALEN]; /* Peer interface address */
- u8 benable; /* This provision discovery
- * request frame is trigger
- * to send or not */
-};
-
-/* When peer device issue prov_disc_req first, we should store the following
- * information */
-/* The UI must know this information to know which config method the
- * remote p2p device needs. */
-struct rx_provdisc_req_info {
- u8 peerDevAddr[ETH_ALEN]; /* Peer device address */
- u8 strconfig_method_desc_of_prov_disc_req[4]; /* description
- * for the config method located in the provisioning
- * discovery request frame. */
-};
-
-struct tx_nego_req_info {
- u16 peer_channel_num[2]; /* The channel number. */
- u8 peerDevAddr[ETH_ALEN]; /* Peer device address */
- u8 benable; /* This negotiation request frame is
- * trigger to send or not */
-};
-
-struct group_id_info {
- u8 go_device_addr[ETH_ALEN]; /* The GO's device address of
- * this P2P group */
- u8 ssid[WLAN_SSID_MAXLEN]; /* The SSID of this P2P group */
-};
-
-struct scan_limit_info {
- u8 scan_op_ch_only; /* When this flag is set, the driver
- * should only scan the op. channel */
- u8 operation_ch[2]; /* Store the op. chan of invitation */
-};
-
-struct wifidirect_info {
- struct adapter *padapter;
- struct timer_list find_phase_timer;
- struct timer_list restore_p2p_state_timer;
-
- /* Used to do the scanning. After confirming the peer is availalble,
- * the driver transmits the P2P frame to peer. */
- struct timer_list pre_tx_scan_timer;
- struct timer_list reset_ch_sitesurvey;
- struct timer_list reset_ch_sitesurvey2; /* Just for resetting the scan
- * limit function by using p2p nego */
- struct tx_provdisc_req_info tx_prov_disc_info;
- struct rx_provdisc_req_info rx_prov_disc_info;
- struct tx_invite_req_info invitereq_info;
- /* Store the profile information of persistent group */
- struct profile_info profileinfo[P2P_MAX_PERSISTENT_GROUP_NUM];
- struct tx_invite_resp_info inviteresp_info;
- struct tx_nego_req_info nego_req_info;
- /* Store the group id info when doing the group negot handshake. */
- struct group_id_info groupid_info;
- /* Used for get the limit scan channel from the Invitation procedure */
- struct scan_limit_info rx_invitereq_info;
- /* Used for get the limit scan chan from the P2P negotiation handshake*/
- struct scan_limit_info p2p_info;
- enum P2P_ROLE role;
- enum P2P_STATE pre_p2p_state;
- enum P2P_STATE p2p_state;
- /* The device address should be the mac address of this device. */
- u8 device_addr[ETH_ALEN];
- u8 interface_addr[ETH_ALEN];
- u8 social_chan[4];
- u8 listen_channel;
- u8 operating_channel;
- u8 listen_dwell; /* This value should be between 1 and 3 */
- u8 support_rate[8];
- u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN];
- u8 intent; /* should only include the intent value. */
- u8 p2p_peer_interface_addr[ETH_ALEN];
- u8 p2p_peer_device_addr[ETH_ALEN];
- u8 peer_intent; /* Included the intent value and tie breaker value. */
- /* Device name for displaying on searching device screen */
- u8 device_name[WPS_MAX_DEVICE_NAME_LEN];
- u8 device_name_len;
- u8 profileindex; /* Used to point to the index of profileinfo array */
- u8 peer_operating_ch;
- u8 find_phase_state_exchange_cnt;
- /* The device password ID for group negotiation */
- u16 device_password_id_for_nego;
- u8 negotiation_dialog_token;
- /* SSID information for group negotitation */
- u8 nego_ssid[WLAN_SSID_MAXLEN];
- u8 nego_ssidlen;
- u8 p2p_group_ssid[WLAN_SSID_MAXLEN];
- u8 p2p_group_ssid_len;
- /* Flag to know if the persistent function should be supported or not.*/
- u8 persistent_supported;
- /* In the Sigma test, the Sigma will provide this enable from the
- * sta_set_p2p CAPI. */
- /* 0: disable */
- /* 1: enable */
- u8 session_available; /* Flag to set the WFD session available to
- * enable or disable "by Sigma" */
- /* In the Sigma test, the Sigma will disable the session available
- * by using the sta_preset CAPI. */
- /* 0: disable */
- /* 1: enable */
- u8 wfd_tdls_enable; /* Flag to enable or disable the TDLS by WFD Sigma*/
- /* 0: disable */
- /* 1: enable */
- u8 wfd_tdls_weaksec; /* Flag to enable or disable the weak security
- * function for TDLS by WFD Sigma */
- /* 0: disable */
- /* In this case, the driver can't issue the tdsl
- * setup request frame. */
- /* 1: enable */
- /* In this case, the driver can issue the tdls
- * setup request frame */
- /* even the current security is weak security. */
-
- /* This field will store the WPS value (PIN value or PBC) that UI had
- * got from the user. */
- enum P2P_WPSINFO ui_got_wps_info;
- u16 supported_wps_cm; /* This field describes the WPS config method
- * which this driver supported. */
- /* The value should be the combination of config
- * method defined in page104 of WPS v2.0 spec.*/
- /* This field will contain the length of body of P2P Channel List
- * attribute of group negotiation response frame. */
- uint channel_list_attr_len;
- /* This field will contain the body of P2P Channel List attribute of
- * group negotitation response frame. */
- /* We will use the channel_cnt and channel_list fields when constructing
- * the group negotiation confirm frame. */
- u8 channel_list_attr[100];
- enum P2P_PS_MODE p2p_ps_mode; /* indicate p2p ps mode */
- enum P2P_PS_STATE p2p_ps_state; /* indicate p2p ps state */
- u8 noa_index; /* Identifies and instance of Notice of Absence timing. */
- u8 ctwindow; /* Client traffic window. A period of time in TU after TBTT. */
- u8 opp_ps; /* opportunistic power save. */
- u8 noa_num; /* number of NoA descriptor in P2P IE. */
- u8 noa_count[P2P_MAX_NOA_NUM]; /* Count for owner, Type of client. */
- /* Max duration for owner, preferred or min acceptable duration for
- * client. */
- u32 noa_duration[P2P_MAX_NOA_NUM];
- /* Length of interval for owner, preferred or max acceptable interval
- * of client. */
- u32 noa_interval[P2P_MAX_NOA_NUM];
- /* schedule expressed in terms of the lower 4 bytes of the TSF timer. */
- u32 noa_start_time[P2P_MAX_NOA_NUM];
-};
-
struct mlme_priv {
spinlock_t lock;
int fw_state; /* shall we protect this variable? maybe not necessarily... */
diff --git a/drivers/staging/rtl8188eu/include/rtw_recv.h b/drivers/staging/rtl8188eu/include/rtw_recv.h
index 052af7b891da..591dd9d90267 100644
--- a/drivers/staging/rtl8188eu/include/rtw_recv.h
+++ b/drivers/staging/rtl8188eu/include/rtw_recv.h
@@ -151,8 +151,6 @@ struct recv_stat {
__le32 rxdw5;
};
-#define EOR BIT(30)
-
/*
accesser of recv_priv: rtw_recv_entry(dispatch / passive level);
recv_thread(passive) ; returnpkt(dispatch)
@@ -179,8 +177,6 @@ struct recv_priv {
struct recv_buf *precv_buf; /* 4 alignment */
struct __queue free_recv_buf_queue;
/* For display the phy informatiom */
- u8 is_signal_dbg; /* for debug */
- u8 signal_strength_dbg; /* for debug */
s8 rssi;
s8 rxpwdb;
u8 signal_strength;
@@ -233,7 +229,6 @@ struct recv_frame {
struct adapter *adapter;
struct rx_pkt_attrib attrib;
uint len;
- u8 *rx_head;
u8 *rx_data;
u8 *rx_tail;
u8 *rx_end;
@@ -258,14 +253,6 @@ u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter);
void rtw_reordering_ctrl_timeout_handler(unsigned long data);
-static inline u8 *get_rxmem(struct recv_frame *precvframe)
-{
- /* always return rx_head... */
- if (precvframe == NULL)
- return NULL;
- return precvframe->rx_head;
-}
-
static inline u8 *recvframe_pull(struct recv_frame *precvframe, int sz)
{
/* rx_data += sz; move rx_data sz bytes hereafter */
diff --git a/drivers/staging/rtl8188eu/include/rtw_security.h b/drivers/staging/rtl8188eu/include/rtw_security.h
index 2663e60bb6c6..7100d6b01b32 100644
--- a/drivers/staging/rtl8188eu/include/rtw_security.h
+++ b/drivers/staging/rtl8188eu/include/rtw_security.h
@@ -255,42 +255,6 @@ static inline u32 rotr(u32 val, int bits)
#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16)
#define TE3(i) rotr(Te0[(i) & 0xff], 24)
-#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
- ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
-
-#define PUTU32(ct, st) { \
-(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \
-(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
-
-#define WPA_GET_BE32(a) ((((u32)(a)[0]) << 24) | (((u32)(a)[1]) << 16) | \
- (((u32)(a)[2]) << 8) | ((u32)(a)[3]))
-
-#define WPA_PUT_LE16(a, val) \
- do { \
- (a)[1] = ((u16)(val)) >> 8; \
- (a)[0] = ((u16)(val)) & 0xff; \
- } while (0)
-
-#define WPA_PUT_BE32(a, val) \
- do { \
- (a)[0] = (u8)((((u32)(val)) >> 24) & 0xff); \
- (a)[1] = (u8)((((u32)(val)) >> 16) & 0xff); \
- (a)[2] = (u8)((((u32)(val)) >> 8) & 0xff); \
- (a)[3] = (u8)(((u32)(val)) & 0xff); \
- } while (0)
-
-#define WPA_PUT_BE64(a, val) \
- do { \
- (a)[0] = (u8)(((u64)(val)) >> 56); \
- (a)[1] = (u8)(((u64)(val)) >> 48); \
- (a)[2] = (u8)(((u64)(val)) >> 40); \
- (a)[3] = (u8)(((u64)(val)) >> 32); \
- (a)[4] = (u8)(((u64)(val)) >> 24); \
- (a)[5] = (u8)(((u64)(val)) >> 16); \
- (a)[6] = (u8)(((u64)(val)) >> 8); \
- (a)[7] = (u8)(((u64)(val)) & 0xff); \
- } while (0)
-
/* ===== start - public domain SHA256 implementation ===== */
/* This is based on SHA256 implementation in LibTomCrypt that was released into
diff --git a/drivers/staging/rtl8188eu/include/wifi.h b/drivers/staging/rtl8188eu/include/wifi.h
index 9e08e6842eca..5630dcb1dd46 100644
--- a/drivers/staging/rtl8188eu/include/wifi.h
+++ b/drivers/staging/rtl8188eu/include/wifi.h
@@ -23,7 +23,6 @@
#define WLAN_HDR_A4_LEN 30
#define WLAN_HDR_A3_QOS_LEN 26
#define WLAN_HDR_A4_QOS_LEN 32
-#define WLAN_SSID_MAXLEN 32
#define WLAN_DATA_MAXLEN 2312
#define WLAN_A3_PN_OFFSET 24
@@ -480,15 +479,6 @@ static inline int IsFrameTypeCtrl(unsigned char *pframe)
Below is the definition for 802.11n
------------------------------------------------------------------------------*/
-#define SetOrderBit(pbuf) \
- do { \
- *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \
- } while (0)
-
-#define GetOrderBit(pbuf) \
- (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0)
-
-
/**
* struct rtw_ieee80211_bar - HT Block Ack Request
*
@@ -653,9 +643,6 @@ enum ht_cap_ampdu_factor {
#define WPS_ATTR_VENDOR_EXT 0x1049
#define WPS_ATTR_SELECTED_REGISTRAR 0x1041
-/* Value of WPS attribute "WPS_ATTR_DEVICE_NAME */
-#define WPS_MAX_DEVICE_NAME_LEN 32
-
/* Value of WPS Request Type Attribute */
#define WPS_REQ_TYPE_ENROLLEE_INFO_ONLY 0x00
#define WPS_REQ_TYPE_ENROLLEE_OPEN_8021X 0x01
@@ -758,14 +745,6 @@ enum ht_cap_ampdu_factor {
#define P2P_STATUS_FAIL_USER_REJECT 0x0B
/* Value of Invitation Flags Attribute */
-#define P2P_INVITATION_FLAGS_PERSISTENT BIT(0)
-
-#define DMP_P2P_DEVCAP_SUPPORT (P2P_DEVCAP_SERVICE_DISCOVERY | \
- P2P_DEVCAP_CLIENT_DISCOVERABILITY | \
- P2P_DEVCAP_CONCURRENT_OPERATION | \
- P2P_DEVCAP_INVITATION_PROC)
-
-#define DMP_P2P_GRPCAP_SUPPORT (P2P_GRPCAP_INTRABSS)
/* Value of Device Capability Bitmap */
#define P2P_DEVCAP_SERVICE_DISCOVERY BIT(0)
@@ -804,13 +783,8 @@ enum ht_cap_ampdu_factor {
#define P2P_PRESENCE_RESPONSE 2
#define P2P_GO_DISC_REQUEST 3
-
-#define P2P_MAX_PERSISTENT_GROUP_NUM 10
-
#define P2P_PROVISIONING_SCAN_CNT 3
-#define P2P_WILDCARD_SSID_LEN 7
-
/* default value, used when: (1)p2p disabled or (2)p2p enabled
* but only do 1 scan phase */
#define P2P_FINDPHASE_EX_NONE 0
@@ -839,8 +813,6 @@ enum ht_cap_ampdu_factor {
#define P2P_RESET_SCAN_CH 25000
#define P2P_MAX_INTENT 15
-#define P2P_MAX_NOA_NUM 2
-
/* WPS Configuration Method */
#define WPS_CM_NONE 0x0000
#define WPS_CM_LABEL 0x0004
@@ -855,64 +827,6 @@ enum ht_cap_ampdu_factor {
#define WPS_CM_SW_DISPLAY_P 0x2008
#define WPS_CM_LCD_DISPLAY_P 0x4008
-enum P2P_ROLE {
- P2P_ROLE_DISABLE = 0,
- P2P_ROLE_DEVICE = 1,
- P2P_ROLE_CLIENT = 2,
- P2P_ROLE_GO = 3
-};
-
-enum P2P_STATE {
- P2P_STATE_NONE = 0, /* P2P disable */
- /* P2P had enabled and do nothing */
- P2P_STATE_IDLE = 1,
- P2P_STATE_LISTEN = 2, /* In pure listen state */
- P2P_STATE_SCAN = 3, /* In scan phase */
- /* In the listen state of find phase */
- P2P_STATE_FIND_PHASE_LISTEN = 4,
- /* In the search state of find phase */
- P2P_STATE_FIND_PHASE_SEARCH = 5,
- /* In P2P provisioning discovery */
- P2P_STATE_TX_PROVISION_DIS_REQ = 6,
- P2P_STATE_RX_PROVISION_DIS_RSP = 7,
- P2P_STATE_RX_PROVISION_DIS_REQ = 8,
- /* Doing the group owner negotiation handshake */
- P2P_STATE_GONEGO_ING = 9,
- /* finish the group negotiation handshake with success */
- P2P_STATE_GONEGO_OK = 10,
- /* finish the group negotiation handshake with failure */
- P2P_STATE_GONEGO_FAIL = 11,
- /* receiving the P2P Invitation request and match with the profile. */
- P2P_STATE_RECV_INVITE_REQ_MATCH = 12,
- /* Doing the P2P WPS */
- P2P_STATE_PROVISIONING_ING = 13,
- /* Finish the P2P WPS */
- P2P_STATE_PROVISIONING_DONE = 14,
- /* Transmit the P2P Invitation request */
- P2P_STATE_TX_INVITE_REQ = 15,
- /* Receiving the P2P Invitation response */
- P2P_STATE_RX_INVITE_RESP_OK = 16,
- /* receiving the P2P Invitation request and dismatch with the profile. */
- P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17,
- /* receiving the P2P Invitation request and this wifi is GO. */
- P2P_STATE_RECV_INVITE_REQ_GO = 18,
- /* receiving the P2P Invitation request to join an existing P2P Group. */
- P2P_STATE_RECV_INVITE_REQ_JOIN = 19,
- /* receiving the P2P Invitation response with failure */
- P2P_STATE_RX_INVITE_RESP_FAIL = 20,
- /* receiving p2p negotiation response with information is not available */
- P2P_STATE_RX_INFOR_NOREADY = 21,
- /* sending p2p negotiation response with information is not available */
- P2P_STATE_TX_INFOR_NOREADY = 22,
-};
-
-enum P2P_WPSINFO {
- P2P_NO_WPSINFO = 0,
- P2P_GOT_WPSINFO_PEER_DISPLAY_PIN = 1,
- P2P_GOT_WPSINFO_SELF_DISPLAY_PIN = 2,
- P2P_GOT_WPSINFO_PBC = 3,
-};
-
#define P2P_PRIVATE_IOCTL_SET_LEN 64
enum P2P_PROTO_WK_ID {
@@ -925,21 +839,6 @@ enum P2P_PROTO_WK_ID {
P2P_RO_CH_WK = 6,
};
-enum P2P_PS_STATE {
- P2P_PS_DISABLE = 0,
- P2P_PS_ENABLE = 1,
- P2P_PS_SCAN = 2,
- P2P_PS_SCAN_DONE = 3,
- P2P_PS_ALLSTASLEEP = 4, /* for P2P GO */
-};
-
-enum P2P_PS_MODE {
- P2P_PS_NONE = 0,
- P2P_PS_CTWINDOW = 1,
- P2P_PS_NOA = 2,
- P2P_PS_MIX = 3, /* CTWindow and NoA */
-};
-
/* =====================WFD Section===================== */
/* For Wi-Fi Display */
#define WFD_ATTR_DEVICE_INFO 0x00
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index 4de9dbc93380..763eccd0c7c9 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -134,6 +134,7 @@ static char *translate_scan(struct adapter *padapter,
if (p && ht_ielen > 0) {
struct ieee80211_ht_cap *pht_capie;
ht_cap = true;
+
pht_capie = (struct ieee80211_ht_cap *)(p + 2);
memcpy(&mcs_rate, pht_capie->mcs.rx_mask, 2);
bw_40MHz = !!(le16_to_cpu(pht_capie->cap_info) &
@@ -285,8 +286,8 @@ static char *translate_scan(struct adapter *padapter,
uint cnt = 0, total_ielen;
u8 *wpsie_ptr = NULL;
uint wps_ielen = 0;
-
u8 *ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
+
total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
while (cnt < total_ielen) {
@@ -442,7 +443,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param,
struct sta_info *psta, *pbcmc_sta;
struct sta_priv *pstapriv = &padapter->stapriv;
- if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) { /* sta mode */
+ if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { /* sta mode */
psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
if (!psta) {
;
@@ -523,6 +524,7 @@ static int rtw_set_wpa_ie(struct adapter *padapter, char *pie, unsigned short ie
/* dump */
{
int i;
+
DBG_88E("\n wpa_ie(length:%d):\n", ielen);
for (i = 0; i < ielen; i += 8)
DBG_88E("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n", buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
@@ -1084,14 +1086,9 @@ static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
struct ndis_802_11_ssid ssid[RTW_SSID_SCAN_AMOUNT];
+
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_set_scan\n"));
- if (padapter->registrypriv.mp_mode == 1) {
- if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
- ret = -1;
- goto exit;
- }
- }
if (_FAIL == rtw_pwr_wakeup(padapter)) {
ret = -1;
goto exit;
@@ -1225,6 +1222,7 @@ static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
u32 cnt = 0;
u32 wait_for_surveydone;
int wait_status;
+
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_wx_get_scan\n"));
RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_, (" Start of Query SIOCGIWSCAN .\n"));
@@ -1613,6 +1611,7 @@ static int rtw_wx_set_enc(struct net_device *dev,
struct iw_point *erq = &(wrqu->encoding);
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+
DBG_88E("+rtw_wx_set_enc, flags = 0x%x\n", erq->flags);
memset(&wep, 0, sizeof(struct ndis_802_11_wep));
diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c
index 8fc3fadf065f..5f6a24546a91 100644
--- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c
+++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c
@@ -413,7 +413,6 @@ static u8 rtw_init_default_value(struct adapter *padapter)
/* misc. */
padapter->bReadPortCancel = false;
padapter->bWritePortCancel = false;
- padapter->bRxRSSIDisplay = 0;
return _SUCCESS;
}
@@ -426,7 +425,6 @@ u8 rtw_reset_drv_sw(struct adapter *padapter)
rtw_hal_def_value_init(padapter);
padapter->bReadPortCancel = false;
padapter->bWritePortCancel = false;
- padapter->bRxRSSIDisplay = 0;
pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */
padapter->xmitpriv.tx_pkts = 0;
diff --git a/drivers/staging/rtl8188eu/os_dep/osdep_service.c b/drivers/staging/rtl8188eu/os_dep/osdep_service.c
index 6ff836f481da..3be87252fd62 100644
--- a/drivers/staging/rtl8188eu/os_dep/osdep_service.c
+++ b/drivers/staging/rtl8188eu/os_dep/osdep_service.c
@@ -21,18 +21,6 @@
#include <linux/vmalloc.h>
#include <rtw_ioctl_set.h>
-/*
- * Translate the OS dependent @param error_code to OS independent
- * RTW_STATUS_CODE
- * @return: one of RTW_STATUS_CODE
- */
-inline int RTW_STATUS_CODE(int error_code)
-{
- if (error_code >= 0)
- return _SUCCESS;
- return _FAIL;
-}
-
u8 *_rtw_malloc(u32 sz)
{
return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
@@ -41,8 +29,8 @@ u8 *_rtw_malloc(u32 sz)
void *rtw_malloc2d(int h, int w, int size)
{
int j;
-
void **a = kzalloc(h * sizeof(void *) + h * w * size, GFP_KERNEL);
+
if (!a)
goto out;
diff --git a/drivers/staging/rtl8188eu/os_dep/recv_linux.c b/drivers/staging/rtl8188eu/os_dep/recv_linux.c
index b85824ec5354..df4bcef95d05 100644
--- a/drivers/staging/rtl8188eu/os_dep/recv_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/recv_linux.c
@@ -88,27 +88,12 @@ int rtw_recv_indicatepkt(struct adapter *padapter,
goto _recv_indicatepkt_drop;
}
- RT_TRACE(_module_recv_osdep_c_, _drv_info_,
- ("rtw_recv_indicatepkt():skb != NULL !!!\n"));
- RT_TRACE(_module_recv_osdep_c_, _drv_info_,
- ("rtw_recv_indicatepkt():precv_frame->rx_head =%p precv_frame->hdr.rx_data =%p\n",
- precv_frame->rx_head, precv_frame->rx_data));
- RT_TRACE(_module_recv_osdep_c_, _drv_info_,
- ("precv_frame->hdr.rx_tail =%p precv_frame->rx_end =%p precv_frame->hdr.len =%d\n",
- precv_frame->rx_tail, precv_frame->rx_end,
- precv_frame->len));
-
skb->data = precv_frame->rx_data;
skb_set_tail_pointer(skb, precv_frame->len);
skb->len = precv_frame->len;
- RT_TRACE(_module_recv_osdep_c_, _drv_info_,
- ("skb->head =%p skb->data =%p skb->tail =%p skb->end =%p skb->len =%d\n",
- skb->head, skb->data, skb_tail_pointer(skb),
- skb_end_pointer(skb), skb->len));
-
if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
struct sk_buff *pskb2 = NULL;
struct sta_info *psta = NULL;
diff --git a/drivers/staging/rtl8188eu/os_dep/rtw_android.c b/drivers/staging/rtl8188eu/os_dep/rtw_android.c
index 41e1b1d15b81..336e7023f7f7 100644
--- a/drivers/staging/rtl8188eu/os_dep/rtw_android.c
+++ b/drivers/staging/rtl8188eu/os_dep/rtw_android.c
@@ -73,6 +73,7 @@ static int g_wifi_on = true;
int rtw_android_cmdstr_to_num(char *cmdstr)
{
int cmd_num;
+
for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++)
if (0 == strncasecmp(cmdstr, android_wifi_cmd_str[cmd_num],
strlen(android_wifi_cmd_str[cmd_num])))
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_intf.c b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
index c6316ffa64d3..963235fd7292 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_intf.c
@@ -83,6 +83,7 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
for (i = 0; i < piface_desc->bNumEndpoints; i++) {
int ep_num;
+
pendp_desc = &phost_iface->endpoint[i].desc;
ep_num = usb_endpoint_num(pendp_desc);
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
index e2dbe1b4afd3..fd5cb8a008f2 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
@@ -125,7 +125,6 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb)
if (pkt_copy) {
pkt_copy->dev = adapt->pnetdev;
precvframe->pkt = pkt_copy;
- precvframe->rx_head = pkt_copy->data;
precvframe->rx_end = pkt_copy->data + alloc_sz;
skb_reserve(pkt_copy, 8 - ((size_t)(pkt_copy->data) & 7));/* force pkt_copy->data at 8-byte alignment address */
skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */
@@ -133,22 +132,9 @@ static int recvbuf2recvframe(struct adapter *adapt, struct sk_buff *pskb)
precvframe->rx_tail = pkt_copy->data;
precvframe->rx_data = pkt_copy->data;
} else {
- if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
- DBG_88E("recvbuf2recvframe: alloc_skb fail , drop frag frame\n");
- rtw_free_recvframe(precvframe, pfree_recv_queue);
- goto _exit_recvbuf2recvframe;
- }
- precvframe->pkt = skb_clone(pskb, GFP_ATOMIC);
- if (precvframe->pkt) {
- precvframe->rx_tail = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE;
- precvframe->rx_head = precvframe->rx_tail;
- precvframe->rx_data = precvframe->rx_tail;
- precvframe->rx_end = pbuf + pattrib->drvinfo_sz + RXDESC_SIZE + alloc_sz;
- } else {
- DBG_88E("recvbuf2recvframe: skb_clone fail\n");
- rtw_free_recvframe(precvframe, pfree_recv_queue);
- goto _exit_recvbuf2recvframe;
- }
+ DBG_88E("recvbuf2recvframe: alloc_skb fail , drop frag frame\n");
+ rtw_free_recvframe(precvframe, pfree_recv_queue);
+ goto _exit_recvbuf2recvframe;
}
recvframe_put(precvframe, skb_len);
@@ -471,7 +457,7 @@ u32 usb_read_port(struct adapter *adapter, u32 addr, struct recv_buf *precvbuf)
if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
- if (NULL != precvbuf->pskb)
+ if (precvbuf->pskb != NULL)
precvbuf->reuse = true;
}
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
index 8a9172aa8178..4c0caa6701a9 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c
@@ -2695,10 +2695,8 @@ static void _rtl92e_pci_disconnect(struct pci_dev *pdev)
priv->polling_timer_on = 0;
_rtl92e_down(dev, true);
rtl92e_dm_deinit(dev);
- if (priv->pFirmware) {
- vfree(priv->pFirmware);
- priv->pFirmware = NULL;
- }
+ vfree(priv->pFirmware);
+ priv->pFirmware = NULL;
_rtl92e_free_rx_ring(dev);
for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
_rtl92e_free_tx_ring(dev, i);
@@ -2797,9 +2795,9 @@ MODULE_FIRMWARE(RTL8192E_BOOT_IMG_FW);
MODULE_FIRMWARE(RTL8192E_MAIN_IMG_FW);
MODULE_FIRMWARE(RTL8192E_DATA_IMG_FW);
-module_param(ifname, charp, S_IRUGO|S_IWUSR);
-module_param(hwwep, int, S_IRUGO|S_IWUSR);
-module_param(channels, int, S_IRUGO|S_IWUSR);
+module_param(ifname, charp, 0644);
+module_param(hwwep, int, 0644);
+module_param(channels, int, 0644);
MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default");
MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support(default use hw. set 0 to use software security)");
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
index d7d85b3f19c4..f0e9885326fe 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
@@ -2766,7 +2766,7 @@ static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
{
/* This is called when wpa_supplicant loads and closes the driver
* interface. */
- printk("%s WPA\n",value ? "enabling" : "disabling");
+ printk("%s WPA\n", value ? "enabling" : "disabling");
ieee->wpa_enabled = value;
return 0;
}
@@ -2869,7 +2869,7 @@ static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
{
- int ret=0;
+ int ret = 0;
unsigned long flags;
switch (name) {
@@ -2878,7 +2878,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v
break;
case IEEE_PARAM_TKIP_COUNTERMEASURES:
- ieee->tkip_countermeasures=value;
+ ieee->tkip_countermeasures = value;
break;
case IEEE_PARAM_DROP_UNENCRYPTED: {
@@ -2915,7 +2915,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v
}
case IEEE_PARAM_PRIVACY_INVOKED:
- ieee->privacy_invoked=value;
+ ieee->privacy_invoked = value;
break;
case IEEE_PARAM_AUTH_ALGS:
@@ -2923,7 +2923,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v
break;
case IEEE_PARAM_IEEE_802_1X:
- ieee->ieee802_1x=value;
+ ieee->ieee802_1x = value;
break;
case IEEE_PARAM_WPAX_SELECT:
// added for WPA2 mixed mode
@@ -2934,7 +2934,7 @@ static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 v
break;
default:
- printk("Unknown WPA param: %d\n",name);
+ printk("Unknown WPA param: %d\n", name);
ret = -EOPNOTSUPP;
}
@@ -3107,7 +3107,7 @@ static inline struct sk_buff *ieee80211_disassociate_skb(
if (!skb)
return NULL;
- disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
+ disass = (struct ieee80211_disassoc *) skb_put(skb, sizeof(struct ieee80211_disassoc));
disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
disass->header.duration_id = 0;
@@ -3129,7 +3129,7 @@ SendDisassociation(
{
struct ieee80211_network *beacon = &ieee->current_network;
struct sk_buff *skb;
- skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
+ skb = ieee80211_disassociate_skb(beacon, ieee, asRsn);
if (skb) {
softmac_mgmt_xmit(skb, ieee);
//dev_kfree_skb_any(skb);//edit by thomas
@@ -3140,7 +3140,7 @@ EXPORT_SYMBOL(SendDisassociation);
int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
{
struct ieee_param *param;
- int ret=0;
+ int ret = 0;
mutex_lock(&ieee->wx_mutex);
//IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
index 1ab0aead298b..2b0e1b4b2345 100644
--- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
@@ -250,7 +250,7 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
memset(txb, 0, sizeof(struct ieee80211_txb));
txb->nr_frags = nr_frags;
- txb->frag_size = txb_size;
+ txb->frag_size = __cpu_to_le16(txb_size);
for (i = 0; i < nr_frags; i++) {
txb->fragments[i] = dev_alloc_skb(txb_size);
@@ -752,7 +752,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
goto failed;
}
txb->encrypted = encrypt;
- txb->payload_size = bytes;
+ txb->payload_size = __cpu_to_le16(bytes);
//if (ieee->current_network.QoS_Enable)
if(qos_actived)
@@ -859,7 +859,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
}
txb->encrypted = 0;
- txb->payload_size = skb->len;
+ txb->payload_size = __cpu_to_le16(skb->len);
memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
}
@@ -896,7 +896,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
}else{
if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
stats->tx_packets++;
- stats->tx_bytes += txb->payload_size;
+ stats->tx_bytes += __le16_to_cpu(txb->payload_size);
return 0;
}
ieee80211_txb_free(txb);
diff --git a/drivers/staging/rtl8192u/r8180_93cx6.h b/drivers/staging/rtl8192u/r8180_93cx6.h
index 9cf7f587c3ab..643d465e7105 100644
--- a/drivers/staging/rtl8192u/r8180_93cx6.h
+++ b/drivers/staging/rtl8192u/r8180_93cx6.h
@@ -1,17 +1,17 @@
/*
- This is part of rtl8187 OpenSource driver
- Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
- Released under the terms of GPL (General Public Licence)
-
- Parts of this driver are based on the GPL part of the
- official realtek driver
- Parts of this driver are based on the rtl8180 driver skeleton
- from Patric Schenke & Andres Salomon
- Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
- We want to thank the Authors of such projects and the Ndiswrapper
- project Authors.
-*/
+ * This is part of rtl8187 OpenSource driver
+ * Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
+ * Released under the terms of GPL (General Public Licence)
+ *
+ * Parts of this driver are based on the GPL part of the
+ * official realtek driver
+ * Parts of this driver are based on the rtl8180 driver skeleton
+ * from Patric Schenke & Andres Salomon
+ * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
+ *
+ * We want to thank the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ */
/*This files contains card eeprom (93c46 or 93c56) programming routines*/
/*memory is addressed by WORDS*/
@@ -39,5 +39,4 @@
#define EPROM_TXPW2 0x1b
#define EPROM_TXPW1 0x3d
-
int eprom_read(struct net_device *dev, u32 addr); /* reads a 16 bits word */
diff --git a/drivers/staging/rtl8192u/r819xU_cmdpkt.c b/drivers/staging/rtl8192u/r819xU_cmdpkt.c
index 545f49ec9c03..1168d133522e 100644
--- a/drivers/staging/rtl8192u/r819xU_cmdpkt.c
+++ b/drivers/staging/rtl8192u/r819xU_cmdpkt.c
@@ -133,11 +133,8 @@ static void cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb)
priv->stats.txretrycount += pstx_fb->retry_cnt;
priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
-
}
-
-
/*-----------------------------------------------------------------------------
* Function: cmpk_handle_tx_feedback()
*
@@ -178,7 +175,6 @@ static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg)
/* Collect info TX feedback packet to fill TCB. */
/* We can not know the packet length and transmit type: broadcast or uni
or multicast. */
-
}
static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev)
@@ -187,9 +183,9 @@ static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev)
u16 tx_rate;
/* 87B have to S/W beacon for DTM encryption_cmn. */
if (priv->ieee80211->current_network.mode == IEEE_A ||
- priv->ieee80211->current_network.mode == IEEE_N_5G ||
- (priv->ieee80211->current_network.mode == IEEE_N_24G &&
- (!priv->ieee80211->pHTInfo->bCurSuppCCK))) {
+ priv->ieee80211->current_network.mode == IEEE_N_5G ||
+ (priv->ieee80211->current_network.mode == IEEE_N_24G &&
+ (!priv->ieee80211->pHTInfo->bCurSuppCCK))) {
tx_rate = 60;
DMESG("send beacon frame tx rate is 6Mbpm\n");
} else {
@@ -198,13 +194,8 @@ static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev)
}
rtl819xusb_beacon_tx(dev, tx_rate); /* HW Beacon */
-
-
}
-
-
-
/*-----------------------------------------------------------------------------
* Function: cmpk_handle_interrupt_status()
*
@@ -242,7 +233,6 @@ static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg)
return;
}
-
/* Statistics of beacon for ad-hoc mode. */
if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) {
/* 2 maybe need endian transform? */
@@ -261,17 +251,13 @@ static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg)
if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
cmdpkt_beacontimerinterrupt_819xusb(dev);
-
}
/* Other informations in interrupt status we need? */
-
DMESG("<---- cmpk_handle_interrupt_status()\n");
-
}
-
/*-----------------------------------------------------------------------------
* Function: cmpk_handle_query_config_rx()
*
@@ -295,7 +281,6 @@ static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg)
{
cmpk_query_cfg_t rx_query_cfg;
-
/* 1. Extract TX feedback info from RFD to temp structure buffer. */
/* It seems that FW use big endian(MIPS) and DRV use little endian in
windows OS. So we have to read the content byte by byte or transfer
@@ -309,10 +294,8 @@ static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg)
(pmsg[10] << 8) | (pmsg[11] << 0);
rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) |
(pmsg[14] << 8) | (pmsg[15] << 0);
-
}
-
/*-----------------------------------------------------------------------------
* Function: cmpk_count_tx_status()
*
@@ -374,8 +357,6 @@ static void cmpk_count_tx_status(struct net_device *dev,
priv->stats.last_packet_rate = pstx_status->rate;
}
-
-
/*-----------------------------------------------------------------------------
* Function: cmpk_handle_tx_status()
*
@@ -400,10 +381,8 @@ static void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg)
memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(cmpk_tx_status_t));
/* 2. Use tx feedback info to count TX statistics. */
cmpk_count_tx_status(dev, &rx_tx_sts);
-
}
-
/*-----------------------------------------------------------------------------
* Function: cmpk_handle_tx_rate_history()
*
@@ -428,7 +407,6 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg)
u32 *ptemp;
struct r8192_priv *priv = ieee80211_priv(dev);
-
#ifdef ENABLE_PS
pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE,
(pu1Byte)(&rtState));
@@ -469,10 +447,8 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg)
for (j = 0; j < 4; j++)
priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
}
-
}
-
/*-----------------------------------------------------------------------------
* Function: cmpk_message_handle_rx()
*
@@ -567,5 +543,4 @@ u32 cmpk_message_handle_rx(struct net_device *dev,
pcmd_buff += cmd_length;
}
return 1; /* This is a command packet. */
-
}
diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c
index 0dd458d1402c..c83d7ebb164f 100644
--- a/drivers/staging/rtl8712/hal_init.c
+++ b/drivers/staging/rtl8712/hal_init.c
@@ -117,16 +117,16 @@ static void fill_fwpriv(struct _adapter *padapter, struct fw_priv *pfwpriv)
static void update_fwhdr(struct fw_hdr *pfwhdr, const u8 *pmappedfw)
{
- pfwhdr->signature = le16_to_cpu(*(u16 *)pmappedfw);
- pfwhdr->version = le16_to_cpu(*(u16 *)(pmappedfw + 2));
+ pfwhdr->signature = le16_to_cpu(*(__le16 *)pmappedfw);
+ pfwhdr->version = le16_to_cpu(*(__le16 *)(pmappedfw + 2));
/* define the size of boot loader */
- pfwhdr->dmem_size = le32_to_cpu(*(uint *)(pmappedfw + 4));
+ pfwhdr->dmem_size = le32_to_cpu(*(__le32 *)(pmappedfw + 4));
/* define the size of FW in IMEM */
- pfwhdr->img_IMEM_size = le32_to_cpu(*(uint *)(pmappedfw + 8));
+ pfwhdr->img_IMEM_size = le32_to_cpu(*(__le32 *)(pmappedfw + 8));
/* define the size of FW in SRAM */
- pfwhdr->img_SRAM_size = le32_to_cpu(*(uint *)(pmappedfw + 12));
+ pfwhdr->img_SRAM_size = le32_to_cpu(*(__le32 *)(pmappedfw + 12));
/* define the size of DMEM variable */
- pfwhdr->fw_priv_sz = le32_to_cpu(*(uint *)(pmappedfw + 16));
+ pfwhdr->fw_priv_sz = le32_to_cpu(*(__le32 *)(pmappedfw + 16));
}
static u8 chk_fwhdr(struct fw_hdr *pfwhdr, u32 ulfilelength)
diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c
index 5dc3b5b9bfff..d84da2b6d6b3 100644
--- a/drivers/staging/rtl8712/ieee80211.c
+++ b/drivers/staging/rtl8712/ieee80211.c
@@ -174,16 +174,16 @@ int r8712_generate_ie(struct registry_priv *pregistrypriv)
sz += 8;
ie += sz;
/*beacon interval : 2bytes*/
- *(u16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);
+ *(__le16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);
sz += 2;
ie += 2;
/*capability info*/
*(u16 *)ie = 0;
- *(u16 *)ie |= cpu_to_le16(cap_IBSS);
+ *(__le16 *)ie |= cpu_to_le16(cap_IBSS);
if (pregistrypriv->preamble == PREAMBLE_SHORT)
- *(u16 *)ie |= cpu_to_le16(cap_ShortPremble);
+ *(__le16 *)ie |= cpu_to_le16(cap_ShortPremble);
if (pdev_network->Privacy)
- *(u16 *)ie |= cpu_to_le16(cap_Privacy);
+ *(__le16 *)ie |= cpu_to_le16(cap_Privacy);
sz += 2;
ie += 2;
/*SSID*/
@@ -202,10 +202,10 @@ int r8712_generate_ie(struct registry_priv *pregistrypriv)
rateLen, pdev_network->rates, &sz);
/*DS parameter set*/
ie = r8712_set_ie(ie, _DSSET_IE_, 1,
- (u8 *)&(pdev_network->Configuration.DSConfig), &sz);
+ (u8 *)&pdev_network->Configuration.DSConfig, &sz);
/*IBSS Parameter Set*/
ie = r8712_set_ie(ie, _IBSS_PARA_IE_, 2,
- (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz);
+ (u8 *)&pdev_network->Configuration.ATIMWindow, &sz);
return sz;
}
@@ -224,7 +224,7 @@ unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit)
goto check_next_ie;
/*check version...*/
memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16));
- val16 = le16_to_cpu(val16);
+ le16_to_cpus(&val16);
if (val16 != 0x0001)
goto check_next_ie;
*wpa_ie_len = *(pbuf + 1);
@@ -304,7 +304,7 @@ int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
}
/*pairwise_cipher*/
if (left >= 2) {
- count = le16_to_cpu(*(u16 *)pos);
+ count = le16_to_cpu(*(__le16 *)pos);
pos += 2;
left -= 2;
if (count == 0 || left < count * WPA_SELECTOR_LEN)
@@ -347,7 +347,7 @@ int r8712_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher,
}
/*pairwise_cipher*/
if (left >= 2) {
- count = le16_to_cpu(*(u16 *)pos);
+ count = le16_to_cpu(*(__le16 *)pos);
pos += 2;
left -= 2;
if (count == 0 || left < count * RSN_SELECTOR_LEN)
diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c
index af7c4a47738a..999c16d9c6c1 100644
--- a/drivers/staging/rtl8712/mlme_linux.c
+++ b/drivers/staging/rtl8712/mlme_linux.c
@@ -117,7 +117,7 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter)
backupTKIPCountermeasure = adapter->securitypriv.
btkip_countermeasure;
memset((unsigned char *)&adapter->securitypriv, 0,
- sizeof(struct security_priv));
+ sizeof(struct security_priv));
setup_timer(&adapter->securitypriv.tkip_timer,
r8712_use_tkipkey_handler,
(unsigned long)adapter);
@@ -125,8 +125,8 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter)
* for the following connection.
*/
memcpy(&adapter->securitypriv.PMKIDList[0],
- &backupPMKIDList[0],
- sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
+ &backupPMKIDList[0],
+ sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE);
adapter->securitypriv.PMKIDIndex = backupPMKIDIndex;
adapter->securitypriv.btkip_countermeasure =
backupTKIPCountermeasure;
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c
index 9f61583af150..f19b6b27aa71 100644
--- a/drivers/staging/rtl8712/rtl8712_cmd.c
+++ b/drivers/staging/rtl8712/rtl8712_cmd.c
@@ -314,7 +314,8 @@ void r8712_fw_cmd_data(struct _adapter *pAdapter, u32 *value, u8 flag)
int r8712_cmd_thread(void *context)
{
struct cmd_obj *pcmd;
- unsigned int cmdsz, wr_sz, *pcmdbuf;
+ unsigned int cmdsz, wr_sz;
+ __le32 *pcmdbuf;
struct tx_desc *pdesc;
void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd);
struct _adapter *padapter = context;
@@ -334,7 +335,7 @@ _next:
r8712_unregister_cmd_alive(padapter);
continue;
}
- pcmdbuf = (unsigned int *)pcmdpriv->cmd_buf;
+ pcmdbuf = (__le32 *)pcmdpriv->cmd_buf;
pdesc = (struct tx_desc *)pcmdbuf;
memset(pdesc, 0, TXDESC_SIZE);
pcmd = cmd_hdl_filter(padapter, pcmd);
@@ -424,7 +425,7 @@ _next:
thread_exit();
}
-void r8712_event_handle(struct _adapter *padapter, uint *peventbuf)
+void r8712_event_handle(struct _adapter *padapter, __le32 *peventbuf)
{
u8 evt_code, evt_seq;
u16 evt_sz;
diff --git a/drivers/staging/rtl8712/rtl8712_event.h b/drivers/staging/rtl8712/rtl8712_event.h
index 29a4c23a0d23..b38374025c93 100644
--- a/drivers/staging/rtl8712/rtl8712_event.h
+++ b/drivers/staging/rtl8712/rtl8712_event.h
@@ -26,7 +26,7 @@
#ifndef _RTL8712_EVENT_H_
#define _RTL8712_EVENT_H_
-void r8712_event_handle(struct _adapter *padapter, uint *peventbuf);
+void r8712_event_handle(struct _adapter *padapter, __le32 *peventbuf);
void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf);
enum rtl8712_c2h_event {
diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c
index 66f0e0a35167..20fe45a43e53 100644
--- a/drivers/staging/rtl8712/rtl8712_recv.c
+++ b/drivers/staging/rtl8712/rtl8712_recv.c
@@ -408,7 +408,7 @@ static int amsdu_to_msdu(struct _adapter *padapter, union recv_frame *prframe)
memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst,
ETH_ALEN);
} else {
- u16 len;
+ __be16 len;
/* Leave Ethernet header part of hdr and full payload */
len = htons(sub_skb->len);
memcpy(skb_push(sub_skb, 2), &len, 2);
@@ -439,21 +439,21 @@ exit:
void r8712_rxcmd_event_hdl(struct _adapter *padapter, void *prxcmdbuf)
{
- uint voffset;
+ __le32 voffset;
u8 *poffset;
u16 cmd_len, drvinfo_sz;
struct recv_stat *prxstat;
poffset = (u8 *)prxcmdbuf;
- voffset = *(uint *)poffset;
+ voffset = *(__le32 *)poffset;
prxstat = (struct recv_stat *)prxcmdbuf;
drvinfo_sz = (le32_to_cpu(prxstat->rxdw0) & 0x000f0000) >> 16;
drvinfo_sz <<= 3;
poffset += RXDESC_SIZE + drvinfo_sz;
do {
- voffset = *(uint *)poffset;
+ voffset = *(__le32 *)poffset;
cmd_len = (u16)(le32_to_cpu(voffset) & 0xffff);
- r8712_event_handle(padapter, (uint *)poffset);
+ r8712_event_handle(padapter, (__le32 *)poffset);
poffset += (cmd_len + 8);/*8 bytes alignment*/
} while (le32_to_cpu(voffset) & BIT(31));
@@ -758,7 +758,7 @@ static void query_rx_phy_status(struct _adapter *padapter,
/* CCK Driver info Structure is not the same as OFDM packet.*/
pcck_buf = (struct phy_cck_rx_status *)pphy_stat;
/* (1)Hardware does not provide RSSI for CCK
- * (2)PWDB, Average PWDB cacluated by hardware
+ * (2)PWDB, Average PWDB calculated by hardware
* (for rate adaptive)
*/
if (!cck_highpwr) {
@@ -853,7 +853,7 @@ static void query_rx_phy_status(struct _adapter *padapter,
rssi = query_rx_pwr_percentage(rx_pwr[i]);
total_rssi += rssi;
}
- /* (2)PWDB, Average PWDB cacluated by hardware (for
+ /* (2)PWDB, Average PWDB calculated by hardware (for
* rate adaptive)
*/
rx_pwr_all = (((pphy_head[PHY_STAT_PWDB_ALL_SHT]) >> 1) & 0x7f)
diff --git a/drivers/staging/rtl8712/rtl8712_recv.h b/drivers/staging/rtl8712/rtl8712_recv.h
index 0b0c2730aac5..0352e6fafd90 100644
--- a/drivers/staging/rtl8712/rtl8712_recv.h
+++ b/drivers/staging/rtl8712/rtl8712_recv.h
@@ -50,12 +50,12 @@
#define REORDER_WAIT_TIME 30 /* (ms)*/
struct recv_stat {
- unsigned int rxdw0;
- unsigned int rxdw1;
- unsigned int rxdw2;
- unsigned int rxdw3;
- unsigned int rxdw4;
- unsigned int rxdw5;
+ __le32 rxdw0;
+ __le32 rxdw1;
+ __le32 rxdw2;
+ __le32 rxdw3;
+ __le32 rxdw4;
+ __le32 rxdw5;
};
struct phy_cck_rx_status {
@@ -69,14 +69,14 @@ struct phy_cck_rx_status {
};
struct phy_stat {
- unsigned int phydw0;
- unsigned int phydw1;
- unsigned int phydw2;
- unsigned int phydw3;
- unsigned int phydw4;
- unsigned int phydw5;
- unsigned int phydw6;
- unsigned int phydw7;
+ __le32 phydw0;
+ __le32 phydw1;
+ __le32 phydw2;
+ __le32 phydw3;
+ __le32 phydw4;
+ __le32 phydw5;
+ __le32 phydw6;
+ __le32 phydw7;
};
#define PHY_STAT_GAIN_TRSW_SHT 0
#define PHY_STAT_PWDB_ALL_SHT 4
diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c
index c4f03a602a2e..041508d6ec6d 100644
--- a/drivers/staging/rtl8712/rtl8712_xmit.c
+++ b/drivers/staging/rtl8712/rtl8712_xmit.c
@@ -302,7 +302,7 @@ u8 r8712_append_mpdu_unit(struct xmit_buf *pxmitbuf,
int last_txcmdsz = 0;
int padding_sz = 0;
- /* 802.3->802.11 convertor */
+ /* 802.3->802.11 converter */
r8712_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
/* free skb struct */
r8712_xmit_complete(padapter, pxmitframe);
diff --git a/drivers/staging/rtl8712/rtl8712_xmit.h b/drivers/staging/rtl8712/rtl8712_xmit.h
index b50e7a1f3a42..02b1593ada01 100644
--- a/drivers/staging/rtl8712/rtl8712_xmit.h
+++ b/drivers/staging/rtl8712/rtl8712_xmit.h
@@ -91,14 +91,14 @@
struct tx_desc {
/*DWORD 0*/
- unsigned int txdw0;
- unsigned int txdw1;
- unsigned int txdw2;
- unsigned int txdw3;
- unsigned int txdw4;
- unsigned int txdw5;
- unsigned int txdw6;
- unsigned int txdw7;
+ __le32 txdw0;
+ __le32 txdw1;
+ __le32 txdw2;
+ __le32 txdw3;
+ __le32 txdw4;
+ __le32 txdw5;
+ __le32 txdw6;
+ __le32 txdw7;
};
diff --git a/drivers/staging/rtl8712/rtl871x_cmd.h b/drivers/staging/rtl8712/rtl871x_cmd.h
index 3284dcf2f1a9..4734ca856aa2 100644
--- a/drivers/staging/rtl8712/rtl871x_cmd.h
+++ b/drivers/staging/rtl8712/rtl871x_cmd.h
@@ -156,9 +156,9 @@ struct setopmode_parm {
* Command-Event Mode
*/
struct sitesurvey_parm {
- sint passive_mode; /*active: 1, passive: 0 */
- sint bsslimit; /* 1 ~ 48 */
- sint ss_ssidlen;
+ __le32 passive_mode; /*active: 1, passive: 0 */
+ __le32 bsslimit; /* 1 ~ 48 */
+ __le32 ss_ssidlen;
u8 ss_ssid[IW_ESSID_MAX_SIZE + 1];
};
diff --git a/drivers/staging/rtl8712/rtl871x_event.h b/drivers/staging/rtl8712/rtl871x_event.h
index 697c8d735150..5db8620980e5 100644
--- a/drivers/staging/rtl8712/rtl871x_event.h
+++ b/drivers/staging/rtl8712/rtl871x_event.h
@@ -66,7 +66,7 @@ struct joinbss_event {
struct stassoc_event {
unsigned char macaddr[6];
unsigned char rsvd[2];
- int cam_id;
+ __le32 cam_id;
};
struct stadel_event {
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
index 590acb5aea3d..0dc18d6bff28 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -199,7 +199,7 @@ static noinline_for_stack char *translate_scan(struct _adapter *padapter,
iwe.cmd = SIOCGIWMODE;
memcpy((u8 *)&cap, r8712_get_capability_from_ie(pnetwork->network.IEs),
2);
- cap = le16_to_cpu(cap);
+ le16_to_cpus(&cap);
if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
if (cap & WLAN_CAPABILITY_BSS)
iwe.u.mode = (u32)IW_MODE_MASTER;
@@ -2322,7 +2322,7 @@ static struct iw_statistics *r871x_get_wireless_stats(struct net_device *dev)
piwstats->qual.level = 0;
piwstats->qual.noise = 0;
} else {
- /* show percentage, we need transfer dbm to orignal value. */
+ /* show percentage, we need transfer dbm to original value. */
tmp_level = padapter->recvpriv.fw_rssi;
tmp_qual = padapter->recvpriv.signal;
tmp_noise = padapter->recvpriv.noise;
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c
index 35cbdc71cad4..fd8d96df02a6 100644
--- a/drivers/staging/rtl8712/rtl871x_mlme.c
+++ b/drivers/staging/rtl8712/rtl871x_mlme.c
@@ -257,10 +257,10 @@ int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork)
struct security_priv *psecuritypriv = &adapter->securitypriv;
if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) &&
- (pnetwork->network.Privacy == 0))
+ (pnetwork->network.Privacy == cpu_to_le32(0)))
ret = false;
else if ((psecuritypriv->PrivacyAlgrthm == _NO_PRIVACY_) &&
- (pnetwork->network.Privacy == 1))
+ (pnetwork->network.Privacy == cpu_to_le32(1)))
ret = false;
else
ret = true;
@@ -933,7 +933,7 @@ void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf)
return;
/* to do : init sta_info variable */
psta->qos_option = 0;
- psta->mac_id = le32_to_cpu((uint)pstassoc->cam_id);
+ psta->mac_id = le32_to_cpu(pstassoc->cam_id);
/* psta->aid = (uint)pstassoc->cam_id; */
if (adapter->securitypriv.AuthAlgrthm == 2)
@@ -1637,14 +1637,14 @@ void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
pdev_network->Rssi = 0;
switch (pregistrypriv->wireless_mode) {
case WIRELESS_11B:
- pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11DS);
+ pdev_network->NetworkTypeInUse = Ndis802_11DS;
break;
case WIRELESS_11G:
case WIRELESS_11BG:
- pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM24);
+ pdev_network->NetworkTypeInUse = Ndis802_11OFDM24;
break;
case WIRELESS_11A:
- pdev_network->NetworkTypeInUse = cpu_to_le32(Ndis802_11OFDM5);
+ pdev_network->NetworkTypeInUse = Ndis802_11OFDM5;
break;
default:
/* TODO */
@@ -1654,8 +1654,7 @@ void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
pregistrypriv->channel);
if (cur_network->network.InfrastructureMode == Ndis802_11IBSS)
pdev_network->Configuration.ATIMWindow = cpu_to_le32(3);
- pdev_network->InfrastructureMode = cpu_to_le32(
- cur_network->network.InfrastructureMode);
+ pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode;
/* 1. Supported rates
* 2. IE
*/
diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
index b98a596757f5..6e264a8d0087 100644
--- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
+++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
@@ -202,7 +202,7 @@ static int mp_start_test(struct _adapter *padapter)
res = _FAIL;
goto end_of_mp_start_test;
}
- /* 3 3. join psudo AdHoc */
+ /* 3 3. join pseudo AdHoc */
tgt_network->join_res = 1;
tgt_network->aid = psta->aid = 1;
memcpy(&tgt_network->network, &bssid, length);
@@ -227,7 +227,7 @@ static int mp_stop_test(struct _adapter *padapter)
spin_lock_irqsave(&pmlmepriv->lock, irqL);
if (!check_fwstate(pmlmepriv, WIFI_MP_STATE))
goto end_of_mp_stop_test;
- /* 3 1. disconnect psudo AdHoc */
+ /* 3 1. disconnect pseudo AdHoc */
r8712_os_indicate_disconnect(padapter);
/* 3 2. clear psta used in mp test mode. */
psta = r8712_get_stainfo(&padapter->stapriv,
diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
index 35c721a50598..147b75beea73 100644
--- a/drivers/staging/rtl8712/rtl871x_recv.c
+++ b/drivers/staging/rtl8712/rtl871x_recv.c
@@ -258,7 +258,7 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter,
/* get ether_type */
ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
memcpy(&ether_type, ptr, 2);
- ether_type = ntohs((unsigned short)ether_type);
+ be16_to_cpus(&ether_type);
if ((psta != NULL) && (psta->ieee8021x_blocked)) {
/* blocked
@@ -640,11 +640,16 @@ sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe)
/* append rx status for mp test packets */
ptr = recvframe_pull(precvframe, (rmv_len -
sizeof(struct ethhdr) + 2) - 24);
+ if (!ptr)
+ return _FAIL;
memcpy(ptr, get_rxmem(precvframe), 24);
ptr += 24;
- } else
+ } else {
ptr = recvframe_pull(precvframe, (rmv_len -
sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
+ if (!ptr)
+ return _FAIL;
+ }
memcpy(ptr, pattrib->dst, ETH_ALEN);
memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c
index a7f04a4b089d..bd83fb492c45 100644
--- a/drivers/staging/rtl8712/rtl871x_security.c
+++ b/drivers/staging/rtl8712/rtl871x_security.c
@@ -192,7 +192,7 @@ void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe)
length = pattrib->last_txcmdsz - pattrib->
hdrlen - pattrib->iv_len -
pattrib->icv_len;
- *((u32 *)crc) = cpu_to_le32(getcrc32(
+ *((__le32 *)crc) = cpu_to_le32(getcrc32(
payload, length));
arcfour_init(&mycontext, wepkey, 3 + keylength);
arcfour_encrypt(&mycontext, payload, payload,
@@ -203,7 +203,7 @@ void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe)
length = pxmitpriv->frag_len -
pattrib->hdrlen - pattrib->iv_len -
pattrib->icv_len;
- *((u32 *)crc) = cpu_to_le32(getcrc32(
+ *((__le32 *)crc) = cpu_to_le32(getcrc32(
payload, length));
arcfour_init(&mycontext, wepkey, 3 + keylength);
arcfour_encrypt(&mycontext, payload, payload,
@@ -248,7 +248,7 @@ void r8712_wep_decrypt(struct _adapter *padapter, u8 *precvframe)
arcfour_init(&mycontext, wepkey, 3 + keylength);
arcfour_encrypt(&mycontext, payload, payload, length);
/* calculate icv and compare the icv */
- *((u32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4));
+ *((__le32 *)crc) = cpu_to_le32(getcrc32(payload, length - 4));
}
}
@@ -616,7 +616,7 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe)
pattrib->hdrlen -
pattrib->iv_len -
pattrib->icv_len;
- *((u32 *)crc) = cpu_to_le32(
+ *((__le32 *)crc) = cpu_to_le32(
getcrc32(payload, length));
arcfour_init(&mycontext, rc4key, 16);
arcfour_encrypt(&mycontext, payload,
@@ -628,7 +628,7 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe)
pattrib->hdrlen -
pattrib->iv_len -
pattrib->icv_len;
- *((u32 *)crc) = cpu_to_le32(getcrc32(
+ *((__le32 *)crc) = cpu_to_le32(getcrc32(
payload, length));
arcfour_init(&mycontext, rc4key, 16);
arcfour_encrypt(&mycontext, payload,
@@ -696,7 +696,7 @@ u32 r8712_tkip_decrypt(struct _adapter *padapter, u8 *precvframe)
/* 4 decrypt payload include icv */
arcfour_init(&mycontext, rc4key, 16);
arcfour_encrypt(&mycontext, payload, payload, length);
- *((u32 *)crc) = cpu_to_le32(getcrc32(payload,
+ *((__le32 *)crc) = cpu_to_le32(getcrc32(payload,
length - 4));
if (crc[3] != payload[length - 1] ||
crc[2] != payload[length - 2] ||
@@ -833,7 +833,7 @@ static void mix_column(u8 *in, u8 *out)
u8 add1b[4];
u8 add1bf7[4];
u8 rotl[4];
- u8 swap_halfs[4];
+ u8 swap_halves[4];
u8 andf7[4];
u8 rotr[4];
u8 temp[4];
@@ -845,10 +845,10 @@ static void mix_column(u8 *in, u8 *out)
else
add1b[i] = 0x00;
}
- swap_halfs[0] = in[2]; /* Swap halves */
- swap_halfs[1] = in[3];
- swap_halfs[2] = in[0];
- swap_halfs[3] = in[1];
+ swap_halves[0] = in[2]; /* Swap halves */
+ swap_halves[1] = in[3];
+ swap_halves[2] = in[0];
+ swap_halves[3] = in[1];
rotl[0] = in[3]; /* Rotate left 8 bits */
rotl[1] = in[0];
rotl[2] = in[1];
@@ -872,7 +872,7 @@ static void mix_column(u8 *in, u8 *out)
rotr[2] = rotr[3];
rotr[3] = temp[0];
xor_32(add1bf7, rotr, temp);
- xor_32(swap_halfs, rotl, tempb);
+ xor_32(swap_halves, rotl, tempb);
xor_32(temp, tempb, out);
}
@@ -1047,8 +1047,8 @@ static sint aes_cipher(u8 *key, uint hdrlen,
u8 aes_out[16];
u8 padded_buffer[16];
u8 mic[8];
- uint frtype = GetFrameType(pframe);
- uint frsubtype = GetFrameSubType(pframe);
+ u16 frtype = GetFrameType(pframe);
+ u16 frsubtype = GetFrameSubType(pframe);
frsubtype >>= 4;
memset((void *)mic_iv, 0, 16);
diff --git a/drivers/staging/rtl8712/usb_ops.c b/drivers/staging/rtl8712/usb_ops.c
index 9172400efe9a..332e2e51d778 100644
--- a/drivers/staging/rtl8712/usb_ops.c
+++ b/drivers/staging/rtl8712/usb_ops.c
@@ -41,7 +41,7 @@ static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
u16 wvalue;
u16 index;
u16 len;
- u32 data;
+ __le32 data;
struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
request = 0x05;
@@ -61,7 +61,7 @@ static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
u16 wvalue;
u16 index;
u16 len;
- u32 data;
+ __le32 data;
struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
request = 0x05;
@@ -81,7 +81,7 @@ static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
u16 wvalue;
u16 index;
u16 len;
- u32 data;
+ __le32 data;
struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
request = 0x05;
@@ -101,7 +101,7 @@ static void usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
u16 wvalue;
u16 index;
u16 len;
- u32 data;
+ __le32 data;
struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
request = 0x05;
@@ -109,8 +109,7 @@ static void usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
index = 0;
wvalue = (u16)(addr & 0x0000ffff);
len = 1;
- data = val;
- data = cpu_to_le32(data & 0x000000ff);
+ data = cpu_to_le32((u32)val & 0x000000ff);
r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len,
requesttype);
}
@@ -122,7 +121,7 @@ static void usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
u16 wvalue;
u16 index;
u16 len;
- u32 data;
+ __le32 data;
struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
request = 0x05;
@@ -130,8 +129,7 @@ static void usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
index = 0;
wvalue = (u16)(addr & 0x0000ffff);
len = 2;
- data = val;
- data = cpu_to_le32(data & 0x0000ffff);
+ data = cpu_to_le32((u32)val & 0x0000ffff);
r8712_usbctrl_vendorreq(pintfpriv, request, wvalue, index, &data, len,
requesttype);
}
@@ -143,7 +141,7 @@ static void usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
u16 wvalue;
u16 index;
u16 len;
- u32 data;
+ __le32 data;
struct intf_priv *pintfpriv = pintfhdl->pintfpriv;
request = 0x05;
diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c
index fc6bb0be2a28..441e76b8959d 100644
--- a/drivers/staging/rtl8712/usb_ops_linux.c
+++ b/drivers/staging/rtl8712/usb_ops_linux.c
@@ -192,7 +192,8 @@ void r8712_usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
static void r8712_usb_read_port_complete(struct urb *purb)
{
- uint isevt, *pbuf;
+ uint isevt;
+ __le32 *pbuf;
struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
struct _adapter *padapter = (struct _adapter *)precvbuf->adapter;
struct recv_priv *precvpriv = &padapter->recvpriv;
@@ -208,7 +209,7 @@ static void r8712_usb_read_port_complete(struct urb *purb)
_pkt *pskb = precvbuf->pskb;
precvbuf->transfer_len = purb->actual_length;
- pbuf = (uint *)precvbuf->pbuf;
+ pbuf = (__le32 *)precvbuf->pbuf;
isevt = le32_to_cpu(*(pbuf + 1)) & 0x1ff;
if ((isevt & 0x1ff) == 0x1ff) {
r8712_rxcmd_event_hdl(padapter, pbuf);
diff --git a/drivers/staging/rtl8712/wifi.h b/drivers/staging/rtl8712/wifi.h
index b8af9656e6da..7ebf247b2aff 100644
--- a/drivers/staging/rtl8712/wifi.h
+++ b/drivers/staging/rtl8712/wifi.h
@@ -229,7 +229,7 @@ enum WIFI_REG_DOMAIN {
#define GetOrder(pbuf) (((*(unsigned short *)(pbuf)) & \
le16_to_cpu(_ORDER_)) != 0)
-#define GetFrameType(pbuf) (le16_to_cpu(*(unsigned short *)(pbuf)) & \
+#define GetFrameType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & \
(BIT(3) | BIT(2)))
#define SetFrameType(pbuf, type) \
@@ -239,7 +239,7 @@ enum WIFI_REG_DOMAIN {
*(unsigned short *)(pbuf) |= cpu_to_le16(type); \
} while (0)
-#define GetFrameSubType(pbuf) (cpu_to_le16(*(unsigned short *)(pbuf)) & \
+#define GetFrameSubType(pbuf) (le16_to_cpu(*(__le16 *)(pbuf)) & \
(BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | \
BIT(2)))
diff --git a/drivers/staging/rtl8712/wlan_bssdef.h b/drivers/staging/rtl8712/wlan_bssdef.h
index 86a88b493a43..c0654ae4d70d 100644
--- a/drivers/staging/rtl8712/wlan_bssdef.h
+++ b/drivers/staging/rtl8712/wlan_bssdef.h
@@ -83,7 +83,7 @@ struct wlan_bssid_ex {
unsigned char MacAddress[6];
u8 Reserved[2];
struct ndis_802_11_ssid Ssid;
- u32 Privacy;
+ __le32 Privacy;
s32 Rssi;
enum NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
struct NDIS_802_11_CONFIGURATION Configuration;
diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c
index 4d8e7c5c26d5..23799013c432 100644
--- a/drivers/staging/rts5208/rtsx_transport.c
+++ b/drivers/staging/rts5208/rtsx_transport.c
@@ -207,7 +207,7 @@ handle_errors:
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);
+ __le32 *cb = (__le32 *)(chip->host_cmds_ptr);
u32 val = 0;
val |= (u32)(cmd_type & 0x03) << 30;
@@ -300,7 +300,7 @@ finish_send_cmd:
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);
+ __le64 *sgb = (__le64 *)(chip->host_sg_tbl_ptr);
u64 val = 0;
u32 temp_len = 0;
u8 temp_opt = 0;
diff --git a/drivers/staging/skein/skein_base.c b/drivers/staging/skein/skein_base.c
index c24a57396483..8db858a11875 100644
--- a/drivers/staging/skein/skein_base.c
+++ b/drivers/staging/skein/skein_base.c
@@ -1,12 +1,12 @@
/***********************************************************************
-**
-** Implementation of the Skein hash function.
-**
-** Source code author: Doug Whiting, 2008.
-**
-** This algorithm and source code is released to the public domain.
-**
-************************************************************************/
+ **
+ ** Implementation of the Skein hash function.
+ **
+ ** Source code author: Doug Whiting, 2008.
+ **
+ ** This algorithm and source code is released to the public domain.
+ **
+ ************************************************************************/
#include <linux/string.h> /* get the memcpy/memset functions */
#include <linux/export.h>
diff --git a/drivers/staging/skein/skein_base.h b/drivers/staging/skein/skein_base.h
index dc464f334a58..cd794c1bc1bb 100644
--- a/drivers/staging/skein/skein_base.h
+++ b/drivers/staging/skein/skein_base.h
@@ -1,28 +1,30 @@
#ifndef _SKEIN_H_
#define _SKEIN_H_ 1
-/**************************************************************************
-**
-** Interface declarations and internal definitions for Skein hashing.
-**
-** Source code author: Doug Whiting, 2008.
-**
-** This algorithm and source code is released to the public domain.
-**
-***************************************************************************
-**
-** The following compile-time switches may be defined to control some
-** tradeoffs between speed, code size, error checking, and security.
-**
-** The "default" note explains what happens when the switch is not defined.
-**
-** SKEIN_ERR_CHECK -- how error checking is handled inside Skein
-** code. If not defined, most error checking
-** is disabled (for performance). Otherwise,
-** the switch value is interpreted as:
-** 0: use assert() to flag errors
-** 1: return SKEIN_FAIL to flag errors
-**
-***************************************************************************/
+/*
+ **************************************************************************
+ *
+ * Interface declarations and internal definitions for Skein hashing.
+ *
+ * Source code author: Doug Whiting, 2008.
+ *
+ * This algorithm and source code is released to the public domain.
+ *
+ **************************************************************************
+ *
+ * The following compile-time switches may be defined to control some
+ * tradeoffs between speed, code size, error checking, and security.
+ *
+ * The "default" note explains what happens when the switch is not defined.
+ *
+ * SKEIN_ERR_CHECK -- how error checking is handled inside Skein
+ * code. If not defined, most error checking
+ * is disabled (for performance). Otherwise,
+ * the switch value is interpreted as:
+ * 0: use assert() to flag errors
+ * 1: return SKEIN_FAIL to flag errors
+ *
+ **************************************************************************
+ */
/*Skein digest sizes for crypto api*/
#define SKEIN256_DIGEST_BIT_SIZE 256
@@ -101,19 +103,19 @@ int skein_512_final(struct skein_512_ctx *ctx, u8 *hash_val);
int skein_1024_final(struct skein_1024_ctx *ctx, u8 *hash_val);
/*
-** Skein APIs for "extended" initialization: MAC keys, tree hashing.
-** After an init_ext() call, just use update/final calls as with init().
-**
-** Notes: Same parameters as _init() calls, plus tree_info/key/key_bytes.
-** When key_bytes == 0 and tree_info == SKEIN_SEQUENTIAL,
-** the results of init_ext() are identical to calling init().
-** The function init() may be called once to "precompute" the IV for
-** a given hash_bit_len value, then by saving a copy of the context
-** the IV computation may be avoided in later calls.
-** Similarly, the function init_ext() may be called once per MAC key
-** to precompute the MAC IV, then a copy of the context saved and
-** reused for each new MAC computation.
-**/
+ * Skein APIs for "extended" initialization: MAC keys, tree hashing.
+ * After an init_ext() call, just use update/final calls as with init().
+ *
+ * Notes: Same parameters as _init() calls, plus tree_info/key/key_bytes.
+ * When key_bytes == 0 and tree_info == SKEIN_SEQUENTIAL,
+ * the results of init_ext() are identical to calling init().
+ * The function init() may be called once to "precompute" the IV for
+ * a given hash_bit_len value, then by saving a copy of the context
+ * the IV computation may be avoided in later calls.
+ * Similarly, the function init_ext() may be called once per MAC key
+ * to precompute the MAC IV, then a copy of the context saved and
+ * reused for each new MAC computation.
+ */
int skein_256_init_ext(struct skein_256_ctx *ctx, size_t hash_bit_len,
u64 tree_info, const u8 *key, size_t key_bytes);
int skein_512_init_ext(struct skein_512_ctx *ctx, size_t hash_bit_len,
@@ -122,10 +124,10 @@ int skein_1024_init_ext(struct skein_1024_ctx *ctx, size_t hash_bit_len,
u64 tree_info, const u8 *key, size_t key_bytes);
/*
-** Skein APIs for MAC and tree hash:
-** final_pad: pad, do final block, but no OUTPUT type
-** output: do just the output stage
-*/
+ * Skein APIs for MAC and tree hash:
+ * final_pad: pad, do final block, but no OUTPUT type
+ * output: do just the output stage
+ */
int skein_256_final_pad(struct skein_256_ctx *ctx, u8 *hash_val);
int skein_512_final_pad(struct skein_512_ctx *ctx, u8 *hash_val);
int skein_1024_final_pad(struct skein_1024_ctx *ctx, u8 *hash_val);
@@ -139,13 +141,15 @@ int skein_512_output(struct skein_512_ctx *ctx, u8 *hash_val);
int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val);
#endif
-/*****************************************************************
-** "Internal" Skein definitions
-** -- not needed for sequential hashing API, but will be
-** helpful for other uses of Skein (e.g., tree hash mode).
-** -- included here so that they can be shared between
-** reference and optimized code.
-******************************************************************/
+/*
+ *****************************************************************
+ * "Internal" Skein definitions
+ * -- not needed for sequential hashing API, but will be
+ * helpful for other uses of Skein (e.g., tree hash mode).
+ * -- included here so that they can be shared between
+ * reference and optimized code.
+ *****************************************************************
+ */
/* tweak word tweak[1]: bit field starting positions */
#define SKEIN_T1_BIT(BIT) ((BIT) - 64) /* second word */
@@ -226,9 +230,9 @@ int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val);
#define SKEIN_CFG_TREE_INFO_SEQUENTIAL SKEIN_CFG_TREE_INFO(0, 0, 0)
/*
-** Skein macros for getting/setting tweak words, etc.
-** These are useful for partial input bytes, hash tree init/update, etc.
-**/
+ * Skein macros for getting/setting tweak words, etc.
+ * These are useful for partial input bytes, hash tree init/update, etc.
+ */
#define skein_get_tweak(ctx_ptr, TWK_NUM) ((ctx_ptr)->h.tweak[TWK_NUM])
#define skein_set_tweak(ctx_ptr, TWK_NUM, t_val) { \
(ctx_ptr)->h.tweak[TWK_NUM] = (t_val); \
@@ -274,9 +278,11 @@ int skein_1024_output(struct skein_1024_ctx *ctx, u8 *hash_val);
#define skein_assert_ret(x, ret_code)
#define skein_assert(x)
-/*****************************************************************
-** Skein block function constants (shared across Ref and Opt code)
-******************************************************************/
+/*
+ *****************************************************************
+ * Skein block function constants (shared across Ref and Opt code)
+ *****************************************************************
+ */
enum {
/* SKEIN_256 round rotation constants */
R_256_0_0 = 14, R_256_0_1 = 16,
diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c
index 59a0a8a82118..256657077a46 100644
--- a/drivers/staging/skein/skein_block.c
+++ b/drivers/staging/skein/skein_block.c
@@ -1,18 +1,20 @@
-/***********************************************************************
-**
-** Implementation of the Skein block functions.
-**
-** Source code author: Doug Whiting, 2008.
-**
-** This algorithm and source code is released to the public domain.
-**
-** Compile-time switches:
-**
-** SKEIN_USE_ASM -- set bits (256/512/1024) to select which
-** versions use ASM code for block processing
-** [default: use C for all block sizes]
-**
-************************************************************************/
+/*
+ ***********************************************************************
+ *
+ * Implementation of the Skein block functions.
+ *
+ * Source code author: Doug Whiting, 2008.
+ *
+ * This algorithm and source code is released to the public domain.
+ *
+ * Compile-time switches:
+ *
+ * SKEIN_USE_ASM -- set bits (256/512/1024) to select which
+ * versions use ASM code for block processing
+ * [default: use C for all block sizes]
+ *
+ ***********************************************************************
+ */
#include <linux/string.h>
#include <linux/bitops.h>
diff --git a/drivers/staging/skein/skein_block.h b/drivers/staging/skein/skein_block.h
index 9d40f4a5267b..ec1baea25c9e 100644
--- a/drivers/staging/skein/skein_block.h
+++ b/drivers/staging/skein/skein_block.h
@@ -1,12 +1,14 @@
-/***********************************************************************
-**
-** Implementation of the Skein hash function.
-**
-** Source code author: Doug Whiting, 2008.
-**
-** This algorithm and source code is released to the public domain.
-**
-************************************************************************/
+/*
+ ***********************************************************************
+ *
+ * Implementation of the Skein hash function.
+ *
+ * Source code author: Doug Whiting, 2008.
+ *
+ * This algorithm and source code is released to the public domain.
+ *
+ ***********************************************************************
+ */
#ifndef _SKEIN_BLOCK_H_
#define _SKEIN_BLOCK_H_
diff --git a/drivers/staging/skein/skein_iv.h b/drivers/staging/skein/skein_iv.h
index 8a06314d0ed4..509d464c65a3 100644
--- a/drivers/staging/skein/skein_iv.h
+++ b/drivers/staging/skein/skein_iv.h
@@ -4,18 +4,18 @@
#include "skein_base.h" /* get Skein macros and types */
/*
-***************** Pre-computed Skein IVs *******************
-**
-** NOTE: these values are not "magic" constants, but
-** are generated using the Threefish block function.
-** They are pre-computed here only for speed; i.e., to
-** avoid the need for a Threefish call during Init().
-**
-** The IV for any fixed hash length may be pre-computed.
-** Only the most common values are included here.
-**
-************************************************************
-**/
+ **************** Pre-computed Skein IVs *******************
+ *
+ * NOTE: these values are not "magic" constants, but
+ * are generated using the Threefish block function.
+ * They are pre-computed here only for speed; i.e., to
+ * avoid the need for a Threefish call during Init().
+ *
+ * The IV for any fixed hash length may be pre-computed.
+ * Only the most common values are included here.
+ *
+ ***********************************************************
+ */
#define MK_64 SKEIN_MK_64
diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c
index f59ce5c0867d..9aaf1fdad08d 100644
--- a/drivers/staging/sm750fb/ddk750_chip.c
+++ b/drivers/staging/sm750fb/ddk750_chip.c
@@ -25,8 +25,9 @@ void sm750_set_chip_type(unsigned short devId, u8 revId)
chip = SM750LE;
pr_info("found sm750le\n");
}
- } else
+ } else {
chip = SM_UNKNOWN;
+ }
}
static unsigned int get_mxclk_freq(void)
@@ -244,7 +245,6 @@ int ddk750_init_hw(struct initchip_param *pInitParam)
/* Set up master clock */
set_master_clock(MHz(pInitParam->masterClock));
-
/*
* Reset the memory controller.
* If the memory controller is not reset in SM750,
@@ -407,5 +407,3 @@ unsigned int sm750_format_pll_reg(struct pll_value *pPLL)
return reg;
}
-
-
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index e9632f162f99..ee741c012b92 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -100,7 +100,6 @@ static const struct fb_videomode lynx750_ext[] = {
FB_VMODE_NONINTERLACED},
};
-
/* no hardware cursor supported under version 2.6.10, kernel bug */
static int lynxfb_ops_cursor(struct fb_info *info, struct fb_cursor *fbcursor)
{
@@ -974,10 +973,12 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
else {
if (!g_fbmode[0]) {
g_fbmode[0] = opt;
- dev_info(&sm750_dev->pdev->dev, "find fbmode0 : %s\n", g_fbmode[0]);
+ dev_info(&sm750_dev->pdev->dev,
+ "find fbmode0 : %s\n", g_fbmode[0]);
} else if (!g_fbmode[1]) {
g_fbmode[1] = opt;
- dev_info(&sm750_dev->pdev->dev, "find fbmode1 : %s\n", g_fbmode[1]);
+ dev_info(&sm750_dev->pdev->dev,
+ "find fbmode1 : %s\n", g_fbmode[1]);
} else {
dev_warn(&sm750_dev->pdev->dev, "How many view you wann set?\n");
}
diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c
index e744aa9730ff..4e7ebc306488 100644
--- a/drivers/staging/speakup/kobjects.c
+++ b/drivers/staging/speakup/kobjects.c
@@ -865,66 +865,66 @@ static struct kobj_attribute version_attribute =
__ATTR_RO(version);
static struct kobj_attribute delimiters_attribute =
- __ATTR(delimiters, S_IWUSR | S_IRUGO, punc_show, punc_store);
+ __ATTR(delimiters, 0644, punc_show, punc_store);
static struct kobj_attribute ex_num_attribute =
- __ATTR(ex_num, S_IWUSR | S_IRUGO, punc_show, punc_store);
+ __ATTR(ex_num, 0644, punc_show, punc_store);
static struct kobj_attribute punc_all_attribute =
- __ATTR(punc_all, S_IWUSR | S_IRUGO, punc_show, punc_store);
+ __ATTR(punc_all, 0644, punc_show, punc_store);
static struct kobj_attribute punc_most_attribute =
- __ATTR(punc_most, S_IWUSR | S_IRUGO, punc_show, punc_store);
+ __ATTR(punc_most, 0644, punc_show, punc_store);
static struct kobj_attribute punc_some_attribute =
- __ATTR(punc_some, S_IWUSR | S_IRUGO, punc_show, punc_store);
+ __ATTR(punc_some, 0644, punc_show, punc_store);
static struct kobj_attribute repeats_attribute =
- __ATTR(repeats, S_IWUSR | S_IRUGO, punc_show, punc_store);
+ __ATTR(repeats, 0644, punc_show, punc_store);
static struct kobj_attribute attrib_bleep_attribute =
- __ATTR(attrib_bleep, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(attrib_bleep, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute bell_pos_attribute =
- __ATTR(bell_pos, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(bell_pos, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute bleep_time_attribute =
- __ATTR(bleep_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(bleep_time, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute bleeps_attribute =
- __ATTR(bleeps, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(bleeps, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute cursor_time_attribute =
- __ATTR(cursor_time, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(cursor_time, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute key_echo_attribute =
- __ATTR(key_echo, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(key_echo, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute no_interrupt_attribute =
- __ATTR(no_interrupt, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(no_interrupt, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute punc_level_attribute =
- __ATTR(punc_level, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(punc_level, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute reading_punc_attribute =
- __ATTR(reading_punc, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(reading_punc, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute say_control_attribute =
- __ATTR(say_control, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(say_control, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute say_word_ctl_attribute =
- __ATTR(say_word_ctl, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(say_word_ctl, 0644, spk_var_show, spk_var_store);
static struct kobj_attribute spell_delay_attribute =
- __ATTR(spell_delay, S_IWUSR | S_IRUGO, spk_var_show, spk_var_store);
+ __ATTR(spell_delay, 0644, spk_var_show, spk_var_store);
/*
* These attributes are i18n related.
*/
static struct kobj_attribute announcements_attribute =
- __ATTR(announcements, S_IWUSR | S_IRUGO, message_show, message_store);
+ __ATTR(announcements, 0644, message_show, message_store);
static struct kobj_attribute characters_attribute =
- __ATTR(characters, S_IWUSR | S_IRUGO, chars_chartab_show,
+ __ATTR(characters, 0644, chars_chartab_show,
chars_chartab_store);
static struct kobj_attribute chartab_attribute =
- __ATTR(chartab, S_IWUSR | S_IRUGO, chars_chartab_show,
+ __ATTR(chartab, 0644, chars_chartab_show,
chars_chartab_store);
static struct kobj_attribute ctl_keys_attribute =
- __ATTR(ctl_keys, S_IWUSR | S_IRUGO, message_show, message_store);
+ __ATTR(ctl_keys, 0644, message_show, message_store);
static struct kobj_attribute colors_attribute =
- __ATTR(colors, S_IWUSR | S_IRUGO, message_show, message_store);
+ __ATTR(colors, 0644, message_show, message_store);
static struct kobj_attribute formatted_attribute =
- __ATTR(formatted, S_IWUSR | S_IRUGO, message_show, message_store);
+ __ATTR(formatted, 0644, message_show, message_store);
static struct kobj_attribute function_names_attribute =
- __ATTR(function_names, S_IWUSR | S_IRUGO, message_show, message_store);
+ __ATTR(function_names, 0644, message_show, message_store);
static struct kobj_attribute key_names_attribute =
- __ATTR(key_names, S_IWUSR | S_IRUGO, message_show, message_store);
+ __ATTR(key_names, 0644, message_show, message_store);
static struct kobj_attribute states_attribute =
- __ATTR(states, S_IWUSR | S_IRUGO, message_show, message_store);
+ __ATTR(states, 0644, message_show, message_store);
/*
* Create groups of attributes so that we can create and destroy them all
diff --git a/drivers/staging/unisys/include/channel.h b/drivers/staging/unisys/include/channel.h
index 259ef6487959..1c95302f7f1b 100644
--- a/drivers/staging/unisys/include/channel.h
+++ b/drivers/staging/unisys/include/channel.h
@@ -21,11 +21,11 @@
#include <linux/uuid.h>
/*
-* Whenever this file is changed a corresponding change must be made in
-* the Console/ServicePart/visordiag_early/supervisor_channel.h file
-* which is needed for Linux kernel compiles. These two files must be
-* in sync.
-*/
+ * Whenever this file is changed a corresponding change must be made in
+ * the Console/ServicePart/visordiag_early/supervisor_channel.h file
+ * which is needed for Linux kernel compiles. These two files must be
+ * in sync.
+ */
/* define the following to prevent include nesting in kernel header
* files of similar abbreviated content
@@ -310,82 +310,82 @@ static inline int spar_check_channel_server(uuid_le typeuuid, char *name,
}
/*
-* Routine Description:
-* Tries to insert the prebuilt signal pointed to by pSignal into the nth
-* Queue of the Channel pointed to by pChannel
-*
-* Parameters:
-* pChannel: (IN) points to the IO Channel
-* Queue: (IN) nth Queue of the IO Channel
-* pSignal: (IN) pointer to the signal
-*
-* Assumptions:
-* - pChannel, Queue and pSignal are valid.
-* - If insertion fails due to a full queue, the caller will determine the
-* retry policy (e.g. wait & try again, report an error, etc.).
-*
-* Return value: 1 if the insertion succeeds, 0 if the queue was
-* full.
-*/
+ * Routine Description:
+ * Tries to insert the prebuilt signal pointed to by pSignal into the nth
+ * Queue of the Channel pointed to by pChannel
+ *
+ * Parameters:
+ * pChannel: (IN) points to the IO Channel
+ * Queue: (IN) nth Queue of the IO Channel
+ * pSignal: (IN) pointer to the signal
+ *
+ * Assumptions:
+ * - pChannel, Queue and pSignal are valid.
+ * - If insertion fails due to a full queue, the caller will determine the
+ * retry policy (e.g. wait & try again, report an error, etc.).
+ *
+ * Return value: 1 if the insertion succeeds, 0 if the queue was
+ * full.
+ */
unsigned char spar_signal_insert(struct channel_header __iomem *ch, u32 queue,
void *sig);
/*
-* Routine Description:
-* Removes one signal from Channel pChannel's nth Queue at the
-* time of the call and copies it into the memory pointed to by
-* pSignal.
-*
-* Parameters:
-* pChannel: (IN) points to the IO Channel
-* Queue: (IN) nth Queue of the IO Channel
-* pSignal: (IN) pointer to where the signals are to be copied
-*
-* Assumptions:
-* - pChannel and Queue are valid.
-* - pSignal points to a memory area large enough to hold queue's SignalSize
-*
-* Return value: 1 if the removal succeeds, 0 if the queue was
-* empty.
-*/
+ * Routine Description:
+ * Removes one signal from Channel pChannel's nth Queue at the
+ * time of the call and copies it into the memory pointed to by
+ * pSignal.
+ *
+ * Parameters:
+ * pChannel: (IN) points to the IO Channel
+ * Queue: (IN) nth Queue of the IO Channel
+ * pSignal: (IN) pointer to where the signals are to be copied
+ *
+ * Assumptions:
+ * - pChannel and Queue are valid.
+ * - pSignal points to a memory area large enough to hold queue's SignalSize
+ *
+ * Return value: 1 if the removal succeeds, 0 if the queue was
+ * empty.
+ */
unsigned char spar_signal_remove(struct channel_header __iomem *ch, u32 queue,
void *sig);
/*
-* Routine Description:
-* Removes all signals present in Channel pChannel's nth Queue at the
-* time of the call and copies them into the memory pointed to by
-* pSignal. Returns the # of signals copied as the value of the routine.
-*
-* Parameters:
-* pChannel: (IN) points to the IO Channel
-* Queue: (IN) nth Queue of the IO Channel
-* pSignal: (IN) pointer to where the signals are to be copied
-*
-* Assumptions:
-* - pChannel and Queue are valid.
-* - pSignal points to a memory area large enough to hold Queue's MaxSignals
-* # of signals, each of which is Queue's SignalSize.
-*
-* Return value:
-* # of signals copied.
-*/
+ * Routine Description:
+ * Removes all signals present in Channel pChannel's nth Queue at the
+ * time of the call and copies them into the memory pointed to by
+ * pSignal. Returns the # of signals copied as the value of the routine.
+ *
+ * Parameters:
+ * pChannel: (IN) points to the IO Channel
+ * Queue: (IN) nth Queue of the IO Channel
+ * pSignal: (IN) pointer to where the signals are to be copied
+ *
+ * Assumptions:
+ * - pChannel and Queue are valid.
+ * - pSignal points to a memory area large enough to hold Queue's MaxSignals
+ * # of signals, each of which is Queue's SignalSize.
+ *
+ * Return value:
+ * # of signals copied.
+ */
unsigned int spar_signal_remove_all(struct channel_header *ch, u32 queue,
void *sig);
/*
-* Routine Description:
-* Determine whether a signal queue is empty.
-*
-* Parameters:
-* pChannel: (IN) points to the IO Channel
-* Queue: (IN) nth Queue of the IO Channel
-*
-* Return value:
-* 1 if the signal queue is empty, 0 otherwise.
-*/
+ * Routine Description:
+ * Determine whether a signal queue is empty.
+ *
+ * Parameters:
+ * pChannel: (IN) points to the IO Channel
+ * Queue: (IN) nth Queue of the IO Channel
+ *
+ * Return value:
+ * 1 if the signal queue is empty, 0 otherwise.
+ */
unsigned char spar_signalqueue_empty(struct channel_header __iomem *ch,
u32 queue);
diff --git a/drivers/staging/unisys/visorbus/controlvmchannel.h b/drivers/staging/unisys/visorbus/controlvmchannel.h
index f0bfc4ded892..859345243afe 100644
--- a/drivers/staging/unisys/visorbus/controlvmchannel.h
+++ b/drivers/staging/unisys/visorbus/controlvmchannel.h
@@ -43,8 +43,6 @@
ULTRA_CONTROLVM_CHANNEL_PROTOCOL_VERSIONID, \
ULTRA_CONTROLVM_CHANNEL_PROTOCOL_SIGNATURE)
-#define MAX_SERIAL_NUM 32
-
/* Defines for various channel queues */
#define CONTROLVM_QUEUE_REQUEST 0
#define CONTROLVM_QUEUE_RESPONSE 1
@@ -436,26 +434,6 @@ struct spar_controlvm_channel_protocol {
struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX];
};
-/* Offsets for VM channel attributes */
-#define VM_CH_REQ_QUEUE_OFFSET \
- offsetof(struct spar_controlvm_channel_protocol, request_queue)
-#define VM_CH_RESP_QUEUE_OFFSET \
- offsetof(struct spar_controlvm_channel_protocol, response_queue)
-#define VM_CH_EVENT_QUEUE_OFFSET \
- offsetof(struct spar_controlvm_channel_protocol, event_queue)
-#define VM_CH_ACK_QUEUE_OFFSET \
- offsetof(struct spar_controlvm_channel_protocol, event_ack_queue)
-#define VM_CH_REQ_MSG_OFFSET \
- offsetof(struct spar_controlvm_channel_protocol, request_msg)
-#define VM_CH_RESP_MSG_OFFSET \
- offsetof(struct spar_controlvm_channel_protocol, response_msg)
-#define VM_CH_EVENT_MSG_OFFSET \
- offsetof(struct spar_controlvm_channel_protocol, event_msg)
-#define VM_CH_ACK_MSG_OFFSET \
- offsetof(struct spar_controlvm_channel_protocol, event_ack_msg)
-#define VM_CH_CRASH_MSG_OFFSET \
- offsetof(struct spar_controlvm_channel_protocol, saved_crash_msg)
-
/* The following header will be located at the beginning of PayloadVmOffset for
* various ControlVm commands. The receiver of a ControlVm command with a
* PayloadVmOffset will dereference this address and then use connection_offset,
@@ -484,56 +462,55 @@ struct spar_controlvm_parameters_header {
/* General Errors------------------------------------------------------[0-99] */
#define CONTROLVM_RESP_SUCCESS 0
-#define CONTROLVM_RESP_ERROR_ALREADY_DONE 1
-#define CONTROLVM_RESP_ERROR_IOREMAP_FAILED 2
-#define CONTROLVM_RESP_ERROR_KMALLOC_FAILED 3
-#define CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN 4
-#define CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT 5
+#define CONTROLVM_RESP_ALREADY_DONE 1
+#define CONTROLVM_RESP_IOREMAP_FAILED 2
+#define CONTROLVM_RESP_KMALLOC_FAILED 3
+#define CONTROLVM_RESP_ID_UNKNOWN 4
+#define CONTROLVM_RESP_ID_INVALID_FOR_CLIENT 5
/* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */
-#define CONTROLVM_RESP_ERROR_CLIENT_SWITCHCOUNT_NONZERO 100
-#define CONTROLVM_RESP_ERROR_EXPECTED_CHIPSET_INIT 101
+#define CONTROLVM_RESP_CLIENT_SWITCHCOUNT_NONZERO 100
+#define CONTROLVM_RESP_EXPECTED_CHIPSET_INIT 101
/* Maximum Limit----------------------------------------------------[200-299] */
#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 /* BUS_CREATE */
#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 /* DEVICE_CREATE */
/* Payload and Parameter Related------------------------------------[400-499] */
-#define CONTROLVM_RESP_ERROR_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT,
+#define CONTROLVM_RESP_PAYLOAD_INVALID 400 /* SWITCH_ATTACHEXTPORT,
* DEVICE_CONFIGURE
*/
-#define CONTROLVM_RESP_ERROR_INITIATOR_PARAMETER_INVALID 401 /* Multiple */
-#define CONTROLVM_RESP_ERROR_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */
-#define CONTROLVM_RESP_ERROR_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */
+#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 /* Multiple */
+#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 /* DEVICE_CONFIGURE */
+#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 /* DEVICE_CONFIGURE */
/* Specified[Packet Structure] Value-------------------------------[500-599] */
-#define CONTROLVM_RESP_ERROR_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT,
+#define CONTROLVM_RESP_BUS_INVALID 500 /* SWITCH_ATTACHINTPORT,
* BUS_CONFIGURE,
* DEVICE_CREATE,
* DEVICE_CONFIG
* DEVICE_DESTROY
*/
-#define CONTROLVM_RESP_ERROR_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT */
+#define CONTROLVM_RESP_DEVICE_INVALID 501 /* SWITCH_ATTACHINTPORT */
/* DEVICE_CREATE,
* DEVICE_CONFIGURE,
* DEVICE_DESTROY
*/
-#define CONTROLVM_RESP_ERROR_CHANNEL_INVALID 502 /* DEVICE_CREATE,
+#define CONTROLVM_RESP_CHANNEL_INVALID 502 /* DEVICE_CREATE,
* DEVICE_CONFIGURE
*/
/* Partition Driver Callback Interface----------------------[600-699] */
-#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE,
- * BUS_DESTROY,
- * DEVICE_CREATE,
- * DEVICE_DESTROY
- */
+#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 /* BUS_CREATE,
+ * BUS_DESTROY,
+ * DEVICE_CREATE,
+ * DEVICE_DESTROY
+ */
/* Unable to invoke VIRTPCI callback */
-#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR 605
- /* BUS_CREATE,
- * BUS_DESTROY,
- * DEVICE_CREATE,
- * DEVICE_DESTROY
- */
+#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 /* BUS_CREATE,
+ * BUS_DESTROY,
+ * DEVICE_CREATE,
+ * DEVICE_DESTROY
+ */
/* VIRTPCI Callback returned error */
-#define CONTROLVM_RESP_ERROR_GENERIC_DRIVER_CALLBACK_ERROR 606
+#define CONTROLVM_RESP_GENERIC_DRIVER_CALLBACK_ERROR 606
/* SWITCH_ATTACHEXTPORT,
* SWITCH_DETACHEXTPORT
* DEVICE_CONFIGURE
@@ -543,19 +520,19 @@ struct spar_controlvm_parameters_header {
/* Bus Related------------------------------------------------------[700-799] */
#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 /* BUS_DESTROY */
/* Channel Related--------------------------------------------------[800-899] */
-#define CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO,
+#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 /* GET_CHANNELINFO,
* DEVICE_DESTROY
*/
-#define CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */
+#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 /* DEVICE_CREATE */
/* Chipset Shutdown Related---------------------------------------[1000-1099] */
-#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_FAILED 1000
-#define CONTROLVM_RESP_ERROR_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001
+#define CONTROLVM_RESP_CHIPSET_SHUTDOWN_FAILED 1000
+#define CONTROLVM_RESP_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001
/* Chipset Stop Related-------------------------------------------[1100-1199] */
-#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_BUS 1100
-#define CONTROLVM_RESP_ERROR_CHIPSET_STOP_FAILED_SWITCH 1101
+#define CONTROLVM_RESP_CHIPSET_STOP_FAILED_BUS 1100
+#define CONTROLVM_RESP_CHIPSET_STOP_FAILED_SWITCH 1101
/* Device Related-------------------------------------------------[1400-1499] */
-#define CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT 1400
+#define CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT 1400
#endif /* __CONTROLVMCHANNEL_H__ */
diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c
index 3457ef338e1e..aea1aa262b28 100644
--- a/drivers/staging/unisys/visorbus/visorbus_main.c
+++ b/drivers/staging/unisys/visorbus/visorbus_main.c
@@ -49,7 +49,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
vdev = to_visor_device(dev);
guid = visorchannel_get_uuid(vdev->visorchannel);
- return snprintf(buf, PAGE_SIZE, "visorbus:%pUl\n", &guid);
+ return sprintf(buf, "visorbus:%pUl\n", &guid);
}
static DEVICE_ATTR_RO(modalias);
@@ -187,8 +187,8 @@ static ssize_t physaddr_show(struct device *dev, struct device_attribute *attr,
if (!vdev->visorchannel)
return 0;
- return snprintf(buf, PAGE_SIZE, "0x%llx\n",
- visorchannel_get_physaddr(vdev->visorchannel));
+ return sprintf(buf, "0x%llx\n",
+ visorchannel_get_physaddr(vdev->visorchannel));
}
static DEVICE_ATTR_RO(physaddr);
@@ -199,7 +199,7 @@ static ssize_t nbytes_show(struct device *dev, struct device_attribute *attr,
if (!vdev->visorchannel)
return 0;
- return snprintf(buf, PAGE_SIZE, "0x%lx\n",
+ return sprintf(buf, "0x%lx\n",
visorchannel_get_nbytes(vdev->visorchannel));
}
static DEVICE_ATTR_RO(nbytes);
@@ -211,8 +211,8 @@ static ssize_t clientpartition_show(struct device *dev,
if (!vdev->visorchannel)
return 0;
- return snprintf(buf, PAGE_SIZE, "0x%llx\n",
- visorchannel_get_clientpartition(vdev->visorchannel));
+ return sprintf(buf, "0x%llx\n",
+ visorchannel_get_clientpartition(vdev->visorchannel));
}
static DEVICE_ATTR_RO(clientpartition);
@@ -224,8 +224,8 @@ static ssize_t typeguid_show(struct device *dev, struct device_attribute *attr,
if (!vdev->visorchannel)
return 0;
- return snprintf(buf, PAGE_SIZE, "%s\n",
- visorchannel_id(vdev->visorchannel, typeid));
+ return sprintf(buf, "%s\n",
+ visorchannel_id(vdev->visorchannel, typeid));
}
static DEVICE_ATTR_RO(typeguid);
@@ -237,8 +237,8 @@ static ssize_t zoneguid_show(struct device *dev, struct device_attribute *attr,
if (!vdev->visorchannel)
return 0;
- return snprintf(buf, PAGE_SIZE, "%s\n",
- visorchannel_zoneid(vdev->visorchannel, zoneid));
+ return sprintf(buf, "%s\n",
+ visorchannel_zoneid(vdev->visorchannel, zoneid));
}
static DEVICE_ATTR_RO(zoneguid);
@@ -257,7 +257,7 @@ static ssize_t typename_show(struct device *dev, struct device_attribute *attr,
if (!i)
return 0;
drv = to_visor_driver(xdrv);
- return snprintf(buf, PAGE_SIZE, "%s\n", drv->channel_types[i - 1].name);
+ return sprintf(buf, "%s\n", drv->channel_types[i - 1].name);
}
static DEVICE_ATTR_RO(typename);
@@ -296,7 +296,7 @@ static ssize_t partition_handle_show(struct device *dev,
struct visor_device *vdev = to_visor_device(dev);
u64 handle = visorchannel_get_clientpartition(vdev->visorchannel);
- return snprintf(buf, PAGE_SIZE, "0x%llx\n", handle);
+ return sprintf(buf, "0x%llx\n", handle);
}
static DEVICE_ATTR_RO(partition_handle);
@@ -305,7 +305,7 @@ static ssize_t partition_guid_show(struct device *dev,
char *buf) {
struct visor_device *vdev = to_visor_device(dev);
- return snprintf(buf, PAGE_SIZE, "{%pUb}\n", &vdev->partition_uuid);
+ return sprintf(buf, "{%pUb}\n", &vdev->partition_uuid);
}
static DEVICE_ATTR_RO(partition_guid);
@@ -314,7 +314,7 @@ static ssize_t partition_name_show(struct device *dev,
char *buf) {
struct visor_device *vdev = to_visor_device(dev);
- return snprintf(buf, PAGE_SIZE, "%s\n", vdev->name);
+ return sprintf(buf, "%s\n", vdev->name);
}
static DEVICE_ATTR_RO(partition_name);
@@ -324,7 +324,7 @@ static ssize_t channel_addr_show(struct device *dev,
struct visor_device *vdev = to_visor_device(dev);
u64 addr = visorchannel_get_physaddr(vdev->visorchannel);
- return snprintf(buf, PAGE_SIZE, "0x%llx\n", addr);
+ return sprintf(buf, "0x%llx\n", addr);
}
static DEVICE_ATTR_RO(channel_addr);
@@ -334,7 +334,7 @@ static ssize_t channel_bytes_show(struct device *dev,
struct visor_device *vdev = to_visor_device(dev);
u64 nbytes = visorchannel_get_nbytes(vdev->visorchannel);
- return snprintf(buf, PAGE_SIZE, "0x%llx\n", nbytes);
+ return sprintf(buf, "0x%llx\n", nbytes);
}
static DEVICE_ATTR_RO(channel_bytes);
@@ -438,8 +438,7 @@ dev_periodic_work(unsigned long __opaque)
struct visor_device *dev = (struct visor_device *)__opaque;
struct visor_driver *drv = to_visor_driver(dev->device.driver);
- if (drv->channel_interrupt)
- drv->channel_interrupt(dev);
+ drv->channel_interrupt(dev);
mod_timer(&dev->timer, jiffies + POLLJIFFIES_NORMALCHANNEL);
}
@@ -561,6 +560,13 @@ EXPORT_SYMBOL_GPL(visorbus_write_channel);
void
visorbus_enable_channel_interrupts(struct visor_device *dev)
{
+ struct visor_driver *drv = to_visor_driver(dev->device.driver);
+
+ if (!drv->channel_interrupt) {
+ dev_err(&dev->device, "%s no interrupt function!\n", __func__);
+ return;
+ }
+
dev_start_periodic_work(dev);
}
EXPORT_SYMBOL_GPL(visorbus_enable_channel_interrupts);
@@ -984,7 +990,7 @@ create_bus_instance(struct visor_device *dev)
goto err_hdr_info;
}
dev->debugfs_client_bus_info =
- debugfs_create_file("client_bus_info", S_IRUSR | S_IRGRP,
+ debugfs_create_file("client_bus_info", 0440,
dev->debugfs_dir, dev,
&client_bus_info_debugfs_fops);
if (!dev->debugfs_client_bus_info) {
@@ -1337,10 +1343,10 @@ visorbus_exit(void)
debugfs_remove_recursive(visorbus_debugfs_dir);
}
-module_param_named(forcematch, visorbus_forcematch, int, S_IRUGO);
+module_param_named(forcematch, visorbus_forcematch, int, 0444);
MODULE_PARM_DESC(visorbus_forcematch,
"1 to force a successful dev <--> drv match");
-module_param_named(forcenomatch, visorbus_forcenomatch, int, S_IRUGO);
+module_param_named(forcenomatch, visorbus_forcenomatch, int, 0444);
MODULE_PARM_DESC(visorbus_forcenomatch,
"1 to force an UNsuccessful dev <--> drv match");
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c
index d7148c351d3f..4e630ea527e8 100644
--- a/drivers/staging/unisys/visorbus/visorchipset.c
+++ b/drivers/staging/unisys/visorbus/visorchipset.c
@@ -188,7 +188,7 @@ static ssize_t toolaction_show(struct device *dev,
visorchannel_read(controlvm_channel,
offsetof(struct spar_controlvm_channel_protocol,
tool_action), &tool_action, sizeof(u8));
- return scnprintf(buf, PAGE_SIZE, "%u\n", tool_action);
+ return sprintf(buf, "%u\n", tool_action);
}
static ssize_t toolaction_store(struct device *dev,
@@ -223,8 +223,7 @@ static ssize_t boottotool_show(struct device *dev,
offsetof(struct spar_controlvm_channel_protocol,
efi_spar_ind), &efi_spar_indication,
sizeof(struct efi_spar_indication));
- return scnprintf(buf, PAGE_SIZE, "%u\n",
- efi_spar_indication.boot_to_tool);
+ return sprintf(buf, "%u\n", efi_spar_indication.boot_to_tool);
}
static ssize_t boottotool_store(struct device *dev,
@@ -259,7 +258,7 @@ static ssize_t error_show(struct device *dev, struct device_attribute *attr,
offsetof(struct spar_controlvm_channel_protocol,
installation_error),
&error, sizeof(u32));
- return scnprintf(buf, PAGE_SIZE, "%i\n", error);
+ return sprintf(buf, "%i\n", error);
}
static ssize_t error_store(struct device *dev, struct device_attribute *attr,
@@ -292,7 +291,7 @@ static ssize_t textid_show(struct device *dev, struct device_attribute *attr,
offsetof(struct spar_controlvm_channel_protocol,
installation_text_id),
&text_id, sizeof(u32));
- return scnprintf(buf, PAGE_SIZE, "%i\n", text_id);
+ return sprintf(buf, "%i\n", text_id);
}
static ssize_t textid_store(struct device *dev, struct device_attribute *attr,
@@ -324,7 +323,7 @@ static ssize_t remaining_steps_show(struct device *dev,
offsetof(struct spar_controlvm_channel_protocol,
installation_remaining_steps),
&remaining_steps, sizeof(u16));
- return scnprintf(buf, PAGE_SIZE, "%hu\n", remaining_steps);
+ return sprintf(buf, "%hu\n", remaining_steps);
}
static ssize_t remaining_steps_store(struct device *dev,
@@ -353,60 +352,12 @@ parser_id_get(struct parser_context *ctx)
{
struct spar_controlvm_parameters_header *phdr = NULL;
- if (!ctx)
- return NULL_UUID_LE;
phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
return phdr->id;
}
-/*
- * Describes the state from the perspective of which controlvm messages have
- * been received for a bus or device.
- */
-
-enum PARSER_WHICH_STRING {
- PARSERSTRING_INITIATOR,
- PARSERSTRING_TARGET,
- PARSERSTRING_CONNECTION,
- PARSERSTRING_NAME, /* TODO: only PARSERSTRING_NAME is used ? */
-};
-
-static void
-parser_param_start(struct parser_context *ctx,
- enum PARSER_WHICH_STRING which_string)
-{
- struct spar_controlvm_parameters_header *phdr = NULL;
-
- if (!ctx)
- return;
-
- phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
- switch (which_string) {
- case PARSERSTRING_INITIATOR:
- ctx->curr = ctx->data + phdr->initiator_offset;
- ctx->bytes_remaining = phdr->initiator_length;
- break;
- case PARSERSTRING_TARGET:
- ctx->curr = ctx->data + phdr->target_offset;
- ctx->bytes_remaining = phdr->target_length;
- break;
- case PARSERSTRING_CONNECTION:
- ctx->curr = ctx->data + phdr->connection_offset;
- ctx->bytes_remaining = phdr->connection_length;
- break;
- case PARSERSTRING_NAME:
- ctx->curr = ctx->data + phdr->name_offset;
- ctx->bytes_remaining = phdr->name_length;
- break;
- default:
- break;
- }
-}
-
static void parser_done(struct parser_context *ctx)
{
- if (!ctx)
- return;
controlvm_payload_bytes_buffered -= ctx->param_bytes;
kfree(ctx);
}
@@ -420,8 +371,6 @@ parser_string_get(struct parser_context *ctx)
void *value = NULL;
int i;
- if (!ctx)
- return NULL;
pscan = ctx->curr;
nscan = ctx->bytes_remaining;
if (nscan == 0)
@@ -444,6 +393,17 @@ parser_string_get(struct parser_context *ctx)
return value;
}
+static void *
+parser_name_get(struct parser_context *ctx)
+{
+ struct spar_controlvm_parameters_header *phdr = NULL;
+
+ phdr = (struct spar_controlvm_parameters_header *)(ctx->data);
+ ctx->curr = ctx->data + phdr->name_offset;
+ ctx->bytes_remaining = phdr->name_length;
+ return parser_string_get(ctx);
+}
+
struct visor_busdev {
u32 bus_no;
u32 dev_no;
@@ -521,7 +481,7 @@ chipset_init(struct controlvm_message *inmsg)
POSTCODE_LINUX(CHIPSET_INIT_ENTRY_PC, 0, 0, DIAG_SEVERITY_PRINT);
if (chipset_inited) {
- rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
+ rc = -CONTROLVM_RESP_ALREADY_DONE;
res = -EIO;
goto out_respond;
}
@@ -613,27 +573,33 @@ save_crash_message(struct controlvm_message *msg, enum crash_obj_type typ)
return err;
}
- if (typ == CRASH_BUS) {
+ switch (typ) {
+ case CRASH_DEV:
+ local_crash_msg_offset += sizeof(struct controlvm_message);
err = visorchannel_write(controlvm_channel,
local_crash_msg_offset,
msg,
- sizeof(struct controlvm_message));
+ sizeof(struct controlvm_message));
if (err) {
- POSTCODE_LINUX(SAVE_MSG_BUS_FAILURE_PC, 0, 0,
+ POSTCODE_LINUX(SAVE_MSG_DEV_FAILURE_PC, 0, 0,
DIAG_SEVERITY_ERR);
return err;
}
- } else {
- local_crash_msg_offset += sizeof(struct controlvm_message);
+ break;
+ case CRASH_BUS:
err = visorchannel_write(controlvm_channel,
local_crash_msg_offset,
msg,
sizeof(struct controlvm_message));
if (err) {
- POSTCODE_LINUX(SAVE_MSG_DEV_FAILURE_PC, 0, 0,
+ POSTCODE_LINUX(SAVE_MSG_BUS_FAILURE_PC, 0, 0,
DIAG_SEVERITY_ERR);
return err;
}
+ break;
+ default:
+ pr_info("Invalid crash_obj_type\n");
+ break;
}
return 0;
}
@@ -722,8 +688,11 @@ bus_create(struct controlvm_message *inmsg)
POSTCODE_LINUX(BUS_CREATE_ENTRY_PC, 0, bus_no, DIAG_SEVERITY_PRINT);
- if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0)
- save_crash_message(inmsg, CRASH_BUS);
+ if (uuid_le_cmp(cmd->create_bus.bus_inst_uuid, spar_siovm_uuid) == 0) {
+ err = save_crash_message(inmsg, CRASH_BUS);
+ if (err)
+ goto err_free_bus_info;
+ }
if (inmsg->hdr.flags.response_expected == 1) {
pmsg_hdr = kzalloc(sizeof(*pmsg_hdr),
@@ -857,9 +826,10 @@ bus_configure(struct controlvm_message *inmsg,
if (err)
goto err_respond;
- bus_info->partition_uuid = parser_id_get(parser_ctx);
- parser_param_start(parser_ctx, PARSERSTRING_NAME);
- bus_info->name = parser_string_get(parser_ctx);
+ if (parser_ctx) {
+ bus_info->partition_uuid = parser_id_get(parser_ctx);
+ bus_info->name = parser_name_get(parser_ctx);
+ }
POSTCODE_LINUX(BUS_CONFIGURE_EXIT_PC, 0, bus_no,
DIAG_SEVERITY_PRINT);
@@ -874,7 +844,7 @@ err_respond:
return err;
}
-static void
+static int
my_device_create(struct controlvm_message *inmsg)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
@@ -884,37 +854,37 @@ my_device_create(struct controlvm_message *inmsg)
struct visor_device *dev_info = NULL;
struct visor_device *bus_info;
struct visorchannel *visorchannel;
- int rc = CONTROLVM_RESP_SUCCESS;
+ int err;
bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL);
if (!bus_info) {
POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
DIAG_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
- goto out_respond;
+ err = -ENODEV;
+ goto err_respond;
}
if (bus_info->state.created == 0) {
POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
DIAG_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_BUS_INVALID;
- goto out_respond;
+ err = -EINVAL;
+ goto err_respond;
}
dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL);
if (dev_info && (dev_info->state.created == 1)) {
POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
DIAG_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
- goto out_respond;
+ err = -EEXIST;
+ goto err_respond;
}
dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
if (!dev_info) {
POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
DIAG_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
- goto out_respond;
+ err = -ENOMEM;
+ goto err_respond;
}
dev_info->chipset_bus_no = bus_no;
@@ -936,20 +906,23 @@ my_device_create(struct controlvm_message *inmsg)
if (!visorchannel) {
POSTCODE_LINUX(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
DIAG_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
- goto out_free_dev_info;
+ err = -ENOMEM;
+ goto err_free_dev_info;
}
dev_info->visorchannel = visorchannel;
dev_info->channel_type_guid = cmd->create_device.data_type_uuid;
if (uuid_le_cmp(cmd->create_device.data_type_uuid,
- spar_vhba_channel_protocol_uuid) == 0)
- save_crash_message(inmsg, CRASH_DEV);
+ spar_vhba_channel_protocol_uuid) == 0) {
+ err = save_crash_message(inmsg, CRASH_DEV);
+ if (err)
+ goto err_free_dev_info;
+ }
if (inmsg->hdr.flags.response_expected == 1) {
pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL);
if (!pmsg_hdr) {
- rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
- goto out_free_dev_info;
+ err = -ENOMEM;
+ goto err_free_dev_info;
}
memcpy(pmsg_hdr, &inmsg->hdr,
@@ -960,17 +933,18 @@ my_device_create(struct controlvm_message *inmsg)
chipset_device_create(dev_info);
POSTCODE_LINUX(DEVICE_CREATE_EXIT_PC, dev_no, bus_no,
DIAG_SEVERITY_PRINT);
- return;
+ return 0;
-out_free_dev_info:
+err_free_dev_info:
kfree(dev_info);
-out_respond:
+err_respond:
if (inmsg->hdr.flags.response_expected == 1)
- device_responder(inmsg->hdr.id, &inmsg->hdr, rc);
+ device_responder(inmsg->hdr.id, &inmsg->hdr, err);
+ return err;
}
-static void
+static int
my_device_changestate(struct controlvm_message *inmsg)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
@@ -979,30 +953,30 @@ my_device_changestate(struct controlvm_message *inmsg)
u32 dev_no = cmd->device_change_state.dev_no;
struct spar_segment_state state = cmd->device_change_state.state;
struct visor_device *dev_info;
- int rc = CONTROLVM_RESP_SUCCESS;
+ int err;
dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL);
if (!dev_info) {
POSTCODE_LINUX(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no,
DIAG_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID;
+ err = -ENODEV;
goto err_respond;
}
if (dev_info->state.created == 0) {
POSTCODE_LINUX(DEVICE_CHANGESTATE_FAILURE_PC, dev_no, bus_no,
DIAG_SEVERITY_ERR);
- rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID;
+ err = -EINVAL;
goto err_respond;
}
if (dev_info->pending_msg_hdr) {
/* only non-NULL if dev is still waiting on a response */
- rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT;
+ err = -EIO;
goto err_respond;
}
if (inmsg->hdr.flags.response_expected == 1) {
pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL);
if (!pmsg_hdr) {
- rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
+ err = -ENOMEM;
goto err_respond;
}
@@ -1023,15 +997,15 @@ my_device_changestate(struct controlvm_message *inmsg)
* Response will be sent from chipset_device_pause.
*/
chipset_device_pause(dev_info);
-
- return;
+ return 0;
err_respond:
if (inmsg->hdr.flags.response_expected == 1)
- device_responder(inmsg->hdr.id, &inmsg->hdr, rc);
+ device_responder(inmsg->hdr.id, &inmsg->hdr, err);
+ return err;
}
-static void
+static int
my_device_destroy(struct controlvm_message *inmsg)
{
struct controlvm_message_packet *cmd = &inmsg->cmd;
@@ -1039,27 +1013,27 @@ my_device_destroy(struct controlvm_message *inmsg)
u32 bus_no = cmd->destroy_device.bus_no;
u32 dev_no = cmd->destroy_device.dev_no;
struct visor_device *dev_info;
- int rc = CONTROLVM_RESP_SUCCESS;
+ int err;
dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL);
if (!dev_info) {
- rc = -CONTROLVM_RESP_ERROR_DEVICE_INVALID;
+ err = -ENODEV;
goto err_respond;
}
if (dev_info->state.created == 0) {
- rc = -CONTROLVM_RESP_ERROR_ALREADY_DONE;
+ err = -EINVAL;
goto err_respond;
}
if (dev_info->pending_msg_hdr) {
/* only non-NULL if dev is still waiting on a response */
- rc = -CONTROLVM_RESP_ERROR_MESSAGE_ID_INVALID_FOR_CLIENT;
+ err = -EIO;
goto err_respond;
}
if (inmsg->hdr.flags.response_expected == 1) {
pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL);
if (!pmsg_hdr) {
- rc = -CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
+ err = -ENOMEM;
goto err_respond;
}
@@ -1069,11 +1043,12 @@ my_device_destroy(struct controlvm_message *inmsg)
}
chipset_device_destroy(dev_info);
- return;
+ return 0;
err_respond:
if (inmsg->hdr.flags.response_expected == 1)
- device_responder(inmsg->hdr.id, &inmsg->hdr, rc);
+ device_responder(inmsg->hdr.id, &inmsg->hdr, err);
+ return err;
}
/**
@@ -1097,14 +1072,14 @@ initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes,
u8 *payload = NULL;
if (!info)
- return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID;
+ return -CONTROLVM_RESP_PAYLOAD_INVALID;
if ((offset == 0) || (bytes == 0))
- return -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID;
+ return -CONTROLVM_RESP_PAYLOAD_INVALID;
payload = memremap(phys_addr + offset, bytes, MEMREMAP_WB);
if (!payload)
- return -CONTROLVM_RESP_ERROR_IOREMAP_FAILED;
+ return -CONTROLVM_RESP_IOREMAP_FAILED;
memset(info, 0, sizeof(struct visor_controlvm_payload_info));
info->offset = offset;
@@ -1153,23 +1128,24 @@ initialize_controlvm_payload(void)
}
/*
- * The general parahotplug flow works as follows. The visorchipset
- * driver receives a DEVICE_CHANGESTATE message from Command
- * specifying a physical device to enable or disable. The CONTROLVM
- * message handler calls parahotplug_process_message, which then adds
- * the message to a global list and kicks off a udev event which
- * causes a user level script to enable or disable the specified
- * device. The udev script then writes to
- * /proc/visorchipset/parahotplug, which causes parahotplug_proc_write
- * to get called, at which point the appropriate CONTROLVM message is
- * retrieved from the list and responded to.
+ * The general parahotplug flow works as follows. The visorchipset receives
+ * a DEVICE_CHANGESTATE message from Command specifying a physical device
+ * to enable or disable. The CONTROLVM message handler calls
+ * parahotplug_process_message, which then adds the message to a global list
+ * and kicks off a udev event which causes a user level script to enable or
+ * disable the specified device. The udev script then writes to
+ * /sys/devices/platform/visorchipset/parahotplug, which causes the
+ * parahotplug store functions to get called, at which point the
+ * appropriate CONTROLVM message is retrieved from the list and responded
+ * to.
*/
#define PARAHOTPLUG_TIMEOUT_MS 2000
/**
- * parahotplug_next_id() - generate unique int to match an outstanding CONTROLVM
- * message with a udev script /proc response
+ * parahotplug_next_id() - generate unique int to match an outstanding
+ * CONTROLVM message with a udev script /sys
+ * response
*
* Return: a unique integer value
*/
@@ -1236,7 +1212,7 @@ static DEFINE_SPINLOCK(parahotplug_request_list_lock); /* lock for above */
* @id: the id of the request
* @active: indicates whether the request is assigned to active partition
*
- * Called from the /proc handler, which means the user script has
+ * Called from the /sys handler, which means the user script has
* finished the enable/disable. Find the matching identifier, and
* respond to the CONTROLVM message with success.
*
@@ -1433,7 +1409,7 @@ parahotplug_process_message(struct controlvm_message *inmsg)
*
* devices are automatically enabled at
* initialization.
- */
+ */
parahotplug_request_kickoff(req);
controlvm_respond_physdev_changestate
(&inmsg->hdr,
@@ -1846,8 +1822,7 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
int allocbytes = sizeof(struct parser_context) + bytes;
struct parser_context *ctx;
- if (retry)
- *retry = false;
+ *retry = false;
/*
* alloc an 0 extra byte to ensure payload is
@@ -1856,14 +1831,12 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
allocbytes++;
if ((controlvm_payload_bytes_buffered + bytes)
> MAX_CONTROLVM_PAYLOAD_BYTES) {
- if (retry)
- *retry = true;
+ *retry = true;
return NULL;
}
ctx = kzalloc(allocbytes, GFP_KERNEL | __GFP_NORETRY);
if (!ctx) {
- if (retry)
- *retry = true;
+ *retry = true;
return NULL;
}
@@ -2001,8 +1974,7 @@ handle_command(struct controlvm_message inmsg, u64 channel_addr)
default:
if (inmsg.hdr.flags.response_expected)
controlvm_respond
- (&inmsg.hdr,
- -CONTROLVM_RESP_ERROR_MESSAGE_ID_UNKNOWN);
+ (&inmsg.hdr, -CONTROLVM_RESP_ID_UNKNOWN);
break;
}
@@ -2057,7 +2029,7 @@ parahotplug_process_list(void)
if (req->msg.hdr.flags.response_expected)
controlvm_respond_physdev_changestate(
&req->msg.hdr,
- CONTROLVM_RESP_ERROR_DEVICE_UDEV_TIMEOUT,
+ CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT,
req->msg.cmd.device_change_state.state);
parahotplug_request_destroy(req);
}
@@ -2277,7 +2249,7 @@ static void exit_unisys(void)
acpi_bus_unregister_driver(&unisys_acpi_driver);
}
-module_param_named(major, visorchipset_major, int, S_IRUGO);
+module_param_named(major, visorchipset_major, int, 0444);
MODULE_PARM_DESC(visorchipset_major,
"major device number to use for the device node");
diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h
index 674a88b657d3..d1d72c184e29 100644
--- a/drivers/staging/unisys/visorbus/vmcallinterface.h
+++ b/drivers/staging/unisys/visorbus/vmcallinterface.h
@@ -16,10 +16,10 @@
#define __IOMONINTF_H__
/*
-* This file contains all structures needed to support the VMCALLs for IO
-* Virtualization. The VMCALLs are provided by Monitor and used by IO code
-* running on IO Partitions.
-*/
+ * This file contains all structures needed to support the VMCALLs for IO
+ * Virtualization. The VMCALLs are provided by Monitor and used by IO code
+ * running on IO Partitions.
+ */
static inline unsigned long
__unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx,
unsigned long reg_ecx)
diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c
index 5a7a87efed27..0ce92c85157c 100644
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
@@ -29,10 +29,6 @@
/* The Send and Receive Buffers of the IO Queue may both be full */
#define IOS_ERROR_THRESHOLD 1000
-/* MAX_BUF = 6 lines x 10 MAXVHBA x 80 characters
- * = 4800 bytes ~ 2^13 = 8192 bytes
- */
-#define MAX_BUF 8192
#define MAX_PENDING_REQUESTS (MIN_NUMSIGNALS * 2)
#define VISORHBA_ERROR_COUNT 30
diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c
index c1f674f5268c..0a8f36125f5b 100644
--- a/drivers/staging/unisys/visornic/visornic_main.c
+++ b/drivers/staging/unisys/visornic/visornic_main.c
@@ -461,10 +461,9 @@ visornic_disable_with_timeout(struct net_device *netdev, const int timeout)
if (devdata->enab_dis_acked)
break;
if (devdata->server_down || devdata->server_change_state) {
- spin_unlock_irqrestore(&devdata->priv_lock, flags);
dev_dbg(&netdev->dev, "%s server went away\n",
__func__);
- return -EIO;
+ break;
}
set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irqrestore(&devdata->priv_lock, flags);
@@ -572,6 +571,8 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout)
unsigned long flags;
int wait = 0;
+ napi_enable(&devdata->napi);
+
/* NOTE: the other end automatically unposts the rcv buffers when it
* gets a disable.
*/
@@ -595,7 +596,6 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout)
/* send enable and wait for ack -- don't hold lock when sending enable
* because if the queue is full, insert might sleep.
*/
- napi_enable(&devdata->napi);
send_enbdis(netdev, 1, devdata);
spin_lock_irqsave(&devdata->priv_lock, flags);
@@ -604,10 +604,9 @@ visornic_enable_with_timeout(struct net_device *netdev, const int timeout)
if (devdata->enab_dis_acked)
break;
if (devdata->server_down || devdata->server_change_state) {
- spin_unlock_irqrestore(&devdata->priv_lock, flags);
dev_dbg(&netdev->dev, "%s server went away\n",
__func__);
- return -EIO;
+ break;
}
set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irqrestore(&devdata->priv_lock, flags);
@@ -2017,8 +2016,6 @@ static int visornic_resume(struct visor_device *dev,
*/
mod_timer(&devdata->irq_poll_timer, msecs_to_jiffies(2));
- init_rcv_bufs(netdev, devdata);
-
rtnl_lock();
dev_open(netdev);
rtnl_unlock();
diff --git a/drivers/staging/vc04_services/interface/vchi/connections/connection.h b/drivers/staging/vc04_services/interface/vchi/connections/connection.h
index fef6ac34c6d2..e793cdf2847c 100644
--- a/drivers/staging/vc04_services/interface/vchi/connections/connection.h
+++ b/drivers/staging/vc04_services/interface/vchi/connections/connection.h
@@ -217,8 +217,7 @@ typedef void (*VCHI_BUFFER_FREE)(VCHI_CONNECTION_SERVICE_HANDLE_T service_hand
System driver struct
*****************************************************************************/
-struct opaque_vchi_connection_api_t
-{
+struct opaque_vchi_connection_api_t {
// Routine to init the connection
VCHI_CONNECTION_INIT_T init;
diff --git a/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h b/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h
index 8b3f76735bd4..a7740a425388 100644
--- a/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h
+++ b/drivers/staging/vc04_services/interface/vchi/message_drivers/message.h
@@ -53,14 +53,12 @@ typedef enum message_event_type {
MESSAGE_EVENT_MSG_DISCARDED
} MESSAGE_EVENT_TYPE_T;
-typedef enum vchi_msg_flags
-{
+typedef enum vchi_msg_flags {
VCHI_MSG_FLAGS_NONE = 0x0,
VCHI_MSG_FLAGS_TERMINATE_DMA = 0x1
} VCHI_MSG_FLAGS_T;
-typedef enum message_tx_channel
-{
+typedef enum message_tx_channel {
MESSAGE_TX_CHANNEL_MESSAGE = 0,
MESSAGE_TX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards
} MESSAGE_TX_CHANNEL_T;
@@ -69,8 +67,7 @@ typedef enum message_tx_channel
#define MESSAGE_TX_CHANNEL_BULK_PREV(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION-1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION)
#define MESSAGE_TX_CHANNEL_BULK_NEXT(c) (MESSAGE_TX_CHANNEL_BULK+((c)-MESSAGE_TX_CHANNEL_BULK+1)%VCHI_MAX_BULK_TX_CHANNELS_PER_CONNECTION)
-typedef enum message_rx_channel
-{
+typedef enum message_rx_channel {
MESSAGE_RX_CHANNEL_MESSAGE = 0,
MESSAGE_RX_CHANNEL_BULK = 1 // drivers may provide multiple bulk channels, from 1 upwards
} MESSAGE_RX_CHANNEL_T;
diff --git a/drivers/staging/vc04_services/interface/vchi/vchi.h b/drivers/staging/vc04_services/interface/vchi/vchi.h
index d6937288210c..44169d6c5a36 100644
--- a/drivers/staging/vc04_services/interface/vchi/vchi.h
+++ b/drivers/staging/vc04_services/interface/vchi/vchi.h
@@ -61,8 +61,7 @@ struct vchi_version {
#define VCHI_VERSION(v_) { v_, v_ }
#define VCHI_VERSION_EX(v_, m_) { v_, m_ }
-typedef enum
-{
+typedef enum {
VCHI_VEC_POINTER,
VCHI_VEC_HANDLE,
VCHI_VEC_LIST
@@ -71,26 +70,22 @@ typedef enum
typedef struct vchi_msg_vector_ex {
VCHI_MSG_VECTOR_TYPE_T type;
- union
- {
+ union {
// a memory handle
- struct
- {
+ struct {
VCHI_MEM_HANDLE_T handle;
uint32_t offset;
int32_t vec_len;
} handle;
// an ordinary data pointer
- struct
- {
+ struct {
const void *vec_base;
int32_t vec_len;
} ptr;
// a nested vector list
- struct
- {
+ struct {
struct vchi_msg_vector_ex *vec;
uint32_t vec_len;
} list;
@@ -114,8 +109,7 @@ struct opaque_vchi_service_t;
// Descriptor for a held message. Allocated by client, initialised by vchi_msg_hold,
// vchi_msg_iter_hold or vchi_msg_iter_hold_next. Fields are for internal VCHI use only.
-typedef struct
-{
+typedef struct {
struct opaque_vchi_service_t *service;
void *message;
} VCHI_HELD_MSG_T;
diff --git a/drivers/staging/vc04_services/interface/vchi/vchi_common.h b/drivers/staging/vc04_services/interface/vchi/vchi_common.h
index d535a72970d3..3f7d8438fe09 100644
--- a/drivers/staging/vc04_services/interface/vchi/vchi_common.h
+++ b/drivers/staging/vc04_services/interface/vchi/vchi_common.h
@@ -36,8 +36,7 @@
//flags used when sending messages (must be bitmapped)
-typedef enum
-{
+typedef enum {
VCHI_FLAGS_NONE = 0x0,
VCHI_FLAGS_BLOCK_UNTIL_OP_COMPLETE = 0x1, // waits for message to be received, or sent (NB. not the same as being seen on other side)
VCHI_FLAGS_CALLBACK_WHEN_OP_COMPLETE = 0x2, // run a callback when message sent
@@ -62,8 +61,7 @@ typedef enum {
} VCHI_CRC_CONTROL_T;
//callback reasons when an event occurs on a service
-typedef enum
-{
+typedef enum {
VCHI_CALLBACK_REASON_MIN,
//This indicates that there is data available
@@ -111,8 +109,7 @@ typedef enum
} VCHI_CALLBACK_REASON_T;
// service control options
-typedef enum
-{
+typedef enum {
VCHI_SERVICE_OPTION_MIN,
VCHI_SERVICE_OPTION_TRACE,
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h
deleted file mode 100644
index 7ea5c64d5343..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (c) 2010-2012 Broadcom. 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") version 2, as published by the Free
- * Software Foundation.
- *
- * 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.
- */
-
-#ifndef VCHIQ_2835_H
-#define VCHIQ_2835_H
-
-#include "vchiq_pagelist.h"
-
-#define VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX 0
-#define VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX 1
-
-#endif /* VCHIQ_2835_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
index 2b500d85cebc..e6241fb5cfa6 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
@@ -48,18 +48,21 @@
#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32)
#include "vchiq_arm.h"
-#include "vchiq_2835.h"
#include "vchiq_connected.h"
#include "vchiq_killable.h"
+#include "vchiq_pagelist.h"
#define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2)
+#define VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX 0
+#define VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX 1
+
#define BELL0 0x00
#define BELL2 0x08
typedef struct vchiq_2835_state_struct {
- int inited;
- VCHIQ_ARM_STATE_T arm_state;
+ int inited;
+ VCHIQ_ARM_STATE_T arm_state;
} VCHIQ_2835_ARM_STATE_T;
struct vchiq_pagelist_info {
@@ -192,31 +195,31 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
vchiq_call_connected_callbacks();
- return 0;
+ return 0;
}
VCHIQ_STATUS_T
vchiq_platform_init_state(VCHIQ_STATE_T *state)
{
- VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
- state->platform_state = kzalloc(sizeof(VCHIQ_2835_ARM_STATE_T), GFP_KERNEL);
- ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 1;
- status = vchiq_arm_init_state(state, &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state);
- if(status != VCHIQ_SUCCESS)
- {
- ((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited = 0;
- }
- return status;
+ VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
+ state->platform_state = kzalloc(sizeof(VCHIQ_2835_ARM_STATE_T), GFP_KERNEL);
+ ((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->inited = 1;
+ status = vchiq_arm_init_state(state, &((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->arm_state);
+ if (status != VCHIQ_SUCCESS)
+ {
+ ((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->inited = 0;
+ }
+ return status;
}
VCHIQ_ARM_STATE_T*
vchiq_platform_get_arm_state(VCHIQ_STATE_T *state)
{
- if(!((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->inited)
- {
- BUG();
- }
- return &((VCHIQ_2835_ARM_STATE_T*)state->platform_state)->arm_state;
+ if (!((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->inited)
+ {
+ BUG();
+ }
+ return &((VCHIQ_2835_ARM_STATE_T *)state->platform_state)->arm_state;
}
void
@@ -292,13 +295,13 @@ vchiq_dump_platform_state(void *dump_context)
VCHIQ_STATUS_T
vchiq_platform_suspend(VCHIQ_STATE_T *state)
{
- return VCHIQ_ERROR;
+ return VCHIQ_ERROR;
}
VCHIQ_STATUS_T
vchiq_platform_resume(VCHIQ_STATE_T *state)
{
- return VCHIQ_SUCCESS;
+ return VCHIQ_SUCCESS;
}
void
@@ -312,15 +315,15 @@ vchiq_platform_resumed(VCHIQ_STATE_T *state)
}
int
-vchiq_platform_videocore_wanted(VCHIQ_STATE_T* state)
+vchiq_platform_videocore_wanted(VCHIQ_STATE_T *state)
{
- return 1; // autosuspend not supported - videocore always wanted
+ return 1; // autosuspend not supported - videocore always wanted
}
int
vchiq_platform_use_suspend_timer(void)
{
- return 0;
+ return 0;
}
void
vchiq_dump_platform_use_state(VCHIQ_STATE_T *state)
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 0d987898b4f8..1dc8627e65b0 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -64,10 +64,10 @@
#define VCHIQ_MINOR 0
/* Some per-instance constants */
-#define MAX_COMPLETIONS 16
+#define MAX_COMPLETIONS 128
#define MAX_SERVICES 64
#define MAX_ELEMENTS 8
-#define MSG_QUEUE_SIZE 64
+#define MSG_QUEUE_SIZE 128
#define KEEPALIVE_VER 1
#define KEEPALIVE_VER_MIN KEEPALIVE_VER
@@ -194,7 +194,7 @@ vchiq_static_assert(ARRAY_SIZE(ioctl_names) ==
(VCHIQ_IOC_MAX + 1));
static void
-dump_phys_mem(void *virt_addr, uint32_t num_bytes);
+dump_phys_mem(void *virt_addr, u32 num_bytes);
/****************************************************************************
*
@@ -208,10 +208,11 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
void *bulk_userdata)
{
VCHIQ_COMPLETION_DATA_T *completion;
+ int insert;
DEBUG_INITIALISE(g_state.local)
- while (instance->completion_insert ==
- (instance->completion_remove + MAX_COMPLETIONS)) {
+ insert = instance->completion_insert;
+ while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) {
/* Out of space - wait for the client */
DEBUG_TRACE(SERVICE_CALLBACK_LINE);
vchiq_log_trace(vchiq_arm_log_level,
@@ -224,14 +225,12 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
} else if (instance->closing) {
vchiq_log_info(vchiq_arm_log_level,
"service_callback closing");
- return VCHIQ_ERROR;
+ return VCHIQ_SUCCESS;
}
DEBUG_TRACE(SERVICE_CALLBACK_LINE);
}
- completion =
- &instance->completions[instance->completion_insert &
- (MAX_COMPLETIONS - 1)];
+ completion = &instance->completions[insert & (MAX_COMPLETIONS - 1)];
completion->header = header;
completion->reason = reason;
@@ -252,9 +251,10 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason,
wmb();
if (reason == VCHIQ_MESSAGE_AVAILABLE)
- user_service->message_available_pos =
- instance->completion_insert;
- instance->completion_insert++;
+ user_service->message_available_pos = insert;
+
+ insert++;
+ instance->completion_insert = insert;
up(&instance->insert_event);
@@ -279,6 +279,7 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
USER_SERVICE_T *user_service;
VCHIQ_SERVICE_T *service;
VCHIQ_INSTANCE_T instance;
+ bool skip_completion = false;
DEBUG_INITIALISE(g_state.local)
DEBUG_TRACE(SERVICE_CALLBACK_LINE);
@@ -345,9 +346,6 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
user_service->msg_queue[user_service->msg_insert &
(MSG_QUEUE_SIZE - 1)] = header;
user_service->msg_insert++;
- spin_unlock(&msg_queue_spinlock);
-
- up(&user_service->insert_event);
/* If there is a thread waiting in DEQUEUE_MESSAGE, or if
** there is a MESSAGE_AVAILABLE in the completion queue then
@@ -356,15 +354,20 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header,
if (((user_service->message_available_pos -
instance->completion_remove) >= 0) ||
user_service->dequeue_pending) {
- DEBUG_TRACE(SERVICE_CALLBACK_LINE);
user_service->dequeue_pending = 0;
- return VCHIQ_SUCCESS;
+ skip_completion = true;
}
+ spin_unlock(&msg_queue_spinlock);
+ up(&user_service->insert_event);
+
header = NULL;
}
DEBUG_TRACE(SERVICE_CALLBACK_LINE);
+ if (skip_completion)
+ return VCHIQ_SUCCESS;
+
return add_completion(instance, reason, header, user_service,
bulk_userdata);
}
@@ -665,7 +668,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
USER_SERVICE_T *user_service =
(USER_SERVICE_T *)service->base.userdata;
/* close_pending is false on first entry, and when the
- wait in vchiq_close_service has been interrupted. */
+ wait in vchiq_close_service has been interrupted. */
if (!user_service->close_pending) {
status = vchiq_close_service(service->handle);
if (status != VCHIQ_SUCCESS)
@@ -691,7 +694,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
USER_SERVICE_T *user_service =
(USER_SERVICE_T *)service->base.userdata;
/* close_pending is false on first entry, and when the
- wait in vchiq_close_service has been interrupted. */
+ wait in vchiq_close_service has been interrupted. */
if (!user_service->close_pending) {
status = vchiq_remove_service(service->handle);
if (status != VCHIQ_SUCCESS)
@@ -892,24 +895,27 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
DEBUG_TRACE(AWAIT_COMPLETION_LINE);
- /* A read memory barrier is needed to stop prefetch of a stale
- ** completion record
- */
- rmb();
-
if (ret == 0) {
int msgbufcount = args.msgbufcount;
+ int remove = instance->completion_remove;
+
for (ret = 0; ret < args.count; ret++) {
VCHIQ_COMPLETION_DATA_T *completion;
VCHIQ_SERVICE_T *service;
USER_SERVICE_T *user_service;
VCHIQ_HEADER_T *header;
- if (instance->completion_remove ==
- instance->completion_insert)
+
+ if (remove == instance->completion_insert)
break;
+
completion = &instance->completions[
- instance->completion_remove &
- (MAX_COMPLETIONS - 1)];
+ remove & (MAX_COMPLETIONS - 1)];
+
+ /*
+ * A read memory barrier is needed to stop
+ * prefetch of a stale completion record
+ */
+ rmb();
service = completion->service_userdata;
user_service = service->base.userdata;
@@ -984,7 +990,13 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
}
- instance->completion_remove++;
+ /*
+ * Ensure that the above copy has completed
+ * before advancing the remove pointer.
+ */
+ mb();
+ remove++;
+ instance->completion_remove = remove;
}
if (msgbufcount != args.msgbufcount) {
@@ -1535,10 +1547,10 @@ vchiq_dump_platform_service_state(void *dump_context, VCHIQ_SERVICE_T *service)
***************************************************************************/
static void
-dump_phys_mem(void *virt_addr, uint32_t num_bytes)
+dump_phys_mem(void *virt_addr, u32 num_bytes)
{
int rc;
- uint8_t *end_virt_addr = virt_addr + num_bytes;
+ u8 *end_virt_addr = virt_addr + num_bytes;
int num_pages;
int offset;
int end_offset;
@@ -1546,7 +1558,7 @@ dump_phys_mem(void *virt_addr, uint32_t num_bytes)
int prev_idx;
struct page *page;
struct page **pages;
- uint8_t *kmapped_virt_ptr;
+ u8 *kmapped_virt_ptr;
/* Align virtAddr and endVirtAddr to 16 byte boundaries. */
@@ -1602,7 +1614,7 @@ dump_phys_mem(void *virt_addr, uint32_t num_bytes)
if (vchiq_arm_log_level >= VCHIQ_LOG_TRACE)
vchiq_log_dump_mem("ph",
- (uint32_t)(unsigned long)&kmapped_virt_ptr[
+ (u32)(unsigned long)&kmapped_virt_ptr[
page_offset],
&kmapped_virt_ptr[page_offset], 16);
@@ -1996,7 +2008,7 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state)
&arm_state->blocked_blocker, timeout_val)
<= 0) {
vchiq_log_error(vchiq_susp_log_level, "%s wait for "
- "previously blocked clients failed" , __func__);
+ "previously blocked clients failed", __func__);
status = VCHIQ_ERROR;
write_lock_bh(&arm_state->susp_res_lock);
goto out;
@@ -2012,7 +2024,7 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state)
if (resume_count > 1) {
status = VCHIQ_ERROR;
vchiq_log_error(vchiq_susp_log_level, "%s waited too "
- "many times for resume" , __func__);
+ "many times for resume", __func__);
goto out;
}
write_unlock_bh(&arm_state->susp_res_lock);
@@ -2372,52 +2384,6 @@ out:
return resume;
}
-void
-vchiq_platform_check_resume(VCHIQ_STATE_T *state)
-{
- VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
- int res = 0;
-
- if (!arm_state)
- goto out;
-
- vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);
-
- write_lock_bh(&arm_state->susp_res_lock);
- if (arm_state->wake_address == 0) {
- vchiq_log_info(vchiq_susp_log_level,
- "%s: already awake", __func__);
- goto unlock;
- }
- if (arm_state->vc_resume_state == VC_RESUME_IN_PROGRESS) {
- vchiq_log_info(vchiq_susp_log_level,
- "%s: already resuming", __func__);
- goto unlock;
- }
-
- if (arm_state->vc_resume_state == VC_RESUME_REQUESTED) {
- set_resume_state(arm_state, VC_RESUME_IN_PROGRESS);
- res = 1;
- } else
- vchiq_log_trace(vchiq_susp_log_level,
- "%s: not resuming (resume state %s)", __func__,
- resume_state_names[arm_state->vc_resume_state +
- VC_RESUME_NUM_OFFSET]);
-
-unlock:
- write_unlock_bh(&arm_state->susp_res_lock);
-
- if (res)
- vchiq_platform_resume(state);
-
-out:
- vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
- return;
-
-}
-
-
-
VCHIQ_STATUS_T
vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
enum USE_TYPE_E use_type)
@@ -2870,10 +2836,10 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
if (state->conn_state == VCHIQ_CONNSTATE_CONNECTED) {
write_lock_bh(&arm_state->susp_res_lock);
if (!arm_state->first_connect) {
- char threadname[10];
+ char threadname[16];
arm_state->first_connect = 1;
write_unlock_bh(&arm_state->susp_res_lock);
- snprintf(threadname, sizeof(threadname), "VCHIQka-%d",
+ snprintf(threadname, sizeof(threadname), "vchiq-keep/%d",
state->id);
arm_state->ka_thread = kthread_create(
&vchiq_keepalive_thread_func,
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
index 9740e1afbc9d..bfbd81d9db33 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
@@ -154,7 +154,7 @@ vchiq_check_resume(VCHIQ_STATE_T *state);
extern void
vchiq_check_suspend(VCHIQ_STATE_T *state);
- VCHIQ_STATUS_T
+VCHIQ_STATUS_T
vchiq_use_service(VCHIQ_SERVICE_HANDLE_T handle);
extern VCHIQ_STATUS_T
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
index 028e90bc1cdc..d587097b261c 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -90,7 +90,7 @@ static atomic_t pause_bulks_count = ATOMIC_INIT(0);
static DEFINE_SPINLOCK(service_spinlock);
DEFINE_SPINLOCK(bulk_waiter_spinlock);
-DEFINE_SPINLOCK(quota_spinlock);
+static DEFINE_SPINLOCK(quota_spinlock);
VCHIQ_STATE_T *vchiq_states[VCHIQ_MAX_STATES];
static unsigned int handle_seq;
@@ -517,7 +517,7 @@ get_connected_service(VCHIQ_STATE_T *state, unsigned int port)
inline void
request_poll(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service, int poll_type)
{
- uint32_t value;
+ u32 value;
if (service) {
do {
@@ -607,15 +607,17 @@ process_free_queue(VCHIQ_STATE_T *state)
BITSET_T service_found[BITSET_SIZE(VCHIQ_MAX_SERVICES)];
int slot_queue_available;
- /* Use a read memory barrier to ensure that any state that may have
- ** been modified by another thread is not masked by stale prefetched
- ** values. */
- rmb();
-
/* Find slots which have been freed by the other side, and return them
** to the available queue. */
slot_queue_available = state->slot_queue_available;
+ /*
+ * Use a memory barrier to ensure that any state that may have been
+ * modified by another thread is not masked by stale prefetched
+ * values.
+ */
+ mb();
+
while (slot_queue_available != local->slot_queue_recycle) {
unsigned int pos;
int slot_index = local->slot_queue[slot_queue_available++ &
@@ -623,6 +625,12 @@ process_free_queue(VCHIQ_STATE_T *state)
char *data = (char *)SLOT_DATA_FROM_INDEX(state, slot_index);
int data_found = 0;
+ /*
+ * Beware of the address dependency - data is calculated
+ * using an index written by the other side.
+ */
+ rmb();
+
vchiq_log_trace(vchiq_core_log_level, "%d: pfq %d=%pK %x %x",
state->id, slot_index, data,
local->slot_queue_recycle, slot_queue_available);
@@ -721,6 +729,12 @@ process_free_queue(VCHIQ_STATE_T *state)
up(&state->data_quota_event);
}
+ /*
+ * Don't allow the slot to be reused until we are no
+ * longer interested in it.
+ */
+ mb();
+
state->slot_queue_available = slot_queue_available;
up(&state->slot_available_event);
}
@@ -920,7 +934,7 @@ queue_message(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
VCHIQ_LOG_INFO))
vchiq_log_dump_mem("Sent", 0,
header->data,
- min((size_t)64,
+ min((size_t)16,
(size_t)callback_result));
spin_lock(&quota_spinlock);
@@ -1073,7 +1087,7 @@ queue_message_sync(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
VCHIQ_LOG_INFO))
vchiq_log_dump_mem("Sent", 0,
header->data,
- min((size_t)64,
+ min((size_t)16,
(size_t)callback_result));
VCHIQ_SERVICE_STATS_INC(service, ctrl_tx_count);
@@ -1286,14 +1300,14 @@ poll_services(VCHIQ_STATE_T *state)
int group, i;
for (group = 0; group < BITSET_SIZE(state->unused_service); group++) {
- uint32_t flags;
+ u32 flags;
flags = atomic_xchg(&state->poll_services[group], 0);
for (i = 0; flags; i++) {
if (flags & (1 << i)) {
VCHIQ_SERVICE_T *service =
find_service_by_port(state,
(group<<5) + i);
- uint32_t service_flags;
+ u32 service_flags;
flags &= ~(1 << i);
if (!service)
continue;
@@ -1513,12 +1527,10 @@ parse_open(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header)
{
VCHIQ_SERVICE_T *service = NULL;
int msgid, size;
- int type;
unsigned int localport, remoteport;
msgid = header->msgid;
size = header->size;
- type = VCHIQ_MSG_TYPE(msgid);
localport = VCHIQ_MSG_DSTPORT(msgid);
remoteport = VCHIQ_MSG_SRCPORT(msgid);
if (size >= sizeof(struct vchiq_open_payload)) {
@@ -1620,7 +1632,7 @@ fail_open:
/* No available service, or an invalid request - send a CLOSE */
if (queue_message(state, NULL,
VCHIQ_MAKE_MSG(VCHIQ_MSG_CLOSE, 0, VCHIQ_MSG_SRCPORT(msgid)),
- NULL, 0, 0, 0) == VCHIQ_RETRY)
+ NULL, NULL, 0, 0) == VCHIQ_RETRY)
goto bail_not_ready;
return 1;
@@ -1736,7 +1748,7 @@ parse_rx_slots(VCHIQ_STATE_T *state)
remoteport, localport, size);
if (size > 0)
vchiq_log_dump_mem("Rcvd", 0, header->data,
- min(64, size));
+ min(16, size));
}
if (((unsigned long)header & VCHIQ_SLOT_MASK) +
@@ -1973,7 +1985,7 @@ parse_rx_slots(VCHIQ_STATE_T *state)
/* Send a PAUSE in response */
if (queue_message(state, NULL,
VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0),
- NULL, 0, 0, QMFLAGS_NO_MUTEX_UNLOCK)
+ NULL, NULL, 0, QMFLAGS_NO_MUTEX_UNLOCK)
== VCHIQ_RETRY)
goto bail_not_ready;
if (state->is_master)
@@ -2072,7 +2084,7 @@ slot_handler_func(void *v)
pause_bulks(state);
if (queue_message(state, NULL,
VCHIQ_MAKE_MSG(VCHIQ_MSG_PAUSE, 0, 0),
- NULL, 0, 0,
+ NULL, NULL, 0,
QMFLAGS_NO_MUTEX_UNLOCK)
!= VCHIQ_RETRY) {
vchiq_set_conn_state(state,
@@ -2092,7 +2104,7 @@ slot_handler_func(void *v)
case VCHIQ_CONNSTATE_RESUMING:
if (queue_message(state, NULL,
VCHIQ_MAKE_MSG(VCHIQ_MSG_RESUME, 0, 0),
- NULL, 0, 0, QMFLAGS_NO_MUTEX_LOCK)
+ NULL, NULL, 0, QMFLAGS_NO_MUTEX_LOCK)
!= VCHIQ_RETRY) {
if (state->is_master)
resume_bulks(state);
@@ -2193,7 +2205,7 @@ sync_func(void *v)
remoteport, localport, size);
if (size > 0)
vchiq_log_dump_mem("Rcvd", 0, header->data,
- min(64, size));
+ min(16, size));
}
switch (type) {
@@ -2317,7 +2329,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero,
VCHIQ_SHARED_STATE_T *local;
VCHIQ_SHARED_STATE_T *remote;
VCHIQ_STATUS_T status;
- char threadname[10];
+ char threadname[16];
static int id;
int i;
@@ -2485,7 +2497,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero,
/*
bring up slot handler thread
*/
- snprintf(threadname, sizeof(threadname), "VCHIQ-%d", state->id);
+ snprintf(threadname, sizeof(threadname), "vchiq-slot/%d", state->id);
state->slot_handler_thread = kthread_create(&slot_handler_func,
(void *)state,
threadname);
@@ -2499,7 +2511,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero,
set_user_nice(state->slot_handler_thread, -19);
wake_up_process(state->slot_handler_thread);
- snprintf(threadname, sizeof(threadname), "VCHIQr-%d", state->id);
+ snprintf(threadname, sizeof(threadname), "vchiq-recy/%d", state->id);
state->recycle_thread = kthread_create(&recycle_func,
(void *)state,
threadname);
@@ -2512,7 +2524,7 @@ vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_SLOT_ZERO_T *slot_zero,
set_user_nice(state->recycle_thread, -19);
wake_up_process(state->recycle_thread);
- snprintf(threadname, sizeof(threadname), "VCHIQs-%d", state->id);
+ snprintf(threadname, sizeof(threadname), "vchiq-sync/%d", state->id);
state->sync_thread = kthread_create(&sync_func,
(void *)state,
threadname);
@@ -2904,7 +2916,7 @@ vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd)
(VCHIQ_MSG_CLOSE,
service->localport,
VCHIQ_MSG_DSTPORT(service->remoteport)),
- NULL, 0, 0, 0);
+ NULL, NULL, 0, 0);
}
break;
@@ -2926,7 +2938,7 @@ vchiq_close_service_internal(VCHIQ_SERVICE_T *service, int close_recvd)
(VCHIQ_MSG_CLOSE,
service->localport,
VCHIQ_MSG_DSTPORT(service->remoteport)),
- NULL, 0, 0, QMFLAGS_NO_MUTEX_UNLOCK);
+ NULL, NULL, 0, QMFLAGS_NO_MUTEX_UNLOCK);
if (status == VCHIQ_SUCCESS) {
if (!close_recvd) {
@@ -3056,7 +3068,7 @@ vchiq_connect_internal(VCHIQ_STATE_T *state, VCHIQ_INSTANCE_T instance)
if (state->conn_state == VCHIQ_CONNSTATE_DISCONNECTED) {
if (queue_message(state, NULL,
- VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, 0,
+ VCHIQ_MAKE_MSG(VCHIQ_MSG_CONNECT, 0, 0), NULL, NULL,
0, QMFLAGS_IS_BLOCKING) == VCHIQ_RETRY)
return VCHIQ_RETRY;
@@ -3509,20 +3521,20 @@ release_message_sync(VCHIQ_STATE_T *state, VCHIQ_HEADER_T *header)
VCHIQ_STATUS_T
vchiq_get_peer_version(VCHIQ_SERVICE_HANDLE_T handle, short *peer_version)
{
- VCHIQ_STATUS_T status = VCHIQ_ERROR;
- VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
+ VCHIQ_STATUS_T status = VCHIQ_ERROR;
+ VCHIQ_SERVICE_T *service = find_service_by_handle(handle);
- if (!service ||
- (vchiq_check_service(service) != VCHIQ_SUCCESS) ||
- !peer_version)
- goto exit;
- *peer_version = service->peer_version;
- status = VCHIQ_SUCCESS;
+ if (!service ||
+ (vchiq_check_service(service) != VCHIQ_SUCCESS) ||
+ !peer_version)
+ goto exit;
+ *peer_version = service->peer_version;
+ status = VCHIQ_SUCCESS;
exit:
- if (service)
- unlock_service(service);
- return status;
+ if (service)
+ unlock_service(service);
+ return status;
}
VCHIQ_STATUS_T
@@ -3626,7 +3638,7 @@ vchiq_set_service_option(VCHIQ_SERVICE_HANDLE_T handle,
return status;
}
-void
+static void
vchiq_dump_shared_state(void *dump_context, VCHIQ_STATE_T *state,
VCHIQ_SHARED_STATE_T *shared, const char *label)
{
@@ -3816,7 +3828,7 @@ vchiq_dump_service_state(void *dump_context, VCHIQ_SERVICE_T *service)
service->stats.bulk_stalls,
service->stats.bulk_aborted_count,
service->stats.error_count);
- }
+ }
}
vchiq_dump(dump_context, buf, len + 1);
@@ -3857,7 +3869,7 @@ VCHIQ_STATUS_T vchiq_send_remote_use(VCHIQ_STATE_T *state)
if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
status = queue_message(state, NULL,
VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE, 0, 0),
- NULL, 0, 0, 0);
+ NULL, NULL, 0, 0);
return status;
}
@@ -3867,7 +3879,7 @@ VCHIQ_STATUS_T vchiq_send_remote_release(VCHIQ_STATE_T *state)
if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
status = queue_message(state, NULL,
VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_RELEASE, 0, 0),
- NULL, 0, 0, 0);
+ NULL, NULL, 0, 0);
return status;
}
@@ -3877,14 +3889,14 @@ VCHIQ_STATUS_T vchiq_send_remote_use_active(VCHIQ_STATE_T *state)
if (state->conn_state != VCHIQ_CONNSTATE_DISCONNECTED)
status = queue_message(state, NULL,
VCHIQ_MAKE_MSG(VCHIQ_MSG_REMOTE_USE_ACTIVE, 0, 0),
- NULL, 0, 0, 0);
+ NULL, NULL, 0, 0);
return status;
}
-void vchiq_log_dump_mem(const char *label, uint32_t addr, const void *void_mem,
+void vchiq_log_dump_mem(const char *label, u32 addr, const void *void_mem,
size_t num_bytes)
{
- const uint8_t *mem = (const uint8_t *)void_mem;
+ const u8 *mem = (const u8 *)void_mem;
size_t offset;
char line_buf[100];
char *s;
@@ -3901,7 +3913,7 @@ void vchiq_log_dump_mem(const char *label, uint32_t addr, const void *void_mem,
for (offset = 0; offset < 16; offset++) {
if (offset < num_bytes) {
- uint8_t ch = mem[offset];
+ u8 ch = mem[offset];
if ((ch < ' ') || (ch > '~'))
ch = '.';
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h
index 4d6a3788e9c5..1d95e3d70621 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.h
@@ -36,8 +36,7 @@
#include "vchiq_core.h"
-typedef struct vchiq_debugfs_node_struct
-{
+typedef struct vchiq_debugfs_node_struct {
struct dentry *dentry;
} VCHIQ_DEBUGFS_NODE_T;
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
index e93922a87263..4317c06943a6 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c
@@ -75,23 +75,23 @@ VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *instance_out)
VCHIQ_STATUS_T status = VCHIQ_ERROR;
VCHIQ_STATE_T *state;
VCHIQ_INSTANCE_T instance = NULL;
- int i;
+ int i;
vchiq_log_trace(vchiq_core_log_level, "%s called", __func__);
- /* VideoCore may not be ready due to boot up timing.
- It may never be ready if kernel and firmware are mismatched, so don't block forever. */
- for (i=0; i<VCHIQ_INIT_RETRIES; i++) {
+ /* VideoCore may not be ready due to boot up timing.
+ It may never be ready if kernel and firmware are mismatched, so don't block forever. */
+ for (i = 0; i < VCHIQ_INIT_RETRIES; i++) {
state = vchiq_get_state();
if (state)
break;
udelay(500);
}
- if (i==VCHIQ_INIT_RETRIES) {
+ if (i == VCHIQ_INIT_RETRIES) {
vchiq_log_error(vchiq_core_log_level,
"%s: videocore not initialized\n", __func__);
goto failed;
- } else if (i>0) {
+ } else if (i > 0) {
vchiq_log_warning(vchiq_core_log_level,
"%s: videocore initialized after %d retries\n", __func__, i);
}
@@ -172,7 +172,7 @@ EXPORT_SYMBOL(vchiq_shutdown);
*
***************************************************************************/
-int vchiq_is_connected(VCHIQ_INSTANCE_T instance)
+static int vchiq_is_connected(VCHIQ_INSTANCE_T instance)
{
return instance->connected;
}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
index d9771394a041..a6b2ae0c9bea 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
@@ -527,7 +527,7 @@ static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason,
SHIM_SERVICE_T *service =
(SHIM_SERVICE_T *)VCHIQ_GET_SERVICE_USERDATA(handle);
- if (!service->callback)
+ if (!service->callback)
goto release;
switch (reason) {
@@ -577,7 +577,7 @@ static VCHIQ_STATUS_T shim_callback(VCHIQ_REASON_T reason,
}
release:
- vchiq_release_message(service->handle, header);
+ vchiq_release_message(service->handle, header);
done:
return VCHIQ_SUCCESS;
}
@@ -739,16 +739,18 @@ int32_t vchi_service_set_option(const VCHI_SERVICE_HANDLE_T handle,
}
EXPORT_SYMBOL(vchi_service_set_option);
-int32_t vchi_get_peer_version( const VCHI_SERVICE_HANDLE_T handle, short *peer_version )
+int32_t vchi_get_peer_version(const VCHI_SERVICE_HANDLE_T handle, short *peer_version)
{
- int32_t ret = -1;
- SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
- if(service)
- {
- VCHIQ_STATUS_T status = vchiq_get_peer_version(service->handle, peer_version);
- ret = vchiq_status_to_vchi( status );
- }
- return ret;
+ int32_t ret = -1;
+ SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
+ if (service)
+ {
+ VCHIQ_STATUS_T status;
+
+ status = vchiq_get_peer_version(service->handle, peer_version);
+ ret = vchiq_status_to_vchi(status);
+ }
+ return ret;
}
EXPORT_SYMBOL(vchi_get_peer_version);
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
index f76f4d790532..e0ba0ed704fd 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
@@ -80,9 +80,8 @@ void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header)
return;
while (queue->write == queue->read + queue->size) {
- if (down_interruptible(&queue->pop) != 0) {
+ if (down_interruptible(&queue->pop) != 0)
flush_signals(current);
- }
}
/*
@@ -107,9 +106,8 @@ void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header)
VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue)
{
while (queue->write == queue->read) {
- if (down_interruptible(&queue->push) != 0) {
+ if (down_interruptible(&queue->push) != 0)
flush_signals(current);
- }
}
up(&queue->push); // We haven't removed anything from the queue.
@@ -128,9 +126,8 @@ VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue)
VCHIQ_HEADER_T *header;
while (queue->write == queue->read) {
- if (down_interruptible(&queue->push) != 0) {
+ if (down_interruptible(&queue->push) != 0)
flush_signals(current);
- }
}
/*
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 87aa5174df22..69e9a7705afb 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -47,7 +47,8 @@ static const char driver_name[] = "vme_user";
static int bus[VME_USER_BUS_MAX];
static unsigned int bus_num;
-/* Currently Documentation/admin-guide/devices.rst defines the following for VME:
+/* Currently Documentation/admin-guide/devices.rst defines the
+ * following for VME:
*
* 221 char VME bus
* 0 = /dev/bus/vme/m0 First master image
diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h
index c2cde7e92c8f..7f08cda27e2c 100644
--- a/drivers/staging/vt6656/card.h
+++ b/drivers/staging/vt6656/card.h
@@ -35,21 +35,23 @@
struct vnt_private;
-void vnt_set_channel(struct vnt_private *, u32);
-void vnt_set_rspinf(struct vnt_private *, u8);
-void vnt_update_ifs(struct vnt_private *);
-void vnt_update_top_rates(struct vnt_private *);
-int vnt_ofdm_min_rate(struct vnt_private *);
-void vnt_adjust_tsf(struct vnt_private *, u8, u64, u64);
-bool vnt_get_current_tsf(struct vnt_private *, u64 *);
-bool vnt_clear_current_tsf(struct vnt_private *);
-void vnt_reset_next_tbtt(struct vnt_private *, u16);
-void vnt_update_next_tbtt(struct vnt_private *, u64, u16);
-u64 vnt_get_next_tbtt(u64, u16);
-u64 vnt_get_tsf_offset(u8 byRxRate, u64 qwTSF1, u64 qwTSF2);
-int vnt_radio_power_off(struct vnt_private *);
-int vnt_radio_power_on(struct vnt_private *);
-u8 vnt_get_pkt_type(struct vnt_private *);
-void vnt_set_bss_mode(struct vnt_private *);
+void vnt_set_channel(struct vnt_private *priv, u32 connection_channel);
+void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type);
+void vnt_update_ifs(struct vnt_private *priv);
+void vnt_update_top_rates(struct vnt_private *priv);
+int vnt_ofdm_min_rate(struct vnt_private *priv);
+void vnt_adjust_tsf(struct vnt_private *priv, u8 rx_rate,
+ u64 time_stamp, u64 local_tsf);
+bool vnt_get_current_tsf(struct vnt_private *priv, u64 *current_tsf);
+bool vnt_clear_current_tsf(struct vnt_private *priv);
+void vnt_reset_next_tbtt(struct vnt_private *priv, u16 beacon_interval);
+void vnt_update_next_tbtt(struct vnt_private *priv, u64 tsf,
+ u16 beacon_interval);
+u64 vnt_get_next_tbtt(u64 tsf, u16 beacon_interval);
+u64 vnt_get_tsf_offset(u8 rx_rate, u64 tsf1, u64 tsf2);
+int vnt_radio_power_off(struct vnt_private *priv);
+int vnt_radio_power_on(struct vnt_private *priv);
+u8 vnt_get_pkt_type(struct vnt_private *priv);
+void vnt_set_bss_mode(struct vnt_private *priv);
#endif /* __CARD_H__ */
diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c
index 73538fb4e4e2..c6ffbe0e2728 100644
--- a/drivers/staging/vt6656/int.c
+++ b/drivers/staging/vt6656/int.c
@@ -142,7 +142,7 @@ void vnt_int_process_data(struct vnt_private *priv)
if (int_data->isr0 != 0) {
if (int_data->isr0 & ISR_BNTX &&
- priv->op_mode == NL80211_IFTYPE_AP)
+ priv->op_mode == NL80211_IFTYPE_AP)
vnt_schedule_command(priv, WLAN_CMD_BECON_SEND);
if (int_data->isr0 & ISR_TBTT &&
diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c
index 0246a8fc47fe..cc18cb141bff 100644
--- a/drivers/staging/vt6656/key.c
+++ b/drivers/staging/vt6656/key.c
@@ -44,8 +44,8 @@ int vnt_key_init_table(struct vnt_private *priv)
}
static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
- struct ieee80211_key_conf *key, u32 key_type, u32 mode,
- bool onfly_latch)
+ struct ieee80211_key_conf *key, u32 key_type,
+ u32 mode, bool onfly_latch)
{
struct vnt_private *priv = hw->priv;
u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -115,7 +115,7 @@ static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
}
int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
- struct ieee80211_vif *vif, struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif, struct ieee80211_key_conf *key)
{
struct ieee80211_bss_conf *conf = &vif->bss_conf;
struct vnt_private *priv = hw->priv;
@@ -138,7 +138,7 @@ int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
vnt_mac_disable_keyentry(priv, u);
vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,
- KEY_CTL_WEP, true);
+ KEY_CTL_WEP, true);
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -161,13 +161,13 @@ int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
vnt_set_keymode(hw, mac_addr, key, VNT_KEY_PAIRWISE,
- key_dec_mode, true);
+ key_dec_mode, true);
} else {
vnt_set_keymode(hw, mac_addr, key, VNT_KEY_DEFAULTKEY,
- key_dec_mode, true);
+ key_dec_mode, true);
vnt_set_keymode(hw, (u8 *)conf->bssid, key,
- VNT_KEY_GROUP_ADDRESS, key_dec_mode, true);
+ VNT_KEY_GROUP_ADDRESS, key_dec_mode, true);
}
return 0;
diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c
index 611da4929ddc..417fdad1f9ae 100644
--- a/drivers/staging/vt6656/mac.c
+++ b/drivers/staging/vt6656/mac.c
@@ -50,7 +50,7 @@ void vnt_mac_set_filter(struct vnt_private *priv, u64 mc_filter)
__le64 le_mc = cpu_to_le64(mc_filter);
vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_MAR0,
- MESSAGE_REQUEST_MACREG, sizeof(le_mc), (u8 *)&le_mc);
+ MESSAGE_REQUEST_MACREG, sizeof(le_mc), (u8 *)&le_mc);
}
/*
@@ -77,7 +77,7 @@ void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type)
data[1] = EnCFG_BBType_MASK;
vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0,
- MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
+ MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
/*
@@ -97,7 +97,7 @@ void vnt_mac_set_bb_type(struct vnt_private *priv, u8 type)
void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx)
{
vnt_control_out(priv, MESSAGE_TYPE_CLRKEYENTRY, 0, 0,
- sizeof(entry_idx), &entry_idx);
+ sizeof(entry_idx), &entry_idx);
}
/*
@@ -115,7 +115,7 @@ void vnt_mac_disable_keyentry(struct vnt_private *priv, u8 entry_idx)
*
*/
void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx,
- u32 key_idx, u8 *addr, u8 *key)
+ u32 key_idx, u8 *addr, u8 *key)
{
struct vnt_mac_set_key set_key;
u16 offset;
@@ -132,10 +132,11 @@ void vnt_mac_set_keyentry(struct vnt_private *priv, u16 key_ctl, u32 entry_idx,
memcpy(set_key.key, key, WLAN_KEY_LEN_CCMP);
dev_dbg(&priv->usb->dev, "offset %d key ctl %d set key %24ph\n",
- offset, key_ctl, (u8 *)&set_key);
+ offset, key_ctl, (u8 *)&set_key);
vnt_control_out(priv, MESSAGE_TYPE_SETKEY, offset,
- (u16)key_idx, sizeof(struct vnt_mac_set_key), (u8 *)&set_key);
+ (u16)key_idx, sizeof(struct vnt_mac_set_key),
+ (u8 *)&set_key);
}
void vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits)
@@ -146,7 +147,8 @@ void vnt_mac_reg_bits_off(struct vnt_private *priv, u8 reg_ofs, u8 bits)
data[1] = bits;
vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
- reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
+ reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data),
+ data);
}
void vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits)
@@ -156,8 +158,8 @@ void vnt_mac_reg_bits_on(struct vnt_private *priv, u8 reg_ofs, u8 bits)
data[0] = bits;
data[1] = bits;
- vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
- reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
+ vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, reg_ofs,
+ MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word)
@@ -167,14 +169,14 @@ void vnt_mac_write_word(struct vnt_private *priv, u8 reg_ofs, u16 word)
data[0] = (u8)(word & 0xff);
data[1] = (u8)(word >> 8);
- vnt_control_out(priv, MESSAGE_TYPE_WRITE,
- reg_ofs, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
+ vnt_control_out(priv, MESSAGE_TYPE_WRITE, reg_ofs,
+ MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
void vnt_mac_set_bssid_addr(struct vnt_private *priv, u8 *addr)
{
vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BSSID0,
- MESSAGE_REQUEST_MACREG, ETH_ALEN, addr);
+ MESSAGE_REQUEST_MACREG, ETH_ALEN, addr);
}
void vnt_mac_enable_protect_mode(struct vnt_private *priv)
@@ -184,8 +186,8 @@ void vnt_mac_enable_protect_mode(struct vnt_private *priv)
data[0] = EnCFG_ProtectMd;
data[1] = EnCFG_ProtectMd;
- vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
- MAC_REG_ENCFG0, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
+ vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0,
+ MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
void vnt_mac_disable_protect_mode(struct vnt_private *priv)
@@ -195,8 +197,8 @@ void vnt_mac_disable_protect_mode(struct vnt_private *priv)
data[0] = 0;
data[1] = EnCFG_ProtectMd;
- vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
- MAC_REG_ENCFG0, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
+ vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG0,
+ MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv)
@@ -206,8 +208,8 @@ void vnt_mac_enable_barker_preamble_mode(struct vnt_private *priv)
data[0] = EnCFG_BarkerPream;
data[1] = EnCFG_BarkerPream;
- vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
- MAC_REG_ENCFG2, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
+ vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2,
+ MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv)
@@ -217,8 +219,8 @@ void vnt_mac_disable_barker_preamble_mode(struct vnt_private *priv)
data[0] = 0;
data[1] = EnCFG_BarkerPream;
- vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK,
- MAC_REG_ENCFG2, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
+ vnt_control_out(priv, MESSAGE_TYPE_WRITE_MASK, MAC_REG_ENCFG2,
+ MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval)
@@ -228,8 +230,8 @@ void vnt_mac_set_beacon_interval(struct vnt_private *priv, u16 interval)
data[0] = (u8)(interval & 0xff);
data[1] = (u8)(interval >> 8);
- vnt_control_out(priv, MESSAGE_TYPE_WRITE,
- MAC_REG_BI, MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
+ vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_BI,
+ MESSAGE_REQUEST_MACREG, ARRAY_SIZE(data), data);
}
void vnt_mac_set_led(struct vnt_private *priv, u8 state, u8 led)
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index 50d02d9aa535..9e074e9daf4e 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -128,7 +128,7 @@ static int vnt_init_registers(struct vnt_private *priv)
u8 calib_tx_iq = 0, calib_tx_dc = 0, calib_rx_iq = 0;
dev_dbg(&priv->usb->dev, "---->INIbInitAdapter. [%d][%d]\n",
- DEVICE_INIT_COLD, priv->packet_type);
+ DEVICE_INIT_COLD, priv->packet_type);
if (!vnt_check_firmware_version(priv)) {
if (vnt_download_firmware(priv) == true) {
@@ -156,16 +156,17 @@ static int vnt_init_registers(struct vnt_private *priv)
init_cmd->long_retry_limit = priv->long_retry_limit;
/* issue card_init command to device */
- status = vnt_control_out(priv,
- MESSAGE_TYPE_CARDINIT, 0, 0,
- sizeof(struct vnt_cmd_card_init), (u8 *)init_cmd);
+ status = vnt_control_out(priv, MESSAGE_TYPE_CARDINIT, 0, 0,
+ sizeof(struct vnt_cmd_card_init),
+ (u8 *)init_cmd);
if (status != STATUS_SUCCESS) {
dev_dbg(&priv->usb->dev, "Issue Card init fail\n");
return false;
}
status = vnt_control_in(priv, MESSAGE_TYPE_INIT_RSP, 0, 0,
- sizeof(struct vnt_rsp_card_init), (u8 *)init_rsp);
+ sizeof(struct vnt_rsp_card_init),
+ (u8 *)init_rsp);
if (status != STATUS_SUCCESS) {
dev_dbg(&priv->usb->dev,
"Cardinit request in status fail!\n");
@@ -173,9 +174,8 @@ static int vnt_init_registers(struct vnt_private *priv)
}
/* local ID for AES functions */
- status = vnt_control_in(priv, MESSAGE_TYPE_READ,
- MAC_REG_LOCALID, MESSAGE_REQUEST_MACREG, 1,
- &priv->local_id);
+ status = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_LOCALID,
+ MESSAGE_REQUEST_MACREG, 1, &priv->local_id);
if (status != STATUS_SUCCESS)
return false;
@@ -278,7 +278,6 @@ static int vnt_init_registers(struct vnt_private *priv)
if (priv->rf_type == RF_VT3226D0) {
if ((priv->eeprom[EEP_OFS_MAJOR_VER] == 0x1) &&
(priv->eeprom[EEP_OFS_MINOR_VER] >= 0x4)) {
-
calib_tx_iq = priv->eeprom[EEP_OFS_CALIB_TX_IQ];
calib_tx_dc = priv->eeprom[EEP_OFS_CALIB_TX_DC];
calib_rx_iq = priv->eeprom[EEP_OFS_CALIB_RX_IQ];
@@ -340,17 +339,18 @@ static int vnt_init_registers(struct vnt_private *priv)
if ((priv->radio_ctl & EEP_RADIOCTL_ENABLE) != 0) {
status = vnt_control_in(priv, MESSAGE_TYPE_READ,
- MAC_REG_GPIOCTL1, MESSAGE_REQUEST_MACREG, 1, &tmp);
+ MAC_REG_GPIOCTL1,
+ MESSAGE_REQUEST_MACREG, 1, &tmp);
if (status != STATUS_SUCCESS)
return false;
if ((tmp & GPIO3_DATA) == 0)
vnt_mac_reg_bits_on(priv, MAC_REG_GPIOCTL1,
- GPIO3_INTMD);
+ GPIO3_INTMD);
else
vnt_mac_reg_bits_off(priv, MAC_REG_GPIOCTL1,
- GPIO3_INTMD);
+ GPIO3_INTMD);
}
vnt_mac_set_led(priv, LEDSTS_TMLEN, 0x38);
@@ -430,7 +430,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
for (ii = 0; ii < priv->num_tx_context; ii++) {
tx_context = kmalloc(sizeof(struct vnt_usb_send_context),
- GFP_KERNEL);
+ GFP_KERNEL);
if (!tx_context)
goto free_tx;
@@ -450,7 +450,7 @@ static bool vnt_alloc_bufs(struct vnt_private *priv)
priv->rcb[ii] = kzalloc(sizeof(struct vnt_rcb), GFP_KERNEL);
if (!priv->rcb[ii]) {
dev_err(&priv->usb->dev,
- "failed to allocate rcb no %d\n", ii);
+ "failed to allocate rcb no %d\n", ii);
goto free_rx_tx;
}
@@ -496,7 +496,8 @@ free_tx:
}
static void vnt_tx_80211(struct ieee80211_hw *hw,
- struct ieee80211_tx_control *control, struct sk_buff *skb)
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb)
{
struct vnt_private *priv = hw->priv;
@@ -610,7 +611,7 @@ static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
}
static void vnt_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif)
+ struct ieee80211_vif *vif)
{
struct vnt_private *priv = hw->priv;
@@ -653,7 +654,7 @@ static int vnt_config(struct ieee80211_hw *hw, u32 changed)
}
if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) ||
- (conf->flags & IEEE80211_CONF_OFFCHANNEL)) {
+ (conf->flags & IEEE80211_CONF_OFFCHANNEL)) {
vnt_set_channel(priv, conf->chandef.chan->hw_value);
if (conf->chandef.chan->band == NL80211_BAND_5GHZ)
@@ -682,8 +683,8 @@ static int vnt_config(struct ieee80211_hw *hw, u32 changed)
}
static void vnt_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf,
- u32 changed)
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *conf, u32 changed)
{
struct vnt_private *priv = hw->priv;
@@ -692,7 +693,6 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BSSID && conf->bssid)
vnt_mac_set_bssid_addr(priv, (u8 *)conf->bssid);
-
if (changed & BSS_CHANGED_BASIC_RATES) {
priv->basic_rates = conf->basic_rates;
@@ -731,11 +731,11 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_TXPOWER)
vnt_rf_setpower(priv, priv->current_rate,
- conf->chandef.chan->hw_value);
+ conf->chandef.chan->hw_value);
if (changed & BSS_CHANGED_BEACON_ENABLED) {
dev_dbg(&priv->usb->dev,
- "Beacon enable %d\n", conf->enable_beacon);
+ "Beacon enable %d\n", conf->enable_beacon);
if (conf->enable_beacon) {
vnt_beacon_enable(priv, vif, conf);
@@ -768,7 +768,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
}
static u64 vnt_prepare_multicast(struct ieee80211_hw *hw,
- struct netdev_hw_addr_list *mc_list)
+ struct netdev_hw_addr_list *mc_list)
{
struct vnt_private *priv = hw->priv;
struct netdev_hw_addr *ha;
@@ -787,7 +787,8 @@ static u64 vnt_prepare_multicast(struct ieee80211_hw *hw,
}
static void vnt_configure(struct ieee80211_hw *hw,
- unsigned int changed_flags, unsigned int *total_flags, u64 multicast)
+ unsigned int changed_flags,
+ unsigned int *total_flags, u64 multicast)
{
struct vnt_private *priv = hw->priv;
u8 rx_mode = 0;
@@ -796,7 +797,7 @@ static void vnt_configure(struct ieee80211_hw *hw,
*total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC;
rc = vnt_control_in(priv, MESSAGE_TYPE_READ, MAC_REG_RCR,
- MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode);
+ MESSAGE_REQUEST_MACREG, sizeof(u8), &rx_mode);
if (!rc)
rx_mode = RCR_MULTICAST | RCR_BROADCAST;
@@ -814,7 +815,6 @@ static void vnt_configure(struct ieee80211_hw *hw,
} else {
rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST);
}
-
}
if (changed_flags & (FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)) {
@@ -830,8 +830,8 @@ static void vnt_configure(struct ieee80211_hw *hw,
}
static int vnt_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- struct ieee80211_vif *vif, struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key)
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+ struct ieee80211_key_conf *key)
{
struct vnt_private *priv = hw->priv;
@@ -871,7 +871,7 @@ static void vnt_sw_scan_complete(struct ieee80211_hw *hw,
}
static int vnt_get_stats(struct ieee80211_hw *hw,
- struct ieee80211_low_level_stats *stats)
+ struct ieee80211_low_level_stats *stats)
{
struct vnt_private *priv = hw->priv;
@@ -925,7 +925,6 @@ static const struct ieee80211_ops vnt_mac_ops = {
int vnt_init(struct vnt_private *priv)
{
-
if (!(vnt_init_registers(priv)))
return -EAGAIN;
@@ -955,9 +954,9 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
udev = usb_get_dev(interface_to_usbdev(intf));
dev_notice(&udev->dev, "%s Ver. %s\n",
- DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+ DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
dev_notice(&udev->dev,
- "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
+ "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
hw = ieee80211_alloc_hw(sizeof(struct vnt_private), &vnt_mac_ops);
if (!hw) {
diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h
index 764c09ccd42d..727ec14380c4 100644
--- a/drivers/staging/vt6656/wcmd.h
+++ b/drivers/staging/vt6656/wcmd.h
@@ -51,9 +51,9 @@ enum vnt_cmd_state {
struct vnt_private;
-void vnt_reset_command_timer(struct vnt_private *);
+void vnt_reset_command_timer(struct vnt_private *priv);
-int vnt_schedule_command(struct vnt_private *, enum vnt_cmd);
+int vnt_schedule_command(struct vnt_private *priv, enum vnt_cmd);
void vnt_run_command(struct work_struct *work);
diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
index b00ea75524e4..c307ccef790e 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -3998,8 +3998,9 @@ static void *host_int_ParseJoinBssParam(struct network_info *ptstrNetworkInfo)
pNewJoinBssParam->rsn_found = true;
index += pu8IEs[index + 1] + 2;
continue;
- } else
+ } else {
index += pu8IEs[index + 1] + 2;
+ }
}
}
diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c
index 3775706578b2..9ab43935869e 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -364,7 +364,7 @@ static int linux_wlan_start_firmware(struct net_device *dev)
return ret;
if (!wait_for_completion_timeout(&wilc->sync_event,
- msecs_to_jiffies(5000)))
+ msecs_to_jiffies(5000)))
return -ETIME;
return 0;
@@ -992,7 +992,7 @@ int wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev)
tx_data->skb = skb;
eth_h = (struct ethhdr *)(skb->data);
- if (eth_h->h_proto == 0x8e88)
+ if (eth_h->h_proto == cpu_to_be16(0x8e88))
netdev_dbg(ndev, "EAPOL transmitted\n");
ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));
diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c
index 07260c497db4..7d32de930576 100644
--- a/drivers/staging/wilc1000/wilc_debugfs.c
+++ b/drivers/staging/wilc1000/wilc_debugfs.c
@@ -17,7 +17,6 @@
#include "wilc_wlan_if.h"
-
static struct dentry *wilc_dir;
/*
@@ -36,7 +35,6 @@ EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL);
* --------------------------------------------------------------------------------
*/
-
static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos)
{
char buf[128];
@@ -52,7 +50,7 @@ static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, si
}
static ssize_t wilc_debug_level_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *ppos)
+ size_t count, loff_t *ppos)
{
int flag = 0;
int ret;
diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c
index 3ad7cec4662d..cd6b8badc5f3 100644
--- a/drivers/staging/wilc1000/wilc_sdio.c
+++ b/drivers/staging/wilc1000/wilc_sdio.c
@@ -81,7 +81,6 @@ static int wilc_sdio_cmd52(struct wilc *wilc, struct sdio_cmd52 *cmd)
return ret;
}
-
static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd)
{
struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
@@ -127,7 +126,7 @@ static int linux_sdio_probe(struct sdio_func *func,
dev_dbg(&func->dev, "Initializing netdev\n");
ret = wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, gpio,
- &wilc_hif_sdio);
+ &wilc_hif_sdio);
if (ret) {
dev_err(&func->dev, "Couldn't initialize netdev\n");
return ret;
@@ -915,7 +914,6 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
__LINE__);
goto _fail_;
}
-
}
} else {
if (g_sdio.irq_gpio) {
@@ -945,7 +943,6 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val)
__LINE__);
goto _fail_;
}
-
}
if (!ret)
break;
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index c1a24f7bc85f..507bdf72aecf 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -665,6 +665,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
{
s32 s32Error = 0;
u32 i;
+ u32 sel_bssi_idx = UINT_MAX;
u8 u8security = NO_ENCRYPT;
enum AUTHTYPE tenuAuth_type = ANY;
@@ -688,18 +689,24 @@ static int connect(struct wiphy *wiphy, struct net_device *dev,
memcmp(last_scanned_shadow[i].ssid,
sme->ssid,
sme->ssid_len) == 0) {
- if (!sme->bssid)
- break;
- else
+ if (!sme->bssid) {
+ if (sel_bssi_idx == UINT_MAX ||
+ last_scanned_shadow[i].rssi >
+ last_scanned_shadow[sel_bssi_idx].rssi)
+ sel_bssi_idx = i;
+ } else {
if (memcmp(last_scanned_shadow[i].bssid,
sme->bssid,
- ETH_ALEN) == 0)
+ ETH_ALEN) == 0) {
+ sel_bssi_idx = i;
break;
+ }
+ }
}
}
- if (i < last_scanned_cnt) {
- pstrNetworkInfo = &last_scanned_shadow[i];
+ if (sel_bssi_idx < last_scanned_cnt) {
+ pstrNetworkInfo = &last_scanned_shadow[sel_bssi_idx];
} else {
s32Error = -ENOENT;
wilc_connecting = 0;
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c
index aa0e5a3d4a89..11870cb3f254 100644
--- a/drivers/staging/wlan-ng/cfg80211.c
+++ b/drivers/staging/wlan-ng/cfg80211.c
@@ -483,8 +483,8 @@ static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
else
netdev_warn(dev,
- "Unhandled authorisation type for connect (%d)\n",
- sme->auth_type);
+ "Unhandled authorisation type for connect (%d)\n",
+ sme->auth_type);
/* Set the encryption - we only support wep */
if (is_wep) {
@@ -667,7 +667,7 @@ void prism2_disconnected(struct wlandevice *wlandev)
void prism2_roamed(struct wlandevice *wlandev)
{
cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid,
- NULL, 0, NULL, 0, GFP_KERNEL);
+ NULL, 0, NULL, 0, GFP_KERNEL);
}
/* Structures for declaring wiphy interface */
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index 60caf9c37727..5f1851c85f12 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -1388,13 +1388,13 @@ static inline int hfa384x_drvr_getconfig16(struct hfa384x *hw, u16 rid, void *va
result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16));
if (result == 0)
- *((u16 *)val) = le16_to_cpu(*((u16 *)val));
+ le16_to_cpus(val);
return result;
}
static inline int hfa384x_drvr_setconfig16(struct hfa384x *hw, u16 rid, u16 val)
{
- u16 value = cpu_to_le16(val);
+ __le16 value = cpu_to_le16(val);
return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
}
diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c
index 8ea6a647d037..4c3d394f3e33 100644
--- a/drivers/staging/wlan-ng/prism2mib.c
+++ b/drivers/staging/wlan-ng/prism2mib.c
@@ -146,7 +146,6 @@ static int prism2mib_priv(struct mibrec *mib,
struct p80211msg_dot11req_mibset *msg, void *data);
static struct mibrec mibtab[] = {
-
/* dot11smt MIB's */
{DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(1),
F_STA | F_WRITE,
@@ -624,7 +623,6 @@ static int prism2mib_excludeunencrypted(struct mibrec *mib,
struct p80211msg_dot11req_mibset *msg,
void *data)
{
-
return prism2mib_flag(mib, isget, wlandev, hw, msg, data);
}
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index 777cd6e11694..6930f7eb741b 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -607,8 +607,12 @@ static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info,
{
switch (var->bits_per_pixel) {
case 8:
- var->red.offset = var->green.offset = var->blue.offset = 0;
- var->red.length = var->green.length = var->blue.length = 6;
+ var->red.offset = 0;
+ var->green.offset = 0;
+ var->blue.offset = 0;
+ var->red.length = 6;
+ var->green.length = 6;
+ var->blue.length = 6;
xgifb_info->video_cmap_len = 256;
break;
case 16:
@@ -1015,7 +1019,8 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
xgifb_info->video_vheight = info->var.yres_virtual;
xgifb_info->video_height =
XGIbios_mode[xgifb_info->mode_idx].yres;
- xgifb_info->org_x = xgifb_info->org_y = 0;
+ xgifb_info->org_x = 0;
+ xgifb_info->org_y = 0;
xgifb_info->video_linelength = info->var.xres_virtual
* (xgifb_info->video_bpp >> 3);
switch (xgifb_info->video_bpp) {
@@ -1311,10 +1316,12 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->yoffset = var->yres_virtual - var->yres - 1;
/* Set everything else to 0 */
- var->red.msb_right =
- var->green.msb_right =
- var->blue.msb_right =
- var->transp.offset = var->transp.length = var->transp.msb_right = 0;
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ var->transp.msb_right = 0;
return 0;
}
@@ -1468,7 +1475,8 @@ static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
{
u8 cr32, temp = 0;
- xgifb_info->TV_plug = xgifb_info->TV_type = 0;
+ xgifb_info->TV_plug = 0;
+ xgifb_info->TV_type = 0;
cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
@@ -1738,7 +1746,9 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto error_0;
}
- xgifb_info->video_vbase = hw_info->pjVideoMemoryAddress =
+ xgifb_info->video_vbase =
+ ioremap_wc(xgifb_info->video_base, xgifb_info->video_size);
+ hw_info->pjVideoMemoryAddress =
ioremap_wc(xgifb_info->video_base, xgifb_info->video_size);
xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base,
xgifb_info->mmio_size);
@@ -1897,7 +1907,8 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
xgifb_info->video_vheight =
xgifb_info->video_height =
XGIbios_mode[xgifb_info->mode_idx].yres;
- xgifb_info->org_x = xgifb_info->org_y = 0;
+ xgifb_info->org_x = 0;
+ xgifb_info->org_y = 0;
xgifb_info->video_linelength =
xgifb_info->video_width *
(xgifb_info->video_bpp >> 3);
diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c
index 14af157958cd..591a3c9babf5 100644
--- a/drivers/staging/xgifb/vb_init.c
+++ b/drivers/staging/xgifb/vb_init.c
@@ -579,8 +579,7 @@ static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
if ((data & 0x10) == 0) {
data = xgifb_reg_get(pVBInfo->P3c4, 0x39);
- data = (data & 0x02) >> 1;
- return data;
+ return (data & 0x02) >> 1;
}
return data & 0x01;
}
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 0aa9e7d697a5..25dbd8c7aec7 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -239,6 +239,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
if (ifp->desc.bNumEndpoints >= num_ep)
goto skip_to_next_endpoint_or_interface_descriptor;
+ /* Check for duplicate endpoint addresses */
+ for (i = 0; i < ifp->desc.bNumEndpoints; ++i) {
+ if (ifp->endpoint[i].desc.bEndpointAddress ==
+ d->bEndpointAddress) {
+ dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n",
+ cfgno, inum, asnum, d->bEndpointAddress);
+ goto skip_to_next_endpoint_or_interface_descriptor;
+ }
+ }
+
endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
++ifp->desc.bNumEndpoints;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1fa5c0f29c64..a56c75e09786 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -103,8 +103,7 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
static void hub_release(struct kref *kref);
static int usb_reset_and_verify_device(struct usb_device *udev);
-static void hub_usb3_port_prepare_disable(struct usb_hub *hub,
- struct usb_port *port_dev);
+static int hub_port_disable(struct usb_hub *hub, int port1, int set_state);
static inline char *portspeed(struct usb_hub *hub, int portstatus)
{
@@ -903,34 +902,6 @@ static int hub_set_port_link_state(struct usb_hub *hub, int port1,
}
/*
- * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
- * a connection with a plugged-in cable but will signal the host when the cable
- * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
- */
-static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
-{
- struct usb_port *port_dev = hub->ports[port1 - 1];
- struct usb_device *hdev = hub->hdev;
- int ret = 0;
-
- if (!hub->error) {
- if (hub_is_superspeed(hub->hdev)) {
- hub_usb3_port_prepare_disable(hub, port_dev);
- ret = hub_set_port_link_state(hub, port_dev->portnum,
- USB_SS_PORT_LS_U3);
- } else {
- ret = usb_clear_port_feature(hdev, port1,
- USB_PORT_FEAT_ENABLE);
- }
- }
- if (port_dev->child && set_state)
- usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
- if (ret && ret != -ENODEV)
- dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
- return ret;
-}
-
-/*
* Disable a port and mark a logical connect-change event, so that some
* time later hub_wq will disconnect() any existing usb_device on the port
* and will re-enumerate if there actually is a device attached.
@@ -4162,6 +4133,34 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
#endif /* CONFIG_PM */
+/*
+ * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
+ * a connection with a plugged-in cable but will signal the host when the cable
+ * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
+ */
+static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
+{
+ struct usb_port *port_dev = hub->ports[port1 - 1];
+ struct usb_device *hdev = hub->hdev;
+ int ret = 0;
+
+ if (!hub->error) {
+ if (hub_is_superspeed(hub->hdev)) {
+ hub_usb3_port_prepare_disable(hub, port_dev);
+ ret = hub_set_port_link_state(hub, port_dev->portnum,
+ USB_SS_PORT_LS_U3);
+ } else {
+ ret = usb_clear_port_feature(hdev, port1,
+ USB_PORT_FEAT_ENABLE);
+ }
+ }
+ if (port_dev->child && set_state)
+ usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
+ if (ret && ret != -ENODEV)
+ dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
+ return ret;
+}
+
/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
*
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index b95930f20d90..c55db4aa54d6 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -3753,7 +3753,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
hs_ep->desc_list = dma_alloc_coherent(hsotg->dev,
MAX_DMA_DESC_NUM_GENERIC *
sizeof(struct dwc2_dma_desc),
- &hs_ep->desc_list_dma, GFP_KERNEL);
+ &hs_ep->desc_list_dma, GFP_ATOMIC);
if (!hs_ep->desc_list) {
ret = -ENOMEM;
goto error2;
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index a786256535b6..11fe68a4627b 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -247,8 +247,6 @@ MODULE_DEVICE_TABLE(of, dwc2_of_match_table);
static void dwc2_get_device_property(struct dwc2_hsotg *hsotg,
char *property, u8 size, u64 *value)
{
- u8 val8;
- u16 val16;
u32 val32;
switch (size) {
@@ -256,17 +254,7 @@ static void dwc2_get_device_property(struct dwc2_hsotg *hsotg,
*value = device_property_read_bool(hsotg->dev, property);
break;
case 1:
- if (device_property_read_u8(hsotg->dev, property, &val8))
- return;
-
- *value = val8;
- break;
case 2:
- if (device_property_read_u16(hsotg->dev, property, &val16))
- return;
-
- *value = val16;
- break;
case 4:
if (device_property_read_u32(hsotg->dev, property, &val32))
return;
@@ -1100,13 +1088,13 @@ static void dwc2_set_gadget_dma(struct dwc2_hsotg *hsotg)
/* Buffer DMA */
dwc2_set_param_bool(hsotg, &p->g_dma,
false, "gadget-dma",
- true, false,
+ dma_capable, false,
dma_capable);
/* DMA Descriptor */
dwc2_set_param_bool(hsotg, &p->g_dma_desc, false,
"gadget-dma-desc",
- p->g_dma, false,
+ !!hw->dma_desc_enable, false,
!!hw->dma_desc_enable);
}
@@ -1130,8 +1118,14 @@ static void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
dwc2_set_param_bool(hsotg, &p->host_dma,
false, "host-dma",
- true, false,
+ dma_capable, false,
dma_capable);
+ dwc2_set_param_host_rx_fifo_size(hsotg,
+ params->host_rx_fifo_size);
+ dwc2_set_param_host_nperio_tx_fifo_size(hsotg,
+ params->host_nperio_tx_fifo_size);
+ dwc2_set_param_host_perio_tx_fifo_size(hsotg,
+ params->host_perio_tx_fifo_size);
}
dwc2_set_param_dma_desc_enable(hsotg, params->dma_desc_enable);
dwc2_set_param_dma_desc_fs_enable(hsotg, params->dma_desc_fs_enable);
@@ -1140,12 +1134,6 @@ static void dwc2_set_parameters(struct dwc2_hsotg *hsotg,
params->host_support_fs_ls_low_power);
dwc2_set_param_enable_dynamic_fifo(hsotg,
params->enable_dynamic_fifo);
- dwc2_set_param_host_rx_fifo_size(hsotg,
- params->host_rx_fifo_size);
- dwc2_set_param_host_nperio_tx_fifo_size(hsotg,
- params->host_nperio_tx_fifo_size);
- dwc2_set_param_host_perio_tx_fifo_size(hsotg,
- params->host_perio_tx_fifo_size);
dwc2_set_param_max_transfer_size(hsotg,
params->max_transfer_size);
dwc2_set_param_max_packet_count(hsotg,
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index de5a8570be04..14b760209680 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -45,9 +45,7 @@
#define DWC3_XHCI_RESOURCES_NUM 2
#define DWC3_SCRATCHBUF_SIZE 4096 /* each buffer is assumed to be 4KiB */
-#define DWC3_EVENT_SIZE 4 /* bytes */
-#define DWC3_EVENT_MAX_NUM 64 /* 2 events/endpoint */
-#define DWC3_EVENT_BUFFERS_SIZE (DWC3_EVENT_SIZE * DWC3_EVENT_MAX_NUM)
+#define DWC3_EVENT_BUFFERS_SIZE 4096
#define DWC3_EVENT_TYPE_MASK 0xfe
#define DWC3_EVENT_TYPE_DEV 0
@@ -311,9 +309,8 @@
#define DWC3_DCFG_SUPERSPEED_PLUS (5 << 0) /* DWC_usb31 only */
#define DWC3_DCFG_SUPERSPEED (4 << 0)
#define DWC3_DCFG_HIGHSPEED (0 << 0)
-#define DWC3_DCFG_FULLSPEED2 (1 << 0)
+#define DWC3_DCFG_FULLSPEED (1 << 0)
#define DWC3_DCFG_LOWSPEED (2 << 0)
-#define DWC3_DCFG_FULLSPEED1 (3 << 0)
#define DWC3_DCFG_NUMP_SHIFT 17
#define DWC3_DCFG_NUMP(n) (((n) >> DWC3_DCFG_NUMP_SHIFT) & 0x1f)
@@ -405,9 +402,8 @@
#define DWC3_DSTS_SUPERSPEED_PLUS (5 << 0) /* DWC_usb31 only */
#define DWC3_DSTS_SUPERSPEED (4 << 0)
#define DWC3_DSTS_HIGHSPEED (0 << 0)
-#define DWC3_DSTS_FULLSPEED2 (1 << 0)
+#define DWC3_DSTS_FULLSPEED (1 << 0)
#define DWC3_DSTS_LOWSPEED (2 << 0)
-#define DWC3_DSTS_FULLSPEED1 (3 << 0)
/* Device Generic Command Register */
#define DWC3_DGCMD_SET_LMP 0x01
diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c
index 29e80cc9b634..eb1b9cb3f9d1 100644
--- a/drivers/usb/dwc3/dwc3-omap.c
+++ b/drivers/usb/dwc3/dwc3-omap.c
@@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
+#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/platform_data/dwc3-omap.h>
@@ -510,7 +511,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
/* check the DMA Status */
reg = dwc3_omap_readl(omap->base, USBOTGSS_SYSCONFIG);
-
+ irq_set_status_flags(omap->irq, IRQ_NOAUTOEN);
ret = devm_request_threaded_irq(dev, omap->irq, dwc3_omap_interrupt,
dwc3_omap_interrupt_thread, IRQF_SHARED,
"dwc3-omap", omap);
@@ -531,7 +532,7 @@ static int dwc3_omap_probe(struct platform_device *pdev)
}
dwc3_omap_enable_irqs(omap);
-
+ enable_irq(omap->irq);
return 0;
err2:
@@ -552,6 +553,7 @@ static int dwc3_omap_remove(struct platform_device *pdev)
extcon_unregister_notifier(omap->edev, EXTCON_USB, &omap->vbus_nb);
extcon_unregister_notifier(omap->edev, EXTCON_USB_HOST, &omap->id_nb);
dwc3_omap_disable_irqs(omap);
+ disable_irq(omap->irq);
of_platform_depopulate(omap->dev);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c
index 2b73339f286b..cce0a220b6b0 100644
--- a/drivers/usb/dwc3/dwc3-pci.c
+++ b/drivers/usb/dwc3/dwc3-pci.c
@@ -38,6 +38,7 @@
#define PCI_DEVICE_ID_INTEL_BXT_M 0x1aaa
#define PCI_DEVICE_ID_INTEL_APL 0x5aaa
#define PCI_DEVICE_ID_INTEL_KBP 0xa2b0
+#define PCI_DEVICE_ID_INTEL_GLK 0x31aa
#define PCI_INTEL_BXT_DSM_UUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511"
#define PCI_INTEL_BXT_FUNC_PMU_PWR 4
@@ -73,16 +74,6 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc)
{
struct platform_device *dwc3 = dwc->dwc3;
struct pci_dev *pdev = dwc->pci;
- int ret;
-
- struct property_entry sysdev_property[] = {
- PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
- { },
- };
-
- ret = platform_device_add_properties(dwc3, sysdev_property);
- if (ret)
- return ret;
if (pdev->vendor == PCI_VENDOR_ID_AMD &&
pdev->device == PCI_DEVICE_ID_AMD_NL_USB) {
@@ -105,6 +96,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc)
PROPERTY_ENTRY_BOOL("snps,disable_scramble_quirk"),
PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"),
PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"),
+ PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
{ },
};
@@ -115,7 +107,8 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc)
int ret;
struct property_entry properties[] = {
- PROPERTY_ENTRY_STRING("dr-mode", "peripheral"),
+ PROPERTY_ENTRY_STRING("dr_mode", "peripheral"),
+ PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
{ }
};
@@ -167,6 +160,7 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc)
PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"),
PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"),
PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"),
+ PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"),
{ },
};
@@ -274,6 +268,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), },
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK), },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
{ } /* Terminating Entry */
};
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 4878d187c7d4..9bb1f8526f3e 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -39,18 +39,13 @@ static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
struct dwc3_ep *dep, struct dwc3_request *req);
-static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
- u32 len, u32 type, bool chain)
+static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum,
+ dma_addr_t buf_dma, u32 len, u32 type, bool chain)
{
- struct dwc3_gadget_ep_cmd_params params;
struct dwc3_trb *trb;
struct dwc3_ep *dep;
- int ret;
-
dep = dwc->eps[epnum];
- if (dep->flags & DWC3_EP_BUSY)
- return 0;
trb = &dwc->ep0_trb[dep->trb_enqueue];
@@ -71,15 +66,23 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
trb->ctrl |= (DWC3_TRB_CTRL_IOC
| DWC3_TRB_CTRL_LST);
- if (chain)
+ trace_dwc3_prepare_trb(dep, trb);
+}
+
+static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum)
+{
+ struct dwc3_gadget_ep_cmd_params params;
+ struct dwc3_ep *dep;
+ int ret;
+
+ dep = dwc->eps[epnum];
+ if (dep->flags & DWC3_EP_BUSY)
return 0;
memset(&params, 0, sizeof(params));
params.param0 = upper_32_bits(dwc->ep0_trb_addr);
params.param1 = lower_32_bits(dwc->ep0_trb_addr);
- trace_dwc3_prepare_trb(dep, trb);
-
ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, &params);
if (ret < 0)
return ret;
@@ -280,8 +283,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
complete(&dwc->ep0_in_setup);
- ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
+ dwc3_ep0_prepare_one_trb(dwc, 0, dwc->ctrl_req_addr, 8,
DWC3_TRBCTL_CONTROL_SETUP, false);
+ ret = dwc3_ep0_start_trans(dwc, 0);
WARN_ON(ret < 0);
}
@@ -912,9 +916,9 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
dwc->ep0_next_event = DWC3_EP0_COMPLETE;
- ret = dwc3_ep0_start_trans(dwc, epnum,
- dwc->ctrl_req_addr, 0,
- DWC3_TRBCTL_CONTROL_DATA, false);
+ dwc3_ep0_prepare_one_trb(dwc, epnum, dwc->ctrl_req_addr,
+ 0, DWC3_TRBCTL_CONTROL_DATA, false);
+ ret = dwc3_ep0_start_trans(dwc, epnum);
WARN_ON(ret < 0);
}
}
@@ -993,9 +997,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
req->direction = !!dep->number;
if (req->request.length == 0) {
- ret = dwc3_ep0_start_trans(dwc, dep->number,
+ dwc3_ep0_prepare_one_trb(dwc, dep->number,
dwc->ctrl_req_addr, 0,
DWC3_TRBCTL_CONTROL_DATA, false);
+ ret = dwc3_ep0_start_trans(dwc, dep->number);
} else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
&& (dep->number == 0)) {
u32 transfer_size = 0;
@@ -1011,7 +1016,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
if (req->request.length > DWC3_EP0_BOUNCE_SIZE) {
transfer_size = ALIGN(req->request.length - maxpacket,
maxpacket);
- ret = dwc3_ep0_start_trans(dwc, dep->number,
+ dwc3_ep0_prepare_one_trb(dwc, dep->number,
req->request.dma,
transfer_size,
DWC3_TRBCTL_CONTROL_DATA,
@@ -1023,18 +1028,20 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
dwc->ep0_bounced = true;
- ret = dwc3_ep0_start_trans(dwc, dep->number,
+ dwc3_ep0_prepare_one_trb(dwc, dep->number,
dwc->ep0_bounce_addr, transfer_size,
DWC3_TRBCTL_CONTROL_DATA, false);
+ ret = dwc3_ep0_start_trans(dwc, dep->number);
} else {
ret = usb_gadget_map_request_by_dev(dwc->sysdev,
&req->request, dep->number);
if (ret)
return;
- ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma,
+ dwc3_ep0_prepare_one_trb(dwc, dep->number, req->request.dma,
req->request.length, DWC3_TRBCTL_CONTROL_DATA,
false);
+ ret = dwc3_ep0_start_trans(dwc, dep->number);
}
WARN_ON(ret < 0);
@@ -1048,8 +1055,9 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3
: DWC3_TRBCTL_CONTROL_STATUS2;
- return dwc3_ep0_start_trans(dwc, dep->number,
+ dwc3_ep0_prepare_one_trb(dwc, dep->number,
dwc->ctrl_req_addr, 0, type, false);
+ return dwc3_ep0_start_trans(dwc, dep->number);
}
static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index efddaf5d11d1..204c754cc647 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -180,11 +180,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
if (req->request.status == -EINPROGRESS)
req->request.status = status;
- if (dwc->ep0_bounced && dep->number == 0)
+ if (dwc->ep0_bounced && dep->number <= 1)
dwc->ep0_bounced = false;
- else
- usb_gadget_unmap_request_by_dev(dwc->sysdev,
- &req->request, req->direction);
+
+ usb_gadget_unmap_request_by_dev(dwc->sysdev,
+ &req->request, req->direction);
trace_dwc3_gadget_giveback(req);
@@ -1720,7 +1720,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc)
reg |= DWC3_DCFG_LOWSPEED;
break;
case USB_SPEED_FULL:
- reg |= DWC3_DCFG_FULLSPEED1;
+ reg |= DWC3_DCFG_FULLSPEED;
break;
case USB_SPEED_HIGH:
reg |= DWC3_DCFG_HIGHSPEED;
@@ -2232,9 +2232,14 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
dep = dwc->eps[epnum];
- if (!(dep->flags & DWC3_EP_ENABLED) &&
- !(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
- return;
+ if (!(dep->flags & DWC3_EP_ENABLED)) {
+ if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
+ return;
+
+ /* Handle only EPCMDCMPLT when EP disabled */
+ if (event->endpoint_event != DWC3_DEPEVT_EPCMDCMPLT)
+ return;
+ }
if (epnum == 0 || epnum == 1) {
dwc3_ep0_interrupt(dwc, event);
@@ -2531,8 +2536,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
dwc->gadget.ep0->maxpacket = 64;
dwc->gadget.speed = USB_SPEED_HIGH;
break;
- case DWC3_DSTS_FULLSPEED2:
- case DWC3_DSTS_FULLSPEED1:
+ case DWC3_DSTS_FULLSPEED:
dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(64);
dwc->gadget.ep0->maxpacket = 64;
dwc->gadget.speed = USB_SPEED_FULL;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 41ab61f9b6e0..002822d98fda 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1694,9 +1694,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
value = min(w_length, (u16) 1);
break;
- /* function drivers must handle get/set altsetting; if there's
- * no get() method, we know only altsetting zero works.
- */
+ /* function drivers must handle get/set altsetting */
case USB_REQ_SET_INTERFACE:
if (ctrl->bRequestType != USB_RECIP_INTERFACE)
goto unknown;
@@ -1705,7 +1703,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
f = cdev->config->interface[intf];
if (!f)
break;
- if (w_value && !f->set_alt)
+
+ /*
+ * If there's no get_alt() method, we know only altsetting zero
+ * works. There is no need to check if set_alt() is not NULL
+ * as we check this in usb_add_function().
+ */
+ if (w_value && !f->get_alt)
break;
value = f->set_alt(f, w_index, w_value);
if (value == USB_GADGET_DELAYED_STATUS) {
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index aab3fc1dbb94..5e746adc8a2d 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -2091,8 +2091,8 @@ static int __ffs_data_do_entity(enum ffs_entity_type type,
case FFS_STRING:
/*
- * Strings are indexed from 1 (0 is magic ;) reserved
- * for languages list or some such)
+ * Strings are indexed from 1 (0 is reserved
+ * for languages list)
*/
if (*valuep > helper->ffs->strings_count)
helper->ffs->strings_count = *valuep;
@@ -2252,7 +2252,7 @@ static int __ffs_data_do_os_desc(enum ffs_os_desc_type type,
if (len < sizeof(*d) ||
d->bFirstInterfaceNumber >= ffs->interfaces_count ||
- !d->Reserved1)
+ d->Reserved1)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(d->Reserved2); ++i)
if (d->Reserved2[i])
@@ -3666,6 +3666,7 @@ static void ffs_closed(struct ffs_data *ffs)
{
struct ffs_dev *ffs_obj;
struct f_fs_opts *opts;
+ struct config_item *ci;
ENTER();
ffs_dev_lock();
@@ -3689,8 +3690,11 @@ static void ffs_closed(struct ffs_data *ffs)
|| !atomic_read(&opts->func_inst.group.cg_item.ci_kref.refcount))
goto done;
- unregister_gadget_item(ffs_obj->opts->
- func_inst.group.cg_item.ci_parent->ci_parent);
+ ci = opts->func_inst.group.cg_item.ci_parent->ci_parent;
+ ffs_dev_unlock();
+
+ unregister_gadget_item(ci);
+ return;
done:
ffs_dev_unlock();
}
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c
index 3151d2a0fe59..5f8139b8e601 100644
--- a/drivers/usb/gadget/function/f_hid.c
+++ b/drivers/usb/gadget/function/f_hid.c
@@ -593,7 +593,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
}
status = usb_ep_enable(hidg->out_ep);
if (status < 0) {
- ERROR(cdev, "Enable IN endpoint FAILED!\n");
+ ERROR(cdev, "Enable OUT endpoint FAILED!\n");
goto fail;
}
hidg->out_ep->driver_data = hidg;
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
index e8f4102d19df..6bde4396927c 100644
--- a/drivers/usb/gadget/legacy/inode.c
+++ b/drivers/usb/gadget/legacy/inode.c
@@ -1126,7 +1126,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
/* data and/or status stage for control request */
} else if (dev->state == STATE_DEV_SETUP) {
- /* IN DATA+STATUS caller makes len <= wLength */
+ len = min_t(size_t, len, dev->setup_wLength);
if (dev->setup_in) {
retval = setup_req (dev->gadget->ep0, dev->req, len);
if (retval == 0) {
@@ -1734,10 +1734,12 @@ static struct usb_gadget_driver gadgetfs_driver = {
* such as configuration notifications.
*/
-static int is_valid_config (struct usb_config_descriptor *config)
+static int is_valid_config(struct usb_config_descriptor *config,
+ unsigned int total)
{
return config->bDescriptorType == USB_DT_CONFIG
&& config->bLength == USB_DT_CONFIG_SIZE
+ && total >= USB_DT_CONFIG_SIZE
&& config->bConfigurationValue != 0
&& (config->bmAttributes & USB_CONFIG_ATT_ONE) != 0
&& (config->bmAttributes & USB_CONFIG_ATT_WAKEUP) == 0;
@@ -1762,7 +1764,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
}
spin_unlock_irq(&dev->lock);
- if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4))
+ if ((len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) ||
+ (len > PAGE_SIZE * 4))
return -EINVAL;
/* we might need to change message format someday */
@@ -1786,7 +1789,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
/* full or low speed config */
dev->config = (void *) kbuf;
total = le16_to_cpu(dev->config->wTotalLength);
- if (!is_valid_config (dev->config) || total >= length)
+ if (!is_valid_config(dev->config, total) ||
+ total > length - USB_DT_DEVICE_SIZE)
goto fail;
kbuf += total;
length -= total;
@@ -1795,10 +1799,13 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
if (kbuf [1] == USB_DT_CONFIG) {
dev->hs_config = (void *) kbuf;
total = le16_to_cpu(dev->hs_config->wTotalLength);
- if (!is_valid_config (dev->hs_config) || total >= length)
+ if (!is_valid_config(dev->hs_config, total) ||
+ total > length - USB_DT_DEVICE_SIZE)
goto fail;
kbuf += total;
length -= total;
+ } else {
+ dev->hs_config = NULL;
}
/* could support multiple configs, using another encoding! */
@@ -1811,7 +1818,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
|| dev->dev->bDescriptorType != USB_DT_DEVICE
|| dev->dev->bNumConfigurations != 1)
goto fail;
- dev->dev->bNumConfigurations = 1;
dev->dev->bcdUSB = cpu_to_le16 (0x0200);
/* triggers gadgetfs_bind(); then we can enumerate. */
diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 9483489080f6..0402177f93cd 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -1317,7 +1317,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver)
if (!ret)
break;
}
- if (!ret && !udc->driver)
+ if (ret)
+ ret = -ENODEV;
+ else if (udc->driver)
+ ret = -EBUSY;
+ else
goto found;
} else {
list_for_each_entry(udc, &udc_list, list) {
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index 02b14e91ae6c..c60abe3a68f9 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -330,7 +330,7 @@ static void nuke(struct dummy *dum, struct dummy_ep *ep)
/* caller must hold lock */
static void stop_activity(struct dummy *dum)
{
- struct dummy_ep *ep;
+ int i;
/* prevent any more requests */
dum->address = 0;
@@ -338,8 +338,8 @@ static void stop_activity(struct dummy *dum)
/* The timer is left running so that outstanding URBs can fail */
/* nuke any pending requests first, so driver i/o is quiesced */
- list_for_each_entry(ep, &dum->gadget.ep_list, ep.ep_list)
- nuke(dum, ep);
+ for (i = 0; i < DUMMY_ENDPOINTS; ++i)
+ nuke(dum, &dum->ep[i]);
/* driver now does any non-usb quiescing necessary */
}
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index be9e63836881..414e3c376dbb 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -43,7 +43,6 @@ struct at91_usbh_data {
struct gpio_desc *overcurrent_pin[AT91_MAX_USBH_PORTS];
u8 ports; /* number of ports on root hub */
u8 overcurrent_supported;
- u8 vbus_pin_active_low[AT91_MAX_USBH_PORTS];
u8 overcurrent_status[AT91_MAX_USBH_PORTS];
u8 overcurrent_changed[AT91_MAX_USBH_PORTS];
};
@@ -266,8 +265,7 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int
if (!valid_port(port))
return;
- gpiod_set_value(pdata->vbus_pin[port],
- pdata->vbus_pin_active_low[port] ^ enable);
+ gpiod_set_value(pdata->vbus_pin[port], enable);
}
static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
@@ -275,8 +273,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
if (!valid_port(port))
return -EINVAL;
- return gpiod_get_value(pdata->vbus_pin[port]) ^
- pdata->vbus_pin_active_low[port];
+ return gpiod_get_value(pdata->vbus_pin[port]);
}
/*
@@ -533,18 +530,17 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
pdata->ports = ports;
at91_for_each_port(i) {
- pdata->vbus_pin[i] = devm_gpiod_get_optional(&pdev->dev,
- "atmel,vbus-gpio",
- GPIOD_IN);
+ if (i >= pdata->ports)
+ break;
+
+ pdata->vbus_pin[i] =
+ devm_gpiod_get_index_optional(&pdev->dev, "atmel,vbus",
+ i, GPIOD_OUT_HIGH);
if (IS_ERR(pdata->vbus_pin[i])) {
err = PTR_ERR(pdata->vbus_pin[i]);
dev_err(&pdev->dev, "unable to claim gpio \"vbus\": %d\n", err);
continue;
}
-
- pdata->vbus_pin_active_low[i] = gpiod_get_value(pdata->vbus_pin[i]);
-
- ohci_at91_usb_set_power(pdata, i, 1);
}
at91_for_each_port(i) {
@@ -552,8 +548,8 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
break;
pdata->overcurrent_pin[i] =
- devm_gpiod_get_optional(&pdev->dev,
- "atmel,oc-gpio", GPIOD_IN);
+ devm_gpiod_get_index_optional(&pdev->dev, "atmel,oc",
+ i, GPIOD_IN);
if (IS_ERR(pdata->overcurrent_pin[i])) {
err = PTR_ERR(pdata->overcurrent_pin[i]);
dev_err(&pdev->dev, "unable to claim gpio \"overcurrent\": %d\n", err);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 321de2e0161b..8414ed2a02de 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -979,6 +979,40 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
xhci->devs[slot_id] = NULL;
}
+/*
+ * Free a virt_device structure.
+ * If the virt_device added a tt_info (a hub) and has children pointing to
+ * that tt_info, then free the child first. Recursive.
+ * We can't rely on udev at this point to find child-parent relationships.
+ */
+void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_id)
+{
+ struct xhci_virt_device *vdev;
+ struct list_head *tt_list_head;
+ struct xhci_tt_bw_info *tt_info, *next;
+ int i;
+
+ vdev = xhci->devs[slot_id];
+ if (!vdev)
+ return;
+
+ tt_list_head = &(xhci->rh_bw[vdev->real_port - 1].tts);
+ list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) {
+ /* is this a hub device that added a tt_info to the tts list */
+ if (tt_info->slot_id == slot_id) {
+ /* are any devices using this tt_info? */
+ for (i = 1; i < HCS_MAX_SLOTS(xhci->hcs_params1); i++) {
+ vdev = xhci->devs[i];
+ if (vdev && (vdev->tt_info == tt_info))
+ xhci_free_virt_devices_depth_first(
+ xhci, i);
+ }
+ }
+ }
+ /* we are now at a leaf device */
+ xhci_free_virt_device(xhci, slot_id);
+}
+
int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
struct usb_device *udev, gfp_t flags)
{
@@ -1795,7 +1829,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
int size;
int i, j, num_ports;
- del_timer_sync(&xhci->cmd_timer);
+ cancel_delayed_work_sync(&xhci->cmd_timer);
/* Free the Event Ring Segment Table and the actual Event Ring */
size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
@@ -1828,8 +1862,8 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
}
}
- for (i = 1; i < MAX_HC_SLOTS; ++i)
- xhci_free_virt_device(xhci, i);
+ for (i = HCS_MAX_SLOTS(xhci->hcs_params1); i > 0; i--)
+ xhci_free_virt_devices_depth_first(xhci, i);
dma_pool_destroy(xhci->segment_pool);
xhci->segment_pool = NULL;
@@ -2342,9 +2376,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
INIT_LIST_HEAD(&xhci->cmd_list);
- /* init command timeout timer */
- setup_timer(&xhci->cmd_timer, xhci_handle_command_timeout,
- (unsigned long)xhci);
+ /* init command timeout work */
+ INIT_DELAYED_WORK(&xhci->cmd_timer, xhci_handle_command_timeout);
+ init_completion(&xhci->cmd_ring_stop_completion);
page_size = readl(&xhci->op_regs->page_size);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 1094ebd2838f..bac961cd24ad 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -579,8 +579,10 @@ static int xhci_mtk_probe(struct platform_device *pdev)
goto disable_ldos;
irq = platform_get_irq(pdev, 0);
- if (irq < 0)
+ if (irq < 0) {
+ ret = irq;
goto disable_clk;
+ }
/* Initialize dma_mask and coherent_dma_mask to 32-bits */
ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index e96ae80d107e..954abfd5014d 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -165,7 +165,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI ||
- pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) {
+ pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI ||
+ pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI)) {
xhci->quirks |= XHCI_PME_STUCK_QUIRK;
}
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index bdf6b13d9b67..25f522b09dd9 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -279,23 +279,76 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci)
readl(&xhci->dba->doorbell[0]);
}
-static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
+static bool xhci_mod_cmd_timer(struct xhci_hcd *xhci, unsigned long delay)
+{
+ return mod_delayed_work(system_wq, &xhci->cmd_timer, delay);
+}
+
+static struct xhci_command *xhci_next_queued_cmd(struct xhci_hcd *xhci)
+{
+ return list_first_entry_or_null(&xhci->cmd_list, struct xhci_command,
+ cmd_list);
+}
+
+/*
+ * Turn all commands on command ring with status set to "aborted" to no-op trbs.
+ * If there are other commands waiting then restart the ring and kick the timer.
+ * This must be called with command ring stopped and xhci->lock held.
+ */
+static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
+ struct xhci_command *cur_cmd)
+{
+ struct xhci_command *i_cmd;
+ u32 cycle_state;
+
+ /* Turn all aborted commands in list to no-ops, then restart */
+ list_for_each_entry(i_cmd, &xhci->cmd_list, cmd_list) {
+
+ if (i_cmd->status != COMP_CMD_ABORT)
+ continue;
+
+ i_cmd->status = COMP_CMD_STOP;
+
+ xhci_dbg(xhci, "Turn aborted command %p to no-op\n",
+ i_cmd->command_trb);
+ /* get cycle state from the original cmd trb */
+ cycle_state = le32_to_cpu(
+ i_cmd->command_trb->generic.field[3]) & TRB_CYCLE;
+ /* modify the command trb to no-op command */
+ i_cmd->command_trb->generic.field[0] = 0;
+ i_cmd->command_trb->generic.field[1] = 0;
+ i_cmd->command_trb->generic.field[2] = 0;
+ i_cmd->command_trb->generic.field[3] = cpu_to_le32(
+ TRB_TYPE(TRB_CMD_NOOP) | cycle_state);
+
+ /*
+ * caller waiting for completion is called when command
+ * completion event is received for these no-op commands
+ */
+ }
+
+ xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
+
+ /* ring command ring doorbell to restart the command ring */
+ if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) &&
+ !(xhci->xhc_state & XHCI_STATE_DYING)) {
+ xhci->current_cmd = cur_cmd;
+ xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
+ xhci_ring_cmd_db(xhci);
+ }
+}
+
+/* Must be called with xhci->lock held, releases and aquires lock back */
+static int xhci_abort_cmd_ring(struct xhci_hcd *xhci, unsigned long flags)
{
u64 temp_64;
int ret;
xhci_dbg(xhci, "Abort command ring\n");
- temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
- xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
+ reinit_completion(&xhci->cmd_ring_stop_completion);
- /*
- * Writing the CMD_RING_ABORT bit should cause a cmd completion event,
- * however on some host hw the CMD_RING_RUNNING bit is correctly cleared
- * but the completion event in never sent. Use the cmd timeout timer to
- * handle those cases. Use twice the time to cover the bit polling retry
- */
- mod_timer(&xhci->cmd_timer, jiffies + (2 * XHCI_CMD_DEFAULT_TIMEOUT));
+ temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
&xhci->op_regs->cmd_ring);
@@ -315,17 +368,30 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
udelay(1000);
ret = xhci_handshake(&xhci->op_regs->cmd_ring,
CMD_RING_RUNNING, 0, 3 * 1000 * 1000);
- if (ret == 0)
- return 0;
-
- xhci_err(xhci, "Stopped the command ring failed, "
- "maybe the host is dead\n");
- del_timer(&xhci->cmd_timer);
- xhci->xhc_state |= XHCI_STATE_DYING;
- xhci_halt(xhci);
- return -ESHUTDOWN;
+ if (ret < 0) {
+ xhci_err(xhci, "Stopped the command ring failed, "
+ "maybe the host is dead\n");
+ xhci->xhc_state |= XHCI_STATE_DYING;
+ xhci_halt(xhci);
+ return -ESHUTDOWN;
+ }
+ }
+ /*
+ * Writing the CMD_RING_ABORT bit should cause a cmd completion event,
+ * however on some host hw the CMD_RING_RUNNING bit is correctly cleared
+ * but the completion event in never sent. Wait 2 secs (arbitrary
+ * number) to handle those cases after negation of CMD_RING_RUNNING.
+ */
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ ret = wait_for_completion_timeout(&xhci->cmd_ring_stop_completion,
+ msecs_to_jiffies(2000));
+ spin_lock_irqsave(&xhci->lock, flags);
+ if (!ret) {
+ xhci_dbg(xhci, "No stop event for abort, ring start fail?\n");
+ xhci_cleanup_command_queue(xhci);
+ } else {
+ xhci_handle_stopped_cmd_ring(xhci, xhci_next_queued_cmd(xhci));
}
-
return 0;
}
@@ -1207,101 +1273,62 @@ void xhci_cleanup_command_queue(struct xhci_hcd *xhci)
xhci_complete_del_and_free_cmd(cur_cmd, COMP_CMD_ABORT);
}
-/*
- * Turn all commands on command ring with status set to "aborted" to no-op trbs.
- * If there are other commands waiting then restart the ring and kick the timer.
- * This must be called with command ring stopped and xhci->lock held.
- */
-static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci,
- struct xhci_command *cur_cmd)
-{
- struct xhci_command *i_cmd, *tmp_cmd;
- u32 cycle_state;
-
- /* Turn all aborted commands in list to no-ops, then restart */
- list_for_each_entry_safe(i_cmd, tmp_cmd, &xhci->cmd_list,
- cmd_list) {
-
- if (i_cmd->status != COMP_CMD_ABORT)
- continue;
-
- i_cmd->status = COMP_CMD_STOP;
-
- xhci_dbg(xhci, "Turn aborted command %p to no-op\n",
- i_cmd->command_trb);
- /* get cycle state from the original cmd trb */
- cycle_state = le32_to_cpu(
- i_cmd->command_trb->generic.field[3]) & TRB_CYCLE;
- /* modify the command trb to no-op command */
- i_cmd->command_trb->generic.field[0] = 0;
- i_cmd->command_trb->generic.field[1] = 0;
- i_cmd->command_trb->generic.field[2] = 0;
- i_cmd->command_trb->generic.field[3] = cpu_to_le32(
- TRB_TYPE(TRB_CMD_NOOP) | cycle_state);
-
- /*
- * caller waiting for completion is called when command
- * completion event is received for these no-op commands
- */
- }
-
- xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
-
- /* ring command ring doorbell to restart the command ring */
- if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) &&
- !(xhci->xhc_state & XHCI_STATE_DYING)) {
- xhci->current_cmd = cur_cmd;
- mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT);
- xhci_ring_cmd_db(xhci);
- }
- return;
-}
-
-
-void xhci_handle_command_timeout(unsigned long data)
+void xhci_handle_command_timeout(struct work_struct *work)
{
struct xhci_hcd *xhci;
int ret;
unsigned long flags;
u64 hw_ring_state;
- bool second_timeout = false;
- xhci = (struct xhci_hcd *) data;
- /* mark this command to be cancelled */
+ xhci = container_of(to_delayed_work(work), struct xhci_hcd, cmd_timer);
+
spin_lock_irqsave(&xhci->lock, flags);
- if (xhci->current_cmd) {
- if (xhci->current_cmd->status == COMP_CMD_ABORT)
- second_timeout = true;
- xhci->current_cmd->status = COMP_CMD_ABORT;
+
+ /*
+ * If timeout work is pending, or current_cmd is NULL, it means we
+ * raced with command completion. Command is handled so just return.
+ */
+ if (!xhci->current_cmd || delayed_work_pending(&xhci->cmd_timer)) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ return;
}
+ /* mark this command to be cancelled */
+ xhci->current_cmd->status = COMP_CMD_ABORT;
/* Make sure command ring is running before aborting it */
hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) &&
(hw_ring_state & CMD_RING_RUNNING)) {
- spin_unlock_irqrestore(&xhci->lock, flags);
+ /* Prevent new doorbell, and start command abort */
+ xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
xhci_dbg(xhci, "Command timeout\n");
- ret = xhci_abort_cmd_ring(xhci);
+ ret = xhci_abort_cmd_ring(xhci, flags);
if (unlikely(ret == -ESHUTDOWN)) {
xhci_err(xhci, "Abort command ring failed\n");
xhci_cleanup_command_queue(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);
xhci_dbg(xhci, "xHCI host controller is dead.\n");
+
+ return;
}
- return;
+
+ goto time_out_completed;
}
- /* command ring failed to restart, or host removed. Bail out */
- if (second_timeout || xhci->xhc_state & XHCI_STATE_REMOVING) {
- spin_unlock_irqrestore(&xhci->lock, flags);
- xhci_dbg(xhci, "command timed out twice, ring start fail?\n");
+ /* host removed. Bail out */
+ if (xhci->xhc_state & XHCI_STATE_REMOVING) {
+ xhci_dbg(xhci, "host removed, ring start fail?\n");
xhci_cleanup_command_queue(xhci);
- return;
+
+ goto time_out_completed;
}
/* command timeout on stopped ring, ring can't be aborted */
xhci_dbg(xhci, "Command timeout on stopped ring\n");
xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd);
+
+time_out_completed:
spin_unlock_irqrestore(&xhci->lock, flags);
return;
}
@@ -1333,7 +1360,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list);
- del_timer(&xhci->cmd_timer);
+ cancel_delayed_work(&xhci->cmd_timer);
trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event);
@@ -1341,7 +1368,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
/* If CMD ring stopped we own the trbs between enqueue and dequeue */
if (cmd_comp_code == COMP_CMD_STOP) {
- xhci_handle_stopped_cmd_ring(xhci, cmd);
+ complete_all(&xhci->cmd_ring_stop_completion);
return;
}
@@ -1359,8 +1386,11 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
*/
if (cmd_comp_code == COMP_CMD_ABORT) {
xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
- if (cmd->status == COMP_CMD_ABORT)
+ if (cmd->status == COMP_CMD_ABORT) {
+ if (xhci->current_cmd == cmd)
+ xhci->current_cmd = NULL;
goto event_handled;
+ }
}
cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb->generic.field[3]));
@@ -1421,7 +1451,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
if (cmd->cmd_list.next != &xhci->cmd_list) {
xhci->current_cmd = list_entry(cmd->cmd_list.next,
struct xhci_command, cmd_list);
- mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT);
+ xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
+ } else if (xhci->current_cmd == cmd) {
+ xhci->current_cmd = NULL;
}
event_handled:
@@ -1939,8 +1971,9 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
struct xhci_ep_ctx *ep_ctx;
u32 trb_comp_code;
u32 remaining, requested;
- bool on_data_stage;
+ u32 trb_type;
+ trb_type = TRB_FIELD_TO_TYPE(le32_to_cpu(ep_trb->generic.field[3]));
slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
xdev = xhci->devs[slot_id];
ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1;
@@ -1950,14 +1983,11 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
requested = td->urb->transfer_buffer_length;
remaining = EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
- /* not setup (dequeue), or status stage means we are at data stage */
- on_data_stage = (ep_trb != ep_ring->dequeue && ep_trb != td->last_trb);
-
switch (trb_comp_code) {
case COMP_SUCCESS:
- if (ep_trb != td->last_trb) {
+ if (trb_type != TRB_STATUS) {
xhci_warn(xhci, "WARN: Success on ctrl %s TRB without IOC set?\n",
- on_data_stage ? "data" : "setup");
+ (trb_type == TRB_DATA) ? "data" : "setup");
*status = -ESHUTDOWN;
break;
}
@@ -1967,15 +1997,25 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
*status = 0;
break;
case COMP_STOP_SHORT:
- if (on_data_stage)
+ if (trb_type == TRB_DATA || trb_type == TRB_NORMAL)
td->urb->actual_length = remaining;
else
xhci_warn(xhci, "WARN: Stopped Short Packet on ctrl setup or status TRB\n");
goto finish_td;
case COMP_STOP:
- if (on_data_stage)
+ switch (trb_type) {
+ case TRB_SETUP:
+ td->urb->actual_length = 0;
+ goto finish_td;
+ case TRB_DATA:
+ case TRB_NORMAL:
td->urb->actual_length = requested - remaining;
- goto finish_td;
+ goto finish_td;
+ default:
+ xhci_warn(xhci, "WARN: unexpected TRB Type %d\n",
+ trb_type);
+ goto finish_td;
+ }
case COMP_STOP_INVAL:
goto finish_td;
default:
@@ -1987,7 +2027,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
/* else fall through */
case COMP_STALL:
/* Did we transfer part of the data (middle) phase? */
- if (on_data_stage)
+ if (trb_type == TRB_DATA || trb_type == TRB_NORMAL)
td->urb->actual_length = requested - remaining;
else if (!td->urb_length_set)
td->urb->actual_length = 0;
@@ -1995,14 +2035,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
}
/* stopped at setup stage, no data transferred */
- if (ep_trb == ep_ring->dequeue)
+ if (trb_type == TRB_SETUP)
goto finish_td;
/*
* if on data stage then update the actual_length of the URB and flag it
* as set, so it won't be overwritten in the event for the last TRB.
*/
- if (on_data_stage) {
+ if (trb_type == TRB_DATA ||
+ trb_type == TRB_NORMAL) {
td->urb_length_set = true;
td->urb->actual_length = requested - remaining;
xhci_dbg(xhci, "Waiting for status stage event\n");
@@ -3790,9 +3831,9 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd,
/* if there are no other commands queued we start the timeout timer */
if (xhci->cmd_list.next == &cmd->cmd_list &&
- !timer_pending(&xhci->cmd_timer)) {
+ !delayed_work_pending(&xhci->cmd_timer)) {
xhci->current_cmd = cmd;
- mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT);
+ xhci_mod_cmd_timer(xhci, XHCI_CMD_DEFAULT_TIMEOUT);
}
queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3,
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 1cd56417cbec..0c8deb9ed42d 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3787,8 +3787,10 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
mutex_lock(&xhci->mutex);
- if (xhci->xhc_state) /* dying, removing or halted */
+ if (xhci->xhc_state) { /* dying, removing or halted */
+ ret = -ESHUTDOWN;
goto out;
+ }
if (!udev->slot_id) {
xhci_dbg_trace(xhci, trace_xhci_dbg_address,
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8ccc11a974b8..2d7b6374b58d 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1568,7 +1568,8 @@ struct xhci_hcd {
#define CMD_RING_STATE_STOPPED (1 << 2)
struct list_head cmd_list;
unsigned int cmd_ring_reserved_trbs;
- struct timer_list cmd_timer;
+ struct delayed_work cmd_timer;
+ struct completion cmd_ring_stop_completion;
struct xhci_command *current_cmd;
struct xhci_ring *event_ring;
struct xhci_erst erst;
@@ -1934,7 +1935,7 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
unsigned int slot_id, unsigned int ep_index,
struct xhci_dequeue_state *deq_state);
void xhci_stop_endpoint_command_watchdog(unsigned long arg);
-void xhci_handle_command_timeout(unsigned long data);
+void xhci_handle_command_timeout(struct work_struct *work);
void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id,
unsigned int ep_index, unsigned int stream_id);
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index 310238c6b5cd..896798071817 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -469,6 +469,7 @@ static const struct musb_platform_ops bfin_ops = {
.init = bfin_musb_init,
.exit = bfin_musb_exit,
+ .fifo_offset = bfin_fifo_offset,
.readb = bfin_readb,
.writeb = bfin_writeb,
.readw = bfin_readw,
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 9e226468a13e..fca288bbc800 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2050,6 +2050,7 @@ struct musb_pending_work {
struct list_head node;
};
+#ifdef CONFIG_PM
/*
* Called from musb_runtime_resume(), musb_resume(), and
* musb_queue_resume_work(). Callers must take musb->lock.
@@ -2077,6 +2078,7 @@ static int musb_run_resume_work(struct musb *musb)
return error;
}
+#endif
/*
* Called to run work if device is active or else queue the work to happen
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index a611e2f67bdc..ade902ea1221 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -216,6 +216,7 @@ struct musb_platform_ops {
void (*pre_root_reset_end)(struct musb *musb);
void (*post_root_reset_end)(struct musb *musb);
int (*phy_callback)(enum musb_vbus_id_status status);
+ void (*clear_ep_rxintr)(struct musb *musb, int epnum);
};
/*
@@ -626,6 +627,12 @@ static inline void musb_platform_post_root_reset_end(struct musb *musb)
musb->ops->post_root_reset_end(musb);
}
+static inline void musb_platform_clear_ep_rxintr(struct musb *musb, int epnum)
+{
+ if (musb->ops->clear_ep_rxintr)
+ musb->ops->clear_ep_rxintr(musb, epnum);
+}
+
/*
* gets the "dr_mode" property from DT and converts it into musb_mode
* if the property is not found or not recognized returns MUSB_OTG
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index feae1561b9ab..9f125e179acd 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -267,6 +267,17 @@ static void otg_timer(unsigned long _musb)
pm_runtime_put_autosuspend(dev);
}
+void dsps_musb_clear_ep_rxintr(struct musb *musb, int epnum)
+{
+ u32 epintr;
+ struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent);
+ const struct dsps_musb_wrapper *wrp = glue->wrp;
+
+ /* musb->lock might already been held */
+ epintr = (1 << epnum) << wrp->rxep_shift;
+ musb_writel(musb->ctrl_base, wrp->epintr_status, epintr);
+}
+
static irqreturn_t dsps_interrupt(int irq, void *hci)
{
struct musb *musb = hci;
@@ -622,6 +633,7 @@ static struct musb_platform_ops dsps_ops = {
.set_mode = dsps_musb_set_mode,
.recover = dsps_musb_recover,
+ .clear_ep_rxintr = dsps_musb_clear_ep_rxintr,
};
static u64 musb_dmamask = DMA_BIT_MASK(32);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index f6cdbad00dac..ac3a4952abb4 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2374,12 +2374,11 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
int is_in = usb_pipein(urb->pipe);
int status = 0;
u16 csr;
+ struct dma_channel *dma = NULL;
musb_ep_select(regs, hw_end);
if (is_dma_capable()) {
- struct dma_channel *dma;
-
dma = is_in ? ep->rx_channel : ep->tx_channel;
if (dma) {
status = ep->musb->dma_controller->channel_abort(dma);
@@ -2395,10 +2394,9 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
/* giveback saves bulk toggle */
csr = musb_h_flush_rxfifo(ep, 0);
- /* REVISIT we still get an irq; should likely clear the
- * endpoint's irq status here to avoid bogus irqs.
- * clearing that status is platform-specific...
- */
+ /* clear the endpoint's irq status here to avoid bogus irqs */
+ if (is_dma_capable() && dma)
+ musb_platform_clear_ep_rxintr(musb, ep->epnum);
} else if (ep->epnum) {
musb_h_tx_flush_fifo(ep);
csr = musb_readw(epio, MUSB_TXCSR);
diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h
index f7b13fd25257..a3dcbd55e436 100644
--- a/drivers/usb/musb/musbhsdma.h
+++ b/drivers/usb/musb/musbhsdma.h
@@ -157,5 +157,5 @@ struct musb_dma_controller {
void __iomem *base;
u8 channel_count;
u8 used_channels;
- u8 irq;
+ int irq;
};
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 5f17a3b9916d..80260b08398b 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -50,6 +50,7 @@
#define CYBERJACK_PRODUCT_ID 0x0100
/* Function prototypes */
+static int cyberjack_attach(struct usb_serial *serial);
static int cyberjack_port_probe(struct usb_serial_port *port);
static int cyberjack_port_remove(struct usb_serial_port *port);
static int cyberjack_open(struct tty_struct *tty,
@@ -77,6 +78,7 @@ static struct usb_serial_driver cyberjack_device = {
.description = "Reiner SCT Cyberjack USB card reader",
.id_table = id_table,
.num_ports = 1,
+ .attach = cyberjack_attach,
.port_probe = cyberjack_port_probe,
.port_remove = cyberjack_port_remove,
.open = cyberjack_open,
@@ -100,6 +102,14 @@ struct cyberjack_private {
short wrsent; /* Data already sent */
};
+static int cyberjack_attach(struct usb_serial *serial)
+{
+ if (serial->num_bulk_out < serial->num_ports)
+ return -ENODEV;
+
+ return 0;
+}
+
static int cyberjack_port_probe(struct usb_serial_port *port)
{
struct cyberjack_private *priv;
diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c
index 8282a6a18fee..22f23a429a95 100644
--- a/drivers/usb/serial/f81534.c
+++ b/drivers/usb/serial/f81534.c
@@ -1237,6 +1237,7 @@ static int f81534_attach(struct usb_serial *serial)
static int f81534_port_probe(struct usb_serial_port *port)
{
struct f81534_port_private *port_priv;
+ int ret;
port_priv = devm_kzalloc(&port->dev, sizeof(*port_priv), GFP_KERNEL);
if (!port_priv)
@@ -1246,10 +1247,11 @@ static int f81534_port_probe(struct usb_serial_port *port)
mutex_init(&port_priv->mcr_mutex);
/* Assign logic-to-phy mapping */
- port_priv->phy_num = f81534_logic_to_phy_port(port->serial, port);
- if (port_priv->phy_num < 0 || port_priv->phy_num >= F81534_NUM_PORT)
- return -ENODEV;
+ ret = f81534_logic_to_phy_port(port->serial, port);
+ if (ret < 0)
+ return ret;
+ port_priv->phy_num = ret;
usb_set_serial_port_data(port, port_priv);
dev_dbg(&port->dev, "%s: port_number: %d, phy_num: %d\n", __func__,
port->port_number, port_priv->phy_num);
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 97cabf803c2f..b2f2e87aed94 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1043,6 +1043,7 @@ static int garmin_write_bulk(struct usb_serial_port *port,
"%s - usb_submit_urb(write bulk) failed with status = %d\n",
__func__, status);
count = status;
+ kfree(buffer);
}
/* we are done with this urb, so let the host driver
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index dcc0c58aaad5..d50e5773483f 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -2751,6 +2751,11 @@ static int edge_startup(struct usb_serial *serial)
EDGE_COMPATIBILITY_MASK1,
EDGE_COMPATIBILITY_MASK2 };
+ if (serial->num_bulk_in < 1 || serial->num_interrupt_in < 1) {
+ dev_err(&serial->interface->dev, "missing endpoints\n");
+ return -ENODEV;
+ }
+
dev = serial->dev;
/* create our private serial structure */
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index c339163698eb..9a0db2965fbb 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -1499,8 +1499,7 @@ static int do_boot_mode(struct edgeport_serial *serial,
dev_dbg(dev, "%s - Download successful -- Device rebooting...\n", __func__);
- /* return an error on purpose */
- return -ENODEV;
+ return 1;
}
stayinbootmode:
@@ -1508,7 +1507,7 @@ stayinbootmode:
dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__);
serial->product_info.TiMode = TI_MODE_BOOT;
- return 0;
+ return 1;
}
static int ti_do_config(struct edgeport_port *port, int feature, int on)
@@ -2546,6 +2545,13 @@ static int edge_startup(struct usb_serial *serial)
int status;
u16 product_id;
+ /* Make sure we have the required endpoints when in download mode. */
+ if (serial->interface->cur_altsetting->desc.bNumEndpoints > 1) {
+ if (serial->num_bulk_in < serial->num_ports ||
+ serial->num_bulk_out < serial->num_ports)
+ return -ENODEV;
+ }
+
/* create our private serial structure */
edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL);
if (!edge_serial)
@@ -2553,14 +2559,18 @@ static int edge_startup(struct usb_serial *serial)
mutex_init(&edge_serial->es_lock);
edge_serial->serial = serial;
+ INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work);
usb_set_serial_data(serial, edge_serial);
status = download_fw(edge_serial);
- if (status) {
+ if (status < 0) {
kfree(edge_serial);
return status;
}
+ if (status > 0)
+ return 1; /* bind but do not register any ports */
+
product_id = le16_to_cpu(
edge_serial->serial->dev->descriptor.idProduct);
@@ -2572,7 +2582,6 @@ static int edge_startup(struct usb_serial *serial)
}
}
- INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work);
edge_heartbeat_schedule(edge_serial);
return 0;
@@ -2580,6 +2589,9 @@ static int edge_startup(struct usb_serial *serial)
static void edge_disconnect(struct usb_serial *serial)
{
+ struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
+
+ cancel_delayed_work_sync(&edge_serial->heartbeat_work);
}
static void edge_release(struct usb_serial *serial)
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 344b4eea4bd5..d57fb5199218 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -68,6 +68,16 @@ struct iuu_private {
u32 clk;
};
+static int iuu_attach(struct usb_serial *serial)
+{
+ unsigned char num_ports = serial->num_ports;
+
+ if (serial->num_bulk_in < num_ports || serial->num_bulk_out < num_ports)
+ return -ENODEV;
+
+ return 0;
+}
+
static int iuu_port_probe(struct usb_serial_port *port)
{
struct iuu_private *priv;
@@ -1196,6 +1206,7 @@ static struct usb_serial_driver iuu_device = {
.tiocmset = iuu_tiocmset,
.set_termios = iuu_set_termios,
.init_termios = iuu_init_termios,
+ .attach = iuu_attach,
.port_probe = iuu_port_probe,
.port_remove = iuu_port_remove,
};
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index e49ad0c63ad8..83523fcf6fb9 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -699,6 +699,19 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
#endif
+static int keyspan_pda_attach(struct usb_serial *serial)
+{
+ unsigned char num_ports = serial->num_ports;
+
+ if (serial->num_bulk_out < num_ports ||
+ serial->num_interrupt_in < num_ports) {
+ dev_err(&serial->interface->dev, "missing endpoints\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static int keyspan_pda_port_probe(struct usb_serial_port *port)
{
@@ -776,6 +789,7 @@ static struct usb_serial_driver keyspan_pda_device = {
.break_ctl = keyspan_pda_break_ctl,
.tiocmget = keyspan_pda_tiocmget,
.tiocmset = keyspan_pda_tiocmset,
+ .attach = keyspan_pda_attach,
.port_probe = keyspan_pda_port_probe,
.port_remove = keyspan_pda_port_remove,
};
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 2363654cafc9..813035f51fe7 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -51,6 +51,7 @@
/* Function prototypes */
+static int kobil_attach(struct usb_serial *serial);
static int kobil_port_probe(struct usb_serial_port *probe);
static int kobil_port_remove(struct usb_serial_port *probe);
static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
@@ -86,6 +87,7 @@ static struct usb_serial_driver kobil_device = {
.description = "KOBIL USB smart card terminal",
.id_table = id_table,
.num_ports = 1,
+ .attach = kobil_attach,
.port_probe = kobil_port_probe,
.port_remove = kobil_port_remove,
.ioctl = kobil_ioctl,
@@ -113,6 +115,16 @@ struct kobil_private {
};
+static int kobil_attach(struct usb_serial *serial)
+{
+ if (serial->num_interrupt_out < serial->num_ports) {
+ dev_err(&serial->interface->dev, "missing interrupt-out endpoint\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static int kobil_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index d52caa03679c..91bc170b408a 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -65,8 +65,6 @@ struct moschip_port {
struct urb *write_urb_pool[NUM_URBS];
};
-static struct usb_serial_driver moschip7720_2port_driver;
-
#define USB_VENDOR_ID_MOSCHIP 0x9710
#define MOSCHIP_DEVICE_ID_7720 0x7720
#define MOSCHIP_DEVICE_ID_7715 0x7715
@@ -970,25 +968,6 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
tty_port_tty_wakeup(&mos7720_port->port->port);
}
-/*
- * mos77xx_probe
- * this function installs the appropriate read interrupt endpoint callback
- * depending on whether the device is a 7720 or 7715, thus avoiding costly
- * run-time checks in the high-frequency callback routine itself.
- */
-static int mos77xx_probe(struct usb_serial *serial,
- const struct usb_device_id *id)
-{
- if (id->idProduct == MOSCHIP_DEVICE_ID_7715)
- moschip7720_2port_driver.read_int_callback =
- mos7715_interrupt_callback;
- else
- moschip7720_2port_driver.read_int_callback =
- mos7720_interrupt_callback;
-
- return 0;
-}
-
static int mos77xx_calc_num_ports(struct usb_serial *serial)
{
u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
@@ -1917,6 +1896,11 @@ static int mos7720_startup(struct usb_serial *serial)
u16 product;
int ret_val;
+ if (serial->num_bulk_in < 2 || serial->num_bulk_out < 2) {
+ dev_err(&serial->interface->dev, "missing bulk endpoints\n");
+ return -ENODEV;
+ }
+
product = le16_to_cpu(serial->dev->descriptor.idProduct);
dev = serial->dev;
@@ -1941,19 +1925,18 @@ static int mos7720_startup(struct usb_serial *serial)
tmp->interrupt_in_endpointAddress;
serial->port[1]->interrupt_in_urb = NULL;
serial->port[1]->interrupt_in_buffer = NULL;
+
+ if (serial->port[0]->interrupt_in_urb) {
+ struct urb *urb = serial->port[0]->interrupt_in_urb;
+
+ urb->complete = mos7715_interrupt_callback;
+ }
}
/* setting configuration feature to one */
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000);
- /* start the interrupt urb */
- ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
- if (ret_val)
- dev_err(&dev->dev,
- "%s - Error %d submitting control urb\n",
- __func__, ret_val);
-
#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
if (product == MOSCHIP_DEVICE_ID_7715) {
ret_val = mos7715_parport_init(serial);
@@ -1961,6 +1944,13 @@ static int mos7720_startup(struct usb_serial *serial)
return ret_val;
}
#endif
+ /* start the interrupt urb */
+ ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL);
+ if (ret_val) {
+ dev_err(&dev->dev, "failed to submit interrupt urb: %d\n",
+ ret_val);
+ }
+
/* LSR For Port 1 */
read_mos_reg(serial, 0, MOS7720_LSR, &data);
dev_dbg(&dev->dev, "LSR:%x\n", data);
@@ -1970,6 +1960,8 @@ static int mos7720_startup(struct usb_serial *serial)
static void mos7720_release(struct usb_serial *serial)
{
+ usb_kill_urb(serial->port[0]->interrupt_in_urb);
+
#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
/* close the parallel port */
@@ -2019,11 +2011,6 @@ static int mos7720_port_probe(struct usb_serial_port *port)
if (!mos7720_port)
return -ENOMEM;
- /* Initialize all port interrupt end point to port 0 int endpoint.
- * Our device has only one interrupt endpoint common to all ports.
- */
- port->interrupt_in_endpointAddress =
- port->serial->port[0]->interrupt_in_endpointAddress;
mos7720_port->port = port;
usb_set_serial_port_data(port, mos7720_port);
@@ -2053,7 +2040,6 @@ static struct usb_serial_driver moschip7720_2port_driver = {
.close = mos7720_close,
.throttle = mos7720_throttle,
.unthrottle = mos7720_unthrottle,
- .probe = mos77xx_probe,
.attach = mos7720_startup,
.release = mos7720_release,
.port_probe = mos7720_port_probe,
@@ -2067,7 +2053,7 @@ static struct usb_serial_driver moschip7720_2port_driver = {
.chars_in_buffer = mos7720_chars_in_buffer,
.break_ctl = mos7720_break,
.read_bulk_callback = mos7720_bulk_in_callback,
- .read_int_callback = NULL /* dynamically assigned in probe() */
+ .read_int_callback = mos7720_interrupt_callback,
};
static struct usb_serial_driver * const serial_drivers[] = {
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 9a220b8e810f..ea27fb23967a 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -214,7 +214,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
struct moschip_port {
int port_num; /*Actual port number in the device(1,2,etc) */
- struct urb *write_urb; /* write URB for this port */
struct urb *read_urb; /* read URB for this port */
__u8 shadowLCR; /* last LCR value received */
__u8 shadowMCR; /* last MCR value received */
@@ -1037,9 +1036,7 @@ static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
serial,
serial->port[0]->interrupt_in_urb->interval);
- /* start interrupt read for mos7840 *
- * will continue as long as mos7840 is connected */
-
+ /* start interrupt read for mos7840 */
response =
usb_submit_urb(serial->port[0]->interrupt_in_urb,
GFP_KERNEL);
@@ -1186,7 +1183,6 @@ static void mos7840_close(struct usb_serial_port *port)
}
}
- usb_kill_urb(mos7840_port->write_urb);
usb_kill_urb(mos7840_port->read_urb);
mos7840_port->read_urb_busy = false;
@@ -1199,12 +1195,6 @@ static void mos7840_close(struct usb_serial_port *port)
}
}
- if (mos7840_port->write_urb) {
- /* if this urb had a transfer buffer already (old tx) free it */
- kfree(mos7840_port->write_urb->transfer_buffer);
- usb_free_urb(mos7840_port->write_urb);
- }
-
Data = 0x0;
mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
@@ -2113,6 +2103,17 @@ static int mos7840_calc_num_ports(struct usb_serial *serial)
return mos7840_num_ports;
}
+static int mos7840_attach(struct usb_serial *serial)
+{
+ if (serial->num_bulk_in < serial->num_ports ||
+ serial->num_bulk_out < serial->num_ports) {
+ dev_err(&serial->interface->dev, "missing endpoints\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static int mos7840_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
@@ -2388,6 +2389,7 @@ static struct usb_serial_driver moschip7840_4port_device = {
.tiocmset = mos7840_tiocmset,
.tiocmiwait = usb_serial_generic_tiocmiwait,
.get_icount = usb_serial_generic_get_icount,
+ .attach = mos7840_attach,
.port_probe = mos7840_port_probe,
.port_remove = mos7840_port_remove,
.read_bulk_callback = mos7840_bulk_in_callback,
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index f6c6900bccf0..a180b17d2432 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -38,6 +38,7 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
const unsigned char *buf, int count);
static int omninet_write_room(struct tty_struct *tty);
static void omninet_disconnect(struct usb_serial *serial);
+static int omninet_attach(struct usb_serial *serial);
static int omninet_port_probe(struct usb_serial_port *port);
static int omninet_port_remove(struct usb_serial_port *port);
@@ -56,6 +57,7 @@ static struct usb_serial_driver zyxel_omninet_device = {
.description = "ZyXEL - omni.net lcd plus usb",
.id_table = id_table,
.num_ports = 1,
+ .attach = omninet_attach,
.port_probe = omninet_port_probe,
.port_remove = omninet_port_remove,
.open = omninet_open,
@@ -104,6 +106,17 @@ struct omninet_data {
__u8 od_outseq; /* Sequence number for bulk_out URBs */
};
+static int omninet_attach(struct usb_serial *serial)
+{
+ /* The second bulk-out endpoint is used for writing. */
+ if (serial->num_bulk_out < 2) {
+ dev_err(&serial->interface->dev, "missing endpoints\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static int omninet_port_probe(struct usb_serial_port *port)
{
struct omninet_data *od;
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index a4b88bc038b6..b8bf52bf7a94 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -134,6 +134,7 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty);
static int oti6858_tiocmget(struct tty_struct *tty);
static int oti6858_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
+static int oti6858_attach(struct usb_serial *serial);
static int oti6858_port_probe(struct usb_serial_port *port);
static int oti6858_port_remove(struct usb_serial_port *port);
@@ -158,6 +159,7 @@ static struct usb_serial_driver oti6858_device = {
.write_bulk_callback = oti6858_write_bulk_callback,
.write_room = oti6858_write_room,
.chars_in_buffer = oti6858_chars_in_buffer,
+ .attach = oti6858_attach,
.port_probe = oti6858_port_probe,
.port_remove = oti6858_port_remove,
};
@@ -324,6 +326,20 @@ static void send_data(struct work_struct *work)
usb_serial_port_softint(port);
}
+static int oti6858_attach(struct usb_serial *serial)
+{
+ unsigned char num_ports = serial->num_ports;
+
+ if (serial->num_bulk_in < num_ports ||
+ serial->num_bulk_out < num_ports ||
+ serial->num_interrupt_in < num_ports) {
+ dev_err(&serial->interface->dev, "missing endpoints\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static int oti6858_port_probe(struct usb_serial_port *port)
{
struct oti6858_private *priv;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index ae682e4eeaef..46fca6b75846 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -220,9 +220,17 @@ static int pl2303_probe(struct usb_serial *serial,
static int pl2303_startup(struct usb_serial *serial)
{
struct pl2303_serial_private *spriv;
+ unsigned char num_ports = serial->num_ports;
enum pl2303_type type = TYPE_01;
unsigned char *buf;
+ if (serial->num_bulk_in < num_ports ||
+ serial->num_bulk_out < num_ports ||
+ serial->num_interrupt_in < num_ports) {
+ dev_err(&serial->interface->dev, "missing endpoints\n");
+ return -ENODEV;
+ }
+
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
if (!spriv)
return -ENOMEM;
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
index 659cb8606bd9..5709cc93b083 100644
--- a/drivers/usb/serial/quatech2.c
+++ b/drivers/usb/serial/quatech2.c
@@ -408,16 +408,12 @@ static void qt2_close(struct usb_serial_port *port)
{
struct usb_serial *serial;
struct qt2_port_private *port_priv;
- unsigned long flags;
int i;
serial = port->serial;
port_priv = usb_get_serial_port_data(port);
- spin_lock_irqsave(&port_priv->urb_lock, flags);
usb_kill_urb(port_priv->write_urb);
- port_priv->urb_in_use = false;
- spin_unlock_irqrestore(&port_priv->urb_lock, flags);
/* flush the port transmit buffer */
i = usb_control_msg(serial->dev,
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index ef0dbf0703c5..475e6c31b266 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -154,6 +154,19 @@ static int spcp8x5_probe(struct usb_serial *serial,
return 0;
}
+static int spcp8x5_attach(struct usb_serial *serial)
+{
+ unsigned char num_ports = serial->num_ports;
+
+ if (serial->num_bulk_in < num_ports ||
+ serial->num_bulk_out < num_ports) {
+ dev_err(&serial->interface->dev, "missing endpoints\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static int spcp8x5_port_probe(struct usb_serial_port *port)
{
const struct usb_device_id *id = usb_get_serial_data(port->serial);
@@ -477,6 +490,7 @@ static struct usb_serial_driver spcp8x5_device = {
.tiocmget = spcp8x5_tiocmget,
.tiocmset = spcp8x5_tiocmset,
.probe = spcp8x5_probe,
+ .attach = spcp8x5_attach,
.port_probe = spcp8x5_port_probe,
.port_remove = spcp8x5_port_remove,
};
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 8db9d071d940..64b85b8dedf3 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -579,6 +579,13 @@ static int ti_startup(struct usb_serial *serial)
goto free_tdev;
}
+ if (serial->num_bulk_in < serial->num_ports ||
+ serial->num_bulk_out < serial->num_ports) {
+ dev_err(&serial->interface->dev, "missing endpoints\n");
+ status = -ENODEV;
+ goto free_tdev;
+ }
+
return 0;
free_tdev:
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index af3c7eecff91..16cc18369111 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -2109,6 +2109,13 @@ UNUSUAL_DEV( 0x152d, 0x2566, 0x0114, 0x0114,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_BROKEN_FUA ),
+/* Reported-by George Cherian <george.cherian@cavium.com> */
+UNUSUAL_DEV(0x152d, 0x9561, 0x0000, 0x9999,
+ "JMicron",
+ "JMS56x",
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_NO_REPORT_OPCODES),
+
/*
* Entrega Technologies U1-SC25 (later Xircom PortGear PGSCSI)
* and Mac USB Dock USB-SCSI */
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index be1ee89ee917..36d75c367d22 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -27,6 +27,45 @@ static LIST_HEAD(parent_list);
static DEFINE_MUTEX(parent_list_lock);
static struct class_compat *mdev_bus_compat_class;
+static LIST_HEAD(mdev_list);
+static DEFINE_MUTEX(mdev_list_lock);
+
+struct device *mdev_parent_dev(struct mdev_device *mdev)
+{
+ return mdev->parent->dev;
+}
+EXPORT_SYMBOL(mdev_parent_dev);
+
+void *mdev_get_drvdata(struct mdev_device *mdev)
+{
+ return mdev->driver_data;
+}
+EXPORT_SYMBOL(mdev_get_drvdata);
+
+void mdev_set_drvdata(struct mdev_device *mdev, void *data)
+{
+ mdev->driver_data = data;
+}
+EXPORT_SYMBOL(mdev_set_drvdata);
+
+struct device *mdev_dev(struct mdev_device *mdev)
+{
+ return &mdev->dev;
+}
+EXPORT_SYMBOL(mdev_dev);
+
+struct mdev_device *mdev_from_dev(struct device *dev)
+{
+ return dev_is_mdev(dev) ? to_mdev_device(dev) : NULL;
+}
+EXPORT_SYMBOL(mdev_from_dev);
+
+uuid_le mdev_uuid(struct mdev_device *mdev)
+{
+ return mdev->uuid;
+}
+EXPORT_SYMBOL(mdev_uuid);
+
static int _find_mdev_device(struct device *dev, void *data)
{
struct mdev_device *mdev;
@@ -42,7 +81,7 @@ static int _find_mdev_device(struct device *dev, void *data)
return 0;
}
-static bool mdev_device_exist(struct parent_device *parent, uuid_le uuid)
+static bool mdev_device_exist(struct mdev_parent *parent, uuid_le uuid)
{
struct device *dev;
@@ -56,9 +95,9 @@ static bool mdev_device_exist(struct parent_device *parent, uuid_le uuid)
}
/* Should be called holding parent_list_lock */
-static struct parent_device *__find_parent_device(struct device *dev)
+static struct mdev_parent *__find_parent_device(struct device *dev)
{
- struct parent_device *parent;
+ struct mdev_parent *parent;
list_for_each_entry(parent, &parent_list, next) {
if (parent->dev == dev)
@@ -69,8 +108,8 @@ static struct parent_device *__find_parent_device(struct device *dev)
static void mdev_release_parent(struct kref *kref)
{
- struct parent_device *parent = container_of(kref, struct parent_device,
- ref);
+ struct mdev_parent *parent = container_of(kref, struct mdev_parent,
+ ref);
struct device *dev = parent->dev;
kfree(parent);
@@ -78,7 +117,7 @@ static void mdev_release_parent(struct kref *kref)
}
static
-inline struct parent_device *mdev_get_parent(struct parent_device *parent)
+inline struct mdev_parent *mdev_get_parent(struct mdev_parent *parent)
{
if (parent)
kref_get(&parent->ref);
@@ -86,7 +125,7 @@ inline struct parent_device *mdev_get_parent(struct parent_device *parent)
return parent;
}
-static inline void mdev_put_parent(struct parent_device *parent)
+static inline void mdev_put_parent(struct mdev_parent *parent)
{
if (parent)
kref_put(&parent->ref, mdev_release_parent);
@@ -95,7 +134,7 @@ static inline void mdev_put_parent(struct parent_device *parent)
static int mdev_device_create_ops(struct kobject *kobj,
struct mdev_device *mdev)
{
- struct parent_device *parent = mdev->parent;
+ struct mdev_parent *parent = mdev->parent;
int ret;
ret = parent->ops->create(kobj, mdev);
@@ -122,7 +161,7 @@ static int mdev_device_create_ops(struct kobject *kobj,
*/
static int mdev_device_remove_ops(struct mdev_device *mdev, bool force_remove)
{
- struct parent_device *parent = mdev->parent;
+ struct mdev_parent *parent = mdev->parent;
int ret;
/*
@@ -153,10 +192,10 @@ static int mdev_device_remove_cb(struct device *dev, void *data)
* Add device to list of registered parent devices.
* Returns a negative value on error, otherwise 0.
*/
-int mdev_register_device(struct device *dev, const struct parent_ops *ops)
+int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
{
int ret;
- struct parent_device *parent;
+ struct mdev_parent *parent;
/* check for mandatory ops */
if (!ops || !ops->create || !ops->remove || !ops->supported_type_groups)
@@ -229,7 +268,7 @@ EXPORT_SYMBOL(mdev_register_device);
void mdev_unregister_device(struct device *dev)
{
- struct parent_device *parent;
+ struct mdev_parent *parent;
bool force_remove = true;
mutex_lock(&parent_list_lock);
@@ -266,7 +305,7 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
{
int ret;
struct mdev_device *mdev;
- struct parent_device *parent;
+ struct mdev_parent *parent;
struct mdev_type *type = to_mdev_type(kobj);
parent = mdev_get_parent(type->parent);
@@ -316,6 +355,11 @@ int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
dev_dbg(&mdev->dev, "MDEV: created\n");
mutex_unlock(&parent->lock);
+
+ mutex_lock(&mdev_list_lock);
+ list_add(&mdev->next, &mdev_list);
+ mutex_unlock(&mdev_list_lock);
+
return ret;
create_failed:
@@ -329,12 +373,30 @@ create_err:
int mdev_device_remove(struct device *dev, bool force_remove)
{
- struct mdev_device *mdev;
- struct parent_device *parent;
+ struct mdev_device *mdev, *tmp;
+ struct mdev_parent *parent;
struct mdev_type *type;
int ret;
+ bool found = false;
mdev = to_mdev_device(dev);
+
+ mutex_lock(&mdev_list_lock);
+ list_for_each_entry(tmp, &mdev_list, next) {
+ if (tmp == mdev) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ list_del(&mdev->next);
+
+ mutex_unlock(&mdev_list_lock);
+
+ if (!found)
+ return -ENODEV;
+
type = to_mdev_type(mdev->type_kobj);
parent = mdev->parent;
mutex_lock(&parent->lock);
@@ -342,6 +404,11 @@ int mdev_device_remove(struct device *dev, bool force_remove)
ret = mdev_device_remove_ops(mdev, force_remove);
if (ret) {
mutex_unlock(&parent->lock);
+
+ mutex_lock(&mdev_list_lock);
+ list_add(&mdev->next, &mdev_list);
+ mutex_unlock(&mdev_list_lock);
+
return ret;
}
@@ -349,7 +416,8 @@ int mdev_device_remove(struct device *dev, bool force_remove)
device_unregister(dev);
mutex_unlock(&parent->lock);
mdev_put_parent(parent);
- return ret;
+
+ return 0;
}
static int __init mdev_init(void)
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index d35097cbf3d7..a9cefd70a705 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -16,10 +16,33 @@
int mdev_bus_register(void);
void mdev_bus_unregister(void);
+struct mdev_parent {
+ struct device *dev;
+ const struct mdev_parent_ops *ops;
+ struct kref ref;
+ struct mutex lock;
+ struct list_head next;
+ struct kset *mdev_types_kset;
+ struct list_head type_list;
+};
+
+struct mdev_device {
+ struct device dev;
+ struct mdev_parent *parent;
+ uuid_le uuid;
+ void *driver_data;
+ struct kref ref;
+ struct list_head next;
+ struct kobject *type_kobj;
+};
+
+#define to_mdev_device(dev) container_of(dev, struct mdev_device, dev)
+#define dev_is_mdev(d) ((d)->bus == &mdev_bus_type)
+
struct mdev_type {
struct kobject kobj;
struct kobject *devices_kobj;
- struct parent_device *parent;
+ struct mdev_parent *parent;
struct list_head next;
struct attribute_group *group;
};
@@ -29,8 +52,8 @@ struct mdev_type {
#define to_mdev_type(_kobj) \
container_of(_kobj, struct mdev_type, kobj)
-int parent_create_sysfs_files(struct parent_device *parent);
-void parent_remove_sysfs_files(struct parent_device *parent);
+int parent_create_sysfs_files(struct mdev_parent *parent);
+void parent_remove_sysfs_files(struct mdev_parent *parent);
int mdev_create_sysfs_files(struct device *dev, struct mdev_type *type);
void mdev_remove_sysfs_files(struct device *dev, struct mdev_type *type);
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 1a53deb2ee10..802df210929b 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -92,7 +92,7 @@ static struct kobj_type mdev_type_ktype = {
.release = mdev_type_release,
};
-struct mdev_type *add_mdev_supported_type(struct parent_device *parent,
+struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
struct attribute_group *group)
{
struct mdev_type *type;
@@ -158,7 +158,7 @@ static void remove_mdev_supported_type(struct mdev_type *type)
kobject_put(&type->kobj);
}
-static int add_mdev_supported_type_groups(struct parent_device *parent)
+static int add_mdev_supported_type_groups(struct mdev_parent *parent)
{
int i;
@@ -183,7 +183,7 @@ static int add_mdev_supported_type_groups(struct parent_device *parent)
}
/* mdev sysfs functions */
-void parent_remove_sysfs_files(struct parent_device *parent)
+void parent_remove_sysfs_files(struct mdev_parent *parent)
{
struct mdev_type *type, *tmp;
@@ -196,7 +196,7 @@ void parent_remove_sysfs_files(struct parent_device *parent)
kset_unregister(parent->mdev_types_kset);
}
-int parent_create_sysfs_files(struct parent_device *parent)
+int parent_create_sysfs_files(struct mdev_parent *parent)
{
int ret;
diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c
index ffc36758cb84..fa848a701b8b 100644
--- a/drivers/vfio/mdev/vfio_mdev.c
+++ b/drivers/vfio/mdev/vfio_mdev.c
@@ -27,7 +27,7 @@
static int vfio_mdev_open(void *device_data)
{
struct mdev_device *mdev = device_data;
- struct parent_device *parent = mdev->parent;
+ struct mdev_parent *parent = mdev->parent;
int ret;
if (unlikely(!parent->ops->open))
@@ -46,7 +46,7 @@ static int vfio_mdev_open(void *device_data)
static void vfio_mdev_release(void *device_data)
{
struct mdev_device *mdev = device_data;
- struct parent_device *parent = mdev->parent;
+ struct mdev_parent *parent = mdev->parent;
if (likely(parent->ops->release))
parent->ops->release(mdev);
@@ -58,7 +58,7 @@ static long vfio_mdev_unlocked_ioctl(void *device_data,
unsigned int cmd, unsigned long arg)
{
struct mdev_device *mdev = device_data;
- struct parent_device *parent = mdev->parent;
+ struct mdev_parent *parent = mdev->parent;
if (unlikely(!parent->ops->ioctl))
return -EINVAL;
@@ -70,7 +70,7 @@ static ssize_t vfio_mdev_read(void *device_data, char __user *buf,
size_t count, loff_t *ppos)
{
struct mdev_device *mdev = device_data;
- struct parent_device *parent = mdev->parent;
+ struct mdev_parent *parent = mdev->parent;
if (unlikely(!parent->ops->read))
return -EINVAL;
@@ -82,7 +82,7 @@ static ssize_t vfio_mdev_write(void *device_data, const char __user *buf,
size_t count, loff_t *ppos)
{
struct mdev_device *mdev = device_data;
- struct parent_device *parent = mdev->parent;
+ struct mdev_parent *parent = mdev->parent;
if (unlikely(!parent->ops->write))
return -EINVAL;
@@ -93,7 +93,7 @@ static ssize_t vfio_mdev_write(void *device_data, const char __user *buf,
static int vfio_mdev_mmap(void *device_data, struct vm_area_struct *vma)
{
struct mdev_device *mdev = device_data;
- struct parent_device *parent = mdev->parent;
+ struct mdev_parent *parent = mdev->parent;
if (unlikely(!parent->ops->mmap))
return -EINVAL;
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index dcd7c2a99618..324c52e3a1a4 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -1142,6 +1142,10 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
return ret;
vdev->barmap[index] = pci_iomap(pdev, index, 0);
+ if (!vdev->barmap[index]) {
+ pci_release_selected_regions(pdev, 1 << index);
+ return -ENOMEM;
+ }
}
vma->vm_private_data = vdev;
diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
index 5ffd1d9ad4bd..357243d76f10 100644
--- a/drivers/vfio/pci/vfio_pci_rdwr.c
+++ b/drivers/vfio/pci/vfio_pci_rdwr.c
@@ -193,7 +193,10 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_device *vdev, char __user *buf,
if (!vdev->has_vga)
return -EINVAL;
- switch (pos) {
+ if (pos > 0xbfffful)
+ return -EINVAL;
+
+ switch ((u32)pos) {
case 0xa0000 ... 0xbffff:
count = min(count, (size_t)(0xc0000 - pos));
iomem = ioremap_nocache(0xa0000, 0xbffff - 0xa0000 + 1);
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index f3726ba12aa6..9266271a787a 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -268,28 +268,38 @@ static void vfio_lock_acct(struct task_struct *task, long npage)
{
struct vwork *vwork;
struct mm_struct *mm;
+ bool is_current;
if (!npage)
return;
- mm = get_task_mm(task);
+ is_current = (task->mm == current->mm);
+
+ mm = is_current ? task->mm : get_task_mm(task);
if (!mm)
- return; /* process exited or nothing to do */
+ return; /* process exited */
if (down_write_trylock(&mm->mmap_sem)) {
mm->locked_vm += npage;
up_write(&mm->mmap_sem);
- mmput(mm);
+ if (!is_current)
+ mmput(mm);
return;
}
+ if (is_current) {
+ mm = get_task_mm(task);
+ if (!mm)
+ return;
+ }
+
/*
* Couldn't get mmap_sem lock, so must setup to update
* mm->locked_vm later. If locked_vm were atomic, we
* wouldn't need this silliness
*/
vwork = kmalloc(sizeof(struct vwork), GFP_KERNEL);
- if (!vwork) {
+ if (WARN_ON(!vwork)) {
mmput(mm);
return;
}
@@ -393,77 +403,71 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr,
static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr,
long npage, unsigned long *pfn_base)
{
- unsigned long limit;
- bool lock_cap = ns_capable(task_active_pid_ns(dma->task)->user_ns,
- CAP_IPC_LOCK);
- struct mm_struct *mm;
- long ret, i = 0, lock_acct = 0;
+ unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+ bool lock_cap = capable(CAP_IPC_LOCK);
+ long ret, pinned = 0, lock_acct = 0;
bool rsvd;
dma_addr_t iova = vaddr - dma->vaddr + dma->iova;
- mm = get_task_mm(dma->task);
- if (!mm)
+ /* This code path is only user initiated */
+ if (!current->mm)
return -ENODEV;
- ret = vaddr_get_pfn(mm, vaddr, dma->prot, pfn_base);
+ ret = vaddr_get_pfn(current->mm, vaddr, dma->prot, pfn_base);
if (ret)
- goto pin_pg_remote_exit;
+ return ret;
+ pinned++;
rsvd = is_invalid_reserved_pfn(*pfn_base);
- limit = task_rlimit(dma->task, RLIMIT_MEMLOCK) >> PAGE_SHIFT;
/*
* Reserved pages aren't counted against the user, externally pinned
* pages are already counted against the user.
*/
if (!rsvd && !vfio_find_vpfn(dma, iova)) {
- if (!lock_cap && mm->locked_vm + 1 > limit) {
+ if (!lock_cap && current->mm->locked_vm + 1 > limit) {
put_pfn(*pfn_base, dma->prot);
pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", __func__,
limit << PAGE_SHIFT);
- ret = -ENOMEM;
- goto pin_pg_remote_exit;
+ return -ENOMEM;
}
lock_acct++;
}
- i++;
- if (likely(!disable_hugepages)) {
- /* Lock all the consecutive pages from pfn_base */
- for (vaddr += PAGE_SIZE, iova += PAGE_SIZE; i < npage;
- i++, vaddr += PAGE_SIZE, iova += PAGE_SIZE) {
- unsigned long pfn = 0;
+ if (unlikely(disable_hugepages))
+ goto out;
- ret = vaddr_get_pfn(mm, vaddr, dma->prot, &pfn);
- if (ret)
- break;
+ /* Lock all the consecutive pages from pfn_base */
+ for (vaddr += PAGE_SIZE, iova += PAGE_SIZE; pinned < npage;
+ pinned++, vaddr += PAGE_SIZE, iova += PAGE_SIZE) {
+ unsigned long pfn = 0;
- if (pfn != *pfn_base + i ||
- rsvd != is_invalid_reserved_pfn(pfn)) {
+ ret = vaddr_get_pfn(current->mm, vaddr, dma->prot, &pfn);
+ if (ret)
+ break;
+
+ if (pfn != *pfn_base + pinned ||
+ rsvd != is_invalid_reserved_pfn(pfn)) {
+ put_pfn(pfn, dma->prot);
+ break;
+ }
+
+ if (!rsvd && !vfio_find_vpfn(dma, iova)) {
+ if (!lock_cap &&
+ current->mm->locked_vm + lock_acct + 1 > limit) {
put_pfn(pfn, dma->prot);
+ pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n",
+ __func__, limit << PAGE_SHIFT);
break;
}
-
- if (!rsvd && !vfio_find_vpfn(dma, iova)) {
- if (!lock_cap &&
- mm->locked_vm + lock_acct + 1 > limit) {
- put_pfn(pfn, dma->prot);
- pr_warn("%s: RLIMIT_MEMLOCK (%ld) "
- "exceeded\n", __func__,
- limit << PAGE_SHIFT);
- break;
- }
- lock_acct++;
- }
+ lock_acct++;
}
}
- vfio_lock_acct(dma->task, lock_acct);
- ret = i;
+out:
+ vfio_lock_acct(current, lock_acct);
-pin_pg_remote_exit:
- mmput(mm);
- return ret;
+ return pinned;
}
static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova,
@@ -473,10 +477,10 @@ static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova,
long unlocked = 0, locked = 0;
long i;
- for (i = 0; i < npage; i++) {
+ for (i = 0; i < npage; i++, iova += PAGE_SIZE) {
if (put_pfn(pfn++, dma->prot)) {
unlocked++;
- if (vfio_find_vpfn(dma, iova + (i << PAGE_SHIFT)))
+ if (vfio_find_vpfn(dma, iova))
locked++;
}
}
diff --git a/drivers/video/fbdev/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c
index 2d3b691f3fc4..038ac6934fe9 100644
--- a/drivers/video/fbdev/cobalt_lcdfb.c
+++ b/drivers/video/fbdev/cobalt_lcdfb.c
@@ -308,6 +308,11 @@ static int cobalt_lcdfb_probe(struct platform_device *dev)
info->screen_size = resource_size(res);
info->screen_base = devm_ioremap(&dev->dev, res->start,
info->screen_size);
+ if (!info->screen_base) {
+ framebuffer_release(info);
+ return -ENOMEM;
+ }
+
info->fbops = &cobalt_lcd_fbops;
info->fix = cobalt_lcdfb_fix;
info->fix.smem_start = res->start;
diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c
index 778acf80aacb..85dd20e05726 100644
--- a/drivers/xen/arm-device.c
+++ b/drivers/xen/arm-device.c
@@ -58,9 +58,13 @@ static int xen_map_device_mmio(const struct resource *resources,
xen_pfn_t *gpfns;
xen_ulong_t *idxs;
int *errs;
- struct xen_add_to_physmap_range xatp;
for (i = 0; i < count; i++) {
+ struct xen_add_to_physmap_range xatp = {
+ .domid = DOMID_SELF,
+ .space = XENMAPSPACE_dev_mmio
+ };
+
r = &resources[i];
nr = DIV_ROUND_UP(resource_size(r), XEN_PAGE_SIZE);
if ((resource_type(r) != IORESOURCE_MEM) || (nr == 0))
@@ -87,9 +91,7 @@ static int xen_map_device_mmio(const struct resource *resources,
idxs[j] = XEN_PFN_DOWN(r->start) + j;
}
- xatp.domid = DOMID_SELF;
xatp.size = nr;
- xatp.space = XENMAPSPACE_dev_mmio;
set_xen_guest_handle(xatp.gpfns, gpfns);
set_xen_guest_handle(xatp.idxs, idxs);
diff --git a/drivers/xen/events/events_fifo.c b/drivers/xen/events/events_fifo.c
index c03f9c86c7e3..3c41470c7fc4 100644
--- a/drivers/xen/events/events_fifo.c
+++ b/drivers/xen/events/events_fifo.c
@@ -369,8 +369,7 @@ static void evtchn_fifo_resume(void)
}
ret = init_control_block(cpu, control_block);
- if (ret < 0)
- BUG();
+ BUG_ON(ret < 0);
}
/*
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index e8c7f09d01be..6890897a6f30 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -125,7 +125,7 @@ static int add_evtchn(struct per_user_data *u, struct user_evtchn *evtchn)
while (*new) {
struct user_evtchn *this;
- this = container_of(*new, struct user_evtchn, node);
+ this = rb_entry(*new, struct user_evtchn, node);
parent = *new;
if (this->port < evtchn->port)
@@ -157,7 +157,7 @@ static struct user_evtchn *find_evtchn(struct per_user_data *u, unsigned port)
while (node) {
struct user_evtchn *evtchn;
- evtchn = container_of(node, struct user_evtchn, node);
+ evtchn = rb_entry(node, struct user_evtchn, node);
if (evtchn->port < port)
node = node->rb_left;
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 478fb91e3df2..f905d6eeb048 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -275,6 +275,10 @@ retry:
rc = 0;
} else
rc = swiotlb_late_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs);
+
+ if (!rc)
+ swiotlb_set_max_segment(PAGE_SIZE);
+
return rc;
error:
if (repeat--) {
@@ -392,7 +396,7 @@ dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
if (dma_capable(dev, dev_addr, size) &&
!range_straddles_page_boundary(phys, size) &&
!xen_arch_need_swiotlb(dev, phys, dev_addr) &&
- !swiotlb_force) {
+ (swiotlb_force != SWIOTLB_FORCE)) {
/* we are not interested in the dma_addr returned by
* xen_dma_map_page, only in the potential cache flushes executed
* by the function. */
@@ -552,7 +556,7 @@ xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
phys_addr_t paddr = sg_phys(sg);
dma_addr_t dev_addr = xen_phys_to_bus(paddr);
- if (swiotlb_force ||
+ if (swiotlb_force == SWIOTLB_FORCE ||
xen_arch_need_swiotlb(hwdev, paddr, dev_addr) ||
!dma_capable(hwdev, dev_addr, sg->length) ||
range_straddles_page_boundary(paddr, sg->length)) {
diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h
index e74f9c1fbd80..867a2e425208 100644
--- a/drivers/xen/xenbus/xenbus_comms.h
+++ b/drivers/xen/xenbus/xenbus_comms.h
@@ -42,7 +42,6 @@ int xb_write(const void *data, unsigned len);
int xb_read(void *data, unsigned len);
int xb_data_to_read(void);
int xb_wait_for_data_to_read(void);
-int xs_input_avail(void);
extern struct xenstore_domain_interface *xen_store_interface;
extern int xen_store_evtchn;
extern enum xenstore_init xen_store_domain_type;
diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
index 6c0ead4be784..79130b310247 100644
--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
+++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
@@ -302,6 +302,29 @@ static void watch_fired(struct xenbus_watch *watch,
mutex_unlock(&adap->dev_data->reply_mutex);
}
+static int xenbus_command_reply(struct xenbus_file_priv *u,
+ unsigned int msg_type, const char *reply)
+{
+ struct {
+ struct xsd_sockmsg hdr;
+ const char body[16];
+ } msg;
+ int rc;
+
+ msg.hdr = u->u.msg;
+ msg.hdr.type = msg_type;
+ msg.hdr.len = strlen(reply) + 1;
+ if (msg.hdr.len > sizeof(msg.body))
+ return -E2BIG;
+
+ mutex_lock(&u->reply_mutex);
+ rc = queue_reply(&u->read_buffers, &msg, sizeof(msg.hdr) + msg.hdr.len);
+ wake_up(&u->read_waitq);
+ mutex_unlock(&u->reply_mutex);
+
+ return rc;
+}
+
static int xenbus_write_transaction(unsigned msg_type,
struct xenbus_file_priv *u)
{
@@ -316,12 +339,12 @@ static int xenbus_write_transaction(unsigned msg_type,
rc = -ENOMEM;
goto out;
}
- } else if (msg_type == XS_TRANSACTION_END) {
+ } else if (u->u.msg.tx_id != 0) {
list_for_each_entry(trans, &u->transactions, list)
if (trans->handle.id == u->u.msg.tx_id)
break;
if (&trans->list == &u->transactions)
- return -ESRCH;
+ return xenbus_command_reply(u, XS_ERROR, "ENOENT");
}
reply = xenbus_dev_request_and_reply(&u->u.msg);
@@ -372,12 +395,12 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u)
path = u->u.buffer + sizeof(u->u.msg);
token = memchr(path, 0, u->u.msg.len);
if (token == NULL) {
- rc = -EILSEQ;
+ rc = xenbus_command_reply(u, XS_ERROR, "EINVAL");
goto out;
}
token++;
if (memchr(token, 0, u->u.msg.len - (token - path)) == NULL) {
- rc = -EILSEQ;
+ rc = xenbus_command_reply(u, XS_ERROR, "EINVAL");
goto out;
}
@@ -411,23 +434,7 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u)
}
/* Success. Synthesize a reply to say all is OK. */
- {
- struct {
- struct xsd_sockmsg hdr;
- char body[3];
- } __packed reply = {
- {
- .type = msg_type,
- .len = sizeof(reply.body)
- },
- "OK"
- };
-
- mutex_lock(&u->reply_mutex);
- rc = queue_reply(&u->read_buffers, &reply, sizeof(reply));
- wake_up(&u->read_waitq);
- mutex_unlock(&u->reply_mutex);
- }
+ rc = xenbus_command_reply(u, msg_type, "OK");
out:
return rc;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 6254cee8f8f3..5db5d1340d69 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -328,6 +328,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
struct file *file = iocb->ki_filp;
struct inode *inode = bdev_file_inode(file);
struct block_device *bdev = I_BDEV(inode);
+ struct blk_plug plug;
struct blkdev_dio *dio;
struct bio *bio;
bool is_read = (iov_iter_rw(iter) == READ);
@@ -353,6 +354,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
dio->multi_bio = false;
dio->should_dirty = is_read && (iter->type == ITER_IOVEC);
+ blk_start_plug(&plug);
for (;;) {
bio->bi_bdev = bdev;
bio->bi_iter.bi_sector = pos >> 9;
@@ -394,6 +396,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
submit_bio(bio);
bio = bio_alloc(GFP_KERNEL, nr_pages);
}
+ blk_finish_plug(&plug);
if (!dio->is_sync)
return -EIOCBQUEUED;
diff --git a/fs/buffer.c b/fs/buffer.c
index d21771fcf7d3..0e87401cf335 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1660,7 +1660,7 @@ void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)
head = page_buffers(page);
bh = head;
do {
- if (!buffer_mapped(bh))
+ if (!buffer_mapped(bh) || (bh->b_blocknr < block))
goto next;
if (bh->b_blocknr >= block + len)
break;
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index 6eeea1dcba41..95cd4c3b06c3 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -248,7 +248,8 @@ retry:
goto out;
if (fscrypt_dummy_context_enabled(inode)) {
- memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE);
+ memset(raw_key, 0x42, keysize/2);
+ memset(raw_key+keysize/2, 0x24, keysize - (keysize/2));
goto got_key;
}
diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
index 6ed7c2eebeec..d6cd7ea4851d 100644
--- a/fs/crypto/policy.c
+++ b/fs/crypto/policy.c
@@ -179,6 +179,11 @@ int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
BUG_ON(1);
}
+ /* No restrictions on file types which are never encrypted */
+ if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) &&
+ !S_ISLNK(child->i_mode))
+ return 1;
+
/* no restrictions if the parent directory is not encrypted */
if (!parent->i_sb->s_cop->is_encrypted(parent))
return 1;
diff --git a/fs/dax.c b/fs/dax.c
index a8732fbed381..5c74f60d0a50 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -451,16 +451,37 @@ void dax_wake_mapping_entry_waiter(struct address_space *mapping,
__wake_up(wq, TASK_NORMAL, wake_all ? 0 : 1, &key);
}
+static int __dax_invalidate_mapping_entry(struct address_space *mapping,
+ pgoff_t index, bool trunc)
+{
+ int ret = 0;
+ void *entry;
+ struct radix_tree_root *page_tree = &mapping->page_tree;
+
+ spin_lock_irq(&mapping->tree_lock);
+ entry = get_unlocked_mapping_entry(mapping, index, NULL);
+ if (!entry || !radix_tree_exceptional_entry(entry))
+ goto out;
+ if (!trunc &&
+ (radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_DIRTY) ||
+ radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_TOWRITE)))
+ goto out;
+ radix_tree_delete(page_tree, index);
+ mapping->nrexceptional--;
+ ret = 1;
+out:
+ put_unlocked_mapping_entry(mapping, index, entry);
+ spin_unlock_irq(&mapping->tree_lock);
+ return ret;
+}
/*
* Delete exceptional DAX entry at @index from @mapping. Wait for radix tree
* entry to get unlocked before deleting it.
*/
int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index)
{
- void *entry;
+ int ret = __dax_invalidate_mapping_entry(mapping, index, true);
- spin_lock_irq(&mapping->tree_lock);
- entry = get_unlocked_mapping_entry(mapping, index, NULL);
/*
* This gets called from truncate / punch_hole path. As such, the caller
* must hold locks protecting against concurrent modifications of the
@@ -468,16 +489,46 @@ int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index)
* caller has seen exceptional entry for this index, we better find it
* at that index as well...
*/
- if (WARN_ON_ONCE(!entry || !radix_tree_exceptional_entry(entry))) {
- spin_unlock_irq(&mapping->tree_lock);
- return 0;
- }
- radix_tree_delete(&mapping->page_tree, index);
+ WARN_ON_ONCE(!ret);
+ return ret;
+}
+
+/*
+ * Invalidate exceptional DAX entry if easily possible. This handles DAX
+ * entries for invalidate_inode_pages() so we evict the entry only if we can
+ * do so without blocking.
+ */
+int dax_invalidate_mapping_entry(struct address_space *mapping, pgoff_t index)
+{
+ int ret = 0;
+ void *entry, **slot;
+ struct radix_tree_root *page_tree = &mapping->page_tree;
+
+ spin_lock_irq(&mapping->tree_lock);
+ entry = __radix_tree_lookup(page_tree, index, NULL, &slot);
+ if (!entry || !radix_tree_exceptional_entry(entry) ||
+ slot_locked(mapping, slot))
+ goto out;
+ if (radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_DIRTY) ||
+ radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_TOWRITE))
+ goto out;
+ radix_tree_delete(page_tree, index);
mapping->nrexceptional--;
+ ret = 1;
+out:
spin_unlock_irq(&mapping->tree_lock);
- dax_wake_mapping_entry_waiter(mapping, index, entry, true);
+ if (ret)
+ dax_wake_mapping_entry_waiter(mapping, index, entry, true);
+ return ret;
+}
- return 1;
+/*
+ * Invalidate exceptional DAX entry if it is clean.
+ */
+int dax_invalidate_mapping_entry_sync(struct address_space *mapping,
+ pgoff_t index)
+{
+ return __dax_invalidate_mapping_entry(mapping, index, false);
}
/*
@@ -488,15 +539,16 @@ int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index)
* otherwise it will simply fall out of the page cache under memory
* pressure without ever having been dirtied.
*/
-static int dax_load_hole(struct address_space *mapping, void *entry,
+static int dax_load_hole(struct address_space *mapping, void **entry,
struct vm_fault *vmf)
{
struct page *page;
+ int ret;
/* Hole page already exists? Return it... */
- if (!radix_tree_exceptional_entry(entry)) {
- vmf->page = entry;
- return VM_FAULT_LOCKED;
+ if (!radix_tree_exceptional_entry(*entry)) {
+ page = *entry;
+ goto out;
}
/* This will replace locked radix tree entry with a hole page */
@@ -504,8 +556,17 @@ static int dax_load_hole(struct address_space *mapping, void *entry,
vmf->gfp_mask | __GFP_ZERO);
if (!page)
return VM_FAULT_OOM;
+ out:
vmf->page = page;
- return VM_FAULT_LOCKED;
+ ret = finish_fault(vmf);
+ vmf->page = NULL;
+ *entry = page;
+ if (!ret) {
+ /* Grab reference for PTE that is now referencing the page */
+ get_page(page);
+ return VM_FAULT_NOPAGE;
+ }
+ return ret;
}
static int copy_user_dax(struct block_device *bdev, sector_t sector, size_t size,
@@ -934,6 +995,17 @@ dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
if (WARN_ON_ONCE(iomap->type != IOMAP_MAPPED))
return -EIO;
+ /*
+ * Write can allocate block for an area which has a hole page mapped
+ * into page tables. We have to tear down these mappings so that data
+ * written by write(2) is visible in mmap.
+ */
+ if ((iomap->flags & IOMAP_F_NEW) && inode->i_mapping->nrpages) {
+ invalidate_inode_pages2_range(inode->i_mapping,
+ pos >> PAGE_SHIFT,
+ (end - 1) >> PAGE_SHIFT);
+ }
+
while (pos < end) {
unsigned offset = pos & (PAGE_SIZE - 1);
struct blk_dax_ctl dax = { 0 };
@@ -992,23 +1064,6 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
if (iov_iter_rw(iter) == WRITE)
flags |= IOMAP_WRITE;
- /*
- * Yes, even DAX files can have page cache attached to them: A zeroed
- * page is inserted into the pagecache when we have to serve a write
- * fault on a hole. It should never be dirtied and can simply be
- * dropped from the pagecache once we get real data for the page.
- *
- * XXX: This is racy against mmap, and there's nothing we can do about
- * it. We'll eventually need to shift this down even further so that
- * we can check if we allocated blocks over a hole first.
- */
- if (mapping->nrpages) {
- ret = invalidate_inode_pages2_range(mapping,
- pos >> PAGE_SHIFT,
- (pos + iov_iter_count(iter) - 1) >> PAGE_SHIFT);
- WARN_ON_ONCE(ret);
- }
-
while (iov_iter_count(iter)) {
ret = iomap_apply(inode, pos, iov_iter_count(iter), flags, ops,
iter, dax_iomap_actor);
@@ -1023,6 +1078,15 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
}
EXPORT_SYMBOL_GPL(dax_iomap_rw);
+static int dax_fault_return(int error)
+{
+ if (error == 0)
+ return VM_FAULT_NOPAGE;
+ if (error == -ENOMEM)
+ return VM_FAULT_OOM;
+ return VM_FAULT_SIGBUS;
+}
+
/**
* dax_iomap_fault - handle a page fault on a DAX file
* @vma: The virtual memory area where the fault occurred
@@ -1055,12 +1119,6 @@ int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
if (pos >= i_size_read(inode))
return VM_FAULT_SIGBUS;
- entry = grab_mapping_entry(mapping, vmf->pgoff, 0);
- if (IS_ERR(entry)) {
- error = PTR_ERR(entry);
- goto out;
- }
-
if ((vmf->flags & FAULT_FLAG_WRITE) && !vmf->cow_page)
flags |= IOMAP_WRITE;
@@ -1071,9 +1129,15 @@ int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
*/
error = ops->iomap_begin(inode, pos, PAGE_SIZE, flags, &iomap);
if (error)
- goto unlock_entry;
+ return dax_fault_return(error);
if (WARN_ON_ONCE(iomap.offset + iomap.length < pos + PAGE_SIZE)) {
- error = -EIO; /* fs corruption? */
+ vmf_ret = dax_fault_return(-EIO); /* fs corruption? */
+ goto finish_iomap;
+ }
+
+ entry = grab_mapping_entry(mapping, vmf->pgoff, 0);
+ if (IS_ERR(entry)) {
+ vmf_ret = dax_fault_return(PTR_ERR(entry));
goto finish_iomap;
}
@@ -1096,13 +1160,13 @@ int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
}
if (error)
- goto finish_iomap;
+ goto error_unlock_entry;
__SetPageUptodate(vmf->cow_page);
vmf_ret = finish_fault(vmf);
if (!vmf_ret)
vmf_ret = VM_FAULT_DONE_COW;
- goto finish_iomap;
+ goto unlock_entry;
}
switch (iomap.type) {
@@ -1114,12 +1178,15 @@ int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
}
error = dax_insert_mapping(mapping, iomap.bdev, sector,
PAGE_SIZE, &entry, vma, vmf);
+ /* -EBUSY is fine, somebody else faulted on the same PTE */
+ if (error == -EBUSY)
+ error = 0;
break;
case IOMAP_UNWRITTEN:
case IOMAP_HOLE:
if (!(vmf->flags & FAULT_FLAG_WRITE)) {
- vmf_ret = dax_load_hole(mapping, entry, vmf);
- break;
+ vmf_ret = dax_load_hole(mapping, &entry, vmf);
+ goto unlock_entry;
}
/*FALLTHRU*/
default:
@@ -1128,31 +1195,25 @@ int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
break;
}
+ error_unlock_entry:
+ vmf_ret = dax_fault_return(error) | major;
+ unlock_entry:
+ put_locked_mapping_entry(mapping, vmf->pgoff, entry);
finish_iomap:
if (ops->iomap_end) {
- if (error || (vmf_ret & VM_FAULT_ERROR)) {
- /* keep previous error */
- ops->iomap_end(inode, pos, PAGE_SIZE, 0, flags,
- &iomap);
- } else {
- error = ops->iomap_end(inode, pos, PAGE_SIZE,
- PAGE_SIZE, flags, &iomap);
- }
- }
- unlock_entry:
- if (vmf_ret != VM_FAULT_LOCKED || error)
- put_locked_mapping_entry(mapping, vmf->pgoff, entry);
- out:
- if (error == -ENOMEM)
- return VM_FAULT_OOM | major;
- /* -EBUSY is fine, somebody else faulted on the same PTE */
- if (error < 0 && error != -EBUSY)
- return VM_FAULT_SIGBUS | major;
- if (vmf_ret) {
- WARN_ON_ONCE(error); /* -EBUSY from ops->iomap_end? */
- return vmf_ret;
+ int copied = PAGE_SIZE;
+
+ if (vmf_ret & VM_FAULT_ERROR)
+ copied = 0;
+ /*
+ * The fault is done by now and there's no way back (other
+ * thread may be already happily using PTE we have installed).
+ * Just ignore error from ->iomap_end since we cannot do much
+ * with it.
+ */
+ ops->iomap_end(inode, pos, PAGE_SIZE, copied, flags, &iomap);
}
- return VM_FAULT_NOPAGE | major;
+ return vmf_ret;
}
EXPORT_SYMBOL_GPL(dax_iomap_fault);
@@ -1277,16 +1338,6 @@ int dax_iomap_pmd_fault(struct vm_area_struct *vma, unsigned long address,
goto fallback;
/*
- * grab_mapping_entry() will make sure we get a 2M empty entry, a DAX
- * PMD or a HZP entry. If it can't (because a 4k page is already in
- * the tree, for instance), it will return -EEXIST and we just fall
- * back to 4k entries.
- */
- entry = grab_mapping_entry(mapping, pgoff, RADIX_DAX_PMD);
- if (IS_ERR(entry))
- goto fallback;
-
- /*
* Note that we don't use iomap_apply here. We aren't doing I/O, only
* setting up a mapping, so really we're using iomap_begin() as a way
* to look up our filesystem block.
@@ -1294,10 +1345,21 @@ int dax_iomap_pmd_fault(struct vm_area_struct *vma, unsigned long address,
pos = (loff_t)pgoff << PAGE_SHIFT;
error = ops->iomap_begin(inode, pos, PMD_SIZE, iomap_flags, &iomap);
if (error)
- goto unlock_entry;
+ goto fallback;
+
if (iomap.offset + iomap.length < pos + PMD_SIZE)
goto finish_iomap;
+ /*
+ * grab_mapping_entry() will make sure we get a 2M empty entry, a DAX
+ * PMD or a HZP entry. If it can't (because a 4k page is already in
+ * the tree, for instance), it will return -EEXIST and we just fall
+ * back to 4k entries.
+ */
+ entry = grab_mapping_entry(mapping, pgoff, RADIX_DAX_PMD);
+ if (IS_ERR(entry))
+ goto finish_iomap;
+
vmf.pgoff = pgoff;
vmf.flags = flags;
vmf.gfp_mask = mapping_gfp_mask(mapping) | __GFP_IO;
@@ -1310,7 +1372,7 @@ int dax_iomap_pmd_fault(struct vm_area_struct *vma, unsigned long address,
case IOMAP_UNWRITTEN:
case IOMAP_HOLE:
if (WARN_ON_ONCE(write))
- goto finish_iomap;
+ goto unlock_entry;
result = dax_pmd_load_hole(vma, pmd, &vmf, address, &iomap,
&entry);
break;
@@ -1319,20 +1381,23 @@ int dax_iomap_pmd_fault(struct vm_area_struct *vma, unsigned long address,
break;
}
+ unlock_entry:
+ put_locked_mapping_entry(mapping, pgoff, entry);
finish_iomap:
if (ops->iomap_end) {
- if (result == VM_FAULT_FALLBACK) {
- ops->iomap_end(inode, pos, PMD_SIZE, 0, iomap_flags,
- &iomap);
- } else {
- error = ops->iomap_end(inode, pos, PMD_SIZE, PMD_SIZE,
- iomap_flags, &iomap);
- if (error)
- result = VM_FAULT_FALLBACK;
- }
+ int copied = PMD_SIZE;
+
+ if (result == VM_FAULT_FALLBACK)
+ copied = 0;
+ /*
+ * The fault is done by now and there's no way back (other
+ * thread may be already happily using PMD we have installed).
+ * Just ignore error from ->iomap_end since we cannot do much
+ * with it.
+ */
+ ops->iomap_end(inode, pos, PMD_SIZE, copied, iomap_flags,
+ &iomap);
}
- unlock_entry:
- put_locked_mapping_entry(mapping, pgoff, entry);
fallback:
if (result == VM_FAULT_FALLBACK) {
split_huge_pmd(vma, pmd, address);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 0093ea2512a8..f073bfca694b 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -751,9 +751,8 @@ static int ext2_get_blocks(struct inode *inode,
mutex_unlock(&ei->truncate_mutex);
goto cleanup;
}
- } else {
- *new = true;
}
+ *new = true;
ext2_splice_branch(inode, iblock, partial, indirect_blks, count);
mutex_unlock(&ei->truncate_mutex);
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index b5f184493c57..d663d3d7c81c 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -258,7 +258,6 @@ out:
static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
int result;
- handle_t *handle = NULL;
struct inode *inode = file_inode(vma->vm_file);
struct super_block *sb = inode->i_sb;
bool write = vmf->flags & FAULT_FLAG_WRITE;
@@ -266,24 +265,12 @@ static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
if (write) {
sb_start_pagefault(sb);
file_update_time(vma->vm_file);
- down_read(&EXT4_I(inode)->i_mmap_sem);
- handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE,
- EXT4_DATA_TRANS_BLOCKS(sb));
- } else
- down_read(&EXT4_I(inode)->i_mmap_sem);
-
- if (IS_ERR(handle))
- result = VM_FAULT_SIGBUS;
- else
- result = dax_iomap_fault(vma, vmf, &ext4_iomap_ops);
-
- if (write) {
- if (!IS_ERR(handle))
- ext4_journal_stop(handle);
- up_read(&EXT4_I(inode)->i_mmap_sem);
+ }
+ down_read(&EXT4_I(inode)->i_mmap_sem);
+ result = dax_iomap_fault(vma, vmf, &ext4_iomap_ops);
+ up_read(&EXT4_I(inode)->i_mmap_sem);
+ if (write)
sb_end_pagefault(sb);
- } else
- up_read(&EXT4_I(inode)->i_mmap_sem);
return result;
}
@@ -292,7 +279,6 @@ static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
pmd_t *pmd, unsigned int flags)
{
int result;
- handle_t *handle = NULL;
struct inode *inode = file_inode(vma->vm_file);
struct super_block *sb = inode->i_sb;
bool write = flags & FAULT_FLAG_WRITE;
@@ -300,27 +286,13 @@ static int ext4_dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
if (write) {
sb_start_pagefault(sb);
file_update_time(vma->vm_file);
- down_read(&EXT4_I(inode)->i_mmap_sem);
- handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE,
- ext4_chunk_trans_blocks(inode,
- PMD_SIZE / PAGE_SIZE));
- } else
- down_read(&EXT4_I(inode)->i_mmap_sem);
-
- if (IS_ERR(handle))
- result = VM_FAULT_SIGBUS;
- else {
- result = dax_iomap_pmd_fault(vma, addr, pmd, flags,
- &ext4_iomap_ops);
}
-
- if (write) {
- if (!IS_ERR(handle))
- ext4_journal_stop(handle);
- up_read(&EXT4_I(inode)->i_mmap_sem);
+ down_read(&EXT4_I(inode)->i_mmap_sem);
+ result = dax_iomap_pmd_fault(vma, addr, pmd, flags,
+ &ext4_iomap_ops);
+ up_read(&EXT4_I(inode)->i_mmap_sem);
+ if (write)
sb_end_pagefault(sb);
- } else
- up_read(&EXT4_I(inode)->i_mmap_sem);
return result;
}
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index d3fea0bd89e2..6043306e8e21 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -510,18 +510,6 @@ void fsnotify_detach_group_marks(struct fsnotify_group *group)
}
}
-void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old)
-{
- assert_spin_locked(&old->lock);
- new->inode = old->inode;
- new->mnt = old->mnt;
- if (old->group)
- fsnotify_get_group(old->group);
- new->group = old->group;
- new->mask = old->mask;
- new->free_mark = old->free_mark;
-}
-
/*
* Nothing fancy, just initialize lists and locks and counters.
*/
diff --git a/fs/xfs/libxfs/xfs_ag_resv.c b/fs/xfs/libxfs/xfs_ag_resv.c
index e5ebc3770460..d346d42c54d1 100644
--- a/fs/xfs/libxfs/xfs_ag_resv.c
+++ b/fs/xfs/libxfs/xfs_ag_resv.c
@@ -256,6 +256,9 @@ xfs_ag_resv_init(
goto out;
}
+ ASSERT(xfs_perag_resv(pag, XFS_AG_RESV_METADATA)->ar_reserved +
+ xfs_perag_resv(pag, XFS_AG_RESV_AGFL)->ar_reserved <=
+ pag->pagf_freeblks + pag->pagf_flcount);
out:
return error;
}
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c
index 6fb2215f8ff7..50add5272807 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.c
+++ b/fs/xfs/libxfs/xfs_refcount_btree.c
@@ -409,13 +409,14 @@ xfs_refcountbt_calc_size(
*/
xfs_extlen_t
xfs_refcountbt_max_size(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ xfs_agblock_t agblocks)
{
/* Bail out if we're uninitialized, which can happen in mkfs. */
if (mp->m_refc_mxr[0] == 0)
return 0;
- return xfs_refcountbt_calc_size(mp, mp->m_sb.sb_agblocks);
+ return xfs_refcountbt_calc_size(mp, agblocks);
}
/*
@@ -430,22 +431,24 @@ xfs_refcountbt_calc_reserves(
{
struct xfs_buf *agbp;
struct xfs_agf *agf;
+ xfs_agblock_t agblocks;
xfs_extlen_t tree_len;
int error;
if (!xfs_sb_version_hasreflink(&mp->m_sb))
return 0;
- *ask += xfs_refcountbt_max_size(mp);
error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
if (error)
return error;
agf = XFS_BUF_TO_AGF(agbp);
+ agblocks = be32_to_cpu(agf->agf_length);
tree_len = be32_to_cpu(agf->agf_refcount_blocks);
xfs_buf_relse(agbp);
+ *ask += xfs_refcountbt_max_size(mp, agblocks);
*used += tree_len;
return error;
diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h
index 3be7768bd51a..9db008b955b7 100644
--- a/fs/xfs/libxfs/xfs_refcount_btree.h
+++ b/fs/xfs/libxfs/xfs_refcount_btree.h
@@ -66,7 +66,8 @@ extern void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp);
extern xfs_extlen_t xfs_refcountbt_calc_size(struct xfs_mount *mp,
unsigned long long len);
-extern xfs_extlen_t xfs_refcountbt_max_size(struct xfs_mount *mp);
+extern xfs_extlen_t xfs_refcountbt_max_size(struct xfs_mount *mp,
+ xfs_agblock_t agblocks);
extern int xfs_refcountbt_calc_reserves(struct xfs_mount *mp,
xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used);
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c
index de25771764ba..74e5a54bc428 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rmap_btree.c
@@ -550,13 +550,14 @@ xfs_rmapbt_calc_size(
*/
xfs_extlen_t
xfs_rmapbt_max_size(
- struct xfs_mount *mp)
+ struct xfs_mount *mp,
+ xfs_agblock_t agblocks)
{
/* Bail out if we're uninitialized, which can happen in mkfs. */
if (mp->m_rmap_mxr[0] == 0)
return 0;
- return xfs_rmapbt_calc_size(mp, mp->m_sb.sb_agblocks);
+ return xfs_rmapbt_calc_size(mp, agblocks);
}
/*
@@ -571,25 +572,24 @@ xfs_rmapbt_calc_reserves(
{
struct xfs_buf *agbp;
struct xfs_agf *agf;
- xfs_extlen_t pool_len;
+ xfs_agblock_t agblocks;
xfs_extlen_t tree_len;
int error;
if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
return 0;
- /* Reserve 1% of the AG or enough for 1 block per record. */
- pool_len = max(mp->m_sb.sb_agblocks / 100, xfs_rmapbt_max_size(mp));
- *ask += pool_len;
-
error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
if (error)
return error;
agf = XFS_BUF_TO_AGF(agbp);
+ agblocks = be32_to_cpu(agf->agf_length);
tree_len = be32_to_cpu(agf->agf_rmap_blocks);
xfs_buf_relse(agbp);
+ /* Reserve 1% of the AG or enough for 1 block per record. */
+ *ask += max(agblocks / 100, xfs_rmapbt_max_size(mp, agblocks));
*used += tree_len;
return error;
diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h
index 2a9ac472fb15..19c08e933049 100644
--- a/fs/xfs/libxfs/xfs_rmap_btree.h
+++ b/fs/xfs/libxfs/xfs_rmap_btree.h
@@ -60,7 +60,8 @@ extern void xfs_rmapbt_compute_maxlevels(struct xfs_mount *mp);
extern xfs_extlen_t xfs_rmapbt_calc_size(struct xfs_mount *mp,
unsigned long long len);
-extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp);
+extern xfs_extlen_t xfs_rmapbt_max_size(struct xfs_mount *mp,
+ xfs_agblock_t agblocks);
extern int xfs_rmapbt_calc_reserves(struct xfs_mount *mp,
xfs_agnumber_t agno, xfs_extlen_t *ask, xfs_extlen_t *used);
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 93d12fa2670d..242e8091296d 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -631,6 +631,20 @@ xfs_growfs_data_private(
xfs_set_low_space_thresholds(mp);
mp->m_alloc_set_aside = xfs_alloc_set_aside(mp);
+ /*
+ * If we expanded the last AG, free the per-AG reservation
+ * so we can reinitialize it with the new size.
+ */
+ if (new) {
+ struct xfs_perag *pag;
+
+ pag = xfs_perag_get(mp, agno);
+ error = xfs_ag_resv_free(pag);
+ xfs_perag_put(pag);
+ if (error)
+ goto out;
+ }
+
/* Reserve AG metadata blocks. */
error = xfs_fs_reserve_ag_blocks(mp);
if (error && error != -ENOSPC)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index ff4d6311c7f4..70ca4f608321 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1597,7 +1597,8 @@ xfs_inode_free_cowblocks(
* If the mapping is dirty or under writeback we cannot touch the
* CoW fork. Leave it alone if we're in the midst of a directio.
*/
- if (mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY) ||
+ if ((VFS_I(ip)->i_state & I_DIRTY_PAGES) ||
+ mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY) ||
mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_WRITEBACK) ||
atomic_read(&VFS_I(ip)->i_dio_count))
return 0;
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
index fe86a668a57e..6e4c7446c3d4 100644
--- a/fs/xfs/xfs_refcount_item.c
+++ b/fs/xfs/xfs_refcount_item.c
@@ -526,13 +526,14 @@ xfs_cui_recover(
xfs_refcount_finish_one_cleanup(tp, rcur, error);
error = xfs_defer_finish(&tp, &dfops, NULL);
if (error)
- goto abort_error;
+ goto abort_defer;
set_bit(XFS_CUI_RECOVERED, &cuip->cui_flags);
error = xfs_trans_commit(tp);
return error;
abort_error:
xfs_refcount_finish_one_cleanup(tp, rcur, error);
+abort_defer:
xfs_defer_cancel(&dfops);
xfs_trans_cancel(tp);
return error;
diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c
index 276d3023d60f..de6195e38910 100644
--- a/fs/xfs/xfs_sysfs.c
+++ b/fs/xfs/xfs_sysfs.c
@@ -396,7 +396,7 @@ max_retries_show(
int retries;
struct xfs_error_cfg *cfg = to_error_cfg(kobject);
- if (cfg->retry_timeout == XFS_ERR_RETRY_FOREVER)
+ if (cfg->max_retries == XFS_ERR_RETRY_FOREVER)
retries = -1;
else
retries = cfg->max_retries;
@@ -422,7 +422,7 @@ max_retries_store(
return -EINVAL;
if (val == -1)
- cfg->retry_timeout = XFS_ERR_RETRY_FOREVER;
+ cfg->max_retries = XFS_ERR_RETRY_FOREVER;
else
cfg->max_retries = val;
return count;
diff --git a/include/asm-generic/asm-prototypes.h b/include/asm-generic/asm-prototypes.h
index df13637e4017..939869c772b1 100644
--- a/include/asm-generic/asm-prototypes.h
+++ b/include/asm-generic/asm-prototypes.h
@@ -1,7 +1,13 @@
#include <linux/bitops.h>
+#undef __memset
extern void *__memset(void *, int, __kernel_size_t);
+#undef __memcpy
extern void *__memcpy(void *, const void *, __kernel_size_t);
+#undef __memmove
extern void *__memmove(void *, const void *, __kernel_size_t);
+#undef memset
extern void *memset(void *, int, __kernel_size_t);
+#undef memcpy
extern void *memcpy(void *, const void *, __kernel_size_t);
+#undef memmove
extern void *memmove(void *, const void *, __kernel_size_t);
diff --git a/include/dt-bindings/mfd/tps65217.h b/include/dt-bindings/mfd/tps65217.h
deleted file mode 100644
index cafb9e60cf12..000000000000
--- a/include/dt-bindings/mfd/tps65217.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This header provides macros for TI TPS65217 DT bindings.
- *
- * Copyright (C) 2016 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __DT_BINDINGS_TPS65217_H__
-#define __DT_BINDINGS_TPS65217_H__
-
-#define TPS65217_IRQ_USB 0
-#define TPS65217_IRQ_AC 1
-#define TPS65217_IRQ_PB 2
-
-#endif
diff --git a/include/linux/dax.h b/include/linux/dax.h
index f97bcfe79472..24ad71173995 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -41,6 +41,9 @@ ssize_t dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
int dax_iomap_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
struct iomap_ops *ops);
int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index);
+int dax_invalidate_mapping_entry(struct address_space *mapping, pgoff_t index);
+int dax_invalidate_mapping_entry_sync(struct address_space *mapping,
+ pgoff_t index);
void dax_wake_mapping_entry_waiter(struct address_space *mapping,
pgoff_t index, void *entry, bool wake_all);
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 702314253797..a0934e6c9bab 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -610,7 +610,6 @@ bool bpf_helper_changes_pkt_data(void *func);
struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
const struct bpf_insn *patch, u32 len);
void bpf_warn_invalid_xdp_action(u32 act);
-void bpf_warn_invalid_xdp_buffer(void);
#ifdef CONFIG_BPF_JIT
extern int bpf_jit_enable;
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 0cf34d6cc253..487246546ebe 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -323,8 +323,6 @@ extern void fsnotify_init_mark(struct fsnotify_mark *mark, void (*free_mark)(str
extern struct fsnotify_mark *fsnotify_find_inode_mark(struct fsnotify_group *group, struct inode *inode);
/* find (and take a reference) to a mark associated with group and vfsmount */
extern struct fsnotify_mark *fsnotify_find_vfsmount_mark(struct fsnotify_group *group, struct vfsmount *mnt);
-/* copy the values from old into new */
-extern void fsnotify_duplicate_mark(struct fsnotify_mark *new, struct fsnotify_mark *old);
/* set the ignored_mask of a mark */
extern void fsnotify_set_mark_ignored_mask_locked(struct fsnotify_mark *mark, __u32 mask);
/* set the mask of a mark (might pin the object into memory */
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index e0341af6950e..76f39754e7b0 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -146,15 +146,6 @@ enum {
DISK_EVENT_EJECT_REQUEST = 1 << 1, /* eject requested */
};
-#define BLK_SCSI_MAX_CMDS (256)
-#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
-
-struct blk_scsi_cmd_filter {
- unsigned long read_ok[BLK_SCSI_CMD_PER_LONG];
- unsigned long write_ok[BLK_SCSI_CMD_PER_LONG];
- struct kobject kobj;
-};
-
struct disk_part_tbl {
struct rcu_head rcu_head;
int len;
diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
index dd85f3503410..7ef111d3ecc5 100644
--- a/include/linux/hid-sensor-hub.h
+++ b/include/linux/hid-sensor-hub.h
@@ -232,6 +232,7 @@ struct hid_sensor_common {
atomic_t data_ready;
atomic_t user_requested_state;
struct iio_trigger *trigger;
+ int timestamp_ns_scale;
struct hid_sensor_hub_attribute_info poll;
struct hid_sensor_hub_attribute_info report_state;
struct hid_sensor_hub_attribute_info power_state;
@@ -271,4 +272,7 @@ int hid_sensor_format_scale(u32 usage_id,
s32 hid_sensor_read_poll_value(struct hid_sensor_common *st);
+int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st,
+ int64_t raw_value);
+
#endif
diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
index f2ee90aed0c2..30c7dc45e45f 100644
--- a/include/linux/hid-sensor-ids.h
+++ b/include/linux/hid-sensor-ids.h
@@ -52,6 +52,9 @@
#define HID_USAGE_SENSOR_ANGL_VELOCITY_Y_AXIS 0x200458
#define HID_USAGE_SENSOR_ANGL_VELOCITY_Z_AXIS 0x200459
+/* Gravity vector */
+#define HID_USAGE_SENSOR_GRAVITY_VECTOR 0x20007B
+
/* ORIENTATION: Compass 3D: (200083) */
#define HID_USAGE_SENSOR_COMPASS_3D 0x200083
#define HID_USAGE_SENSOR_DATA_ORIENTATION 0x200470
@@ -95,6 +98,7 @@
#define HID_USAGE_SENSOR_TIME_HOUR 0x200525
#define HID_USAGE_SENSOR_TIME_MINUTE 0x200526
#define HID_USAGE_SENSOR_TIME_SECOND 0x200527
+#define HID_USAGE_SENSOR_TIME_TIMESTAMP 0x200529
/* Units */
#define HID_USAGE_SENSOR_UNITS_NOT_SPECIFIED 0x00
diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h
index 70a5164f4728..48767c776119 100644
--- a/include/linux/iio/buffer.h
+++ b/include/linux/iio/buffer.h
@@ -11,139 +11,15 @@
#define _IIO_BUFFER_GENERIC_H_
#include <linux/sysfs.h>
#include <linux/iio/iio.h>
-#include <linux/kref.h>
-
-#ifdef CONFIG_IIO_BUFFER
struct iio_buffer;
-/**
- * INDIO_BUFFER_FLAG_FIXED_WATERMARK - Watermark level of the buffer can not be
- * configured. It has a fixed value which will be buffer specific.
- */
-#define INDIO_BUFFER_FLAG_FIXED_WATERMARK BIT(0)
-
-/**
- * struct iio_buffer_access_funcs - access functions for buffers.
- * @store_to: actually store stuff to the buffer
- * @read_first_n: try to get a specified number of bytes (must exist)
- * @data_available: indicates how much data is available for reading from
- * the buffer.
- * @request_update: if a parameter change has been marked, update underlying
- * storage.
- * @set_bytes_per_datum:set number of bytes per datum
- * @set_length: set number of datums in buffer
- * @enable: called if the buffer is attached to a device and the
- * device starts sampling. Calls are balanced with
- * @disable.
- * @disable: called if the buffer is attached to a device and the
- * device stops sampling. Calles are balanced with @enable.
- * @release: called when the last reference to the buffer is dropped,
- * should free all resources allocated by the buffer.
- * @modes: Supported operating modes by this buffer type
- * @flags: A bitmask combination of INDIO_BUFFER_FLAG_*
- *
- * The purpose of this structure is to make the buffer element
- * modular as event for a given driver, different usecases may require
- * different buffer designs (space efficiency vs speed for example).
- *
- * It is worth noting that a given buffer implementation may only support a
- * small proportion of these functions. The core code 'should' cope fine with
- * any of them not existing.
- **/
-struct iio_buffer_access_funcs {
- int (*store_to)(struct iio_buffer *buffer, const void *data);
- int (*read_first_n)(struct iio_buffer *buffer,
- size_t n,
- char __user *buf);
- size_t (*data_available)(struct iio_buffer *buffer);
-
- int (*request_update)(struct iio_buffer *buffer);
-
- int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
- int (*set_length)(struct iio_buffer *buffer, int length);
-
- int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
- int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
-
- void (*release)(struct iio_buffer *buffer);
-
- unsigned int modes;
- unsigned int flags;
-};
-
-/**
- * struct iio_buffer - general buffer structure
- * @length: [DEVICE] number of datums in buffer
- * @bytes_per_datum: [DEVICE] size of individual datum including timestamp
- * @scan_el_attrs: [DRIVER] control of scan elements if that scan mode
- * control method is used
- * @scan_mask: [INTERN] bitmask used in masking scan mode elements
- * @scan_timestamp: [INTERN] does the scan mode include a timestamp
- * @access: [DRIVER] buffer access functions associated with the
- * implementation.
- * @scan_el_dev_attr_list:[INTERN] list of scan element related attributes.
- * @buffer_group: [INTERN] attributes of the buffer group
- * @scan_el_group: [DRIVER] attribute group for those attributes not
- * created from the iio_chan_info array.
- * @pollq: [INTERN] wait queue to allow for polling on the buffer.
- * @stufftoread: [INTERN] flag to indicate new data.
- * @attrs: [INTERN] standard attributes of the buffer
- * @demux_list: [INTERN] list of operations required to demux the scan.
- * @demux_bounce: [INTERN] buffer for doing gather from incoming scan.
- * @buffer_list: [INTERN] entry in the devices list of current buffers.
- * @ref: [INTERN] reference count of the buffer.
- * @watermark: [INTERN] number of datums to wait for poll/read.
- */
-struct iio_buffer {
- int length;
- int bytes_per_datum;
- struct attribute_group *scan_el_attrs;
- long *scan_mask;
- bool scan_timestamp;
- const struct iio_buffer_access_funcs *access;
- struct list_head scan_el_dev_attr_list;
- struct attribute_group buffer_group;
- struct attribute_group scan_el_group;
- wait_queue_head_t pollq;
- bool stufftoread;
- const struct attribute **attrs;
- struct list_head demux_list;
- void *demux_bounce;
- struct list_head buffer_list;
- struct kref ref;
- unsigned int watermark;
-};
-
-/**
- * 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
- **/
-void iio_buffer_init(struct iio_buffer *buffer);
+void iio_buffer_set_attrs(struct iio_buffer *buffer,
+ const struct attribute **attrs);
-int iio_scan_mask_query(struct iio_dev *indio_dev,
- struct iio_buffer *buffer, int bit);
-
-/**
- * iio_push_to_buffers() - push to a registered buffer.
- * @indio_dev: iio_dev structure for device.
- * @data: Full scan.
- */
int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data);
-/*
+/**
* iio_push_to_buffers_with_timestamp() - push data and timestamp to buffers
* @indio_dev: iio_dev structure for device.
* @data: sample data
@@ -168,34 +44,10 @@ static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev,
return iio_push_to_buffers(indio_dev, data);
}
-int iio_update_demux(struct iio_dev *indio_dev);
-
bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
- const unsigned long *mask);
-
-struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer);
-void iio_buffer_put(struct iio_buffer *buffer);
-
-/**
- * iio_device_attach_buffer - Attach a buffer to a IIO device
- * @indio_dev: The device the buffer should be attached to
- * @buffer: The buffer to attach to the device
- *
- * This function attaches a buffer to a IIO device. The buffer stays attached to
- * the device until the device is freed. The function should only be called at
- * most once per device.
- */
-static inline void iio_device_attach_buffer(struct iio_dev *indio_dev,
- struct iio_buffer *buffer)
-{
- indio_dev->buffer = iio_buffer_get(buffer);
-}
-
-#else /* CONFIG_IIO_BUFFER */
-
-static inline void iio_buffer_get(struct iio_buffer *buffer) {}
-static inline void iio_buffer_put(struct iio_buffer *buffer) {}
+ const unsigned long *mask);
-#endif /* CONFIG_IIO_BUFFER */
+void iio_device_attach_buffer(struct iio_dev *indio_dev,
+ struct iio_buffer *buffer);
#endif /* _IIO_BUFFER_GENERIC_H_ */
diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h
new file mode 100644
index 000000000000..8daba198fafa
--- /dev/null
+++ b/include/linux/iio/buffer_impl.h
@@ -0,0 +1,162 @@
+#ifndef _IIO_BUFFER_GENERIC_IMPL_H_
+#define _IIO_BUFFER_GENERIC_IMPL_H_
+#include <linux/sysfs.h>
+#include <linux/kref.h>
+
+#ifdef CONFIG_IIO_BUFFER
+
+struct iio_dev;
+struct iio_buffer;
+
+/**
+ * INDIO_BUFFER_FLAG_FIXED_WATERMARK - Watermark level of the buffer can not be
+ * configured. It has a fixed value which will be buffer specific.
+ */
+#define INDIO_BUFFER_FLAG_FIXED_WATERMARK BIT(0)
+
+/**
+ * struct iio_buffer_access_funcs - access functions for buffers.
+ * @store_to: actually store stuff to the buffer
+ * @read_first_n: try to get a specified number of bytes (must exist)
+ * @data_available: indicates how much data is available for reading from
+ * the buffer.
+ * @request_update: if a parameter change has been marked, update underlying
+ * storage.
+ * @set_bytes_per_datum:set number of bytes per datum
+ * @set_length: set number of datums in buffer
+ * @enable: called if the buffer is attached to a device and the
+ * device starts sampling. Calls are balanced with
+ * @disable.
+ * @disable: called if the buffer is attached to a device and the
+ * device stops sampling. Calles are balanced with @enable.
+ * @release: called when the last reference to the buffer is dropped,
+ * should free all resources allocated by the buffer.
+ * @modes: Supported operating modes by this buffer type
+ * @flags: A bitmask combination of INDIO_BUFFER_FLAG_*
+ *
+ * The purpose of this structure is to make the buffer element
+ * modular as event for a given driver, different usecases may require
+ * different buffer designs (space efficiency vs speed for example).
+ *
+ * It is worth noting that a given buffer implementation may only support a
+ * small proportion of these functions. The core code 'should' cope fine with
+ * any of them not existing.
+ **/
+struct iio_buffer_access_funcs {
+ int (*store_to)(struct iio_buffer *buffer, const void *data);
+ int (*read_first_n)(struct iio_buffer *buffer,
+ size_t n,
+ char __user *buf);
+ size_t (*data_available)(struct iio_buffer *buffer);
+
+ int (*request_update)(struct iio_buffer *buffer);
+
+ int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
+ int (*set_length)(struct iio_buffer *buffer, int length);
+
+ int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
+ int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
+
+ void (*release)(struct iio_buffer *buffer);
+
+ unsigned int modes;
+ unsigned int flags;
+};
+
+/**
+ * struct iio_buffer - general buffer structure
+ *
+ * Note that the internals of this structure should only be of interest to
+ * those writing new buffer implementations.
+ */
+struct iio_buffer {
+ /** @length: Number of datums in buffer. */
+ int length;
+
+ /** @bytes_per_datum: Size of individual datum including timestamp. */
+ int bytes_per_datum;
+
+ /**
+ * @access: Buffer access functions associated with the
+ * implementation.
+ */
+ const struct iio_buffer_access_funcs *access;
+
+ /** @scan_mask: Bitmask used in masking scan mode elements. */
+ long *scan_mask;
+
+ /** @demux_list: List of operations required to demux the scan. */
+ struct list_head demux_list;
+
+ /** @pollq: Wait queue to allow for polling on the buffer. */
+ wait_queue_head_t pollq;
+
+ /** @watermark: Number of datums to wait for poll/read. */
+ unsigned int watermark;
+
+ /* private: */
+ /*
+ * @scan_el_attrs: Control of scan elements if that scan mode
+ * control method is used.
+ */
+ struct attribute_group *scan_el_attrs;
+
+ /* @scan_timestamp: Does the scan mode include a timestamp. */
+ bool scan_timestamp;
+
+ /* @scan_el_dev_attr_list: List of scan element related attributes. */
+ struct list_head scan_el_dev_attr_list;
+
+ /* @buffer_group: Attributes of the buffer group. */
+ struct attribute_group buffer_group;
+
+ /*
+ * @scan_el_group: Attribute group for those attributes not
+ * created from the iio_chan_info array.
+ */
+ struct attribute_group scan_el_group;
+
+ /* @stufftoread: Flag to indicate new data. */
+ bool stufftoread;
+
+ /* @attrs: Standard attributes of the buffer. */
+ const struct attribute **attrs;
+
+ /* @demux_bounce: Buffer for doing gather from incoming scan. */
+ void *demux_bounce;
+
+ /* @buffer_list: Entry in the devices list of current buffers. */
+ struct list_head buffer_list;
+
+ /* @ref: Reference count of the buffer. */
+ struct kref ref;
+};
+
+/**
+ * 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
+ **/
+void iio_buffer_init(struct iio_buffer *buffer);
+
+struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer);
+void iio_buffer_put(struct iio_buffer *buffer);
+
+#else /* CONFIG_IIO_BUFFER */
+
+static inline void iio_buffer_get(struct iio_buffer *buffer) {}
+static inline void iio_buffer_put(struct iio_buffer *buffer) {}
+
+#endif /* CONFIG_IIO_BUFFER */
+#endif /* _IIO_BUFFER_GENERIC_IMPL_H_ */
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index 228bd44efa4c..497f2b3a5a62 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -116,6 +116,16 @@ struct st_sensor_bdu {
};
/**
+ * struct st_sensor_das - ST sensor device data alignment selection
+ * @addr: address of the register.
+ * @mask: mask to write the das flag for left alignment.
+ */
+struct st_sensor_das {
+ u8 addr;
+ u8 mask;
+};
+
+/**
* struct st_sensor_data_ready_irq - ST sensor device data-ready interrupt
* @addr: address of the register.
* @mask_int1: mask to enable/disable IRQ on INT1 pin.
@@ -185,6 +195,7 @@ struct st_sensor_transfer_function {
* @enable_axis: Enable one or more axis of the sensor.
* @fs: Full scale register and full scale list available.
* @bdu: Block data update register.
+ * @das: Data Alignment Selection register.
* @drdy_irq: Data ready register of the sensor.
* @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read.
* @bootime: samples to discard when sensor passing from power-down to power-up.
@@ -200,6 +211,7 @@ struct st_sensor_settings {
struct st_sensor_axis enable_axis;
struct st_sensor_fullscale fs;
struct st_sensor_bdu bdu;
+ struct st_sensor_das das;
struct st_sensor_data_ready_irq drdy_irq;
bool multi_read_bit;
unsigned int bootime;
diff --git a/include/linux/iio/common/st_sensors_i2c.h b/include/linux/iio/common/st_sensors_i2c.h
index 1796af093368..254de3c7dde8 100644
--- a/include/linux/iio/common/st_sensors_i2c.h
+++ b/include/linux/iio/common/st_sensors_i2c.h
@@ -28,4 +28,13 @@ static inline void st_sensors_of_i2c_probe(struct i2c_client *client,
}
#endif
+#ifdef CONFIG_ACPI
+int st_sensors_match_acpi_device(struct device *dev);
+#else
+static inline int st_sensors_match_acpi_device(struct device *dev)
+{
+ return -ENODEV;
+}
+#endif
+
#endif /* ST_SENSORS_I2C_H */
diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h
index 1683bc710d14..027cfa9c3703 100644
--- a/include/linux/iio/kfifo_buf.h
+++ b/include/linux/iio/kfifo_buf.h
@@ -1,9 +1,8 @@
#ifndef __LINUX_IIO_KFIFO_BUF_H__
#define __LINUX_IIO_KFIFO_BUF_H__
-#include <linux/kfifo.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/buffer.h>
+struct iio_buffer;
+struct device;
struct iio_buffer *iio_kfifo_allocate(void);
void iio_kfifo_free(struct iio_buffer *r);
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index ec819e9a115a..b6e048e1045f 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -13,34 +13,10 @@
#ifndef MDEV_H
#define MDEV_H
-/* Parent device */
-struct parent_device {
- struct device *dev;
- const struct parent_ops *ops;
-
- /* internal */
- struct kref ref;
- struct mutex lock;
- struct list_head next;
- struct kset *mdev_types_kset;
- struct list_head type_list;
-};
-
-/* Mediated device */
-struct mdev_device {
- struct device dev;
- struct parent_device *parent;
- uuid_le uuid;
- void *driver_data;
-
- /* internal */
- struct kref ref;
- struct list_head next;
- struct kobject *type_kobj;
-};
+struct mdev_device;
/**
- * struct parent_ops - Structure to be registered for each parent device to
+ * struct mdev_parent_ops - Structure to be registered for each parent device to
* register the device to mdev module.
*
* @owner: The module owner.
@@ -86,10 +62,9 @@ struct mdev_device {
* @mdev: mediated device structure
* @vma: vma structure
* Parent device that support mediated device should be registered with mdev
- * module with parent_ops structure.
+ * module with mdev_parent_ops structure.
**/
-
-struct parent_ops {
+struct mdev_parent_ops {
struct module *owner;
const struct attribute_group **dev_attr_groups;
const struct attribute_group **mdev_attr_groups;
@@ -103,7 +78,7 @@ struct parent_ops {
size_t count, loff_t *ppos);
ssize_t (*write)(struct mdev_device *mdev, const char __user *buf,
size_t count, loff_t *ppos);
- ssize_t (*ioctl)(struct mdev_device *mdev, unsigned int cmd,
+ long (*ioctl)(struct mdev_device *mdev, unsigned int cmd,
unsigned long arg);
int (*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma);
};
@@ -142,27 +117,22 @@ struct mdev_driver {
};
#define to_mdev_driver(drv) container_of(drv, struct mdev_driver, driver)
-#define to_mdev_device(dev) container_of(dev, struct mdev_device, dev)
-
-static inline void *mdev_get_drvdata(struct mdev_device *mdev)
-{
- return mdev->driver_data;
-}
-static inline void mdev_set_drvdata(struct mdev_device *mdev, void *data)
-{
- mdev->driver_data = data;
-}
+extern void *mdev_get_drvdata(struct mdev_device *mdev);
+extern void mdev_set_drvdata(struct mdev_device *mdev, void *data);
+extern uuid_le mdev_uuid(struct mdev_device *mdev);
extern struct bus_type mdev_bus_type;
-#define dev_is_mdev(d) ((d)->bus == &mdev_bus_type)
-
extern int mdev_register_device(struct device *dev,
- const struct parent_ops *ops);
+ const struct mdev_parent_ops *ops);
extern void mdev_unregister_device(struct device *dev);
extern int mdev_register_driver(struct mdev_driver *drv, struct module *owner);
extern void mdev_unregister_driver(struct mdev_driver *drv);
+extern struct device *mdev_parent_dev(struct mdev_device *mdev);
+extern struct device *mdev_dev(struct mdev_device *mdev);
+extern struct mdev_device *mdev_from_dev(struct device *dev);
+
#endif /* MDEV_H */
diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h
index 1683003603f3..098c3501ad2c 100644
--- a/include/linux/mfd/cros_ec_commands.h
+++ b/include/linux/mfd/cros_ec_commands.h
@@ -1441,7 +1441,8 @@ enum motionsensor_type {
MOTIONSENSE_TYPE_PROX = 3,
MOTIONSENSE_TYPE_LIGHT = 4,
MOTIONSENSE_TYPE_ACTIVITY = 5,
- MOTIONSENSE_TYPE_MAX
+ MOTIONSENSE_TYPE_BARO = 6,
+ MOTIONSENSE_TYPE_MAX,
};
/* List of motion sensor locations. */
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 93bdb3485192..6533c16e27ad 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -1384,6 +1384,8 @@ int set_phv_bit(struct mlx4_dev *dev, u8 port, int new_val);
int get_phv_bit(struct mlx4_dev *dev, u8 port, int *phv);
int mlx4_get_is_vlan_offload_disabled(struct mlx4_dev *dev, u8 port,
bool *vlan_offload_disabled);
+void mlx4_handle_eth_header_mcast_prio(struct mlx4_net_trans_rule_hw_ctrl *ctrl,
+ struct _rule_hw *eth_header);
int mlx4_find_cached_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *idx);
int mlx4_find_cached_vlan(struct mlx4_dev *dev, u8 port, u16 vid, int *idx);
int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index);
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 9f489365b3d3..52b437431c6a 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -1071,11 +1071,6 @@ enum {
MLX5_INFINIBAND_PORT_COUNTERS_GROUP = 0x20,
};
-enum {
- MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP = 0x0,
- MLX5_PCIE_TIMERS_AND_STATES_COUNTERS_GROUP = 0x2,
-};
-
static inline u16 mlx5_to_sw_pkey_sz(int pkey_sz)
{
if (pkey_sz > MLX5_MAX_LOG_PKEY_TABLE)
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 0ae55361e674..735b36335f29 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -123,7 +123,6 @@ enum {
MLX5_REG_HOST_ENDIANNESS = 0x7004,
MLX5_REG_MCIA = 0x9014,
MLX5_REG_MLCR = 0x902b,
- MLX5_REG_MPCNT = 0x9051,
};
enum mlx5_dcbx_oper_mode {
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 57bec544e20a..a852e9db6f0d 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -1757,80 +1757,6 @@ struct mlx5_ifc_eth_802_3_cntrs_grp_data_layout_bits {
u8 reserved_at_4c0[0x300];
};
-struct mlx5_ifc_pcie_perf_cntrs_grp_data_layout_bits {
- u8 life_time_counter_high[0x20];
-
- u8 life_time_counter_low[0x20];
-
- u8 rx_errors[0x20];
-
- u8 tx_errors[0x20];
-
- u8 l0_to_recovery_eieos[0x20];
-
- u8 l0_to_recovery_ts[0x20];
-
- u8 l0_to_recovery_framing[0x20];
-
- u8 l0_to_recovery_retrain[0x20];
-
- u8 crc_error_dllp[0x20];
-
- u8 crc_error_tlp[0x20];
-
- u8 reserved_at_140[0x680];
-};
-
-struct mlx5_ifc_pcie_tas_cntrs_grp_data_layout_bits {
- u8 life_time_counter_high[0x20];
-
- u8 life_time_counter_low[0x20];
-
- u8 time_to_boot_image_start[0x20];
-
- u8 time_to_link_image[0x20];
-
- u8 calibration_time[0x20];
-
- u8 time_to_first_perst[0x20];
-
- u8 time_to_detect_state[0x20];
-
- u8 time_to_l0[0x20];
-
- u8 time_to_crs_en[0x20];
-
- u8 time_to_plastic_image_start[0x20];
-
- u8 time_to_iron_image_start[0x20];
-
- u8 perst_handler[0x20];
-
- u8 times_in_l1[0x20];
-
- u8 times_in_l23[0x20];
-
- u8 dl_down[0x20];
-
- u8 config_cycle1usec[0x20];
-
- u8 config_cycle2to7usec[0x20];
-
- u8 config_cycle_8to15usec[0x20];
-
- u8 config_cycle_16_to_63usec[0x20];
-
- u8 config_cycle_64usec[0x20];
-
- u8 correctable_err_msg_sent[0x20];
-
- u8 non_fatal_err_msg_sent[0x20];
-
- u8 fatal_err_msg_sent[0x20];
-
- u8 reserved_at_2e0[0x4e0];
-};
-
struct mlx5_ifc_cmd_inter_comp_event_bits {
u8 command_completion_vector[0x20];
@@ -2995,12 +2921,6 @@ union mlx5_ifc_eth_cntrs_grp_data_layout_auto_bits {
u8 reserved_at_0[0x7c0];
};
-union mlx5_ifc_pcie_cntrs_grp_data_layout_auto_bits {
- struct mlx5_ifc_pcie_perf_cntrs_grp_data_layout_bits pcie_perf_cntrs_grp_data_layout;
- struct mlx5_ifc_pcie_tas_cntrs_grp_data_layout_bits pcie_tas_cntrs_grp_data_layout;
- u8 reserved_at_0[0x7c0];
-};
-
union mlx5_ifc_event_auto_bits {
struct mlx5_ifc_comp_event_bits comp_event;
struct mlx5_ifc_dct_events_bits dct_events;
@@ -7320,18 +7240,6 @@ struct mlx5_ifc_ppcnt_reg_bits {
union mlx5_ifc_eth_cntrs_grp_data_layout_auto_bits counter_set;
};
-struct mlx5_ifc_mpcnt_reg_bits {
- u8 reserved_at_0[0x8];
- u8 pcie_index[0x8];
- u8 reserved_at_10[0xa];
- u8 grp[0x6];
-
- u8 clr[0x1];
- u8 reserved_at_21[0x1f];
-
- union mlx5_ifc_pcie_cntrs_grp_data_layout_auto_bits counter_set;
-};
-
struct mlx5_ifc_ppad_reg_bits {
u8 reserved_at_0[0x3];
u8 single_mac[0x1];
@@ -7937,7 +7845,6 @@ union mlx5_ifc_ports_control_registers_document_bits {
struct mlx5_ifc_pmtu_reg_bits pmtu_reg;
struct mlx5_ifc_ppad_reg_bits ppad_reg;
struct mlx5_ifc_ppcnt_reg_bits ppcnt_reg;
- struct mlx5_ifc_mpcnt_reg_bits mpcnt_reg;
struct mlx5_ifc_pplm_reg_bits pplm_reg;
struct mlx5_ifc_pplr_reg_bits pplr_reg;
struct mlx5_ifc_ppsc_reg_bits ppsc_reg;
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index c56b39890a41..6b5818d6de32 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -73,13 +73,13 @@
*/
enum pageflags {
PG_locked, /* Page is locked. Don't touch. */
- PG_waiters, /* Page has waiters, check its waitqueue */
PG_error,
PG_referenced,
PG_uptodate,
PG_dirty,
PG_lru,
PG_active,
+ PG_waiters, /* Page has waiters, check its waitqueue. Must be bit #7 and in the same byte as "PG_locked" */
PG_slab,
PG_owner_priv_1, /* Owner use. If pagecache, fs may use*/
PG_arch_1,
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 5dea8f6440e4..52bda854593b 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -306,7 +306,9 @@ void radix_tree_iter_replace(struct radix_tree_root *,
void radix_tree_replace_slot(struct radix_tree_root *root,
void **slot, void *item);
void __radix_tree_delete_node(struct radix_tree_root *root,
- struct radix_tree_node *node);
+ struct radix_tree_node *node,
+ radix_tree_update_node_t update_node,
+ void *private);
void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *);
void *radix_tree_delete(struct radix_tree_root *, unsigned long);
void radix_tree_clear_tags(struct radix_tree_root *root,
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 183f37c8a5e1..4ee479f2f355 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -9,7 +9,13 @@ struct device;
struct page;
struct scatterlist;
-extern int swiotlb_force;
+enum swiotlb_force {
+ SWIOTLB_NORMAL, /* Default - depending on HW DMA mask etc. */
+ SWIOTLB_FORCE, /* swiotlb=force */
+ SWIOTLB_NO_FORCE, /* swiotlb=noforce */
+};
+
+extern enum swiotlb_force swiotlb_force;
/*
* Maximum allowable number of contiguous slabs to map,
@@ -108,11 +114,14 @@ swiotlb_dma_supported(struct device *hwdev, u64 mask);
#ifdef CONFIG_SWIOTLB
extern void __init swiotlb_free(void);
+unsigned int swiotlb_max_segment(void);
#else
static inline void swiotlb_free(void) { }
+static inline unsigned int swiotlb_max_segment(void) { return 0; }
#endif
extern void swiotlb_print_info(void);
extern int is_swiotlb_buffer(phys_addr_t paddr);
+extern void swiotlb_set_max_segment(unsigned int);
#endif /* __LINUX_SWIOTLB_H */
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index f0cf5a1b777e..0378e88f6fd3 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -110,6 +110,7 @@ struct netns_ipv4 {
int sysctl_tcp_orphan_retries;
int sysctl_tcp_fin_timeout;
unsigned int sysctl_tcp_notsent_lowat;
+ int sysctl_tcp_tw_reuse;
int sysctl_igmp_max_memberships;
int sysctl_igmp_max_msf;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 207147b4c6b2..6061963cca98 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -252,7 +252,6 @@ extern int sysctl_tcp_wmem[3];
extern int sysctl_tcp_rmem[3];
extern int sysctl_tcp_app_win;
extern int sysctl_tcp_adv_win_scale;
-extern int sysctl_tcp_tw_reuse;
extern int sysctl_tcp_frto;
extern int sysctl_tcp_low_latency;
extern int sysctl_tcp_nometrics_save;
diff --git a/include/trace/events/swiotlb.h b/include/trace/events/swiotlb.h
index 7ea4c5e7c448..288c0c54a2b4 100644
--- a/include/trace/events/swiotlb.h
+++ b/include/trace/events/swiotlb.h
@@ -11,16 +11,16 @@ TRACE_EVENT(swiotlb_bounced,
TP_PROTO(struct device *dev,
dma_addr_t dev_addr,
size_t size,
- int swiotlb_force),
+ enum swiotlb_force swiotlb_force),
TP_ARGS(dev, dev_addr, size, swiotlb_force),
TP_STRUCT__entry(
- __string( dev_name, dev_name(dev) )
- __field( u64, dma_mask )
- __field( dma_addr_t, dev_addr )
- __field( size_t, size )
- __field( int, swiotlb_force )
+ __string( dev_name, dev_name(dev) )
+ __field( u64, dma_mask )
+ __field( dma_addr_t, dev_addr )
+ __field( size_t, size )
+ __field( enum swiotlb_force, swiotlb_force )
),
TP_fast_assign(
@@ -37,7 +37,10 @@ TRACE_EVENT(swiotlb_bounced,
__entry->dma_mask,
(unsigned long long)__entry->dev_addr,
__entry->size,
- __entry->swiotlb_force ? "swiotlb_force" : "" )
+ __print_symbolic(__entry->swiotlb_force,
+ { SWIOTLB_NORMAL, "NORMAL" },
+ { SWIOTLB_FORCE, "FORCE" },
+ { SWIOTLB_NO_FORCE, "NO_FORCE" }))
);
#endif /* _TRACE_SWIOTLB_H */
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index e54d14a7f876..ffafd6c25a48 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -42,6 +42,7 @@ enum iio_chan_type {
IIO_ELECTRICALCONDUCTIVITY,
IIO_COUNT,
IIO_INDEX,
+ IIO_GRAVITY,
};
enum iio_modifier {
diff --git a/include/uapi/linux/usb/functionfs.h b/include/uapi/linux/usb/functionfs.h
index acc63697a0cc..b2a31a55a612 100644
--- a/include/uapi/linux/usb/functionfs.h
+++ b/include/uapi/linux/usb/functionfs.h
@@ -93,6 +93,7 @@ struct usb_ext_prop_desc {
* | 0 | magic | LE32 | FUNCTIONFS_DESCRIPTORS_MAGIC_V2 |
* | 4 | length | LE32 | length of the whole data chunk |
* | 8 | flags | LE32 | combination of functionfs_flags |
+ * | | eventfd | LE32 | eventfd file descriptor |
* | | fs_count | LE32 | number of full-speed descriptors |
* | | hs_count | LE32 | number of high-speed descriptors |
* | | ss_count | LE32 | number of super-speed descriptors |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
index 8b1dde96a0fa..7b44195da81b 100644
--- a/kernel/audit_tree.c
+++ b/kernel/audit_tree.c
@@ -231,9 +231,11 @@ static void untag_chunk(struct node *p)
if (size)
new = alloc_chunk(size);
+ mutex_lock(&entry->group->mark_mutex);
spin_lock(&entry->lock);
if (chunk->dead || !entry->inode) {
spin_unlock(&entry->lock);
+ mutex_unlock(&entry->group->mark_mutex);
if (new)
free_chunk(new);
goto out;
@@ -251,6 +253,7 @@ static void untag_chunk(struct node *p)
list_del_rcu(&chunk->hash);
spin_unlock(&hash_lock);
spin_unlock(&entry->lock);
+ mutex_unlock(&entry->group->mark_mutex);
fsnotify_destroy_mark(entry, audit_tree_group);
goto out;
}
@@ -258,8 +261,8 @@ static void untag_chunk(struct node *p)
if (!new)
goto Fallback;
- fsnotify_duplicate_mark(&new->mark, entry);
- if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.inode, NULL, 1)) {
+ if (fsnotify_add_mark_locked(&new->mark, entry->group, entry->inode,
+ NULL, 1)) {
fsnotify_put_mark(&new->mark);
goto Fallback;
}
@@ -293,6 +296,7 @@ static void untag_chunk(struct node *p)
owner->root = new;
spin_unlock(&hash_lock);
spin_unlock(&entry->lock);
+ mutex_unlock(&entry->group->mark_mutex);
fsnotify_destroy_mark(entry, audit_tree_group);
fsnotify_put_mark(&new->mark); /* drop initial reference */
goto out;
@@ -309,6 +313,7 @@ Fallback:
put_tree(owner);
spin_unlock(&hash_lock);
spin_unlock(&entry->lock);
+ mutex_unlock(&entry->group->mark_mutex);
out:
fsnotify_put_mark(entry);
spin_lock(&hash_lock);
@@ -386,18 +391,21 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
chunk_entry = &chunk->mark;
+ mutex_lock(&old_entry->group->mark_mutex);
spin_lock(&old_entry->lock);
if (!old_entry->inode) {
/* old_entry is being shot, lets just lie */
spin_unlock(&old_entry->lock);
+ mutex_unlock(&old_entry->group->mark_mutex);
fsnotify_put_mark(old_entry);
free_chunk(chunk);
return -ENOENT;
}
- fsnotify_duplicate_mark(chunk_entry, old_entry);
- if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->inode, NULL, 1)) {
+ if (fsnotify_add_mark_locked(chunk_entry, old_entry->group,
+ old_entry->inode, NULL, 1)) {
spin_unlock(&old_entry->lock);
+ mutex_unlock(&old_entry->group->mark_mutex);
fsnotify_put_mark(chunk_entry);
fsnotify_put_mark(old_entry);
return -ENOSPC;
@@ -413,6 +421,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
chunk->dead = 1;
spin_unlock(&chunk_entry->lock);
spin_unlock(&old_entry->lock);
+ mutex_unlock(&old_entry->group->mark_mutex);
fsnotify_destroy_mark(chunk_entry, audit_tree_group);
@@ -445,6 +454,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree)
spin_unlock(&hash_lock);
spin_unlock(&chunk_entry->lock);
spin_unlock(&old_entry->lock);
+ mutex_unlock(&old_entry->group->mark_mutex);
fsnotify_destroy_mark(old_entry, audit_tree_group);
fsnotify_put_mark(chunk_entry); /* drop initial reference */
fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 042fd7e8e030..f75c4d031eeb 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1471,6 +1471,7 @@ int __cpuhp_setup_state(enum cpuhp_state state,
bool multi_instance)
{
int cpu, ret = 0;
+ bool dynstate;
if (cpuhp_cb_check(state) || !name)
return -EINVAL;
@@ -1480,6 +1481,12 @@ int __cpuhp_setup_state(enum cpuhp_state state,
ret = cpuhp_store_callbacks(state, name, startup, teardown,
multi_instance);
+ dynstate = state == CPUHP_AP_ONLINE_DYN;
+ if (ret > 0 && dynstate) {
+ state = ret;
+ ret = 0;
+ }
+
if (ret || !invoke || !startup)
goto out;
@@ -1508,7 +1515,7 @@ out:
* If the requested state is CPUHP_AP_ONLINE_DYN, return the
* dynamically allocated state in case of success.
*/
- if (!ret && state == CPUHP_AP_ONLINE_DYN)
+ if (!ret && dynstate)
return state;
return ret;
}
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 6f382e07de77..0b92d605fb69 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -640,6 +640,7 @@ static inline void radix_tree_shrink(struct radix_tree_root *root,
update_node(node, private);
}
+ WARN_ON_ONCE(!list_empty(&node->private_list));
radix_tree_node_free(node);
}
}
@@ -666,6 +667,7 @@ static void delete_node(struct radix_tree_root *root,
root->rnode = NULL;
}
+ WARN_ON_ONCE(!list_empty(&node->private_list));
radix_tree_node_free(node);
node = parent;
@@ -767,6 +769,7 @@ static void radix_tree_free_nodes(struct radix_tree_node *node)
struct radix_tree_node *old = child;
offset = child->offset + 1;
child = child->parent;
+ WARN_ON_ONCE(!list_empty(&node->private_list));
radix_tree_node_free(old);
if (old == entry_to_node(node))
return;
@@ -1824,15 +1827,19 @@ EXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot);
* __radix_tree_delete_node - try to free node after clearing a slot
* @root: radix tree root
* @node: node containing @index
+ * @update_node: callback for changing leaf nodes
+ * @private: private data to pass to @update_node
*
* After clearing the slot at @index in @node from radix tree
* rooted at @root, call this function to attempt freeing the
* node and shrinking the tree.
*/
void __radix_tree_delete_node(struct radix_tree_root *root,
- struct radix_tree_node *node)
+ struct radix_tree_node *node,
+ radix_tree_update_node_t update_node,
+ void *private)
{
- delete_node(root, node, NULL, NULL);
+ delete_node(root, node, update_node, private);
}
/**
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index cb1b54ee8527..975b8fc4f1e1 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -53,7 +53,7 @@
*/
#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
-int swiotlb_force;
+enum swiotlb_force swiotlb_force;
/*
* Used to do a quick range check in swiotlb_tbl_unmap_single and
@@ -83,6 +83,12 @@ static unsigned int *io_tlb_list;
static unsigned int io_tlb_index;
/*
+ * Max segment that we can provide which (if pages are contingous) will
+ * not be bounced (unless SWIOTLB_FORCE is set).
+ */
+unsigned int max_segment;
+
+/*
* We need to save away the original address corresponding to a mapped entry
* for the sync operations.
*/
@@ -106,8 +112,12 @@ setup_io_tlb_npages(char *str)
}
if (*str == ',')
++str;
- if (!strcmp(str, "force"))
- swiotlb_force = 1;
+ if (!strcmp(str, "force")) {
+ swiotlb_force = SWIOTLB_FORCE;
+ } else if (!strcmp(str, "noforce")) {
+ swiotlb_force = SWIOTLB_NO_FORCE;
+ io_tlb_nslabs = 1;
+ }
return 0;
}
@@ -120,6 +130,20 @@ unsigned long swiotlb_nr_tbl(void)
}
EXPORT_SYMBOL_GPL(swiotlb_nr_tbl);
+unsigned int swiotlb_max_segment(void)
+{
+ return max_segment;
+}
+EXPORT_SYMBOL_GPL(swiotlb_max_segment);
+
+void swiotlb_set_max_segment(unsigned int val)
+{
+ if (swiotlb_force == SWIOTLB_FORCE)
+ max_segment = 1;
+ else
+ max_segment = rounddown(val, PAGE_SIZE);
+}
+
/* default to 64MB */
#define IO_TLB_DEFAULT_SIZE (64UL<<20)
unsigned long swiotlb_size_or_default(void)
@@ -201,6 +225,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
if (verbose)
swiotlb_print_info();
+ swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT);
return 0;
}
@@ -279,6 +304,7 @@ swiotlb_late_init_with_default_size(size_t default_size)
rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs);
if (rc)
free_pages((unsigned long)vstart, order);
+
return rc;
}
@@ -333,6 +359,8 @@ swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
late_alloc = 1;
+ swiotlb_set_max_segment(io_tlb_nslabs << IO_TLB_SHIFT);
+
return 0;
cleanup4:
@@ -347,6 +375,7 @@ cleanup2:
io_tlb_end = 0;
io_tlb_start = 0;
io_tlb_nslabs = 0;
+ max_segment = 0;
return -ENOMEM;
}
@@ -375,6 +404,7 @@ void __init swiotlb_free(void)
PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT));
}
io_tlb_nslabs = 0;
+ max_segment = 0;
}
int is_swiotlb_buffer(phys_addr_t paddr)
@@ -543,8 +573,15 @@ static phys_addr_t
map_single(struct device *hwdev, phys_addr_t phys, size_t size,
enum dma_data_direction dir, unsigned long attrs)
{
- dma_addr_t start_dma_addr = phys_to_dma(hwdev, io_tlb_start);
+ dma_addr_t start_dma_addr;
+ if (swiotlb_force == SWIOTLB_NO_FORCE) {
+ dev_warn_ratelimited(hwdev, "Cannot do DMA to address %pa\n",
+ &phys);
+ return SWIOTLB_MAP_ERROR;
+ }
+
+ start_dma_addr = phys_to_dma(hwdev, io_tlb_start);
return swiotlb_tbl_map_single(hwdev, start_dma_addr, phys, size,
dir, attrs);
}
@@ -721,6 +758,9 @@ static void
swiotlb_full(struct device *dev, size_t size, enum dma_data_direction dir,
int do_panic)
{
+ if (swiotlb_force == SWIOTLB_NO_FORCE)
+ return;
+
/*
* Ran out of IOMMU space for this operation. This is very bad.
* Unfortunately the drivers cannot handle this operation properly.
@@ -763,7 +803,7 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page,
* we can safely return the device addr and not worry about bounce
* buffering it.
*/
- if (dma_capable(dev, dev_addr, size) && !swiotlb_force)
+ if (dma_capable(dev, dev_addr, size) && swiotlb_force != SWIOTLB_FORCE)
return dev_addr;
trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
@@ -904,7 +944,7 @@ swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
phys_addr_t paddr = sg_phys(sg);
dma_addr_t dev_addr = phys_to_dma(hwdev, paddr);
- if (swiotlb_force ||
+ if (swiotlb_force == SWIOTLB_FORCE ||
!dma_capable(hwdev, dev_addr, sg->length)) {
phys_addr_t map = map_single(hwdev, sg_phys(sg),
sg->length, dir, attrs);
diff --git a/mm/filemap.c b/mm/filemap.c
index 82f26cde830c..d0e4d1002059 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -912,6 +912,29 @@ void add_page_wait_queue(struct page *page, wait_queue_t *waiter)
}
EXPORT_SYMBOL_GPL(add_page_wait_queue);
+#ifndef clear_bit_unlock_is_negative_byte
+
+/*
+ * PG_waiters is the high bit in the same byte as PG_lock.
+ *
+ * On x86 (and on many other architectures), we can clear PG_lock and
+ * test the sign bit at the same time. But if the architecture does
+ * not support that special operation, we just do this all by hand
+ * instead.
+ *
+ * The read of PG_waiters has to be after (or concurrently with) PG_locked
+ * being cleared, but a memory barrier should be unneccssary since it is
+ * in the same byte as PG_locked.
+ */
+static inline bool clear_bit_unlock_is_negative_byte(long nr, volatile void *mem)
+{
+ clear_bit_unlock(nr, mem);
+ /* smp_mb__after_atomic(); */
+ return test_bit(PG_waiters, mem);
+}
+
+#endif
+
/**
* unlock_page - unlock a locked page
* @page: the page
@@ -921,16 +944,19 @@ EXPORT_SYMBOL_GPL(add_page_wait_queue);
* mechanism between PageLocked pages and PageWriteback pages is shared.
* But that's OK - sleepers in wait_on_page_writeback() just go back to sleep.
*
- * The mb is necessary to enforce ordering between the clear_bit and the read
- * of the waitqueue (to avoid SMP races with a parallel wait_on_page_locked()).
+ * Note that this depends on PG_waiters being the sign bit in the byte
+ * that contains PG_locked - thus the BUILD_BUG_ON(). That allows us to
+ * clear the PG_locked bit and test PG_waiters at the same time fairly
+ * portably (architectures that do LL/SC can test any bit, while x86 can
+ * test the sign bit).
*/
void unlock_page(struct page *page)
{
+ BUILD_BUG_ON(PG_waiters != 7);
page = compound_head(page);
VM_BUG_ON_PAGE(!PageLocked(page), page);
- clear_bit_unlock(PG_locked, &page->flags);
- smp_mb__after_atomic();
- wake_up_page(page, PG_locked);
+ if (clear_bit_unlock_is_negative_byte(PG_locked, &page->flags))
+ wake_up_page_bit(page, PG_locked);
}
EXPORT_SYMBOL(unlock_page);
diff --git a/mm/memory.c b/mm/memory.c
index 7d23b5050248..9f2c15cdb32c 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3008,13 +3008,6 @@ static int do_set_pmd(struct vm_fault *vmf, struct page *page)
ret = 0;
count_vm_event(THP_FILE_MAPPED);
out:
- /*
- * If we are going to fallback to pte mapping, do a
- * withdraw with pmd lock held.
- */
- if (arch_needs_pgtable_deposit() && ret == VM_FAULT_FALLBACK)
- vmf->prealloc_pte = pgtable_trans_huge_withdraw(vma->vm_mm,
- vmf->pmd);
spin_unlock(vmf->ptl);
return ret;
}
@@ -3055,20 +3048,18 @@ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
ret = do_set_pmd(vmf, page);
if (ret != VM_FAULT_FALLBACK)
- goto fault_handled;
+ return ret;
}
if (!vmf->pte) {
ret = pte_alloc_one_map(vmf);
if (ret)
- goto fault_handled;
+ return ret;
}
/* Re-check under ptl */
- if (unlikely(!pte_none(*vmf->pte))) {
- ret = VM_FAULT_NOPAGE;
- goto fault_handled;
- }
+ if (unlikely(!pte_none(*vmf->pte)))
+ return VM_FAULT_NOPAGE;
flush_icache_page(vma, page);
entry = mk_pte(page, vma->vm_page_prot);
@@ -3088,15 +3079,8 @@ int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
/* no need to invalidate: a not-present page won't be cached */
update_mmu_cache(vma, vmf->address, vmf->pte);
- ret = 0;
-fault_handled:
- /* preallocated pagetable is unused: free it */
- if (vmf->prealloc_pte) {
- pte_free(vmf->vma->vm_mm, vmf->prealloc_pte);
- vmf->prealloc_pte = 0;
- }
- return ret;
+ return 0;
}
@@ -3360,15 +3344,24 @@ static int do_shared_fault(struct vm_fault *vmf)
static int do_fault(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
+ int ret;
/* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */
if (!vma->vm_ops->fault)
- return VM_FAULT_SIGBUS;
- if (!(vmf->flags & FAULT_FLAG_WRITE))
- return do_read_fault(vmf);
- if (!(vma->vm_flags & VM_SHARED))
- return do_cow_fault(vmf);
- return do_shared_fault(vmf);
+ ret = VM_FAULT_SIGBUS;
+ else if (!(vmf->flags & FAULT_FLAG_WRITE))
+ ret = do_read_fault(vmf);
+ else if (!(vma->vm_flags & VM_SHARED))
+ ret = do_cow_fault(vmf);
+ else
+ ret = do_shared_fault(vmf);
+
+ /* preallocated pagetable is unused: free it */
+ if (vmf->prealloc_pte) {
+ pte_free(vma->vm_mm, vmf->prealloc_pte);
+ vmf->prealloc_pte = 0;
+ }
+ return ret;
}
static int numa_migrate_prep(struct page *page, struct vm_area_struct *vma,
diff --git a/mm/truncate.c b/mm/truncate.c
index fd97f1dbce29..dd7b24e083c5 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -24,20 +24,12 @@
#include <linux/rmap.h>
#include "internal.h"
-static void clear_exceptional_entry(struct address_space *mapping,
- pgoff_t index, void *entry)
+static void clear_shadow_entry(struct address_space *mapping, pgoff_t index,
+ void *entry)
{
struct radix_tree_node *node;
void **slot;
- /* Handled by shmem itself */
- if (shmem_mapping(mapping))
- return;
-
- if (dax_mapping(mapping)) {
- dax_delete_mapping_entry(mapping, index);
- return;
- }
spin_lock_irq(&mapping->tree_lock);
/*
* Regular page slots are stabilized by the page lock even
@@ -55,6 +47,56 @@ unlock:
spin_unlock_irq(&mapping->tree_lock);
}
+/*
+ * Unconditionally remove exceptional entry. Usually called from truncate path.
+ */
+static void truncate_exceptional_entry(struct address_space *mapping,
+ pgoff_t index, void *entry)
+{
+ /* Handled by shmem itself */
+ if (shmem_mapping(mapping))
+ return;
+
+ if (dax_mapping(mapping)) {
+ dax_delete_mapping_entry(mapping, index);
+ return;
+ }
+ clear_shadow_entry(mapping, index, entry);
+}
+
+/*
+ * Invalidate exceptional entry if easily possible. This handles exceptional
+ * entries for invalidate_inode_pages() so for DAX it evicts only unlocked and
+ * clean entries.
+ */
+static int invalidate_exceptional_entry(struct address_space *mapping,
+ pgoff_t index, void *entry)
+{
+ /* Handled by shmem itself */
+ if (shmem_mapping(mapping))
+ return 1;
+ if (dax_mapping(mapping))
+ return dax_invalidate_mapping_entry(mapping, index);
+ clear_shadow_entry(mapping, index, entry);
+ return 1;
+}
+
+/*
+ * Invalidate exceptional entry if clean. This handles exceptional entries for
+ * invalidate_inode_pages2() so for DAX it evicts only clean entries.
+ */
+static int invalidate_exceptional_entry2(struct address_space *mapping,
+ pgoff_t index, void *entry)
+{
+ /* Handled by shmem itself */
+ if (shmem_mapping(mapping))
+ return 1;
+ if (dax_mapping(mapping))
+ return dax_invalidate_mapping_entry_sync(mapping, index);
+ clear_shadow_entry(mapping, index, entry);
+ return 1;
+}
+
/**
* do_invalidatepage - invalidate part or all of a page
* @page: the page which is affected
@@ -262,7 +304,8 @@ void truncate_inode_pages_range(struct address_space *mapping,
break;
if (radix_tree_exceptional_entry(page)) {
- clear_exceptional_entry(mapping, index, page);
+ truncate_exceptional_entry(mapping, index,
+ page);
continue;
}
@@ -351,7 +394,8 @@ void truncate_inode_pages_range(struct address_space *mapping,
}
if (radix_tree_exceptional_entry(page)) {
- clear_exceptional_entry(mapping, index, page);
+ truncate_exceptional_entry(mapping, index,
+ page);
continue;
}
@@ -470,7 +514,8 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
break;
if (radix_tree_exceptional_entry(page)) {
- clear_exceptional_entry(mapping, index, page);
+ invalidate_exceptional_entry(mapping, index,
+ page);
continue;
}
@@ -592,7 +637,9 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
break;
if (radix_tree_exceptional_entry(page)) {
- clear_exceptional_entry(mapping, index, page);
+ if (!invalidate_exceptional_entry2(mapping,
+ index, page))
+ ret = -EBUSY;
continue;
}
diff --git a/mm/workingset.c b/mm/workingset.c
index 241fa5d6b3b2..abb58ffa3c64 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -473,7 +473,8 @@ static enum lru_status shadow_lru_isolate(struct list_head *item,
if (WARN_ON_ONCE(node->exceptional))
goto out_invalid;
inc_node_state(page_pgdat(virt_to_page(node)), WORKINGSET_NODERECLAIM);
- __radix_tree_delete_node(&mapping->page_tree, node);
+ __radix_tree_delete_node(&mapping->page_tree, node,
+ workingset_update_node, mapping);
out_invalid:
spin_unlock(&mapping->tree_lock);
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 019557d0a11d..09cfe87f0a44 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -1059,7 +1059,9 @@ static void __exit lane_module_cleanup(void)
{
int i;
+#ifdef CONFIG_PROC_FS
remove_proc_entry("lec", atm_proc_root);
+#endif
deregister_atm_ioctl(&lane_ioctl_ops);
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 8e0c0635ee97..fb55327dcfea 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -75,6 +75,7 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
struct nlattr *nla;
struct sk_buff *skb;
unsigned long flags;
+ void *msg_header;
al = sizeof(struct net_dm_alert_msg);
al += dm_hit_limit * sizeof(struct net_dm_drop_point);
@@ -82,21 +83,41 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
skb = genlmsg_new(al, GFP_KERNEL);
- if (skb) {
- genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
- 0, NET_DM_CMD_ALERT);
- nla = nla_reserve(skb, NLA_UNSPEC,
- sizeof(struct net_dm_alert_msg));
- msg = nla_data(nla);
- memset(msg, 0, al);
- } else {
- mod_timer(&data->send_timer, jiffies + HZ / 10);
+ if (!skb)
+ goto err;
+
+ msg_header = genlmsg_put(skb, 0, 0, &net_drop_monitor_family,
+ 0, NET_DM_CMD_ALERT);
+ if (!msg_header) {
+ nlmsg_free(skb);
+ skb = NULL;
+ goto err;
+ }
+ nla = nla_reserve(skb, NLA_UNSPEC,
+ sizeof(struct net_dm_alert_msg));
+ if (!nla) {
+ nlmsg_free(skb);
+ skb = NULL;
+ goto err;
}
+ msg = nla_data(nla);
+ memset(msg, 0, al);
+ goto out;
+err:
+ mod_timer(&data->send_timer, jiffies + HZ / 10);
+out:
spin_lock_irqsave(&data->lock, flags);
swap(data->skb, skb);
spin_unlock_irqrestore(&data->lock, flags);
+ if (skb) {
+ struct nlmsghdr *nlh = (struct nlmsghdr *)skb->data;
+ struct genlmsghdr *gnlh = (struct genlmsghdr *)nlmsg_data(nlh);
+
+ genlmsg_end(skb, genlmsg_data(gnlh));
+ }
+
return skb;
}
diff --git a/net/core/filter.c b/net/core/filter.c
index e6c412b94dec..1969b3f118c1 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2972,12 +2972,6 @@ void bpf_warn_invalid_xdp_action(u32 act)
}
EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action);
-void bpf_warn_invalid_xdp_buffer(void)
-{
- WARN_ONCE(1, "Illegal XDP buffer encountered, expect throughput degradation\n");
-}
-EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_buffer);
-
static u32 sk_filter_convert_ctx_access(enum bpf_access_type type, int dst_reg,
int src_reg, int ctx_off,
struct bpf_insn *insn_buf,
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index d6447dc10371..fe4e1531976c 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -468,8 +468,9 @@ ip_proto_again:
if (hdr->flags & GRE_ACK)
offset += sizeof(((struct pptp_gre_header *)0)->ack);
- ppp_hdr = skb_header_pointer(skb, nhoff + offset,
- sizeof(_ppp_hdr), _ppp_hdr);
+ ppp_hdr = __skb_header_pointer(skb, nhoff + offset,
+ sizeof(_ppp_hdr),
+ data, hlen, _ppp_hdr);
if (!ppp_hdr)
goto out_bad;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 18b5aae99bec..75e3ea7bda08 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3898,6 +3898,9 @@ static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh)
u32 filter_mask;
int err;
+ if (nlmsg_len(nlh) < sizeof(*ifsm))
+ return -EINVAL;
+
ifsm = nlmsg_data(nlh);
if (ifsm->ifindex > 0)
dev = __dev_get_by_index(net, ifsm->ifindex);
@@ -3947,6 +3950,9 @@ static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
cb->seq = net->dev_base_seq;
+ if (nlmsg_len(cb->nlh) < sizeof(*ifsm))
+ return -EINVAL;
+
ifsm = nlmsg_data(cb->nlh);
filter_mask = ifsm->filter_mask;
if (!filter_mask)
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 3ff8938893ec..eae0332b0e8c 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -85,7 +85,7 @@ struct fib_table *fib_new_table(struct net *net, u32 id)
if (tb)
return tb;
- if (id == RT_TABLE_LOCAL)
+ if (id == RT_TABLE_LOCAL && !net->ipv4.fib_has_custom_rules)
alias = fib_new_table(net, RT_TABLE_MAIN);
tb = fib_trie_table(id, alias);
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 68d622133f53..5b15459955f8 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -219,9 +219,14 @@ static void igmp_start_timer(struct ip_mc_list *im, int max_delay)
static void igmp_gq_start_timer(struct in_device *in_dev)
{
int tv = prandom_u32() % in_dev->mr_maxdelay;
+ unsigned long exp = jiffies + tv + 2;
+
+ if (in_dev->mr_gq_running &&
+ time_after_eq(exp, (in_dev->mr_gq_timer).expires))
+ return;
in_dev->mr_gq_running = 1;
- if (!mod_timer(&in_dev->mr_gq_timer, jiffies+tv+2))
+ if (!mod_timer(&in_dev->mr_gq_timer, exp))
in_dev_hold(in_dev);
}
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 57e1405e8282..53ae0c6315ad 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -1225,8 +1225,14 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
* which has interface index (iif) as the first member of the
* underlying inet{6}_skb_parm struct. This code then overlays
* PKTINFO_SKB_CB and in_pktinfo also has iif as the first
- * element so the iif is picked up from the prior IPCB
+ * element so the iif is picked up from the prior IPCB. If iif
+ * is the loopback interface, then return the sending interface
+ * (e.g., process binds socket to eth0 for Tx which is
+ * redirected to loopback in the rtable/dst).
*/
+ if (pktinfo->ipi_ifindex == LOOPBACK_IFINDEX)
+ pktinfo->ipi_ifindex = inet_iif(skb);
+
pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb);
} else {
pktinfo->ipi_ifindex = 0;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index a82a11747b3f..0fcac8e7a2b2 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1914,7 +1914,8 @@ local_input:
}
}
- rth = rt_dst_alloc(net->loopback_dev, flags | RTCF_LOCAL, res.type,
+ rth = rt_dst_alloc(l3mdev_master_dev_rcu(dev) ? : net->loopback_dev,
+ flags | RTCF_LOCAL, res.type,
IN_DEV_CONF_GET(in_dev, NOPOLICY), false, do_cache);
if (!rth)
goto e_nobufs;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 80bc36b25de2..22cbd61079b5 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -433,13 +433,6 @@ static struct ctl_table ipv4_table[] = {
.extra2 = &tcp_adv_win_scale_max,
},
{
- .procname = "tcp_tw_reuse",
- .data = &sysctl_tcp_tw_reuse,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec
- },
- {
.procname = "tcp_frto",
.data = &sysctl_tcp_frto,
.maxlen = sizeof(int),
@@ -960,6 +953,13 @@ static struct ctl_table ipv4_net_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
+ {
+ .procname = "tcp_tw_reuse",
+ .data = &init_net.ipv4.sysctl_tcp_tw_reuse,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
#ifdef CONFIG_IP_ROUTE_MULTIPATH
{
.procname = "fib_multipath_use_neigh",
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 30d81f533ada..fe9da4fb96bf 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -84,7 +84,6 @@
#include <crypto/hash.h>
#include <linux/scatterlist.h>
-int sysctl_tcp_tw_reuse __read_mostly;
int sysctl_tcp_low_latency __read_mostly;
#ifdef CONFIG_TCP_MD5SIG
@@ -120,7 +119,7 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
and use initial timestamp retrieved from peer table.
*/
if (tcptw->tw_ts_recent_stamp &&
- (!twp || (sysctl_tcp_tw_reuse &&
+ (!twp || (sock_net(sk)->ipv4.sysctl_tcp_tw_reuse &&
get_seconds() - tcptw->tw_ts_recent_stamp > 1))) {
tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
if (tp->write_seq == 0)
@@ -2456,6 +2455,7 @@ static int __net_init tcp_sk_init(struct net *net)
net->ipv4.sysctl_tcp_orphan_retries = 0;
net->ipv4.sysctl_tcp_fin_timeout = TCP_FIN_TIMEOUT;
net->ipv4.sysctl_tcp_notsent_lowat = UINT_MAX;
+ net->ipv4.sysctl_tcp_tw_reuse = 0;
return 0;
fail:
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 70d0de404197..38122d04fadc 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1373,7 +1373,7 @@ emsgsize:
*/
cork->length += length;
- if (((length > mtu) ||
+ if ((((length + fragheaderlen) > mtu) ||
(skb && skb_is_gso(skb))) &&
(sk->sk_protocol == IPPROTO_UDP) &&
(rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len &&
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 8938b6ba57a0..3d73278b86ca 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -47,7 +47,8 @@ static inline struct l2tp_ip_sock *l2tp_ip_sk(const struct sock *sk)
return (struct l2tp_ip_sock *)sk;
}
-static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif, u32 tunnel_id)
+static struct sock *__l2tp_ip_bind_lookup(const struct net *net, __be32 laddr,
+ __be32 raddr, int dif, u32 tunnel_id)
{
struct sock *sk;
@@ -61,6 +62,7 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif
if ((l2tp->conn_id == tunnel_id) &&
net_eq(sock_net(sk), net) &&
!(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
+ (!inet->inet_daddr || !raddr || inet->inet_daddr == raddr) &&
(!sk->sk_bound_dev_if || !dif ||
sk->sk_bound_dev_if == dif))
goto found;
@@ -71,15 +73,6 @@ found:
return sk;
}
-static inline struct sock *l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif, u32 tunnel_id)
-{
- struct sock *sk = __l2tp_ip_bind_lookup(net, laddr, dif, tunnel_id);
- if (sk)
- sock_hold(sk);
-
- return sk;
-}
-
/* When processing receive frames, there are two cases to
* consider. Data frames consist of a non-zero session-id and an
* optional cookie. Control frames consist of a regular L2TP header
@@ -183,8 +176,8 @@ pass_up:
struct iphdr *iph = (struct iphdr *) skb_network_header(skb);
read_lock_bh(&l2tp_ip_lock);
- sk = __l2tp_ip_bind_lookup(net, iph->daddr, inet_iif(skb),
- tunnel_id);
+ sk = __l2tp_ip_bind_lookup(net, iph->daddr, iph->saddr,
+ inet_iif(skb), tunnel_id);
if (!sk) {
read_unlock_bh(&l2tp_ip_lock);
goto discard;
@@ -280,7 +273,7 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
inet->inet_saddr = 0; /* Use device */
write_lock_bh(&l2tp_ip_lock);
- if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr,
+ if (__l2tp_ip_bind_lookup(net, addr->l2tp_addr.s_addr, 0,
sk->sk_bound_dev_if, addr->l2tp_conn_id)) {
write_unlock_bh(&l2tp_ip_lock);
ret = -EADDRINUSE;
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index f092ac441fdd..331ccf5a7bad 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -59,12 +59,14 @@ static inline struct l2tp_ip6_sock *l2tp_ip6_sk(const struct sock *sk)
static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
struct in6_addr *laddr,
+ const struct in6_addr *raddr,
int dif, u32 tunnel_id)
{
struct sock *sk;
sk_for_each_bound(sk, &l2tp_ip6_bind_table) {
- const struct in6_addr *addr = inet6_rcv_saddr(sk);
+ const struct in6_addr *sk_laddr = inet6_rcv_saddr(sk);
+ const struct in6_addr *sk_raddr = &sk->sk_v6_daddr;
struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk);
if (l2tp == NULL)
@@ -72,7 +74,8 @@ static struct sock *__l2tp_ip6_bind_lookup(struct net *net,
if ((l2tp->conn_id == tunnel_id) &&
net_eq(sock_net(sk), net) &&
- (!addr || ipv6_addr_equal(addr, laddr)) &&
+ (!sk_laddr || ipv6_addr_any(sk_laddr) || ipv6_addr_equal(sk_laddr, laddr)) &&
+ (!raddr || ipv6_addr_any(sk_raddr) || ipv6_addr_equal(sk_raddr, raddr)) &&
(!sk->sk_bound_dev_if || !dif ||
sk->sk_bound_dev_if == dif))
goto found;
@@ -83,17 +86,6 @@ found:
return sk;
}
-static inline struct sock *l2tp_ip6_bind_lookup(struct net *net,
- struct in6_addr *laddr,
- int dif, u32 tunnel_id)
-{
- struct sock *sk = __l2tp_ip6_bind_lookup(net, laddr, dif, tunnel_id);
- if (sk)
- sock_hold(sk);
-
- return sk;
-}
-
/* When processing receive frames, there are two cases to
* consider. Data frames consist of a non-zero session-id and an
* optional cookie. Control frames consist of a regular L2TP header
@@ -197,8 +189,8 @@ pass_up:
struct ipv6hdr *iph = ipv6_hdr(skb);
read_lock_bh(&l2tp_ip6_lock);
- sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, inet6_iif(skb),
- tunnel_id);
+ sk = __l2tp_ip6_bind_lookup(net, &iph->daddr, &iph->saddr,
+ inet6_iif(skb), tunnel_id);
if (!sk) {
read_unlock_bh(&l2tp_ip6_lock);
goto discard;
@@ -330,7 +322,7 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
rcu_read_unlock();
write_lock_bh(&l2tp_ip6_lock);
- if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, bound_dev_if,
+ if (__l2tp_ip6_bind_lookup(net, &addr->l2tp_addr, NULL, bound_dev_if,
addr->l2tp_conn_id)) {
write_unlock_bh(&l2tp_ip6_lock);
err = -EADDRINUSE;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 2c21b7039136..0d8b716e509e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3287,7 +3287,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2);
int hw_headroom = sdata->local->hw.extra_tx_headroom;
struct ethhdr eth;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_tx_info *info;
struct ieee80211_hdr *hdr = (void *)fast_tx->hdr;
struct ieee80211_tx_data tx;
ieee80211_tx_result r;
@@ -3351,6 +3351,7 @@ static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata,
memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN);
memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN);
+ info = IEEE80211_SKB_CB(skb);
memset(info, 0, sizeof(*info));
info->band = fast_tx->band;
info->control.vif = &sdata->vif;
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 2d4c4d3911c0..9c62b6325f7a 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -606,7 +606,6 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
rcu_assign_pointer(flow->sf_acts, acts);
packet->priority = flow->key.phy.priority;
packet->mark = flow->key.phy.skb_mark;
- packet->protocol = flow->key.eth.type;
rcu_read_lock();
dp = get_dp_rcu(net, ovs_header->dp_ifindex);
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 08aa926cd5cf..2c0a00f7f1b7 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -312,7 +312,8 @@ static bool icmp6hdr_ok(struct sk_buff *skb)
* Returns 0 if it encounters a non-vlan or incomplete packet.
* Returns 1 after successfully parsing vlan tag.
*/
-static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh)
+static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh,
+ bool untag_vlan)
{
struct vlan_head *vh = (struct vlan_head *)skb->data;
@@ -330,7 +331,20 @@ static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh)
key_vh->tci = vh->tci | htons(VLAN_TAG_PRESENT);
key_vh->tpid = vh->tpid;
- __skb_pull(skb, sizeof(struct vlan_head));
+ if (unlikely(untag_vlan)) {
+ int offset = skb->data - skb_mac_header(skb);
+ u16 tci;
+ int err;
+
+ __skb_push(skb, offset);
+ err = __skb_vlan_pop(skb, &tci);
+ __skb_pull(skb, offset);
+ if (err)
+ return err;
+ __vlan_hwaccel_put_tag(skb, key_vh->tpid, tci);
+ } else {
+ __skb_pull(skb, sizeof(struct vlan_head));
+ }
return 1;
}
@@ -351,13 +365,13 @@ static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key)
key->eth.vlan.tpid = skb->vlan_proto;
} else {
/* Parse outer vlan tag in the non-accelerated case. */
- res = parse_vlan_tag(skb, &key->eth.vlan);
+ res = parse_vlan_tag(skb, &key->eth.vlan, true);
if (res <= 0)
return res;
}
/* Parse inner vlan tag. */
- res = parse_vlan_tag(skb, &key->eth.cvlan);
+ res = parse_vlan_tag(skb, &key->eth.cvlan, false);
if (res <= 0)
return res;
@@ -800,29 +814,15 @@ int ovs_flow_key_extract_userspace(struct net *net, const struct nlattr *attr,
if (err)
return err;
- if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) {
- /* key_extract assumes that skb->protocol is set-up for
- * layer 3 packets which is the case for other callers,
- * in particular packets recieved from the network stack.
- * Here the correct value can be set from the metadata
- * extracted above.
- */
- skb->protocol = key->eth.type;
- } else {
- struct ethhdr *eth;
-
- skb_reset_mac_header(skb);
- eth = eth_hdr(skb);
-
- /* Normally, setting the skb 'protocol' field would be
- * handled by a call to eth_type_trans(), but it assumes
- * there's a sending device, which we may not have.
- */
- if (eth_proto_is_802_3(eth->h_proto))
- skb->protocol = eth->h_proto;
- else
- skb->protocol = htons(ETH_P_802_2);
- }
+ /* key_extract assumes that skb->protocol is set-up for
+ * layer 3 packets which is the case for other callers,
+ * in particular packets received from the network stack.
+ * Here the correct value can be set from the metadata
+ * extracted above.
+ * For L2 packet key eth type would be zero. skb protocol
+ * would be set to correct value later during key-extact.
+ */
+ skb->protocol = key->eth.type;
return key_extract(skb, key);
}
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 3fbba79a4ef0..1ecdf809b5fa 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -148,13 +148,15 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
unsigned long cl;
unsigned long fh;
int err;
- int tp_created = 0;
+ int tp_created;
if ((n->nlmsg_type != RTM_GETTFILTER) &&
!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
return -EPERM;
replay:
+ tp_created = 0;
+
err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL);
if (err < 0)
return err;
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 333f8e268431..970db7a41684 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -153,10 +153,14 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
switch (ip_tunnel_info_af(info)) {
case AF_INET:
+ skb_key.enc_control.addr_type =
+ FLOW_DISSECTOR_KEY_IPV4_ADDRS;
skb_key.enc_ipv4.src = key->u.ipv4.src;
skb_key.enc_ipv4.dst = key->u.ipv4.dst;
break;
case AF_INET6:
+ skb_key.enc_control.addr_type =
+ FLOW_DISSECTOR_KEY_IPV6_ADDRS;
skb_key.enc_ipv6.src = key->u.ipv6.src;
skb_key.enc_ipv6.dst = key->u.ipv6.dst;
break;
diff --git a/net/socket.c b/net/socket.c
index 8487bf136e5c..a8c2307590b8 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -537,7 +537,7 @@ int sockfs_setattr(struct dentry *dentry, struct iattr *iattr)
{
int err = simple_setattr(dentry, iattr);
- if (!err) {
+ if (!err && (iattr->ia_valid & ATTR_UID)) {
struct socket *sock = SOCKET_I(d_inode(dentry));
sock->sk->sk_uid = iattr->ia_uid;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 333c5dae0072..800caaa699a1 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -441,15 +441,19 @@ static void __tipc_shutdown(struct socket *sock, int error)
while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
if (TIPC_SKB_CB(skb)->bytes_read) {
kfree_skb(skb);
- } else {
- if (!tipc_sk_type_connectionless(sk) &&
- sk->sk_state != TIPC_DISCONNECTING) {
- tipc_set_sk_state(sk, TIPC_DISCONNECTING);
- tipc_node_remove_conn(net, dnode, tsk->portid);
- }
- tipc_sk_respond(sk, skb, error);
+ continue;
+ }
+ if (!tipc_sk_type_connectionless(sk) &&
+ sk->sk_state != TIPC_DISCONNECTING) {
+ tipc_set_sk_state(sk, TIPC_DISCONNECTING);
+ tipc_node_remove_conn(net, dnode, tsk->portid);
}
+ tipc_sk_respond(sk, skb, error);
}
+
+ if (tipc_sk_type_connectionless(sk))
+ return;
+
if (sk->sk_state != TIPC_DISCONNECTING) {
skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
TIPC_CONN_MSG, SHORT_H_SIZE, 0, dnode,
@@ -457,10 +461,8 @@ static void __tipc_shutdown(struct socket *sock, int error)
tsk->portid, error);
if (skb)
tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
- if (!tipc_sk_type_connectionless(sk)) {
- tipc_node_remove_conn(net, dnode, tsk->portid);
- tipc_set_sk_state(sk, TIPC_DISCONNECTING);
- }
+ tipc_node_remove_conn(net, dnode, tsk->portid);
+ tipc_set_sk_state(sk, TIPC_DISCONNECTING);
}
}
diff --git a/samples/Kconfig b/samples/Kconfig
index a6d2a43bbf2e..b124f62ed6cb 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -105,4 +105,11 @@ config SAMPLE_BLACKFIN_GPTIMERS
help
Build samples of blackfin gptimers sample module.
+config SAMPLE_VFIO_MDEV_MTTY
+ tristate "Build VFIO mtty example mediated device sample code -- loadable modules only"
+ depends on VFIO_MDEV_DEVICE && m
+ help
+ Build a virtual tty sample driver for use as a VFIO
+ mediated device
+
endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
index e17d66d77f09..86a137e451d9 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -2,4 +2,5 @@
obj-$(CONFIG_SAMPLES) += kobject/ kprobes/ trace_events/ livepatch/ \
hw_breakpoint/ kfifo/ kdb/ hidraw/ rpmsg/ seccomp/ \
- configfs/ connector/ v4l/ trace_printk/ blackfin/
+ configfs/ connector/ v4l/ trace_printk/ blackfin/ \
+ vfio-mdev/
diff --git a/samples/vfio-mdev/Makefile b/samples/vfio-mdev/Makefile
index a932edbe38eb..cbbd868a50a8 100644
--- a/samples/vfio-mdev/Makefile
+++ b/samples/vfio-mdev/Makefile
@@ -1,13 +1 @@
-#
-# Makefile for mtty.c file
-#
-KERNEL_DIR:=/lib/modules/$(shell uname -r)/build
-
-obj-m:=mtty.o
-
-modules clean modules_install:
- $(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(PWD) $@
-
-default: modules
-
-module: modules
+obj-$(CONFIG_SAMPLE_VFIO_MDEV_MTTY) += mtty.o
diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 6b633a4ea333..1fc57a5093a7 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -164,7 +164,7 @@ static struct mdev_state *find_mdev_state_by_uuid(uuid_le uuid)
struct mdev_state *mds;
list_for_each_entry(mds, &mdev_devices_list, next) {
- if (uuid_le_cmp(mds->mdev->uuid, uuid) == 0)
+ if (uuid_le_cmp(mdev_uuid(mds->mdev), uuid) == 0)
return mds;
}
@@ -341,7 +341,8 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
pr_err("Serial port %d: Fifo level trigger\n",
index);
#endif
- mtty_trigger_interrupt(mdev_state->mdev->uuid);
+ mtty_trigger_interrupt(
+ mdev_uuid(mdev_state->mdev));
}
} else {
#if defined(DEBUG_INTR)
@@ -355,7 +356,8 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
*/
if (mdev_state->s[index].uart_reg[UART_IER] &
UART_IER_RLSI)
- mtty_trigger_interrupt(mdev_state->mdev->uuid);
+ mtty_trigger_interrupt(
+ mdev_uuid(mdev_state->mdev));
}
mutex_unlock(&mdev_state->rxtx_lock);
break;
@@ -374,7 +376,8 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
pr_err("Serial port %d: IER_THRI write\n",
index);
#endif
- mtty_trigger_interrupt(mdev_state->mdev->uuid);
+ mtty_trigger_interrupt(
+ mdev_uuid(mdev_state->mdev));
}
mutex_unlock(&mdev_state->rxtx_lock);
@@ -445,7 +448,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
#if defined(DEBUG_INTR)
pr_err("Serial port %d: MCR_OUT2 write\n", index);
#endif
- mtty_trigger_interrupt(mdev_state->mdev->uuid);
+ mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev));
}
if ((mdev_state->s[index].uart_reg[UART_IER] & UART_IER_MSI) &&
@@ -453,7 +456,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state,
#if defined(DEBUG_INTR)
pr_err("Serial port %d: MCR RTS/DTR write\n", index);
#endif
- mtty_trigger_interrupt(mdev_state->mdev->uuid);
+ mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev));
}
break;
@@ -504,7 +507,8 @@ static void handle_bar_read(unsigned int index, struct mdev_state *mdev_state,
#endif
if (mdev_state->s[index].uart_reg[UART_IER] &
UART_IER_THRI)
- mtty_trigger_interrupt(mdev_state->mdev->uuid);
+ mtty_trigger_interrupt(
+ mdev_uuid(mdev_state->mdev));
}
mutex_unlock(&mdev_state->rxtx_lock);
@@ -734,7 +738,7 @@ int mtty_create(struct kobject *kobj, struct mdev_device *mdev)
for (i = 0; i < 2; i++) {
snprintf(name, MTTY_STRING_LEN, "%s-%d",
- dev_driver_string(mdev->parent->dev), i + 1);
+ dev_driver_string(mdev_parent_dev(mdev)), i + 1);
if (!strcmp(kobj->name, name)) {
nr_ports = i + 1;
break;
@@ -1298,10 +1302,8 @@ static ssize_t
sample_mdev_dev_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct mdev_device *mdev = to_mdev_device(dev);
-
- if (mdev)
- return sprintf(buf, "This is MDEV %s\n", dev_name(&mdev->dev));
+ if (mdev_from_dev(dev))
+ return sprintf(buf, "This is MDEV %s\n", dev_name(dev));
return sprintf(buf, "\n");
}
@@ -1402,7 +1404,7 @@ struct attribute_group *mdev_type_groups[] = {
NULL,
};
-struct parent_ops mdev_fops = {
+struct mdev_parent_ops mdev_fops = {
.owner = THIS_MODULE,
.dev_attr_groups = mtty_dev_groups,
.mdev_attr_groups = mdev_dev_groups,
@@ -1447,6 +1449,7 @@ static int __init mtty_dev_init(void)
if (IS_ERR(mtty_dev.vd_class)) {
pr_err("Error: failed to register mtty_dev class\n");
+ ret = PTR_ERR(mtty_dev.vd_class);
goto failed1;
}
@@ -1458,7 +1461,8 @@ static int __init mtty_dev_init(void)
if (ret)
goto failed2;
- if (mdev_register_device(&mtty_dev.dev, &mdev_fops) != 0)
+ ret = mdev_register_device(&mtty_dev.dev, &mdev_fops);
+ if (ret)
goto failed3;
mutex_init(&mdev_list_lock);
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
index 950fd2e64bb7..12262c0cc691 100644
--- a/scripts/gcc-plugins/gcc-common.h
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -39,6 +39,9 @@
#include "hash-map.h"
#endif
+#if BUILDING_GCC_VERSION >= 7000
+#include "memmodel.h"
+#endif
#include "emit-rtl.h"
#include "debug.h"
#include "target.h"
@@ -91,6 +94,9 @@
#include "tree-ssa-alias.h"
#include "tree-ssa.h"
#include "stringpool.h"
+#if BUILDING_GCC_VERSION >= 7000
+#include "tree-vrp.h"
+#endif
#include "tree-ssanames.h"
#include "print-tree.h"
#include "tree-eh.h"
@@ -287,6 +293,22 @@ static inline struct cgraph_node *cgraph_next_function_with_gimple_body(struct c
return NULL;
}
+static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node, bool (*callback)(cgraph_node_ptr, void *), void *data, bool include_overwritable)
+{
+ cgraph_node_ptr alias;
+
+ if (callback(node, data))
+ return true;
+
+ for (alias = node->same_body; alias; alias = alias->next) {
+ if (include_overwritable || cgraph_function_body_availability(alias) > AVAIL_OVERWRITABLE)
+ if (cgraph_for_node_and_aliases(alias, callback, data, include_overwritable))
+ return true;
+ }
+
+ return false;
+}
+
#define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \
for ((node) = cgraph_first_function_with_gimple_body(); (node); \
(node) = cgraph_next_function_with_gimple_body(node))
@@ -399,6 +421,7 @@ typedef union gimple_statement_d gassign;
typedef union gimple_statement_d gcall;
typedef union gimple_statement_d gcond;
typedef union gimple_statement_d gdebug;
+typedef union gimple_statement_d ggoto;
typedef union gimple_statement_d gphi;
typedef union gimple_statement_d greturn;
@@ -452,6 +475,16 @@ static inline const gdebug *as_a_const_gdebug(const_gimple stmt)
return stmt;
}
+static inline ggoto *as_a_ggoto(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const ggoto *as_a_const_ggoto(const_gimple stmt)
+{
+ return stmt;
+}
+
static inline gphi *as_a_gphi(gimple stmt)
{
return stmt;
@@ -496,6 +529,14 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt)
typedef struct rtx_def rtx_insn;
+static inline const char *get_decl_section_name(const_tree decl)
+{
+ if (DECL_SECTION_NAME(decl) == NULL_TREE)
+ return NULL;
+
+ return TREE_STRING_POINTER(DECL_SECTION_NAME(decl));
+}
+
static inline void set_decl_section_name(tree node, const char *value)
{
if (value)
@@ -511,6 +552,7 @@ typedef struct gimple_statement_base gassign;
typedef struct gimple_statement_call gcall;
typedef struct gimple_statement_base gcond;
typedef struct gimple_statement_base gdebug;
+typedef struct gimple_statement_base ggoto;
typedef struct gimple_statement_phi gphi;
typedef struct gimple_statement_base greturn;
@@ -564,6 +606,16 @@ static inline const gdebug *as_a_const_gdebug(const_gimple stmt)
return stmt;
}
+static inline ggoto *as_a_ggoto(gimple stmt)
+{
+ return stmt;
+}
+
+static inline const ggoto *as_a_const_ggoto(const_gimple stmt)
+{
+ return stmt;
+}
+
static inline gphi *as_a_gphi(gimple stmt)
{
return as_a<gphi>(stmt);
@@ -611,6 +663,11 @@ inline bool is_a_helper<const gassign *>::test(const_gimple gs)
#define INSN_DELETED_P(insn) (insn)->deleted()
+static inline const char *get_decl_section_name(const_tree decl)
+{
+ return DECL_SECTION_NAME(decl);
+}
+
/* symtab/cgraph related */
#define debug_cgraph_node(node) (node)->debug()
#define cgraph_get_node(decl) cgraph_node::get(decl)
@@ -619,6 +676,7 @@ inline bool is_a_helper<const gassign *>::test(const_gimple gs)
#define cgraph_n_nodes symtab->cgraph_count
#define cgraph_max_uid symtab->cgraph_max_uid
#define varpool_get_node(decl) varpool_node::get(decl)
+#define dump_varpool_node(file, node) (node)->dump(file)
#define cgraph_create_edge(caller, callee, call_stmt, count, freq, nest) \
(caller)->create_edge((callee), (call_stmt), (count), (freq))
@@ -674,6 +732,11 @@ static inline cgraph_node_ptr cgraph_alias_target(cgraph_node_ptr node)
return node->get_alias_target();
}
+static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node, bool (*callback)(cgraph_node_ptr, void *), void *data, bool include_overwritable)
+{
+ return node->call_for_symbol_thunks_and_aliases(callback, data, include_overwritable);
+}
+
static inline struct cgraph_node_hook_list *cgraph_add_function_insertion_hook(cgraph_node_hook hook, void *data)
{
return symtab->add_cgraph_insertion_hook(hook, data);
@@ -731,6 +794,13 @@ static inline gimple gimple_build_assign_with_ops(enum tree_code subcode, tree l
template <>
template <>
+inline bool is_a_helper<const ggoto *>::test(const_gimple gs)
+{
+ return gs->code == GIMPLE_GOTO;
+}
+
+template <>
+template <>
inline bool is_a_helper<const greturn *>::test(const_gimple gs)
{
return gs->code == GIMPLE_RETURN;
@@ -766,6 +836,16 @@ static inline const gcall *as_a_const_gcall(const_gimple stmt)
return as_a<const gcall *>(stmt);
}
+static inline ggoto *as_a_ggoto(gimple stmt)
+{
+ return as_a<ggoto *>(stmt);
+}
+
+static inline const ggoto *as_a_const_ggoto(const_gimple stmt)
+{
+ return as_a<const ggoto *>(stmt);
+}
+
static inline gphi *as_a_gphi(gimple stmt)
{
return as_a<gphi *>(stmt);
@@ -828,4 +908,9 @@ static inline void debug_gimple_stmt(const_gimple s)
#define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s))
#endif
+#if BUILDING_GCC_VERSION >= 7000
+#define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \
+ get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep)
+#endif
+
#endif
diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c
index 12541126575b..8ff203ad4809 100644
--- a/scripts/gcc-plugins/latent_entropy_plugin.c
+++ b/scripts/gcc-plugins/latent_entropy_plugin.c
@@ -328,9 +328,9 @@ static enum tree_code get_op(tree *rhs)
op = LROTATE_EXPR;
/*
* This code limits the value of random_const to
- * the size of a wide int for the rotation
+ * the size of a long for the rotation
*/
- random_const &= HOST_BITS_PER_WIDE_INT - 1;
+ random_const %= TYPE_PRECISION(long_unsigned_type_node);
break;
}
diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c
index ee47924aef0d..827161bc269c 100644
--- a/sound/firewire/fireworks/fireworks_stream.c
+++ b/sound/firewire/fireworks/fireworks_stream.c
@@ -117,7 +117,7 @@ destroy_stream(struct snd_efw *efw, struct amdtp_stream *stream)
conn = &efw->in_conn;
amdtp_stream_destroy(stream);
- cmp_connection_destroy(&efw->out_conn);
+ cmp_connection_destroy(conn);
}
static int
diff --git a/sound/firewire/tascam/tascam-stream.c b/sound/firewire/tascam/tascam-stream.c
index 4ad3bd7fd445..f1657a4e0621 100644
--- a/sound/firewire/tascam/tascam-stream.c
+++ b/sound/firewire/tascam/tascam-stream.c
@@ -343,7 +343,7 @@ int snd_tscm_stream_init_duplex(struct snd_tscm *tscm)
if (err < 0)
amdtp_stream_destroy(&tscm->rx_stream);
- return 0;
+ return err;
}
/* At bus reset, streaming is stopped and some registers are clear. */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9448daff9d8b..7d660ee1d5e8 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2230,6 +2230,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
+ SND_PCI_QUIRK(0x1043, 0x8691, "ASUS ROG Ranger VIII", ALC882_FIXUP_GPIO3),
SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
@@ -6983,6 +6984,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
+ SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 15d1d5c63c3c..c90607ebe155 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -384,6 +384,9 @@ static void snd_complete_urb(struct urb *urb)
if (unlikely(atomic_read(&ep->chip->shutdown)))
goto exit_clear;
+ if (unlikely(!test_bit(EP_FLAG_RUNNING, &ep->flags)))
+ goto exit_clear;
+
if (usb_pipeout(ep->pipe)) {
retire_outbound_urb(ep, ctx);
/* can be stopped during retire callback */
@@ -534,6 +537,11 @@ static int wait_clear_urbs(struct snd_usb_endpoint *ep)
alive, ep->ep_num);
clear_bit(EP_FLAG_STOPPING, &ep->flags);
+ ep->data_subs = NULL;
+ ep->sync_slave = NULL;
+ ep->retire_data_urb = NULL;
+ ep->prepare_data_urb = NULL;
+
return 0;
}
@@ -912,9 +920,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
/**
* snd_usb_endpoint_start: start an snd_usb_endpoint
*
- * @ep: the endpoint to start
- * @can_sleep: flag indicating whether the operation is executed in
- * non-atomic context
+ * @ep: the endpoint to start
*
* A call to this function will increment the use count of the endpoint.
* In case it is not already running, the URBs for this endpoint will be
@@ -924,7 +930,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
*
* Returns an error if the URB submission failed, 0 in all other cases.
*/
-int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep)
+int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
{
int err;
unsigned int i;
@@ -938,8 +944,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep)
/* just to be sure */
deactivate_urbs(ep, false);
- if (can_sleep)
- wait_clear_urbs(ep);
ep->active_mask = 0;
ep->unlink_mask = 0;
@@ -1020,10 +1024,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep)
if (--ep->use_count == 0) {
deactivate_urbs(ep, false);
- ep->data_subs = NULL;
- ep->sync_slave = NULL;
- ep->retire_data_urb = NULL;
- ep->prepare_data_urb = NULL;
set_bit(EP_FLAG_STOPPING, &ep->flags);
}
}
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index 6428392d8f62..584f295d7c77 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -18,7 +18,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
struct audioformat *fmt,
struct snd_usb_endpoint *sync_ep);
-int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep);
+int snd_usb_endpoint_start(struct snd_usb_endpoint *ep);
void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep);
void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep);
int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 34c6d4f2c0b6..9aa5b1855481 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -218,7 +218,7 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
}
}
-static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep)
+static int start_endpoints(struct snd_usb_substream *subs)
{
int err;
@@ -231,7 +231,7 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep)
dev_dbg(&subs->dev->dev, "Starting data EP @%p\n", ep);
ep->data_subs = subs;
- err = snd_usb_endpoint_start(ep, can_sleep);
+ err = snd_usb_endpoint_start(ep);
if (err < 0) {
clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags);
return err;
@@ -260,7 +260,7 @@ static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep)
dev_dbg(&subs->dev->dev, "Starting sync EP @%p\n", ep);
ep->sync_slave = subs->data_endpoint;
- err = snd_usb_endpoint_start(ep, can_sleep);
+ err = snd_usb_endpoint_start(ep);
if (err < 0) {
clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags);
return err;
@@ -850,7 +850,7 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
/* for playback, submit the URBs now; otherwise, the first hwptr_done
* updates for all URBs would happen at the same time when starting */
if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
- ret = start_endpoints(subs, true);
+ ret = start_endpoints(subs);
unlock:
snd_usb_unlock_shutdown(subs->stream->chip);
@@ -1666,7 +1666,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- err = start_endpoints(subs, false);
+ err = start_endpoints(subs);
if (err < 0)
return err;
diff --git a/tools/iio/iio_event_monitor.c b/tools/iio/iio_event_monitor.c
index d9b7e0f306c6..b61245e1181d 100644
--- a/tools/iio/iio_event_monitor.c
+++ b/tools/iio/iio_event_monitor.c
@@ -57,6 +57,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_RESISTANCE] = "resistance",
[IIO_PH] = "ph",
[IIO_UVINDEX] = "uvindex",
+ [IIO_GRAVITY] = "gravity",
};
static const char * const iio_ev_type_text[] = {
@@ -149,6 +150,7 @@ static bool event_is_known(struct iio_event_data *event)
case IIO_RESISTANCE:
case IIO_PH:
case IIO_UVINDEX:
+ case IIO_GRAVITY:
break;
default:
return false;
diff --git a/usr/Makefile b/usr/Makefile
index 17a513268325..0b87e71c00fc 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -5,8 +5,10 @@
klibcdirs:;
PHONY += klibcdirs
-suffix_y = $(CONFIG_INITRAMFS_COMPRESSION)
-AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/initramfs_data.cpio$(suffix_y)"
+suffix_y = $(subst $\",,$(CONFIG_INITRAMFS_COMPRESSION))
+datafile_y = initramfs_data.cpio$(suffix_y)
+AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/$(datafile_y)"
+
# Generate builtin.o based on initramfs_data.o
obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o
@@ -14,7 +16,7 @@ obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o
# initramfs_data.o contains the compressed initramfs_data.cpio image.
# The image is included using .incbin, a dependency which is not
# tracked automatically.
-$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio$(suffix_y) FORCE
+$(obj)/initramfs_data.o: $(obj)/$(datafile_y) FORCE
#####
# Generate the initramfs cpio archive
@@ -38,10 +40,8 @@ endif
quiet_cmd_initfs = GEN $@
cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input)
-targets := initramfs_data.cpio.gz initramfs_data.cpio.bz2 \
- initramfs_data.cpio.lzma initramfs_data.cpio.xz \
- initramfs_data.cpio.lzo initramfs_data.cpio.lz4 \
- initramfs_data.cpio
+targets := $(datafile_y)
+
# do not try to update files included in initramfs
$(deps_initramfs): ;
@@ -51,6 +51,6 @@ $(deps_initramfs): klibcdirs
# 2) There are changes in which files are included (added or deleted)
# 3) If gen_init_cpio are newer than initramfs_data.cpio
# 4) arguments to gen_initramfs.sh changes
-$(obj)/initramfs_data.cpio$(suffix_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
+$(obj)/$(datafile_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs
$(Q)$(initramfs) -l $(ramfs-input) > $(obj)/.initramfs_data.cpio.d
$(call if_changed,initfs)