summary refs log tree commit diff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 11:30:39 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-15 11:30:39 -0800
commit46f7b635569731ff81a3b72d1bcd4415b293b637 (patch)
treee97e5e28d1768bb281116d92292851758ea20024
parent9682ec9692e5ac11c6caebd079324e727b19e7ce (diff)
parent533e80b1ea709577ec5cf73b8b566569bc711259 (diff)
downloadlinux-46f7b635569731ff81a3b72d1bcd4415b293b637.tar.gz
Merge tag 'staging-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging drivers patches from Greg KH:
 "Here's the big staging driver tree update for 3.20-rc1.

  Lots of little things in here, adding up to lots of overall cleanups.
  The IIO driver updates are also in here as they cross the staging tree
  boundry a lot.  I2O has moved into staging as well, as a plan to drop
  it from the tree eventually as that's a dead subsystem.

  All of this has been in linux-next with no reported issues for a
  while"

* tag 'staging-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (740 commits)
  staging: lustre: lustre: libcfs: define symbols as static
  staging: rtl8712: Do coding style cleanup
  staging: lustre: make obd_updatemax_lock static
  staging: rtl8188eu: core: switch with redundant cases
  staging: rtl8188eu: odm: conditional setting with no effect
  staging: rtl8188eu: odm: condition with no effect
  staging: ft1000: fix braces warning
  staging: sm7xxfb: fix remaining CamelCase
  staging: sm7xxfb: fix CamelCase
  staging: rtl8723au: multiple condition with no effect - if identical to else
  staging: sm7xxfb: make smtc_scr_info static
  staging/lustre/mdc: Initialize req in mdc_enqueue for !it case
  staging/lustre/clio: Do not allow group locks with gid 0
  staging/lustre/llite: don't add to page cache upon failure
  staging/lustre/llite: Add exception entry check after radix_tree
  staging/lustre/libcfs: protect kkuc_groups from write access
  staging/lustre/fld: refer to MDT0 for fld lookup in some cases
  staging/lustre/llite: Solve a race to access lli_has_smd in read case
  staging/lustre/ptlrpc: hold rq_lock when modify rq_flags
  staging/lustre/lnet: portal spreading rotor should be unsigned
  ...
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio200
-rw-r--r--Documentation/devicetree/bindings/i2c/trivial-devices.txt1
-rw-r--r--Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt22
-rw-r--r--Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt129
-rw-r--r--Documentation/devicetree/bindings/iio/sensorhub.txt25
-rw-r--r--Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt4
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--Documentation/driver-model/devres.txt2
-rw-r--r--MAINTAINERS20
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/iio/Kconfig1
-rw-r--r--drivers/iio/accel/Kconfig31
-rw-r--r--drivers/iio/accel/Makefile6
-rw-r--r--drivers/iio/accel/hid-sensor-accel-3d.c8
-rw-r--r--drivers/iio/accel/kxcjk-1013.c52
-rw-r--r--drivers/iio/accel/mma8452.c2
-rw-r--r--drivers/iio/accel/mma9551.c637
-rw-r--r--drivers/iio/accel/mma9551_core.c798
-rw-r--r--drivers/iio/accel/mma9551_core.h81
-rw-r--r--drivers/iio/accel/mma9553.c1334
-rw-r--r--drivers/iio/accel/ssp_accel_sensor.c169
-rw-r--r--drivers/iio/adc/Kconfig25
-rw-r--r--drivers/iio/adc/Makefile2
-rw-r--r--drivers/iio/adc/cc10001_adc.c423
-rw-r--r--drivers/iio/adc/qcom-spmi-vadc.c1016
-rw-r--r--drivers/iio/adc/ti_am335x_adc.c11
-rw-r--r--drivers/iio/amplifiers/ad8366.c4
-rw-r--r--drivers/iio/common/Kconfig1
-rw-r--r--drivers/iio/common/Makefile1
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.c75
-rw-r--r--drivers/iio/common/hid-sensors/hid-sensor-trigger.h5
-rw-r--r--drivers/iio/common/ssp_sensors/Kconfig26
-rw-r--r--drivers/iio/common/ssp_sensors/Makefile8
-rw-r--r--drivers/iio/common/ssp_sensors/ssp.h257
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_dev.c712
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_iio.c107
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_iio_sensor.h71
-rw-r--r--drivers/iio/common/ssp_sensors/ssp_spi.c608
-rw-r--r--drivers/iio/common/st_sensors/st_sensors_spi.c2
-rw-r--r--drivers/iio/frequency/ad9523.c2
-rw-r--r--drivers/iio/frequency/adf4350.c7
-rw-r--r--drivers/iio/gyro/Makefile2
-rw-r--r--drivers/iio/gyro/hid-sensor-gyro-3d.c8
-rw-r--r--drivers/iio/gyro/ssp_gyro_sensor.c168
-rw-r--r--drivers/iio/iio_core.h9
-rw-r--r--drivers/iio/imu/Kconfig11
-rw-r--r--drivers/iio/imu/Makefile2
-rw-r--r--drivers/iio/imu/inv_mpu6050/Kconfig1
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_core.c124
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h6
-rw-r--r--drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c39
-rw-r--r--drivers/iio/imu/kmx61.c1595
-rw-r--r--drivers/iio/industrialio-buffer.c410
-rw-r--r--drivers/iio/industrialio-core.c57
-rw-r--r--drivers/iio/industrialio-event.c15
-rw-r--r--drivers/iio/industrialio-triggered-buffer.c13
-rw-r--r--drivers/iio/inkern.c30
-rw-r--r--drivers/iio/kfifo_buf.c87
-rw-r--r--drivers/iio/light/Kconfig24
-rw-r--r--drivers/iio/light/Makefile2
-rw-r--r--drivers/iio/light/cm32181.c2
-rw-r--r--drivers/iio/light/cm3232.c403
-rw-r--r--drivers/iio/light/hid-sensor-als.c9
-rw-r--r--drivers/iio/light/hid-sensor-prox.c10
-rw-r--r--drivers/iio/light/jsa1212.c471
-rw-r--r--drivers/iio/light/lm3533-als.c2
-rw-r--r--drivers/iio/light/tcs3414.c4
-rw-r--r--drivers/iio/magnetometer/Kconfig15
-rw-r--r--drivers/iio/magnetometer/Makefile1
-rw-r--r--drivers/iio/magnetometer/ak09911.c326
-rw-r--r--drivers/iio/magnetometer/ak8975.c505
-rw-r--r--drivers/iio/magnetometer/hid-sensor-magn-3d.c9
-rw-r--r--drivers/iio/orientation/hid-sensor-incl-3d.c9
-rw-r--r--drivers/iio/pressure/bmp280.c150
-rw-r--r--drivers/iio/pressure/hid-sensor-press.c9
-rw-r--r--drivers/iio/proximity/Kconfig17
-rw-r--r--drivers/iio/proximity/Makefile1
-rw-r--r--drivers/iio/proximity/as3935.c18
-rw-r--r--drivers/iio/proximity/sx9500.c752
-rw-r--r--drivers/iio/trigger/iio-trig-sysfs.c2
-rw-r--r--drivers/message/Makefile1
-rw-r--r--drivers/staging/Kconfig8
-rw-r--r--drivers/staging/Makefile4
-rw-r--r--drivers/staging/android/Kconfig26
-rw-r--r--drivers/staging/android/Makefile2
-rw-r--r--drivers/staging/android/alarm-dev.c446
-rw-r--r--drivers/staging/android/android_alarm.h41
-rw-r--r--drivers/staging/android/ashmem.c12
-rw-r--r--drivers/staging/android/ion/ion.c3
-rw-r--r--drivers/staging/android/ion/ion_cma_heap.c20
-rw-r--r--drivers/staging/android/ion/ion_heap.c2
-rw-r--r--drivers/staging/android/logger.c808
-rw-r--r--drivers/staging/android/logger.h89
-rw-r--r--drivers/staging/android/sync_debug.c3
-rw-r--r--drivers/staging/android/uapi/android_alarm.h62
-rw-r--r--drivers/staging/board/board.c3
-rw-r--r--drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c5
-rw-r--r--drivers/staging/comedi/Kconfig21
-rw-r--r--drivers/staging/comedi/comedi_compat32.c99
-rw-r--r--drivers/staging/comedi/comedi_compat32.h38
-rw-r--r--drivers/staging/comedi/comedi_fops.c467
-rw-r--r--drivers/staging/comedi/comedi_pcmcia.c5
-rw-r--r--drivers/staging/comedi/comedi_pcmcia.h55
-rw-r--r--drivers/staging/comedi/comedi_usb.c3
-rw-r--r--drivers/staging/comedi/comedi_usb.h50
-rw-r--r--drivers/staging/comedi/comedidev.h103
-rw-r--r--drivers/staging/comedi/drivers.c2
-rw-r--r--drivers/staging/comedi/drivers/8253.h92
-rw-r--r--drivers/staging/comedi/drivers/8255.c174
-rw-r--r--drivers/staging/comedi/drivers/8255.h32
-rw-r--r--drivers/staging/comedi/drivers/8255_pci.c65
-rw-r--r--drivers/staging/comedi/drivers/Makefile1
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c2365
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1032.c78
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c844
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c3
-rw-r--r--drivers/staging/comedi/drivers/adl_pci6208.c3
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7x3x.c62
-rw-r--r--drivers/staging/comedi/drivers/adl_pci8164.c2
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c2
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c4
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c665
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c2
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1724.c2
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c240
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c2
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c5
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c2
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c124
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c10
-rw-r--r--drivers/staging/comedi/drivers/comedi_bond.c1
-rw-r--r--drivers/staging/comedi/drivers/comedi_isadma.c262
-rw-r--r--drivers/staging/comedi/drivers/comedi_isadma.h116
-rw-r--r--drivers/staging/comedi/drivers/comedi_parport.c2
-rw-r--r--drivers/staging/comedi/drivers/dac02.c2
-rw-r--r--drivers/staging/comedi/drivers/das08.c17
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c5
-rw-r--r--drivers/staging/comedi/drivers/das08_isa.c18
-rw-r--r--drivers/staging/comedi/drivers/das08_pci.c2
-rw-r--r--drivers/staging/comedi/drivers/das16.c469
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c2
-rw-r--r--drivers/staging/comedi/drivers/das1800.c340
-rw-r--r--drivers/staging/comedi/drivers/das6402.c4
-rw-r--r--drivers/staging/comedi/drivers/das800.c2
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c4
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c231
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c2
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c3
-rw-r--r--drivers/staging/comedi/drivers/dyna_pci10xx.c35
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c4
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c2
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.h5
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c2
-rw-r--r--drivers/staging/comedi/drivers/me4000.c4
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c5
-rw-r--r--drivers/staging/comedi/drivers/mf6x4.c2
-rw-r--r--drivers/staging/comedi/drivers/mite.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c3
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c30
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c192
-rw-r--r--drivers/staging/comedi/drivers/ni_at_ao.c3
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c5
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c6
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c16
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h8
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_common.c55
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c15
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_isadma.c149
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_isadma.h23
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_pci.c7
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c7
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c9
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c4
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.c43
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c43
-rw-r--r--drivers/staging/comedi/drivers/ni_usb6501.c3
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c6
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c12
-rw-r--r--drivers/staging/comedi/drivers/pcl726.c7
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c19
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c258
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c240
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c422
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c3
-rw-r--r--drivers/staging/comedi/drivers/pcmda12.c2
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c2
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c3
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c12
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c16
-rw-r--r--drivers/staging/comedi/drivers/rti800.c3
-rw-r--r--drivers/staging/comedi/drivers/rti802.c2
-rw-r--r--drivers/staging/comedi/drivers/s626.c2
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c6
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c5
-rw-r--r--drivers/staging/comedi/drivers/usbduxsigma.c9
-rw-r--r--drivers/staging/comedi/drivers/vmk80xx.c80
-rw-r--r--drivers/staging/comedi/drivers/z8536.h202
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c2
-rw-r--r--drivers/staging/comedi/range.c56
-rw-r--r--drivers/staging/cptm1217/Kconfig12
-rw-r--r--drivers/staging/cptm1217/Makefile2
-rw-r--r--drivers/staging/cptm1217/TODO5
-rw-r--r--drivers/staging/cptm1217/clearpad_tm1217.c665
-rw-r--r--drivers/staging/cptm1217/cp_tm1217.h8
-rw-r--r--drivers/staging/dgap/dgap.c38
-rw-r--r--drivers/staging/dgnc/dgnc_driver.c40
-rw-r--r--drivers/staging/dgnc/dgnc_utils.c2
-rw-r--r--drivers/staging/dgnc/digi.h60
-rw-r--r--drivers/staging/dgnc/dpacompat.h12
-rw-r--r--drivers/staging/emxx_udc/emxx_udc.c52
-rw-r--r--drivers/staging/fbtft/Kconfig169
-rw-r--r--drivers/staging/fbtft/Makefile34
-rw-r--r--drivers/staging/fbtft/README32
-rw-r--r--drivers/staging/fbtft/fb_agm1264k-fl.c462
-rw-r--r--drivers/staging/fbtft/fb_bd663474.c193
-rw-r--r--drivers/staging/fbtft/fb_hx8340bn.c229
-rw-r--r--drivers/staging/fbtft/fb_hx8347d.c181
-rw-r--r--drivers/staging/fbtft/fb_hx8353d.c166
-rw-r--r--drivers/staging/fbtft/fb_ili9320.c234
-rw-r--r--drivers/staging/fbtft/fb_ili9325.c291
-rw-r--r--drivers/staging/fbtft/fb_ili9340.c163
-rw-r--r--drivers/staging/fbtft/fb_ili9341.c179
-rw-r--r--drivers/staging/fbtft/fb_ili9481.c117
-rw-r--r--drivers/staging/fbtft/fb_ili9486.c121
-rw-r--r--drivers/staging/fbtft/fb_pcd8544.c177
-rw-r--r--drivers/staging/fbtft/fb_ra8875.c331
-rw-r--r--drivers/staging/fbtft/fb_s6d02a1.c168
-rw-r--r--drivers/staging/fbtft/fb_s6d1121.c208
-rw-r--r--drivers/staging/fbtft/fb_ssd1289.c206
-rw-r--r--drivers/staging/fbtft/fb_ssd1306.c229
-rw-r--r--drivers/staging/fbtft/fb_ssd1331.c205
-rw-r--r--drivers/staging/fbtft/fb_ssd1351.c258
-rw-r--r--drivers/staging/fbtft/fb_st7735r.c195
-rw-r--r--drivers/staging/fbtft/fb_tinylcd.c124
-rw-r--r--drivers/staging/fbtft/fb_tls8204.c176
-rw-r--r--drivers/staging/fbtft/fb_uc1701.c210
-rw-r--r--drivers/staging/fbtft/fb_upd161704.c206
-rw-r--r--drivers/staging/fbtft/fb_watterott.c324
-rw-r--r--drivers/staging/fbtft/fbtft-bus.c256
-rw-r--r--drivers/staging/fbtft/fbtft-core.c1521
-rw-r--r--drivers/staging/fbtft/fbtft-io.c239
-rw-r--r--drivers/staging/fbtft/fbtft-sysfs.c222
-rw-r--r--drivers/staging/fbtft/fbtft.h447
-rw-r--r--drivers/staging/fbtft/fbtft_device.c1444
-rw-r--r--drivers/staging/fbtft/flexfb.c592
-rw-r--r--drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c111
-rw-r--r--drivers/staging/ft1000/ft1000-usb/ft1000_hw.c8
-rw-r--r--drivers/staging/gdm724x/gdm_lte.c3
-rw-r--r--drivers/staging/gdm724x/gdm_mux.c2
-rw-r--r--drivers/staging/gs_fpgaboot/io.c9
-rw-r--r--drivers/staging/i2o/Kconfig (renamed from drivers/message/i2o/Kconfig)1
-rw-r--r--drivers/staging/i2o/Makefile (renamed from drivers/message/i2o/Makefile)0
-rw-r--r--drivers/staging/i2o/README (renamed from drivers/message/i2o/README)0
-rw-r--r--drivers/staging/i2o/README.ioctl (renamed from drivers/message/i2o/README.ioctl)0
-rw-r--r--drivers/staging/i2o/bus-osm.c (renamed from drivers/message/i2o/bus-osm.c)2
-rw-r--r--drivers/staging/i2o/config-osm.c (renamed from drivers/message/i2o/config-osm.c)2
-rw-r--r--drivers/staging/i2o/core.h (renamed from drivers/message/i2o/core.h)0
-rw-r--r--drivers/staging/i2o/debug.c (renamed from drivers/message/i2o/debug.c)2
-rw-r--r--drivers/staging/i2o/device.c (renamed from drivers/message/i2o/device.c)2
-rw-r--r--drivers/staging/i2o/driver.c (renamed from drivers/message/i2o/driver.c)2
-rw-r--r--drivers/staging/i2o/exec-osm.c (renamed from drivers/message/i2o/exec-osm.c)2
-rw-r--r--drivers/staging/i2o/i2o.h (renamed from include/linux/i2o.h)0
-rw-r--r--drivers/staging/i2o/i2o_block.c (renamed from drivers/message/i2o/i2o_block.c)2
-rw-r--r--drivers/staging/i2o/i2o_block.h (renamed from drivers/message/i2o/i2o_block.h)0
-rw-r--r--drivers/staging/i2o/i2o_config.c (renamed from drivers/message/i2o/i2o_config.c)0
-rw-r--r--drivers/staging/i2o/i2o_proc.c (renamed from drivers/message/i2o/i2o_proc.c)2
-rw-r--r--drivers/staging/i2o/i2o_scsi.c (renamed from drivers/message/i2o/i2o_scsi.c)2
-rw-r--r--drivers/staging/i2o/iop.c (renamed from drivers/message/i2o/iop.c)2
-rw-r--r--drivers/staging/i2o/memory.c (renamed from drivers/message/i2o/memory.c)2
-rw-r--r--drivers/staging/i2o/pci.c (renamed from drivers/message/i2o/pci.c)2
-rw-r--r--drivers/staging/iio/Documentation/iio_event_monitor.c23
-rw-r--r--drivers/staging/iio/Documentation/ring.txt8
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_core.c13
-rw-r--r--drivers/staging/iio/accel/lis3l02dq_ring.c2
-rw-r--r--drivers/staging/iio/accel/sca3000_core.c45
-rw-r--r--drivers/staging/iio/accel/sca3000_ring.c29
-rw-r--r--drivers/staging/iio/adc/ad7192.c2
-rw-r--r--drivers/staging/iio/adc/mxs-lradc.c45
-rw-r--r--drivers/staging/iio/iio_dummy_evgen.c17
-rw-r--r--drivers/staging/iio/iio_dummy_evgen.h6
-rw-r--r--drivers/staging/iio/iio_simple_dummy.c210
-rw-r--r--drivers/staging/iio/iio_simple_dummy.h13
-rw-r--r--drivers/staging/iio/iio_simple_dummy_buffer.c12
-rw-r--r--drivers/staging/iio/iio_simple_dummy_events.c66
-rw-r--r--drivers/staging/iio/impedance-analyzer/ad5933.c53
-rw-r--r--drivers/staging/iio/light/tsl2583.c2
-rw-r--r--drivers/staging/iio/light/tsl2x7x_core.c2
-rw-r--r--drivers/staging/iio/meter/ade7758.h1
-rw-r--r--drivers/staging/iio/meter/ade7758_core.c15
-rw-r--r--drivers/staging/iio/meter/ade7758_ring.c7
-rw-r--r--drivers/staging/iio/meter/ade7759.c2
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs.h3
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h28
-rw-r--r--drivers/staging/lustre/include/linux/libcfs/libcfs_private.h8
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-lnet.h36
-rw-r--r--drivers/staging/lustre/include/linux/lnet/lib-types.h8
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c14
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h2
-rw-r--r--drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c13
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c2
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h14
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c28
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c36
-rw-r--r--drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c4
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-move.c49
-rw-r--r--drivers/staging/lustre/lnet/lnet/lib-ptl.c8
-rw-r--r--drivers/staging/lustre/lnet/lnet/lo.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/module.c2
-rw-r--r--drivers/staging/lustre/lnet/lnet/router.c40
-rw-r--r--drivers/staging/lustre/lnet/lnet/router_proc.c2
-rw-r--r--drivers/staging/lustre/lnet/selftest/conctl.c2
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.c2
-rw-r--r--drivers/staging/lustre/lnet/selftest/conrpc.h2
-rw-r--r--drivers/staging/lustre/lnet/selftest/console.c30
-rw-r--r--drivers/staging/lustre/lnet/selftest/framework.c4
-rw-r--r--drivers/staging/lustre/lnet/selftest/module.c50
-rw-r--r--drivers/staging/lustre/lnet/selftest/rpc.c8
-rw-r--r--drivers/staging/lustre/lnet/selftest/selftest.h12
-rw-r--r--drivers/staging/lustre/lnet/selftest/timer.c2
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_internal.h2
-rw-r--r--drivers/staging/lustre/lustre/fid/fid_request.c4
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_cache.c6
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_internal.h2
-rw-r--r--drivers/staging/lustre/lustre/fld/fld_request.c11
-rw-r--r--drivers/staging/lustre/lustre/fld/lproc_fld.c16
-rw-r--r--drivers/staging/lustre/lustre/include/lclient.h3
-rw-r--r--drivers/staging/lustre/lustre/include/lprocfs_status.h44
-rw-r--r--drivers/staging/lustre/lustre/include/lustre/lustre_idl.h5
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fid.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_fld.h4
-rw-r--r--drivers/staging/lustre/lustre/include/lustre_update.h189
-rw-r--r--drivers/staging/lustre/lustre/lclient/lcommon_cl.c6
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_internal.h5
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_pool.c36
-rw-r--r--drivers/staging/lustre/lustre/ldlm/ldlm_resource.c7
-rw-r--r--drivers/staging/lustre/lustre/libcfs/debug.c12
-rw-r--r--drivers/staging/lustre/lustre/libcfs/hash.c18
-rw-r--r--drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c4
-rw-r--r--drivers/staging/lustre/lustre/libcfs/libcfs_string.c16
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c7
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c24
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c2
-rw-r--r--drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c4
-rw-r--r--drivers/staging/lustre/lustre/libcfs/module.c8
-rw-r--r--drivers/staging/lustre/lustre/libcfs/nidstrings.c233
-rw-r--r--drivers/staging/lustre/lustre/libcfs/tracefile.c3
-rw-r--r--drivers/staging/lustre/lustre/llite/dir.c11
-rw-r--r--drivers/staging/lustre/lustre/llite/file.c8
-rw-r--r--drivers/staging/lustre/lustre/llite/lproc_llite.c8
-rw-r--r--drivers/staging/lustre/lustre/llite/super25.c141
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_io.c15
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_lock.c1
-rw-r--r--drivers/staging/lustre/lustre/lmv/lmv_obd.c87
-rw-r--r--drivers/staging/lustre/lustre/lmv/lproc_lmv.c4
-rw-r--r--drivers/staging/lustre/lustre/lov/lproc_lov.c20
-rw-r--r--drivers/staging/lustre/lustre/mdc/lproc_mdc.c9
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_lib.c7
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_locks.c1
-rw-r--r--drivers/staging/lustre/lustre/mdc/mdc_request.c62
-rw-r--r--drivers/staging/lustre/lustre/obdclass/cl_object.c5
-rw-r--r--drivers/staging/lustre/lustre/obdclass/class_obd.c2
-rw-r--r--drivers/staging/lustre/lustre/obdclass/genops.c10
-rw-r--r--drivers/staging/lustre/lustre/obdclass/linux/linux-module.c31
-rw-r--r--drivers/staging/lustre/lustre/obdclass/llog_swab.c5
-rw-r--r--drivers/staging/lustre/lustre/obdclass/lprocfs_status.c26
-rw-r--r--drivers/staging/lustre/lustre/obdclass/obd_mount.c5
-rw-r--r--drivers/staging/lustre/lustre/osc/lproc_osc.c77
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_cache.c12
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_internal.h5
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_lock.c12
-rw-r--r--drivers/staging/lustre/lustre/osc/osc_request.c2
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/client.c14
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/layout.c1
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c41
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c23
-rw-r--r--drivers/staging/lustre/lustre/ptlrpc/sec_gc.c2
-rw-r--r--drivers/staging/media/davinci_vpfe/dm365_ipipe.c4
-rw-r--r--drivers/staging/mt29f_spinand/Kconfig2
-rw-r--r--drivers/staging/mt29f_spinand/mt29f_spinand.c17
-rw-r--r--drivers/staging/netlogic/xlr_net.c2
-rw-r--r--drivers/staging/nvec/nvec.c2
-rw-r--r--drivers/staging/octeon-usb/octeon-hcd.c2
-rw-r--r--drivers/staging/octeon/ethernet-rx.c2
-rw-r--r--drivers/staging/octeon/ethernet.c2
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon.c2
-rw-r--r--drivers/staging/olpc_dcon/olpc_dcon_xo_1.c2
-rw-r--r--drivers/staging/panel/panel.c104
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_ap.c2
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_mlme_ext.c67
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_wlan_util.c7
-rw-r--r--drivers/staging/rtl8188eu/hal/odm.c22
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c36
-rw-r--r--drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c14
-rw-r--r--drivers/staging/rtl8188eu/include/osdep_service.h2
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_cmd.h1
-rw-r--r--drivers/staging/rtl8188eu/include/rtl8188e_hal.h1
-rw-r--r--drivers/staging/rtl8188eu/include/rtw_mlme_ext.h4
-rw-r--r--drivers/staging/rtl8188eu/include/usb_ops_linux.h1
-rw-r--r--drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c27
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_cam.c29
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_cam.h2
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_dm.c4
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_pm.c14
-rw-r--r--drivers/staging/rtl8192e/rtl8192e/rtl_pm.h2
-rw-r--r--drivers/staging/rtl8192e/rtl819x_HTProc.c4
-rw-r--r--drivers/staging/rtl8192e/rtllib_module.c4
-rw-r--r--drivers/staging/rtl8192e/rtllib_rx.c127
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c28
-rw-r--r--drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c2
-rw-r--r--drivers/staging/rtl8192u/r8190_rtl8256.c2
-rw-r--r--drivers/staging/rtl8192u/r8192U_dm.c2309
-rw-r--r--drivers/staging/rtl8712/drv_types.h6
-rw-r--r--drivers/staging/rtl8712/osdep_service.h9
-rw-r--r--drivers/staging/rtl8712/recv_linux.c14
-rw-r--r--drivers/staging/rtl8712/recv_osdep.h1
-rw-r--r--drivers/staging/rtl8712/rtl8712_cmd.h12
-rw-r--r--drivers/staging/rtl8712/rtl8712_event.h2
-rw-r--r--drivers/staging/rtl8712/rtl871x_ioctl_linux.c4
-rw-r--r--drivers/staging/rtl8712/rtl871x_mlme.c4
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_ioctl.c525
-rw-r--r--drivers/staging/rtl8712/rtl871x_mp_ioctl.h46
-rw-r--r--drivers/staging/rtl8712/rtl871x_pwrctrl.h22
-rw-r--r--drivers/staging/rtl8712/rtl871x_sta_mgt.c5
-rw-r--r--drivers/staging/rtl8712/rtl871x_xmit.c2
-rw-r--r--drivers/staging/rtl8712/sta_info.h2
-rw-r--r--drivers/staging/rtl8712/usb_intf.c5
-rw-r--r--drivers/staging/rtl8723au/core/rtw_ap.c10
-rw-r--r--drivers/staging/rtl8723au/core/rtw_cmd.c61
-rw-r--r--drivers/staging/rtl8723au/core/rtw_efuse.c32
-rw-r--r--drivers/staging/rtl8723au/core/rtw_xmit.c9
-rw-r--r--drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c8
-rw-r--r--drivers/staging/rtl8723au/hal/odm.c87
-rw-r--r--drivers/staging/rtl8723au/hal/odm_HWConfig.c8
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c62
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c35
-rw-r--r--drivers/staging/rtl8723au/hal/rtl8723au_xmit.c4
-rw-r--r--drivers/staging/rtl8723au/hal/usb_halinit.c14
-rw-r--r--drivers/staging/rtl8723au/include/Hal8723APhyCfg.h55
-rw-r--r--drivers/staging/rtl8723au/include/Hal8723PwrSeq.h46
-rw-r--r--drivers/staging/rtl8723au/include/osdep_intf.h3
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h177
-rw-r--r--drivers/staging/rtl8723au/include/rtl8723a_recv.h4
-rw-r--r--drivers/staging/rtl8723au/include/rtw_cmd.h10
-rw-r--r--drivers/staging/rtl8723au/include/rtw_mlme_ext.h2
-rw-r--r--drivers/staging/rtl8723au/include/wifi.h14
-rw-r--r--drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c3
-rw-r--r--drivers/staging/rtl8723au/os_dep/os_intfs.c2
-rw-r--r--drivers/staging/rtl8723au/os_dep/usb_intf.c170
-rw-r--r--drivers/staging/rts5208/ms.c12
-rw-r--r--drivers/staging/rts5208/rtsx_transport.c12
-rw-r--r--drivers/staging/skein/skein_block.c17
-rw-r--r--drivers/staging/skein/skein_generic.c1
-rw-r--r--drivers/staging/sm7xxfb/Kconfig13
-rw-r--r--drivers/staging/sm7xxfb/Makefile1
-rw-r--r--drivers/staging/sm7xxfb/TODO12
-rw-r--r--drivers/staging/sm7xxfb/sm7xx.h779
-rw-r--r--drivers/staging/sm7xxfb/sm7xxfb.c1024
-rw-r--r--drivers/staging/speakup/i18n.h2
-rw-r--r--drivers/staging/speakup/kobjects.c2
-rw-r--r--drivers/staging/speakup/selection.c2
-rw-r--r--drivers/staging/speakup/synth.c6
-rw-r--r--drivers/staging/unisys/Kconfig1
-rw-r--r--drivers/staging/unisys/Makefile1
-rw-r--r--drivers/staging/unisys/channels/Kconfig10
-rw-r--r--drivers/staging/unisys/channels/Makefile11
-rw-r--r--drivers/staging/unisys/channels/channel.c219
-rw-r--r--drivers/staging/unisys/channels/chanstub.c75
-rw-r--r--drivers/staging/unisys/channels/chanstub.h23
-rw-r--r--drivers/staging/unisys/common-spar/include/version.h1
-rw-r--r--drivers/staging/unisys/include/timskmod.h4
-rw-r--r--drivers/staging/unisys/uislib/Kconfig2
-rw-r--r--drivers/staging/unisys/uislib/uislib.c755
-rw-r--r--drivers/staging/unisys/uislib/uisqueue.c215
-rw-r--r--drivers/staging/unisys/uislib/uisthread.c1
-rw-r--r--drivers/staging/unisys/uislib/uisutils.c99
-rw-r--r--drivers/staging/unisys/virthba/Kconfig2
-rw-r--r--drivers/staging/unisys/virthba/virthba.c353
-rw-r--r--drivers/staging/unisys/virtpci/virtpci.c61
-rw-r--r--drivers/staging/unisys/visorchannel/visorchannel.h69
-rw-r--r--drivers/staging/unisys/visorchannel/visorchannel_funcs.c206
-rw-r--r--drivers/staging/unisys/visorchipset/file.c122
-rw-r--r--drivers/staging/unisys/visorchipset/file.h3
-rw-r--r--drivers/staging/unisys/visorchipset/globals.h2
-rw-r--r--drivers/staging/unisys/visorchipset/testing.h43
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset.h55
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset_main.c5
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset_umode.h2
-rw-r--r--drivers/staging/unisys/visorutil/charqueue.c2
-rw-r--r--drivers/staging/unisys/visorutil/procobjecttree.c21
-rw-r--r--drivers/staging/vt6655/baseband.c343
-rw-r--r--drivers/staging/vt6655/baseband.h17
-rw-r--r--drivers/staging/vt6655/card.c9
-rw-r--r--drivers/staging/vt6655/channel.c18
-rw-r--r--drivers/staging/vt6655/channel.h2
-rw-r--r--drivers/staging/vt6655/device.h25
-rw-r--r--drivers/staging/vt6655/device_main.c172
-rw-r--r--drivers/staging/vt6655/dpc.c15
-rw-r--r--drivers/staging/vt6655/mac.c25
-rw-r--r--drivers/staging/vt6655/mac.h684
-rw-r--r--drivers/staging/vt6655/power.c26
-rw-r--r--drivers/staging/vt6655/rf.c27
-rw-r--r--drivers/staging/vt6655/rf.h8
-rw-r--r--drivers/staging/vt6655/rxtx.c3
-rw-r--r--drivers/staging/vt6655/upc.h8
-rw-r--r--drivers/staging/vt6656/card.c2
-rw-r--r--drivers/staging/vt6656/device.h6
-rw-r--r--drivers/staging/vt6656/dpc.h2
-rw-r--r--drivers/staging/vt6656/main_usb.c3
-rw-r--r--drivers/staging/vt6656/rxtx.c109
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h6
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c17
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c2
-rw-r--r--drivers/staging/wlan-ng/p80211req.c2
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.h2
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c4
-rw-r--r--drivers/staging/xgifb/XGI_main_26.c10
-rw-r--r--include/dt-bindings/iio/qcom,spmi-vadc.h119
-rw-r--r--include/linux/iio/buffer.h76
-rw-r--r--include/linux/iio/common/ssp_sensors.h82
-rw-r--r--include/linux/iio/consumer.h12
-rw-r--r--include/linux/iio/iio.h11
-rw-r--r--include/linux/iio/kfifo_buf.h5
-rw-r--r--include/linux/iio/types.h14
525 files changed, 31906 insertions, 15103 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 117521dbf2b3..9a70c31619ea 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -92,6 +92,18 @@ Description:
 		is required is a consistent labeling.  Units after application
 		of scale and offset are millivolts.
 
+What:		/sys/bus/iio/devices/iio:deviceX/in_currentY_raw
+What:		/sys/bus/iio/devices/iio:deviceX/in_currentY_supply_raw
+KernelVersion:	3.17
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Raw (unscaled no bias removal etc.) current measurement from
+		channel Y. In special cases where the channel does not
+		correspond to externally available input one of the named
+		versions may be used. The number must always be specified and
+		unique to allow association with event codes. Units after
+		application of scale and offset are milliamps.
+
 What:		/sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw
 KernelVersion:	3.2
 Contact:	linux-iio@vger.kernel.org
@@ -234,6 +246,8 @@ What:		/sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_z_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_voltageY_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_voltage_offset
+What:		/sys/bus/iio/devices/iio:deviceX/in_currentY_offset
+What:		/sys/bus/iio/devices/iio:deviceX/in_current_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_tempY_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_temp_offset
 What:		/sys/bus/iio/devices/iio:deviceX/in_pressureY_offset
@@ -262,9 +276,14 @@ What:		/sys/bus/iio/devices/iio:deviceX/in_voltage_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_scale
 What:		/sys/bus/iio/devices/iio:deviceX/out_voltageY_scale
 What:		/sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale
+What:		/sys/bus/iio/devices/iio:deviceX/in_currentY_scale
+What:		/sys/bus/iio/devices/iio:deviceX/in_currentY_supply_scale
+What:		/sys/bus/iio/devices/iio:deviceX/in_current_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_anglvel_scale
+What:		/sys/bus/iio/devices/iio:deviceX/in_energy_scale
+What:		/sys/bus/iio/devices/iio:deviceX/in_distance_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_magn_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_magn_x_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
@@ -276,6 +295,7 @@ What:		/sys/bus/iio/devices/iio:deviceX/in_rot_from_north_true_tilt_comp_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_pressure_scale
 What:		/sys/bus/iio/devices/iio:deviceX/in_humidityrelative_scale
+What:		/sys/bus/iio/devices/iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_scale
 KernelVersion:	2.6.35
 Contact:	linux-iio@vger.kernel.org
 Description:
@@ -323,6 +343,44 @@ Description:
 		production inaccuracies).  If shared across all channels,
 		<type>_calibscale is used.
 
+What:		/sys/bus/iio/devices/iio:deviceX/in_activity_calibgender
+What:		/sys/bus/iio/devices/iio:deviceX/in_energy_calibgender
+What:		/sys/bus/iio/devices/iio:deviceX/in_distance_calibgender
+What:		/sys/bus/iio/devices/iio:deviceX/in_velocity_calibgender
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Gender of the user (e.g.: male, female) used by some pedometers
+		to compute the stride length, distance, speed and activity
+		type.
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_activity_calibgender_available
+What:		/sys/bus/iio/devices/iio:deviceX/in_energy_calibgender_available
+What:		/sys/bus/iio/devices/iio:deviceX/in_distance_calibgender_available
+What:		/sys/bus/iio/devices/iio:deviceX/in_velocity_calibgender_available
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Lists all available gender values (e.g.: male, female).
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_activity_calibheight
+What:		/sys/bus/iio/devices/iio:deviceX/in_energy_calibheight
+What:		/sys/bus/iio/devices/iio:deviceX/in_distance_calibheight
+What:		/sys/bus/iio/devices/iio:deviceX/in_velocity_calibheight
+KernelVersion:	3.19
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Height of the user (in meters) used by some pedometers
+		to compute the stride length, distance, speed and activity
+		type.
+
+What:		/sys/bus/iio/devices/iio:deviceX/in_energy_calibweight
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Weight of the user (in kg). It is needed by some pedometers
+		to compute the calories burnt by the user.
+
 What:		/sys/bus/iio/devices/iio:deviceX/in_accel_scale_available
 What:		/sys/.../iio:deviceX/in_voltageX_scale_available
 What:		/sys/.../iio:deviceX/in_voltage-voltage_scale_available
@@ -783,6 +841,14 @@ What:		/sys/.../events/in_tempY_roc_falling_period
 What:		/sys/.../events/in_accel_x&y&z_mag_falling_period
 What:		/sys/.../events/in_intensity0_thresh_period
 What:		/sys/.../events/in_proximity0_thresh_period
+What:		/sys/.../events/in_activity_still_thresh_rising_period
+What:		/sys/.../events/in_activity_still_thresh_falling_period
+What:		/sys/.../events/in_activity_walking_thresh_rising_period
+What:		/sys/.../events/in_activity_walking_thresh_falling_period
+What:		/sys/.../events/in_activity_jogging_thresh_rising_period
+What:		/sys/.../events/in_activity_jogging_thresh_falling_period
+What:		/sys/.../events/in_activity_running_thresh_rising_period
+What:		/sys/.../events/in_activity_running_thresh_falling_period
 KernelVersion:	2.6.37
 Contact:	linux-iio@vger.kernel.org
 Description:
@@ -790,6 +856,40 @@ Description:
 		met before an event is generated. If direction is not
 		specified then this period applies to both directions.
 
+What:		/sys/.../events/in_activity_still_thresh_rising_en
+What:		/sys/.../events/in_activity_still_thresh_falling_en
+What:		/sys/.../events/in_activity_walking_thresh_rising_en
+What:		/sys/.../events/in_activity_walking_thresh_falling_en
+What:		/sys/.../events/in_activity_jogging_thresh_rising_en
+What:		/sys/.../events/in_activity_jogging_thresh_falling_en
+What:		/sys/.../events/in_activity_running_thresh_rising_en
+What:		/sys/.../events/in_activity_running_thresh_falling_en
+KernelVersion:	3.19
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Enables or disables activitity events. Depending on direction
+		an event is generated when sensor ENTERS or LEAVES a given state.
+
+What:		/sys/.../events/in_activity_still_thresh_rising_value
+What:		/sys/.../events/in_activity_still_thresh_falling_value
+What:		/sys/.../events/in_activity_walking_thresh_rising_value
+What:		/sys/.../events/in_activity_walking_thresh_falling_value
+What:		/sys/.../events/in_activity_jogging_thresh_rising_value
+What:		/sys/.../events/in_activity_jogging_thresh_falling_value
+What:		/sys/.../events/in_activity_running_thresh_rising_value
+What:		/sys/.../events/in_activity_running_thresh_falling_value
+KernelVersion:	3.19
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Confidence value (in units as percentage) to be used
+		for deciding when an event should be generated. E.g for
+		running: If the confidence value reported by the sensor
+		is greater than in_activity_running_thresh_rising_value
+		then the sensor ENTERS running state. Conversely, if the
+		confidence value reported by the sensor is lower than
+		in_activity_running_thresh_falling_value then the sensor
+		is LEAVING running state.
+
 What:		/sys/.../iio:deviceX/events/in_accel_mag_en
 What:		/sys/.../iio:deviceX/events/in_accel_mag_rising_en
 What:		/sys/.../iio:deviceX/events/in_accel_mag_falling_en
@@ -822,6 +922,25 @@ Description:
 		number or direction is not specified, applies to all channels of
 		this type.
 
+What:		/sys/.../events/in_steps_change_en
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Event generated when channel passes a threshold on the absolute
+		change in value. E.g. for steps: a step change event is
+		generated each time the user takes N steps, where N is set using
+		in_steps_change_value.
+
+What:		/sys/.../events/in_steps_change_value
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Specifies the value of change threshold that the
+		device is comparing against for the events enabled by
+		<type>[Y][_name]_roc[_rising|falling|]_en. E.g. for steps:
+		if set to 3, a step change event will be generated every 3
+		steps.
+
 What:		/sys/bus/iio/devices/iio:deviceX/trigger/current_trigger
 KernelVersion:	2.6.35
 Contact:	linux-iio@vger.kernel.org
@@ -956,6 +1075,16 @@ Description:
 		and the relevant _type attributes to establish the data storage
 		format.
 
+What:		/sys/.../iio:deviceX/in_activity_still_input
+What:		/sys/.../iio:deviceX/in_activity_walking_input
+What:		/sys/.../iio:deviceX/in_activity_jogging_input
+What:		/sys/.../iio:deviceX/in_activity_running_input
+KernelVersion:	3.19
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This attribute is used to read the confidence for an activity
+		expressed in units as percentage.
+
 What:		/sys/.../iio:deviceX/in_anglvel_z_quadrature_correction_raw
 KernelVersion:	2.6.38
 Contact:	linux-iio@vger.kernel.org
@@ -973,6 +1102,24 @@ Description:
 		For a list of available output power modes read
 		in_accel_power_mode_available.
 
+What:		/sys/.../iio:deviceX/in_energy_input
+What:		/sys/.../iio:deviceX/in_energy_raw
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This attribute is used to read the energy value reported by the
+		device (e.g.: human activity sensors report energy burnt by the
+		user). Units after application of scale are Joules.
+
+What:		/sys/.../iio:deviceX/in_distance_input
+What:		/sys/.../iio:deviceX/in_distance_raw
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This attribute is used to read the distance covered by the user
+		since the last reboot while activated. Units after application
+		of scale are meters.
+
 What:		/sys/bus/iio/devices/iio:deviceX/store_eeprom
 KernelVersion:	3.4.0
 Contact:	linux-iio@vger.kernel.org
@@ -992,7 +1139,9 @@ Description:
 		reflectivity of infrared or ultrasound emitted.
 		Often these sensors are unit less and as such conversion
 		to SI units is not possible.  Where it is, the units should
-		be meters.
+		be meters.  If such a conversion is not possible, the reported
+		values should behave in the same way as a distance, i.e. lower
+		values indicate something is closer to the sensor.
 
 What:		/sys/.../iio:deviceX/in_illuminanceY_input
 What:		/sys/.../iio:deviceX/in_illuminanceY_raw
@@ -1024,6 +1173,12 @@ Description:
 		This attribute is used to get/set the integration time in
 		seconds.
 
+What:		/sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_integration_time
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Number of seconds in which to compute speed.
+
 What:		/sys/bus/iio/devices/iio:deviceX/in_rot_quaternion_raw
 KernelVersion:	3.15
 Contact:	linux-iio@vger.kernel.org
@@ -1051,3 +1206,46 @@ Description:
 		after application of scale and offset. If no offset or scale is
 		present, output should be considered as processed with the
 		unit in milliamps.
+
+What:		/sys/.../iio:deviceX/in_energy_en
+What:		/sys/.../iio:deviceX/in_distance_en
+What:		/sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_en
+What:		/sys/.../iio:deviceX/in_steps_en
+KernelVersion:	3.19
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Activates a device feature that runs in firmware/hardware.
+		E.g. for steps: the pedometer saves power while not used;
+		when activated, it will count the steps taken by the user in
+		firmware and export them through in_steps_input.
+
+What:		/sys/.../iio:deviceX/in_steps_input
+KernelVersion:	3.19
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This attribute is used to read the number of steps taken by the user
+		since the last reboot while activated.
+
+What:		/sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_input
+What:		/sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_raw
+KernelVersion:	3.19
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This attribute is used to read the current speed value of the
+		user (which is the norm or magnitude of the velocity vector).
+		Units after application of scale are m/s.
+
+What:		/sys/.../iio:deviceX/in_steps_debounce_count
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Specifies the number of steps that must occur within
+		in_steps_filter_debounce_time for the pedometer to decide the
+		consumer is making steps.
+
+What:		/sys/.../iio:deviceX/in_steps_debounce_time
+KernelVersion:	3.20
+Contact:	linux-iio@vger.kernel.org
+Description:
+		Specifies number of seconds in which we compute the steps
+		that occur in order to decide if the consumer is making steps.
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index f9463b492f44..4dcd88d5f7ca 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -35,6 +35,7 @@ atmel,24c512		i2c serial eeprom  (24cxx)
 atmel,24c1024		i2c serial eeprom  (24cxx)
 atmel,at97sc3204t	i2c trusted platform module (TPM)
 capella,cm32181		CM32181: Ambient Light Sensor
+capella,cm3232		CM3232: Ambient Light Sensor
 catalyst,24c32		i2c serial eeprom
 cirrus,cs42l51		Cirrus Logic CS42L51 audio codec
 dallas,ds1307		64 x 8, Serial, I2C Real-Time Clock
diff --git a/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
new file mode 100644
index 000000000000..904f76de9055
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/cc10001_adc.txt
@@ -0,0 +1,22 @@
+* Cosmic Circuits - Analog to Digital Converter (CC-10001-ADC)
+
+Required properties:
+  - compatible: Should be "cosmic,10001-adc"
+  - reg: Should contain adc registers location and length.
+  - clock-names: Should contain "adc".
+  - clocks: Should contain a clock specifier for each entry in clock-names
+  - vref-supply: The regulator supply ADC reference voltage.
+
+Optional properties:
+  - adc-reserved-channels: Bitmask of reserved channels,
+    i.e. channels that cannot be used by the OS.
+
+Example:
+adc: adc@18101600 {
+	compatible = "cosmic,10001-adc";
+	reg = <0x18101600 0x24>;
+	adc-reserved-channels = <0x2>;
+	clocks = <&adc_clk>;
+	clock-names = "adc";
+	vref-supply = <&reg_1v8>;
+};
diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt
new file mode 100644
index 000000000000..0fb46137f936
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.txt
@@ -0,0 +1,129 @@
+Qualcomm's SPMI PMIC voltage ADC
+
+SPMI PMIC voltage ADC (VADC) provides interface to clients to read
+voltage. The VADC is a 15-bit sigma-delta ADC.
+
+VADC node:
+
+- compatible:
+    Usage: required
+    Value type: <string>
+    Definition: Should contain "qcom,spmi-vadc".
+
+- reg:
+    Usage: required
+    Value type: <prop-encoded-array>
+    Definition: VADC base address and length in the SPMI PMIC register map.
+
+- #address-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Must be one. Child node 'reg' property should define ADC
+            channel number.
+
+- #size-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Must be zero.
+
+- #io-channel-cells:
+    Usage: required
+    Value type: <u32>
+    Definition: Must be one. For details about IIO bindings see:
+            Documentation/devicetree/bindings/iio/iio-bindings.txt
+
+- interrupts:
+    Usage: optional
+    Value type: <prop-encoded-array>
+    Definition: End of conversion interrupt.
+
+Channel node properties:
+
+- reg:
+    Usage: required
+    Value type: <u32>
+    Definition: ADC channel number.
+            See include/dt-bindings/iio/qcom,spmi-vadc.h
+
+- qcom,decimation:
+    Usage: optional
+    Value type: <u32>
+    Definition: This parameter is used to decrease ADC sampling rate.
+            Quicker measurements can be made by reducing decimation ratio.
+            Valid values are 512, 1024, 2048, 4096.
+            If property is not found, default value of 512 will be used.
+
+- qcom,pre-scaling:
+    Usage: optional
+    Value type: <u32 array>
+    Definition: Used for scaling the channel input signal before the signal is
+            fed to VADC. The configuration for this node is to know the
+            pre-determined ratio and use it for post scaling. Select one from
+            the following options.
+            <1 1>, <1 3>, <1 4>, <1 6>, <1 20>, <1 8>, <10 81>, <1 10>
+            If property is not found default value depending on chip will be used.
+
+- qcom,ratiometric:
+    Usage: optional
+    Value type: <empty>
+    Definition: Channel calibration type. If this property is specified
+            VADC will use the VDD reference (1.8V) and GND for channel
+            calibration. If property is not found, channel will be
+            calibrated with 0.625V and 1.25V reference channels, also
+            known as absolute calibration.
+
+- qcom,hw-settle-time:
+    Usage: optional
+    Value type: <u32>
+    Definition: Time between AMUX getting configured and the ADC starting
+            conversion. Delay = 100us * (value) for value < 11, and
+            2ms * (value - 10) otherwise.
+            Valid values are: 0, 100, 200, 300, 400, 500, 600, 700, 800,
+            900 us and 1, 2, 4, 6, 8, 10 ms
+            If property is not found, channel will use 0us.
+
+- qcom,avg-samples:
+    Usage: optional
+    Value type: <u32>
+    Definition: Number of samples to be used for measurement.
+            Averaging provides the option to obtain a single measurement
+            from the ADC that is an average of multiple samples. The value
+            selected is 2^(value).
+            Valid values are: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512
+            If property is not found, 1 sample will be used.
+
+NOTE:
+
+Following channels, also known as reference point channels, are used for
+result calibration and their channel configuration nodes should be defined:
+VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV,
+VADC_GND_REF and VADC_VDD_VADC.
+
+Example:
+
+	/* VADC node */
+	pmic_vadc: vadc@3100 {
+		compatible = "qcom,spmi-vadc";
+		reg = <0x3100 0x100>;
+		interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#io-channel-cells = <1>;
+		io-channel-ranges;
+
+		/* Channel node */
+		usb_id_nopull {
+			reg = <VADC_LR_MUX10_USB_ID>;
+			qcom,decimation = <512>;
+			qcom,ratiometric;
+			qcom,hw-settle-time = <200>;
+			qcom,avg-samples = <1>;
+			qcom,pre-scaling = <1 3>;
+		};
+	};
+
+	/* IIO client node */
+	usb {
+		io-channels = <&pmic_vadc VADC_LR_MUX10_USB_ID>;
+		io-channel-names = "vadc";
+	};
diff --git a/Documentation/devicetree/bindings/iio/sensorhub.txt b/Documentation/devicetree/bindings/iio/sensorhub.txt
new file mode 100644
index 000000000000..8d57571d5c0b
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/sensorhub.txt
@@ -0,0 +1,25 @@
+Samsung Sensorhub driver
+
+Sensorhub is a MCU which manages several sensors and also plays the role
+of a virtual sensor device.
+
+Required properties:
+- compatible: "samsung,sensorhub-rinato" or "samsung,sensorhub-thermostat"
+- spi-max-frequency: max SPI clock frequency
+- interrupt-parent: interrupt parent
+- interrupts: communication interrupt
+- ap-mcu-gpios: [out] ap to sensorhub line - used during communication
+- mcu-ap-gpios: [in] sensorhub to ap - used during communication
+- mcu-reset-gpios: [out] sensorhub reset
+
+Example:
+
+	shub_spi: shub {
+		compatible = "samsung,sensorhub-rinato";
+		spi-max-frequency = <5000000>;
+		interrupt-parent = <&gpx0>;
+		interrupts = <2 0>;
+		ap-mcu-gpios = <&gpx0 0 0>;
+		mcu-ap-gpios = <&gpx0 4 0>;
+		mcu-reset-gpios = <&gpx0 5 0>;
+	};
diff --git a/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt b/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
index ee05dc390694..307537787574 100644
--- a/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
+++ b/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
@@ -12,9 +12,9 @@ Optional properties:
                                property is not present, then the touchscreen is
                                disabled. 5 wires is valid for i.MX28 SoC only.
 - fsl,ave-ctrl: number of samples per direction to calculate an average value.
-                Allowed value is 1 ... 31, default is 4
+                Allowed value is 1 ... 32, default is 4
 - fsl,ave-delay: delay between consecutive samples. Allowed value is
-                 1 ... 2047. It is used if 'fsl,ave-ctrl' > 1, counts at
+                 2 ... 2048. It is used if 'fsl,ave-ctrl' > 1, counts at
                  2 kHz and its default is 2 (= 1 ms)
 - fsl,settling: delay between plate switch to next sample. Allowed value is
                 1 ... 2047. It counts at 2 kHz and its default is
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 797e6b024241..1eb6444a48c4 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -38,6 +38,7 @@ chunghwa	Chunghwa Picture Tubes Ltd.
 cirrus	Cirrus Logic, Inc.
 cnm	Chips&Media, Inc.
 cortina	Cortina Systems, Inc.
+cosmic	Cosmic Circuits
 crystalfontz	Crystalfontz America, Inc.
 dallas	Maxim Integrated Products (formerly Dallas Semiconductor)
 davicom	DAVICOM Semiconductor, Inc.
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index b5ab416cd53a..6d1e8eeb5990 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -258,6 +258,8 @@ IIO
   devm_iio_device_free()
   devm_iio_device_register()
   devm_iio_device_unregister()
+  devm_iio_kfifo_allocate()
+  devm_iio_kfifo_free()
   devm_iio_trigger_alloc()
   devm_iio_trigger_free()
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 71a65389ca4d..348f5c16ef50 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2399,6 +2399,12 @@ F:	security/capability.c
 F:	security/commoncap.c
 F:	kernel/capability.c
 
+CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER
+M:	Kevin Tsai <ktsai@capellamicro.com>
+S:	Maintained
+F:	drivers/iio/light/cm*
+F:	Documentation/devicetree/bindings/i2c/trivial-devices.txt
+
 CC2520 IEEE-802.15.4 RADIO DRIVER
 M:	Varka Bhadram <varkabhadram@gmail.com>
 L:	linux-wpan@vger.kernel.org
@@ -3904,6 +3910,12 @@ S:	Supported
 F:	Documentation/fault-injection/
 F:	lib/fault-inject.c
 
+FBTFT Framebuffer drivers
+M:	Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+M:	Noralf Trønnes <noralf@tronnes.org>
+S:	Maintained
+F:	drivers/staging/fbtft/
+
 FCOE SUBSYSTEM (libfc, libfcoe, fcoe)
 M:	Robert Love <robert.w.love@intel.com>
 L:	fcoe-devel@open-fcoe.org
@@ -9262,6 +9274,14 @@ L:	linux-wireless@vger.kernel.org
 S:	Maintained
 F:	drivers/staging/rtl8723au/
 
+STAGING - SILICON MOTION SM7XX FRAME BUFFER DRIVER
+M:	Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+M:	Teddy Wang <teddy.wang@siliconmotion.com>
+M:	Sudip Mukherjee <sudip@vectorindia.org>
+L:	linux-fbdev@vger.kernel.org
+S:	Maintained
+F:	drivers/staging/sm7xxfb/
+
 STAGING - SLICOSS
 M:	Lior Dotan <liodot@gmail.com>
 M:	Christopher Harrer <charrer@alacritech.com>
diff --git a/drivers/Kconfig b/drivers/Kconfig
index c70d6e45dc10..c0cc96bab9e7 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -36,8 +36,6 @@ source "drivers/message/fusion/Kconfig"
 
 source "drivers/firewire/Kconfig"
 
-source "drivers/message/i2o/Kconfig"
-
 source "drivers/macintosh/Kconfig"
 
 source "drivers/net/Kconfig"
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 345395e9dc6e..4132935dc929 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -27,7 +27,6 @@ boolean "IIO callback buffer used for push in-kernel interfaces"
 	  usage.  That is, those where the data is pushed to the consumer.
 
 config IIO_KFIFO_BUF
-	select IIO_TRIGGER
 	tristate "Industrial I/O buffering based on kfifo"
 	help
 	  A simple fifo based on kfifo.  Note that this currently provides
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 9b9be8725e9d..7c9a9a94a8ce 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -43,6 +43,9 @@ config HID_SENSOR_ACCEL_3D
 	  Say yes here to build support for the HID SENSOR
 	  accelerometers 3D.
 
+	  To compile this driver as a module, choose M here: the
+	  module will be called hid-sensor-accel-3d.
+
 config IIO_ST_ACCEL_3AXIS
 	tristate "STMicroelectronics accelerometers 3-Axis Driver"
 	depends on (I2C || SPI_MASTER) && SYSFS
@@ -80,6 +83,9 @@ config KXSD9
 	  Say yes here to build support for the Kionix KXSD9 accelerometer.
 	  Currently this only supports the device via an SPI interface.
 
+	  To compile this driver as a module, choose M here: the module
+	  will be called kxsd9.
+
 config MMA8452
 	tristate "Freescale MMA8452Q Accelerometer Driver"
 	depends on I2C
@@ -105,4 +111,29 @@ config KXCJK1013
 	  To compile this driver as a module, choose M here: the module will
 	  be called kxcjk-1013.
 
+config MMA9551_CORE
+	tristate
+
+config MMA9551
+	tristate "Freescale MMA9551L Intelligent Motion-Sensing Platform Driver"
+	depends on I2C
+	select MMA9551_CORE
+
+	help
+	  Say yes here to build support for the Freescale MMA9551L
+	  Intelligent Motion-Sensing Platform Driver.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called mma9551.
+
+config MMA9553
+	tristate "Freescale MMA9553L Intelligent Pedometer Platform Driver"
+	depends on I2C
+	select MMA9551_CORE
+	help
+	  Say yes here to build support for the Freescale MMA9553L
+	  Intelligent Pedometer Platform Driver.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called mma9553.
 endmenu
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index a593996c6539..99d89e46cad1 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -10,6 +10,12 @@ obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
 obj-$(CONFIG_KXSD9)	+= kxsd9.o
 obj-$(CONFIG_MMA8452)	+= mma8452.o
 
+obj-$(CONFIG_MMA9551_CORE)	+= mma9551_core.o
+obj-$(CONFIG_MMA9551)		+= mma9551.o
+obj-$(CONFIG_MMA9553)		+= mma9553.o
+
+obj-$(CONFIG_IIO_SSP_SENSORS_COMMONS) += ssp_accel_sensor.o
+
 obj-$(CONFIG_IIO_ST_ACCEL_3AXIS) += st_accel.o
 st_accel-y := st_accel_core.o
 st_accel-$(CONFIG_IIO_BUFFER) += st_accel_buffer.o
diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index d5d95317003a..df6a593bd4bd 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -111,19 +111,12 @@ static int accel_3d_read_raw(struct iio_dev *indio_dev,
 	int report_id = -1;
 	u32 address;
 	int ret_type;
-	s32 poll_value;
 
 	*val = 0;
 	*val2 = 0;
 	switch (mask) {
 	case 0:
-		poll_value = hid_sensor_read_poll_value(
-					&accel_state->common_attributes);
-		if (poll_value < 0)
-			return -EINVAL;
-
 		hid_sensor_power_state(&accel_state->common_attributes, true);
-		msleep_interruptible(poll_value * 2);
 		report_id = accel_state->accel[chan->scan_index].report_id;
 		address = accel_3d_addresses[chan->scan_index];
 		if (report_id >= 0)
@@ -419,6 +412,7 @@ static struct platform_driver hid_accel_3d_platform_driver = {
 	.id_table = hid_accel_3d_ids,
 	.driver = {
 		.name	= KBUILD_MODNAME,
+		.pm	= &hid_sensor_pm_ops,
 	},
 	.probe		= hid_accel_3d_probe,
 	.remove		= hid_accel_3d_remove,
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index da2fe93739a2..567de269cc00 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -108,6 +108,7 @@ struct kxcjk1013_data {
 	bool motion_trigger_on;
 	int64_t timestamp;
 	enum kx_chipset chipset;
+	bool is_smo8500_device;
 };
 
 enum kxcjk1013_axis {
@@ -377,6 +378,7 @@ static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data)
 
 static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
 {
+#ifdef CONFIG_PM
 	int ret;
 
 	if (on)
@@ -388,8 +390,11 @@ static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
 	if (ret < 0) {
 		dev_err(&data->client->dev,
 			"Failed: kxcjk1013_set_power_state for %d\n", on);
+		if (on)
+			pm_runtime_put_noidle(&data->client->dev);
 		return ret;
 	}
+#endif
 
 	return 0;
 }
@@ -858,6 +863,8 @@ static int kxcjk1013_write_event_config(struct iio_dev *indio_dev,
 
 	ret =  kxcjk1013_setup_any_motion_interrupt(data, state);
 	if (ret < 0) {
+		kxcjk1013_set_power_state(data, false);
+		data->ev_enable_state = 0;
 		mutex_unlock(&data->mutex);
 		return ret;
 	}
@@ -1008,6 +1015,7 @@ static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig,
 	else
 		ret = kxcjk1013_setup_new_data_interrupt(data, state);
 	if (ret < 0) {
+		kxcjk1013_set_power_state(data, false);
 		mutex_unlock(&data->mutex);
 		return ret;
 	}
@@ -1131,12 +1139,16 @@ static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private)
 }
 
 static const char *kxcjk1013_match_acpi_device(struct device *dev,
-					       enum kx_chipset *chipset)
+					       enum kx_chipset *chipset,
+					       bool *is_smo8500_device)
 {
 	const struct acpi_device_id *id;
+
 	id = acpi_match_device(dev->driver->acpi_match_table, dev);
 	if (!id)
 		return NULL;
+	if (strcmp(id->id, "SMO8500") == 0)
+		*is_smo8500_device = true;
 	*chipset = (enum kx_chipset)id->driver_data;
 
 	return dev_name(dev);
@@ -1151,6 +1163,8 @@ static int kxcjk1013_gpio_probe(struct i2c_client *client,
 
 	if (!client)
 		return -EINVAL;
+	if (data->is_smo8500_device)
+		return -ENOTSUPP;
 
 	dev = &client->dev;
 
@@ -1200,7 +1214,8 @@ static int kxcjk1013_probe(struct i2c_client *client,
 		name = id->name;
 	} else if (ACPI_HANDLE(&client->dev)) {
 		name = kxcjk1013_match_acpi_device(&client->dev,
-						   &data->chipset);
+						   &data->chipset,
+						   &data->is_smo8500_device);
 	} else
 		return -ENODEV;
 
@@ -1228,21 +1243,25 @@ static int kxcjk1013_probe(struct i2c_client *client,
 						KXCJK1013_IRQ_NAME,
 						indio_dev);
 		if (ret)
-			return ret;
+			goto err_poweroff;
 
 		data->dready_trig = devm_iio_trigger_alloc(&client->dev,
 							   "%s-dev%d",
 							   indio_dev->name,
 							   indio_dev->id);
-		if (!data->dready_trig)
-			return -ENOMEM;
+		if (!data->dready_trig) {
+			ret = -ENOMEM;
+			goto err_poweroff;
+		}
 
 		data->motion_trig = devm_iio_trigger_alloc(&client->dev,
 							  "%s-any-motion-dev%d",
 							  indio_dev->name,
 							  indio_dev->id);
-		if (!data->motion_trig)
-			return -ENOMEM;
+		if (!data->motion_trig) {
+			ret = -ENOMEM;
+			goto err_poweroff;
+		}
 
 		data->dready_trig->dev.parent = &client->dev;
 		data->dready_trig->ops = &kxcjk1013_trigger_ops;
@@ -1251,7 +1270,7 @@ static int kxcjk1013_probe(struct i2c_client *client,
 		iio_trigger_get(indio_dev->trig);
 		ret = iio_trigger_register(data->dready_trig);
 		if (ret)
-			return ret;
+			goto err_poweroff;
 
 		data->motion_trig->dev.parent = &client->dev;
 		data->motion_trig->ops = &kxcjk1013_trigger_ops;
@@ -1300,6 +1319,8 @@ err_trigger_unregister:
 		iio_trigger_unregister(data->dready_trig);
 	if (data->motion_trig)
 		iio_trigger_unregister(data->motion_trig);
+err_poweroff:
+	kxcjk1013_set_mode(data, STANDBY);
 
 	return ret;
 }
@@ -1349,10 +1370,7 @@ static int kxcjk1013_resume(struct device *dev)
 	int ret = 0;
 
 	mutex_lock(&data->mutex);
-	/* Check, if the suspend occured while active */
-	if (data->dready_trigger_on || data->motion_trigger_on ||
-							data->ev_enable_state)
-		ret = kxcjk1013_set_mode(data, OPERATION);
+	ret = kxcjk1013_set_mode(data, OPERATION);
 	mutex_unlock(&data->mutex);
 
 	return ret;
@@ -1364,8 +1382,14 @@ static int kxcjk1013_runtime_suspend(struct device *dev)
 {
 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 	struct kxcjk1013_data *data = iio_priv(indio_dev);
+	int ret;
 
-	return kxcjk1013_set_mode(data, STANDBY);
+	ret = kxcjk1013_set_mode(data, STANDBY);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "powering off device failed\n");
+		return -EAGAIN;
+	}
+	return 0;
 }
 
 static int kxcjk1013_runtime_resume(struct device *dev)
@@ -1399,6 +1423,7 @@ static const struct acpi_device_id kx_acpi_match[] = {
 	{"KXCJ1013", KXCJK1013},
 	{"KXCJ1008", KXCJ91008},
 	{"KXTJ1009", KXTJ21009},
+	{"SMO8500",  KXCJ91008},
 	{ },
 };
 MODULE_DEVICE_TABLE(acpi, kx_acpi_match);
@@ -1407,6 +1432,7 @@ static const struct i2c_device_id kxcjk1013_id[] = {
 	{"kxcjk1013", KXCJK1013},
 	{"kxcj91008", KXCJ91008},
 	{"kxtj21009", KXTJ21009},
+	{"SMO8500",   KXCJ91008},
 	{}
 };
 
diff --git a/drivers/iio/accel/mma8452.c b/drivers/iio/accel/mma8452.c
index 3c12d4966376..5b80657883bb 100644
--- a/drivers/iio/accel/mma8452.c
+++ b/drivers/iio/accel/mma8452.c
@@ -111,7 +111,7 @@ static const int mma8452_samp_freq[8][2] = {
 	{6, 250000}, {1, 560000}
 };
 
-/* 
+/*
  * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048
  * The userspace interface uses m/s^2 and we declare micro units
  * So scale factor is given by:
diff --git a/drivers/iio/accel/mma9551.c b/drivers/iio/accel/mma9551.c
new file mode 100644
index 000000000000..46c38351c6a3
--- /dev/null
+++ b/drivers/iio/accel/mma9551.c
@@ -0,0 +1,637 @@
+/*
+ * Freescale MMA9551L Intelligent Motion-Sensing Platform driver
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/acpi.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+#include <linux/pm_runtime.h>
+#include "mma9551_core.h"
+
+#define MMA9551_DRV_NAME		"mma9551"
+#define MMA9551_IRQ_NAME		"mma9551_event"
+#define MMA9551_GPIO_NAME		"mma9551_int"
+#define MMA9551_GPIO_COUNT		4
+
+/* Tilt application (inclination in IIO terms). */
+#define MMA9551_TILT_XZ_ANG_REG		0x00
+#define MMA9551_TILT_YZ_ANG_REG		0x01
+#define MMA9551_TILT_XY_ANG_REG		0x02
+#define MMA9551_TILT_ANGFLG		BIT(7)
+#define MMA9551_TILT_QUAD_REG		0x03
+#define MMA9551_TILT_XY_QUAD_SHIFT	0
+#define MMA9551_TILT_YZ_QUAD_SHIFT	2
+#define MMA9551_TILT_XZ_QUAD_SHIFT	4
+#define MMA9551_TILT_CFG_REG		0x01
+#define MMA9551_TILT_ANG_THRESH_MASK	GENMASK(3, 0)
+
+#define MMA9551_DEFAULT_SAMPLE_RATE	122	/* Hz */
+
+/* Tilt events are mapped to the first three GPIO pins. */
+enum mma9551_tilt_axis {
+	mma9551_x = 0,
+	mma9551_y,
+	mma9551_z,
+};
+
+struct mma9551_data {
+	struct i2c_client *client;
+	struct mutex mutex;
+	int event_enabled[3];
+	int irqs[MMA9551_GPIO_COUNT];
+};
+
+static int mma9551_read_incli_chan(struct i2c_client *client,
+				   const struct iio_chan_spec *chan,
+				   int *val)
+{
+	u8 quad_shift, angle, quadrant;
+	u16 reg_addr;
+	int ret;
+
+	switch (chan->channel2) {
+	case IIO_MOD_X:
+		reg_addr = MMA9551_TILT_YZ_ANG_REG;
+		quad_shift = MMA9551_TILT_YZ_QUAD_SHIFT;
+		break;
+	case IIO_MOD_Y:
+		reg_addr = MMA9551_TILT_XZ_ANG_REG;
+		quad_shift = MMA9551_TILT_XZ_QUAD_SHIFT;
+		break;
+	case IIO_MOD_Z:
+		reg_addr = MMA9551_TILT_XY_ANG_REG;
+		quad_shift = MMA9551_TILT_XY_QUAD_SHIFT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = mma9551_set_power_state(client, true);
+	if (ret < 0)
+		return ret;
+
+	ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
+				       reg_addr, &angle);
+	if (ret < 0)
+		goto out_poweroff;
+
+	ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
+				       MMA9551_TILT_QUAD_REG, &quadrant);
+	if (ret < 0)
+		goto out_poweroff;
+
+	angle &= ~MMA9551_TILT_ANGFLG;
+	quadrant = (quadrant >> quad_shift) & 0x03;
+
+	if (quadrant == 1 || quadrant == 3)
+		*val = 90 * (quadrant + 1) - angle;
+	else
+		*val = angle + 90 * quadrant;
+
+	ret = IIO_VAL_INT;
+
+out_poweroff:
+	mma9551_set_power_state(client, false);
+	return ret;
+}
+
+static int mma9551_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val, int *val2, long mask)
+{
+	struct mma9551_data *data = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_PROCESSED:
+		switch (chan->type) {
+		case IIO_INCLI:
+			mutex_lock(&data->mutex);
+			ret = mma9551_read_incli_chan(data->client, chan, val);
+			mutex_unlock(&data->mutex);
+			return ret;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_RAW:
+		switch (chan->type) {
+		case IIO_ACCEL:
+			mutex_lock(&data->mutex);
+			ret = mma9551_read_accel_chan(data->client,
+						      chan, val, val2);
+			mutex_unlock(&data->mutex);
+			return ret;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_ACCEL:
+			return mma9551_read_accel_scale(val, val2);
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mma9551_read_event_config(struct iio_dev *indio_dev,
+				     const struct iio_chan_spec *chan,
+				     enum iio_event_type type,
+				     enum iio_event_direction dir)
+{
+	struct mma9551_data *data = iio_priv(indio_dev);
+
+	switch (chan->type) {
+	case IIO_INCLI:
+		/* IIO counts axes from 1, because IIO_NO_MOD is 0. */
+		return data->event_enabled[chan->channel2 - 1];
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mma9551_config_incli_event(struct iio_dev *indio_dev,
+				      enum iio_modifier axis,
+				      int state)
+{
+	struct mma9551_data *data = iio_priv(indio_dev);
+	enum mma9551_tilt_axis mma_axis;
+	int ret;
+
+	/* IIO counts axes from 1, because IIO_NO_MOD is 0. */
+	mma_axis = axis - 1;
+
+	if (data->event_enabled[mma_axis] == state)
+		return 0;
+
+	if (state == 0) {
+		ret = mma9551_gpio_config(data->client,
+					  (enum mma9551_gpio_pin)mma_axis,
+					  MMA9551_APPID_NONE, 0, 0);
+		if (ret < 0)
+			return ret;
+
+		ret = mma9551_set_power_state(data->client, false);
+		if (ret < 0)
+			return ret;
+	} else {
+		int bitnum;
+
+		/* Bit 7 of each angle register holds the angle flag. */
+		switch (axis) {
+		case IIO_MOD_X:
+			bitnum = 7 + 8 * MMA9551_TILT_YZ_ANG_REG;
+			break;
+		case IIO_MOD_Y:
+			bitnum = 7 + 8 * MMA9551_TILT_XZ_ANG_REG;
+			break;
+		case IIO_MOD_Z:
+			bitnum = 7 + 8 * MMA9551_TILT_XY_ANG_REG;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+
+		ret = mma9551_set_power_state(data->client, true);
+		if (ret < 0)
+			return ret;
+
+		ret = mma9551_gpio_config(data->client,
+					  (enum mma9551_gpio_pin)mma_axis,
+					  MMA9551_APPID_TILT, bitnum, 0);
+		if (ret < 0) {
+			mma9551_set_power_state(data->client, false);
+			return ret;
+		}
+	}
+
+	data->event_enabled[mma_axis] = state;
+
+	return ret;
+}
+
+static int mma9551_write_event_config(struct iio_dev *indio_dev,
+				      const struct iio_chan_spec *chan,
+				      enum iio_event_type type,
+				      enum iio_event_direction dir,
+				      int state)
+{
+	struct mma9551_data *data = iio_priv(indio_dev);
+	int ret;
+
+	switch (chan->type) {
+	case IIO_INCLI:
+		mutex_lock(&data->mutex);
+		ret = mma9551_config_incli_event(indio_dev,
+						 chan->channel2, state);
+		mutex_unlock(&data->mutex);
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mma9551_write_event_value(struct iio_dev *indio_dev,
+				     const struct iio_chan_spec *chan,
+				     enum iio_event_type type,
+				     enum iio_event_direction dir,
+				     enum iio_event_info info,
+				     int val, int val2)
+{
+	struct mma9551_data *data = iio_priv(indio_dev);
+	int ret;
+
+	switch (chan->type) {
+	case IIO_INCLI:
+		if (val2 != 0 || val < 1 || val > 10)
+			return -EINVAL;
+		mutex_lock(&data->mutex);
+		ret = mma9551_update_config_bits(data->client,
+						 MMA9551_APPID_TILT,
+						 MMA9551_TILT_CFG_REG,
+						 MMA9551_TILT_ANG_THRESH_MASK,
+						 val);
+		mutex_unlock(&data->mutex);
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mma9551_read_event_value(struct iio_dev *indio_dev,
+				    const struct iio_chan_spec *chan,
+				    enum iio_event_type type,
+				    enum iio_event_direction dir,
+				    enum iio_event_info info,
+				    int *val, int *val2)
+{
+	struct mma9551_data *data = iio_priv(indio_dev);
+	int ret;
+	u8 tmp;
+
+	switch (chan->type) {
+	case IIO_INCLI:
+		mutex_lock(&data->mutex);
+		ret = mma9551_read_config_byte(data->client,
+					       MMA9551_APPID_TILT,
+					       MMA9551_TILT_CFG_REG, &tmp);
+		mutex_unlock(&data->mutex);
+		if (ret < 0)
+			return ret;
+		*val = tmp & MMA9551_TILT_ANG_THRESH_MASK;
+		*val2 = 0;
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct iio_event_spec mma9551_incli_event = {
+	.type = IIO_EV_TYPE_ROC,
+	.dir = IIO_EV_DIR_RISING,
+	.mask_separate = BIT(IIO_EV_INFO_ENABLE),
+	.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
+};
+
+#define MMA9551_INCLI_CHANNEL(axis) {				\
+	.type = IIO_INCLI,					\
+	.modified = 1,						\
+	.channel2 = axis,					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
+	.event_spec = &mma9551_incli_event,			\
+	.num_event_specs = 1,					\
+}
+
+static const struct iio_chan_spec mma9551_channels[] = {
+	MMA9551_ACCEL_CHANNEL(IIO_MOD_X),
+	MMA9551_ACCEL_CHANNEL(IIO_MOD_Y),
+	MMA9551_ACCEL_CHANNEL(IIO_MOD_Z),
+
+	MMA9551_INCLI_CHANNEL(IIO_MOD_X),
+	MMA9551_INCLI_CHANNEL(IIO_MOD_Y),
+	MMA9551_INCLI_CHANNEL(IIO_MOD_Z),
+};
+
+static const struct iio_info mma9551_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = mma9551_read_raw,
+	.read_event_config = mma9551_read_event_config,
+	.write_event_config = mma9551_write_event_config,
+	.read_event_value = mma9551_read_event_value,
+	.write_event_value = mma9551_write_event_value,
+};
+
+static irqreturn_t mma9551_event_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct mma9551_data *data = iio_priv(indio_dev);
+	int i, ret, mma_axis = -1;
+	u16 reg;
+	u8 val;
+
+	mutex_lock(&data->mutex);
+
+	for (i = 0; i < 3; i++)
+		if (irq == data->irqs[i]) {
+			mma_axis = i;
+			break;
+		}
+
+	if (mma_axis == -1) {
+		/* IRQ was triggered on 4th line, which we don't use. */
+		dev_warn(&data->client->dev,
+			 "irq triggered on unused line %d\n", data->irqs[3]);
+		goto out;
+	}
+
+	switch (mma_axis) {
+	case mma9551_x:
+		reg = MMA9551_TILT_YZ_ANG_REG;
+		break;
+	case mma9551_y:
+		reg = MMA9551_TILT_XZ_ANG_REG;
+		break;
+	case mma9551_z:
+		reg = MMA9551_TILT_XY_ANG_REG;
+		break;
+	}
+
+	/*
+	 * Read the angle even though we don't use it, otherwise we
+	 * won't get any further interrupts.
+	 */
+	ret = mma9551_read_status_byte(data->client, MMA9551_APPID_TILT,
+				       reg, &val);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"error %d reading tilt register in IRQ\n", ret);
+		goto out;
+	}
+
+	iio_push_event(indio_dev,
+		       IIO_MOD_EVENT_CODE(IIO_INCLI, 0, (mma_axis + 1),
+					  IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING),
+		       iio_get_time_ns());
+
+out:
+	mutex_unlock(&data->mutex);
+
+	return IRQ_HANDLED;
+}
+
+static int mma9551_init(struct mma9551_data *data)
+{
+	int ret;
+
+	ret = mma9551_read_version(data->client);
+	if (ret)
+		return ret;
+
+	return mma9551_set_device_state(data->client, true);
+}
+
+static int mma9551_gpio_probe(struct iio_dev *indio_dev)
+{
+	struct gpio_desc *gpio;
+	int i, ret;
+	struct mma9551_data *data = iio_priv(indio_dev);
+	struct device *dev = &data->client->dev;
+
+	for (i = 0; i < MMA9551_GPIO_COUNT; i++) {
+		gpio = devm_gpiod_get_index(dev, MMA9551_GPIO_NAME, i);
+		if (IS_ERR(gpio)) {
+			dev_err(dev, "acpi gpio get index failed\n");
+			return PTR_ERR(gpio);
+		}
+
+		ret = gpiod_direction_input(gpio);
+		if (ret)
+			return ret;
+
+		data->irqs[i] = gpiod_to_irq(gpio);
+		ret = devm_request_threaded_irq(dev, data->irqs[i],
+				NULL, mma9551_event_handler,
+				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+				MMA9551_IRQ_NAME, indio_dev);
+		if (ret < 0) {
+			dev_err(dev, "request irq %d failed\n", data->irqs[i]);
+			return ret;
+		}
+
+		dev_dbg(dev, "gpio resource, no:%d irq:%d\n",
+			desc_to_gpio(gpio), data->irqs[i]);
+	}
+
+	return 0;
+}
+
+static const char *mma9551_match_acpi_device(struct device *dev)
+{
+	const struct acpi_device_id *id;
+
+	id = acpi_match_device(dev->driver->acpi_match_table, dev);
+	if (!id)
+		return NULL;
+
+	return dev_name(dev);
+}
+
+static int mma9551_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct mma9551_data *data;
+	struct iio_dev *indio_dev;
+	const char *name = NULL;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+
+	if (id)
+		name = id->name;
+	else if (ACPI_HANDLE(&client->dev))
+		name = mma9551_match_acpi_device(&client->dev);
+
+	ret = mma9551_init(data);
+	if (ret < 0)
+		return ret;
+
+	mutex_init(&data->mutex);
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->channels = mma9551_channels;
+	indio_dev->num_channels = ARRAY_SIZE(mma9551_channels);
+	indio_dev->name = name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &mma9551_info;
+
+	ret = mma9551_gpio_probe(indio_dev);
+	if (ret < 0)
+		goto out_poweroff;
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0) {
+		dev_err(&client->dev, "unable to register iio device\n");
+		goto out_poweroff;
+	}
+
+	ret = pm_runtime_set_active(&client->dev);
+	if (ret < 0)
+		goto out_iio_unregister;
+
+	pm_runtime_enable(&client->dev);
+	pm_runtime_set_autosuspend_delay(&client->dev,
+					 MMA9551_AUTO_SUSPEND_DELAY_MS);
+	pm_runtime_use_autosuspend(&client->dev);
+
+	return 0;
+
+out_iio_unregister:
+	iio_device_unregister(indio_dev);
+out_poweroff:
+	mma9551_set_device_state(client, false);
+
+	return ret;
+}
+
+static int mma9551_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct mma9551_data *data = iio_priv(indio_dev);
+
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_put_noidle(&client->dev);
+
+	iio_device_unregister(indio_dev);
+	mutex_lock(&data->mutex);
+	mma9551_set_device_state(data->client, false);
+	mutex_unlock(&data->mutex);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mma9551_runtime_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct mma9551_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = mma9551_set_device_state(data->client, false);
+	mutex_unlock(&data->mutex);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "powering off device failed\n");
+		return -EAGAIN;
+	}
+
+	return 0;
+}
+
+static int mma9551_runtime_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct mma9551_data *data = iio_priv(indio_dev);
+	int ret;
+
+	ret = mma9551_set_device_state(data->client, true);
+	if (ret < 0)
+		return ret;
+
+	mma9551_sleep(MMA9551_DEFAULT_SAMPLE_RATE);
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int mma9551_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct mma9551_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = mma9551_set_device_state(data->client, false);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static int mma9551_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct mma9551_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = mma9551_set_device_state(data->client, true);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+#endif
+
+static const struct dev_pm_ops mma9551_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mma9551_suspend, mma9551_resume)
+	SET_RUNTIME_PM_OPS(mma9551_runtime_suspend,
+			   mma9551_runtime_resume, NULL)
+};
+
+static const struct acpi_device_id mma9551_acpi_match[] = {
+	{"MMA9551", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match);
+
+static const struct i2c_device_id mma9551_id[] = {
+	{"mma9551", 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, mma9551_id);
+
+static struct i2c_driver mma9551_driver = {
+	.driver = {
+		   .name = MMA9551_DRV_NAME,
+		   .acpi_match_table = ACPI_PTR(mma9551_acpi_match),
+		   .pm = &mma9551_pm_ops,
+		   },
+	.probe = mma9551_probe,
+	.remove = mma9551_remove,
+	.id_table = mma9551_id,
+};
+
+module_i2c_driver(mma9551_driver);
+
+MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
+MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MMA9551L motion-sensing platform driver");
diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c
new file mode 100644
index 000000000000..7f55a6d7cd03
--- /dev/null
+++ b/drivers/iio/accel/mma9551_core.c
@@ -0,0 +1,798 @@
+/*
+ * Common code for Freescale MMA955x Intelligent Sensor Platform drivers
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/iio/iio.h>
+#include <linux/pm_runtime.h>
+#include "mma9551_core.h"
+
+/* Command masks for mailbox write command */
+#define MMA9551_CMD_READ_VERSION_INFO	0x00
+#define MMA9551_CMD_READ_CONFIG		0x10
+#define MMA9551_CMD_WRITE_CONFIG	0x20
+#define MMA9551_CMD_READ_STATUS		0x30
+
+/* Mailbox read command */
+#define MMA9551_RESPONSE_COCO		BIT(7)
+
+/* Error-Status codes returned in mailbox read command */
+#define MMA9551_MCI_ERROR_NONE			0x00
+#define MMA9551_MCI_ERROR_PARAM			0x04
+#define MMA9551_MCI_INVALID_COUNT		0x19
+#define MMA9551_MCI_ERROR_COMMAND		0x1C
+#define MMA9551_MCI_ERROR_INVALID_LENGTH	0x21
+#define MMA9551_MCI_ERROR_FIFO_BUSY		0x22
+#define MMA9551_MCI_ERROR_FIFO_ALLOCATED	0x23
+#define MMA9551_MCI_ERROR_FIFO_OVERSIZE		0x24
+
+/* GPIO Application */
+#define MMA9551_GPIO_POL_MSB		0x08
+#define MMA9551_GPIO_POL_LSB		0x09
+
+/* Sleep/Wake application */
+#define MMA9551_SLEEP_CFG		0x06
+#define MMA9551_SLEEP_CFG_SNCEN		BIT(0)
+#define MMA9551_SLEEP_CFG_FLEEN		BIT(1)
+#define MMA9551_SLEEP_CFG_SCHEN		BIT(2)
+
+/* AFE application */
+#define MMA9551_AFE_X_ACCEL_REG		0x00
+#define MMA9551_AFE_Y_ACCEL_REG		0x02
+#define MMA9551_AFE_Z_ACCEL_REG		0x04
+
+/* Reset/Suspend/Clear application */
+#define MMA9551_RSC_RESET		0x00
+#define MMA9551_RSC_OFFSET(mask)	(3 - (ffs(mask) - 1) / 8)
+#define MMA9551_RSC_VAL(mask)		(mask >> (((ffs(mask) - 1) / 8) * 8))
+
+/*
+ * A response is composed of:
+ * - control registers: MB0-3
+ * - data registers: MB4-31
+ *
+ * A request is composed of:
+ * - mbox to write to (always 0)
+ * - control registers: MB1-4
+ * - data registers: MB5-31
+ */
+#define MMA9551_MAILBOX_CTRL_REGS	4
+#define MMA9551_MAX_MAILBOX_DATA_REGS	28
+#define MMA9551_MAILBOX_REGS		32
+
+#define MMA9551_I2C_READ_RETRIES	5
+#define MMA9551_I2C_READ_DELAY	50	/* us */
+
+struct mma9551_mbox_request {
+	u8 start_mbox;		/* Always 0. */
+	u8 app_id;
+	/*
+	 * See Section 5.3.1 of the MMA955xL Software Reference Manual.
+	 *
+	 * Bit 7: reserved, always 0
+	 * Bits 6-4: command
+	 * Bits 3-0: upper bits of register offset
+	 */
+	u8 cmd_off;
+	u8 lower_off;
+	u8 nbytes;
+	u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS - 1];
+} __packed;
+
+struct mma9551_mbox_response {
+	u8 app_id;
+	/*
+	 * See Section 5.3.3 of the MMA955xL Software Reference Manual.
+	 *
+	 * Bit 7: COCO
+	 * Bits 6-0: Error code.
+	 */
+	u8 coco_err;
+	u8 nbytes;
+	u8 req_bytes;
+	u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+} __packed;
+
+struct mma9551_version_info {
+	__be32 device_id;
+	u8 rom_version[2];
+	u8 fw_version[2];
+	u8 hw_version[2];
+	u8 fw_build[2];
+};
+
+static int mma9551_transfer(struct i2c_client *client,
+			    u8 app_id, u8 command, u16 offset,
+			    u8 *inbytes, int num_inbytes,
+			    u8 *outbytes, int num_outbytes)
+{
+	struct mma9551_mbox_request req;
+	struct mma9551_mbox_response rsp;
+	struct i2c_msg in, out;
+	u8 req_len, err_code;
+	int ret, retries;
+
+	if (offset >= 1 << 12) {
+		dev_err(&client->dev, "register offset too large\n");
+		return -EINVAL;
+	}
+
+	req_len = 1 + MMA9551_MAILBOX_CTRL_REGS + num_inbytes;
+	req.start_mbox = 0;
+	req.app_id = app_id;
+	req.cmd_off = command | (offset >> 8);
+	req.lower_off = offset;
+
+	if (command == MMA9551_CMD_WRITE_CONFIG)
+		req.nbytes = num_inbytes;
+	else
+		req.nbytes = num_outbytes;
+	if (num_inbytes)
+		memcpy(req.buf, inbytes, num_inbytes);
+
+	out.addr = client->addr;
+	out.flags = 0;
+	out.len = req_len;
+	out.buf = (u8 *)&req;
+
+	ret = i2c_transfer(client->adapter, &out, 1);
+	if (ret < 0) {
+		dev_err(&client->dev, "i2c write failed\n");
+		return ret;
+	}
+
+	retries = MMA9551_I2C_READ_RETRIES;
+	do {
+		udelay(MMA9551_I2C_READ_DELAY);
+
+		in.addr = client->addr;
+		in.flags = I2C_M_RD;
+		in.len = sizeof(rsp);
+		in.buf = (u8 *)&rsp;
+
+		ret = i2c_transfer(client->adapter, &in, 1);
+		if (ret < 0) {
+			dev_err(&client->dev, "i2c read failed\n");
+			return ret;
+		}
+
+		if (rsp.coco_err & MMA9551_RESPONSE_COCO)
+			break;
+	} while (--retries > 0);
+
+	if (retries == 0) {
+		dev_err(&client->dev,
+			"timed out while waiting for command response\n");
+		return -ETIMEDOUT;
+	}
+
+	if (rsp.app_id != app_id) {
+		dev_err(&client->dev,
+			"app_id mismatch in response got %02x expected %02x\n",
+			rsp.app_id, app_id);
+		return -EINVAL;
+	}
+
+	err_code = rsp.coco_err & ~MMA9551_RESPONSE_COCO;
+	if (err_code != MMA9551_MCI_ERROR_NONE) {
+		dev_err(&client->dev, "read returned error %x\n", err_code);
+		return -EINVAL;
+	}
+
+	if (rsp.nbytes != rsp.req_bytes) {
+		dev_err(&client->dev,
+			"output length mismatch got %d expected %d\n",
+			rsp.nbytes, rsp.req_bytes);
+		return -EINVAL;
+	}
+
+	if (num_outbytes)
+		memcpy(outbytes, rsp.buf, num_outbytes);
+
+	return 0;
+}
+
+/**
+ * mma9551_read_config_byte() - read 1 configuration byte
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @val:	Pointer to store value read
+ *
+ * Read one configuration byte from the device using MMA955xL command format.
+ * Commands to the MMA955xL platform consist of a write followed
+ * by one or more reads.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_read_config_byte(struct i2c_client *client, u8 app_id,
+			     u16 reg, u8 *val)
+{
+	return mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
+				reg, NULL, 0, val, 1);
+}
+EXPORT_SYMBOL(mma9551_read_config_byte);
+
+/**
+ * mma9551_write_config_byte() - write 1 configuration byte
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @val:	Value to write
+ *
+ * Write one configuration byte from the device using MMA955xL command format.
+ * Commands to the MMA955xL platform consist of a write followed by one or
+ * more reads.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
+			      u16 reg, u8 val)
+{
+	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
+				&val, 1, NULL, 0);
+}
+EXPORT_SYMBOL(mma9551_write_config_byte);
+
+/**
+ * mma9551_read_status_byte() - read 1 status byte
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @val:	Pointer to store value read
+ *
+ * Read one status byte from the device using MMA955xL command format.
+ * Commands to the MMA955xL platform consist of a write followed by one or
+ * more reads.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
+			     u16 reg, u8 *val)
+{
+	return mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
+				reg, NULL, 0, val, 1);
+}
+EXPORT_SYMBOL(mma9551_read_status_byte);
+
+/**
+ * mma9551_read_config_word() - read 1 config word
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @val:	Pointer to store value read
+ *
+ * Read one configuration word from the device using MMA955xL command format.
+ * Commands to the MMA955xL platform consist of a write followed by one or
+ * more reads.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
+			    u16 reg, u16 *val)
+{
+	int ret;
+	__be16 v;
+
+	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
+			       reg, NULL, 0, (u8 *)&v, 2);
+	*val = be16_to_cpu(v);
+
+	return ret;
+}
+EXPORT_SYMBOL(mma9551_read_config_word);
+
+/**
+ * mma9551_write_config_word() - write 1 config word
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @val:	Value to write
+ *
+ * Write one configuration word from the device using MMA955xL command format.
+ * Commands to the MMA955xL platform consist of a write followed by one or
+ * more reads.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
+			     u16 reg, u16 val)
+{
+	__be16 v = cpu_to_be16(val);
+
+	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
+				(u8 *) &v, 2, NULL, 0);
+}
+EXPORT_SYMBOL(mma9551_write_config_word);
+
+/**
+ * mma9551_read_status_word() - read 1 status word
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @val:	Pointer to store value read
+ *
+ * Read one status word from the device using MMA955xL command format.
+ * Commands to the MMA955xL platform consist of a write followed by one or
+ * more reads.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
+			     u16 reg, u16 *val)
+{
+	int ret;
+	__be16 v;
+
+	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
+			       reg, NULL, 0, (u8 *)&v, 2);
+	*val = be16_to_cpu(v);
+
+	return ret;
+}
+EXPORT_SYMBOL(mma9551_read_status_word);
+
+/**
+ * mma9551_read_config_words() - read multiple config words
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @len:	Length of array to read in bytes
+ * @val:	Array of words to read
+ *
+ * Read multiple configuration registers (word-sized registers).
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
+			     u16 reg, u8 len, u16 *buf)
+{
+	int ret, i;
+	int len_words = len / sizeof(u16);
+	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+
+	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
+			       reg, NULL, 0, (u8 *) be_buf, len);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < len_words; i++)
+		buf[i] = be16_to_cpu(be_buf[i]);
+
+	return 0;
+}
+EXPORT_SYMBOL(mma9551_read_config_words);
+
+/**
+ * mma9551_read_status_words() - read multiple status words
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @len:	Length of array to read in bytes
+ * @val:	Array of words to read
+ *
+ * Read multiple status registers (word-sized registers).
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
+			      u16 reg, u8 len, u16 *buf)
+{
+	int ret, i;
+	int len_words = len / sizeof(u16);
+	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+
+	ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
+			       reg, NULL, 0, (u8 *) be_buf, len);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < len_words; i++)
+		buf[i] = be16_to_cpu(be_buf[i]);
+
+	return 0;
+}
+EXPORT_SYMBOL(mma9551_read_status_words);
+
+/**
+ * mma9551_write_config_words() - write multiple config words
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @len:	Length of array to write in bytes
+ * @val:	Array of words to write
+ *
+ * Write multiple configuration registers (word-sized registers).
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
+			       u16 reg, u8 len, u16 *buf)
+{
+	int i;
+	int len_words = len / sizeof(u16);
+	__be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS];
+
+	for (i = 0; i < len_words; i++)
+		be_buf[i] = cpu_to_be16(buf[i]);
+
+	return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
+				reg, (u8 *) be_buf, len, NULL, 0);
+}
+EXPORT_SYMBOL(mma9551_write_config_words);
+
+/**
+ * mma9551_update_config_bits() - update bits in register
+ * @client:	I2C client
+ * @app_id:	Application ID
+ * @reg:	Application register
+ * @mask:	Mask for the bits to update
+ * @val:	Value of the bits to update
+ *
+ * Update bits in the given register using a bit mask.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,
+			       u16 reg, u8 mask, u8 val)
+{
+	int ret;
+	u8 tmp, orig;
+
+	ret = mma9551_read_config_byte(client, app_id, reg, &orig);
+	if (ret < 0)
+		return ret;
+
+	tmp = orig & ~mask;
+	tmp |= val & mask;
+
+	if (tmp == orig)
+		return 0;
+
+	return mma9551_write_config_byte(client, app_id, reg, tmp);
+}
+EXPORT_SYMBOL(mma9551_update_config_bits);
+
+/**
+ * mma9551_gpio_config() - configure gpio
+ * @client:	I2C client
+ * @pin:	GPIO pin to configure
+ * @app_id:	Application ID
+ * @bitnum:	Bit number of status register being assigned to the GPIO pin.
+ * @polarity:	The polarity parameter is described in section 6.2.2, page 66,
+ *		of the Software Reference Manual.  Basically, polarity=0 means
+ *		the interrupt line has the same value as the selected bit,
+ *		while polarity=1 means the line is inverted.
+ *
+ * Assign a bit from an application’s status register to a specific GPIO pin.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,
+			u8 app_id, u8 bitnum, int polarity)
+{
+	u8 reg, pol_mask, pol_val;
+	int ret;
+
+	if (pin > mma9551_gpio_max) {
+		dev_err(&client->dev, "bad GPIO pin\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Pin 6 is configured by regs 0x00 and 0x01, pin 7 by 0x02 and
+	 * 0x03, and so on.
+	 */
+	reg = pin * 2;
+
+	ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
+					reg, app_id);
+	if (ret < 0) {
+		dev_err(&client->dev, "error setting GPIO app_id\n");
+		return ret;
+	}
+
+	ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
+					reg + 1, bitnum);
+	if (ret < 0) {
+		dev_err(&client->dev, "error setting GPIO bit number\n");
+		return ret;
+	}
+
+	switch (pin) {
+	case mma9551_gpio6:
+		reg = MMA9551_GPIO_POL_LSB;
+		pol_mask = 1 << 6;
+		break;
+	case mma9551_gpio7:
+		reg = MMA9551_GPIO_POL_LSB;
+		pol_mask = 1 << 7;
+		break;
+	case mma9551_gpio8:
+		reg = MMA9551_GPIO_POL_MSB;
+		pol_mask = 1 << 0;
+		break;
+	case mma9551_gpio9:
+		reg = MMA9551_GPIO_POL_MSB;
+		pol_mask = 1 << 1;
+		break;
+	}
+	pol_val = polarity ? pol_mask : 0;
+
+	ret = mma9551_update_config_bits(client, MMA9551_APPID_GPIO, reg,
+					 pol_mask, pol_val);
+	if (ret < 0)
+		dev_err(&client->dev, "error setting GPIO polarity\n");
+
+	return ret;
+}
+EXPORT_SYMBOL(mma9551_gpio_config);
+
+/**
+ * mma9551_read_version() - read device version information
+ * @client:	I2C client
+ *
+ * Read version information and print device id and firmware version.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_read_version(struct i2c_client *client)
+{
+	struct mma9551_version_info info;
+	int ret;
+
+	ret = mma9551_transfer(client, MMA9551_APPID_VERSION, 0x00, 0x00,
+			       NULL, 0, (u8 *)&info, sizeof(info));
+	if (ret < 0)
+		return ret;
+
+	dev_info(&client->dev, "device ID 0x%x, firmware version %02x.%02x\n",
+		 be32_to_cpu(info.device_id), info.fw_version[0],
+		 info.fw_version[1]);
+
+	return 0;
+}
+EXPORT_SYMBOL(mma9551_read_version);
+
+/**
+ * mma9551_set_device_state() - sets HW power mode
+ * @client:	I2C client
+ * @enable:	Use true to power on device, false to cause the device
+ *		to enter sleep.
+ *
+ * Set power on/off for device using the Sleep/Wake Application.
+ * When enable is true, power on chip and enable doze mode.
+ * When enable is false, enter sleep mode (device remains in the
+ * lowest-power mode).
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_set_device_state(struct i2c_client *client, bool enable)
+{
+	return mma9551_update_config_bits(client, MMA9551_APPID_SLEEP_WAKE,
+					  MMA9551_SLEEP_CFG,
+					  MMA9551_SLEEP_CFG_SNCEN |
+					  MMA9551_SLEEP_CFG_FLEEN |
+					  MMA9551_SLEEP_CFG_SCHEN,
+					  enable ? MMA9551_SLEEP_CFG_SCHEN |
+					  MMA9551_SLEEP_CFG_FLEEN :
+					  MMA9551_SLEEP_CFG_SNCEN);
+}
+EXPORT_SYMBOL(mma9551_set_device_state);
+
+/**
+ * mma9551_set_power_state() - sets runtime PM state
+ * @client:	I2C client
+ * @on:		Use true to power on device, false to power off
+ *
+ * Resume or suspend the device using Runtime PM.
+ * The device will suspend after the autosuspend delay.
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_set_power_state(struct i2c_client *client, bool on)
+{
+#ifdef CONFIG_PM
+	int ret;
+
+	if (on)
+		ret = pm_runtime_get_sync(&client->dev);
+	else {
+		pm_runtime_mark_last_busy(&client->dev);
+		ret = pm_runtime_put_autosuspend(&client->dev);
+	}
+
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"failed to change power state to %d\n", on);
+		if (on)
+			pm_runtime_put_noidle(&client->dev);
+
+		return ret;
+	}
+#endif
+
+	return 0;
+}
+EXPORT_SYMBOL(mma9551_set_power_state);
+
+/**
+ * mma9551_sleep() - sleep
+ * @freq:	Application frequency
+ *
+ * Firmware applications run at a certain frequency on the
+ * device. Sleep for one application cycle to make sure the
+ * application had time to run once and initialize set values.
+ */
+void mma9551_sleep(int freq)
+{
+	int sleep_val = 1000 / freq;
+
+	if (sleep_val < 20)
+		usleep_range(sleep_val * 1000, 20000);
+	else
+		msleep_interruptible(sleep_val);
+}
+EXPORT_SYMBOL(mma9551_sleep);
+
+/**
+ * mma9551_read_accel_chan() - read accelerometer channel
+ * @client:	I2C client
+ * @chan:	IIO channel
+ * @val:	Pointer to the accelerometer value read
+ * @val2:	Unused
+ *
+ * Read accelerometer value for the specified channel.
+ *
+ * Locking note: This function must be called with the device lock held.
+ * Locking is not handled inside the function. Callers should ensure they
+ * serialize access to the HW.
+ *
+ * Returns: IIO_VAL_INT on success, negative value on failure.
+ */
+int mma9551_read_accel_chan(struct i2c_client *client,
+			    const struct iio_chan_spec *chan,
+			    int *val, int *val2)
+{
+	u16 reg_addr;
+	s16 raw_accel;
+	int ret;
+
+	switch (chan->channel2) {
+	case IIO_MOD_X:
+		reg_addr = MMA9551_AFE_X_ACCEL_REG;
+		break;
+	case IIO_MOD_Y:
+		reg_addr = MMA9551_AFE_Y_ACCEL_REG;
+		break;
+	case IIO_MOD_Z:
+		reg_addr = MMA9551_AFE_Z_ACCEL_REG;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = mma9551_set_power_state(client, true);
+	if (ret < 0)
+		return ret;
+
+	ret = mma9551_read_status_word(client, MMA9551_APPID_AFE,
+				       reg_addr, &raw_accel);
+	if (ret < 0)
+		goto out_poweroff;
+
+	*val = raw_accel;
+
+	ret = IIO_VAL_INT;
+
+out_poweroff:
+	mma9551_set_power_state(client, false);
+	return ret;
+}
+EXPORT_SYMBOL(mma9551_read_accel_chan);
+
+/**
+ * mma9551_read_accel_scale() - read accelerometer scale
+ * @val:	Pointer to the accelerometer scale (int value)
+ * @val2:	Pointer to the accelerometer scale (micro value)
+ *
+ * Read accelerometer scale.
+ *
+ * Returns: IIO_VAL_INT_PLUS_MICRO.
+ */
+int mma9551_read_accel_scale(int *val, int *val2)
+{
+	*val = 0;
+	*val2 = 2440;
+
+	return IIO_VAL_INT_PLUS_MICRO;
+}
+EXPORT_SYMBOL(mma9551_read_accel_scale);
+
+/**
+ * mma9551_app_reset() - reset application
+ * @client:	I2C client
+ * @app_mask:	Application to reset
+ *
+ * Reset the given application (using the Reset/Suspend/Clear
+ * Control Application)
+ *
+ * Returns: 0 on success, negative value on failure.
+ */
+int mma9551_app_reset(struct i2c_client *client, u32 app_mask)
+{
+	return mma9551_write_config_byte(client, MMA9551_APPID_RCS,
+					 MMA9551_RSC_RESET +
+					 MMA9551_RSC_OFFSET(app_mask),
+					 MMA9551_RSC_VAL(app_mask));
+}
+EXPORT_SYMBOL(mma9551_app_reset);
+
+MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
+MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MMA955xL sensors core");
diff --git a/drivers/iio/accel/mma9551_core.h b/drivers/iio/accel/mma9551_core.h
new file mode 100644
index 000000000000..edaa56b1078e
--- /dev/null
+++ b/drivers/iio/accel/mma9551_core.h
@@ -0,0 +1,81 @@
+/*
+ * Common code for Freescale MMA955x Intelligent Sensor Platform drivers
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _MMA9551_CORE_H_
+#define _MMA9551_CORE_H_
+
+/* Applications IDs */
+#define MMA9551_APPID_VERSION		0x00
+#define MMA9551_APPID_GPIO		0x03
+#define MMA9551_APPID_AFE		0x06
+#define MMA9551_APPID_TILT		0x0B
+#define MMA9551_APPID_SLEEP_WAKE	0x12
+#define MMA9551_APPID_PEDOMETER	        0x15
+#define MMA9551_APPID_RCS		0x17
+#define MMA9551_APPID_NONE		0xff
+
+/* Reset/Suspend/Clear application app masks */
+#define MMA9551_RSC_PED			BIT(21)
+
+#define MMA9551_AUTO_SUSPEND_DELAY_MS	2000
+
+enum mma9551_gpio_pin {
+	mma9551_gpio6 = 0,
+	mma9551_gpio7,
+	mma9551_gpio8,
+	mma9551_gpio9,
+	mma9551_gpio_max = mma9551_gpio9,
+};
+
+#define MMA9551_ACCEL_CHANNEL(axis) {				\
+	.type = IIO_ACCEL,					\
+	.modified = 1,						\
+	.channel2 = axis,					\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
+}
+
+int mma9551_read_config_byte(struct i2c_client *client, u8 app_id,
+			     u16 reg, u8 *val);
+int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
+			      u16 reg, u8 val);
+int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
+			     u16 reg, u8 *val);
+int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
+			    u16 reg, u16 *val);
+int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
+			     u16 reg, u16 val);
+int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
+			     u16 reg, u16 *val);
+int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
+			     u16 reg, u8 len, u16 *buf);
+int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
+			      u16 reg, u8 len, u16 *buf);
+int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
+			       u16 reg, u8 len, u16 *buf);
+int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,
+			       u16 reg, u8 mask, u8 val);
+int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,
+			u8 app_id, u8 bitnum, int polarity);
+int mma9551_read_version(struct i2c_client *client);
+int mma9551_set_device_state(struct i2c_client *client, bool enable);
+int mma9551_set_power_state(struct i2c_client *client, bool on);
+void mma9551_sleep(int freq);
+int mma9551_read_accel_chan(struct i2c_client *client,
+			    const struct iio_chan_spec *chan,
+			    int *val, int *val2);
+int mma9551_read_accel_scale(int *val, int *val2);
+int mma9551_app_reset(struct i2c_client *client, u32 app_mask);
+
+#endif /* _MMA9551_CORE_H_ */
diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c
new file mode 100644
index 000000000000..d23ebf192f63
--- /dev/null
+++ b/drivers/iio/accel/mma9553.c
@@ -0,0 +1,1334 @@
+/*
+ * Freescale MMA9553L Intelligent Pedometer driver
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+#include <linux/pm_runtime.h>
+#include "mma9551_core.h"
+
+#define MMA9553_DRV_NAME			"mma9553"
+#define MMA9553_IRQ_NAME			"mma9553_event"
+#define MMA9553_GPIO_NAME			"mma9553_int"
+
+/* Pedometer configuration registers (R/W) */
+#define MMA9553_REG_CONF_SLEEPMIN		0x00
+#define MMA9553_REG_CONF_SLEEPMAX		0x02
+#define MMA9553_REG_CONF_SLEEPTHD		0x04
+#define MMA9553_MASK_CONF_WORD			GENMASK(15, 0)
+
+#define MMA9553_REG_CONF_CONF_STEPLEN		0x06
+#define MMA9553_MASK_CONF_CONFIG		BIT(15)
+#define MMA9553_MASK_CONF_ACT_DBCNTM		BIT(14)
+#define MMA9553_MASK_CONF_SLP_DBCNTM		BIT(13)
+#define MMA9553_MASK_CONF_STEPLEN		GENMASK(7, 0)
+
+#define MMA9553_REG_CONF_HEIGHT_WEIGHT		0x08
+#define MMA9553_MASK_CONF_HEIGHT		GENMASK(15, 8)
+#define MMA9553_MASK_CONF_WEIGHT		GENMASK(7, 0)
+
+#define MMA9553_REG_CONF_FILTER			0x0A
+#define MMA9553_MASK_CONF_FILTSTEP		GENMASK(15, 8)
+#define MMA9553_MASK_CONF_MALE			BIT(7)
+#define MMA9553_MASK_CONF_FILTTIME		GENMASK(6, 0)
+
+#define MMA9553_REG_CONF_SPEED_STEP		0x0C
+#define MMA9553_MASK_CONF_SPDPRD		GENMASK(15, 8)
+#define MMA9553_MASK_CONF_STEPCOALESCE		GENMASK(7, 0)
+
+#define MMA9553_REG_CONF_ACTTHD			0x0E
+
+/* Pedometer status registers (R-only) */
+#define MMA9553_REG_STATUS			0x00
+#define MMA9553_MASK_STATUS_MRGFL		BIT(15)
+#define MMA9553_MASK_STATUS_SUSPCHG		BIT(14)
+#define MMA9553_MASK_STATUS_STEPCHG		BIT(13)
+#define MMA9553_MASK_STATUS_ACTCHG		BIT(12)
+#define MMA9553_MASK_STATUS_SUSP		BIT(11)
+#define MMA9553_MASK_STATUS_ACTIVITY		(BIT(10) | BIT(9) | BIT(8))
+#define MMA9553_MASK_STATUS_VERSION		0x00FF
+
+#define MMA9553_REG_STEPCNT			0x02
+#define MMA9553_REG_DISTANCE			0x04
+#define MMA9553_REG_SPEED			0x06
+#define MMA9553_REG_CALORIES			0x08
+#define MMA9553_REG_SLEEPCNT			0x0A
+
+/* Pedometer events are always mapped to this pin. */
+#define MMA9553_DEFAULT_GPIO_PIN	mma9551_gpio6
+#define MMA9553_DEFAULT_GPIO_POLARITY	0
+
+/* Bitnum used for gpio configuration = bit number in high status byte */
+#define STATUS_TO_BITNUM(bit)		(ffs(bit) - 9)
+
+#define MMA9553_DEFAULT_SAMPLE_RATE	30	/* Hz */
+
+/*
+ * The internal activity level must be stable for ACTTHD samples before
+ * ACTIVITY is updated.The ACTIVITY variable contains the current activity
+ * level and is updated every time a step is detected or once a second
+ * if there are no steps.
+ */
+#define MMA9553_ACTIVITY_THD_TO_SEC(thd) ((thd) / MMA9553_DEFAULT_SAMPLE_RATE)
+#define MMA9553_ACTIVITY_SEC_TO_THD(sec) ((sec) * MMA9553_DEFAULT_SAMPLE_RATE)
+
+/*
+ * Autonomously suspend pedometer if acceleration vector magnitude
+ * is near 1g (4096 at 0.244 mg/LSB resolution) for 30 seconds.
+ */
+#define MMA9553_DEFAULT_SLEEPMIN	3688	/* 0,9 g */
+#define MMA9553_DEFAULT_SLEEPMAX	4508	/* 1,1 g */
+#define MMA9553_DEFAULT_SLEEPTHD	(MMA9553_DEFAULT_SAMPLE_RATE * 30)
+
+#define MMA9553_CONFIG_RETRIES		2
+
+/* Status register - activity field  */
+enum activity_level {
+	ACTIVITY_UNKNOWN,
+	ACTIVITY_REST,
+	ACTIVITY_WALKING,
+	ACTIVITY_JOGGING,
+	ACTIVITY_RUNNING,
+};
+
+static struct mma9553_event_info {
+	enum iio_chan_type type;
+	enum iio_modifier mod;
+	enum iio_event_direction dir;
+} mma9553_events_info[] = {
+	{
+		.type = IIO_STEPS,
+		.mod = IIO_NO_MOD,
+		.dir = IIO_EV_DIR_NONE,
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.mod = IIO_MOD_STILL,
+		.dir = IIO_EV_DIR_RISING,
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.mod = IIO_MOD_STILL,
+		.dir = IIO_EV_DIR_FALLING,
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.mod = IIO_MOD_WALKING,
+		.dir = IIO_EV_DIR_RISING,
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.mod = IIO_MOD_WALKING,
+		.dir = IIO_EV_DIR_FALLING,
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.mod = IIO_MOD_JOGGING,
+		.dir = IIO_EV_DIR_RISING,
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.mod = IIO_MOD_JOGGING,
+		.dir = IIO_EV_DIR_FALLING,
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.mod = IIO_MOD_RUNNING,
+		.dir = IIO_EV_DIR_RISING,
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.mod = IIO_MOD_RUNNING,
+		.dir = IIO_EV_DIR_FALLING,
+	},
+};
+
+#define MMA9553_EVENTS_INFO_SIZE ARRAY_SIZE(mma9553_events_info)
+
+struct mma9553_event {
+	struct mma9553_event_info *info;
+	bool enabled;
+};
+
+struct mma9553_conf_regs {
+	u16 sleepmin;
+	u16 sleepmax;
+	u16 sleepthd;
+	u16 config;
+	u16 height_weight;
+	u16 filter;
+	u16 speed_step;
+	u16 actthd;
+} __packed;
+
+struct mma9553_data {
+	struct i2c_client *client;
+	struct mutex mutex;
+	struct mma9553_conf_regs conf;
+	struct mma9553_event events[MMA9553_EVENTS_INFO_SIZE];
+	int num_events;
+	u8 gpio_bitnum;
+	/*
+	 * This is used for all features that depend on step count:
+	 * step count, distance, speed, calories.
+	 */
+	bool stepcnt_enabled;
+	u16 stepcnt;
+	u8 activity;
+	s64 timestamp;
+};
+
+static u8 mma9553_get_bits(u16 val, u16 mask)
+{
+	return (val & mask) >> (ffs(mask) - 1);
+}
+
+static u16 mma9553_set_bits(u16 current_val, u16 val, u16 mask)
+{
+	return (current_val & ~mask) | (val << (ffs(mask) - 1));
+}
+
+static enum iio_modifier mma9553_activity_to_mod(enum activity_level activity)
+{
+	switch (activity) {
+	case ACTIVITY_RUNNING:
+		return IIO_MOD_RUNNING;
+	case ACTIVITY_JOGGING:
+		return IIO_MOD_JOGGING;
+	case ACTIVITY_WALKING:
+		return IIO_MOD_WALKING;
+	case ACTIVITY_REST:
+		return IIO_MOD_STILL;
+	case ACTIVITY_UNKNOWN:
+	default:
+		return IIO_NO_MOD;
+	}
+}
+
+static void mma9553_init_events(struct mma9553_data *data)
+{
+	int i;
+
+	data->num_events = MMA9553_EVENTS_INFO_SIZE;
+	for (i = 0; i < data->num_events; i++) {
+		data->events[i].info = &mma9553_events_info[i];
+		data->events[i].enabled = false;
+	}
+}
+
+static struct mma9553_event *mma9553_get_event(struct mma9553_data *data,
+					       enum iio_chan_type type,
+					       enum iio_modifier mod,
+					       enum iio_event_direction dir)
+{
+	int i;
+
+	for (i = 0; i < data->num_events; i++)
+		if (data->events[i].info->type == type &&
+		    data->events[i].info->mod == mod &&
+		    data->events[i].info->dir == dir)
+			return &data->events[i];
+
+	return NULL;
+}
+
+static bool mma9553_is_any_event_enabled(struct mma9553_data *data,
+					 bool check_type,
+					 enum iio_chan_type type)
+{
+	int i;
+
+	for (i = 0; i < data->num_events; i++)
+		if ((check_type && data->events[i].info->type == type &&
+		     data->events[i].enabled) ||
+		     (!check_type && data->events[i].enabled))
+			return true;
+
+	return false;
+}
+
+static int mma9553_set_config(struct mma9553_data *data, u16 reg,
+			      u16 *p_reg_val, u16 val, u16 mask)
+{
+	int ret, retries;
+	u16 reg_val, config;
+
+	reg_val = *p_reg_val;
+	if (val == mma9553_get_bits(reg_val, mask))
+		return 0;
+
+	reg_val = mma9553_set_bits(reg_val, val, mask);
+	ret = mma9551_write_config_word(data->client, MMA9551_APPID_PEDOMETER,
+					reg, reg_val);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"error writing config register 0x%x\n", reg);
+		return ret;
+	}
+
+	*p_reg_val = reg_val;
+
+	/* Reinitializes the pedometer with current configuration values */
+	config = mma9553_set_bits(data->conf.config, 1,
+				  MMA9553_MASK_CONF_CONFIG);
+
+	ret = mma9551_write_config_word(data->client, MMA9551_APPID_PEDOMETER,
+					MMA9553_REG_CONF_CONF_STEPLEN, config);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"error writing config register 0x%x\n",
+			MMA9553_REG_CONF_CONF_STEPLEN);
+		return ret;
+	}
+
+	retries = MMA9553_CONFIG_RETRIES;
+	do {
+		mma9551_sleep(MMA9553_DEFAULT_SAMPLE_RATE);
+		ret = mma9551_read_config_word(data->client,
+					       MMA9551_APPID_PEDOMETER,
+					       MMA9553_REG_CONF_CONF_STEPLEN,
+					       &config);
+		if (ret < 0)
+			return ret;
+	} while (mma9553_get_bits(config, MMA9553_MASK_CONF_CONFIG) &&
+		 --retries > 0);
+
+	return 0;
+}
+
+static int mma9553_read_activity_stepcnt(struct mma9553_data *data,
+					 u8 *activity, u16 *stepcnt)
+{
+	u32 status_stepcnt;
+	u16 status;
+	int ret;
+
+	ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER,
+					MMA9553_REG_STATUS, sizeof(u32),
+					(u16 *) &status_stepcnt);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"error reading status and stepcnt\n");
+		return ret;
+	}
+
+	status = status_stepcnt & MMA9553_MASK_CONF_WORD;
+	*activity = mma9553_get_bits(status, MMA9553_MASK_STATUS_ACTIVITY);
+	*stepcnt = status_stepcnt >> 16;
+
+	return 0;
+}
+
+static int mma9553_conf_gpio(struct mma9553_data *data)
+{
+	u8 bitnum = 0, appid = MMA9551_APPID_PEDOMETER;
+	int ret;
+	struct mma9553_event *ev_step_detect;
+	bool activity_enabled;
+
+	activity_enabled =
+	    mma9553_is_any_event_enabled(data, true, IIO_ACTIVITY);
+	ev_step_detect =
+	    mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE);
+
+	/*
+	 * If both step detector and activity are enabled, use the MRGFL bit.
+	 * This bit is the logical OR of the SUSPCHG, STEPCHG, and ACTCHG flags.
+	 */
+	if (activity_enabled && ev_step_detect->enabled)
+		bitnum = STATUS_TO_BITNUM(MMA9553_MASK_STATUS_MRGFL);
+	else if (ev_step_detect->enabled)
+		bitnum = STATUS_TO_BITNUM(MMA9553_MASK_STATUS_STEPCHG);
+	else if (activity_enabled)
+		bitnum = STATUS_TO_BITNUM(MMA9553_MASK_STATUS_ACTCHG);
+	else			/* Reset */
+		appid = MMA9551_APPID_NONE;
+
+	if (data->gpio_bitnum == bitnum)
+		return 0;
+
+	/* Save initial values for activity and stepcnt */
+	if (activity_enabled || ev_step_detect->enabled)
+		mma9553_read_activity_stepcnt(data, &data->activity,
+					      &data->stepcnt);
+
+	ret = mma9551_gpio_config(data->client,
+				  MMA9553_DEFAULT_GPIO_PIN,
+				  appid, bitnum, MMA9553_DEFAULT_GPIO_POLARITY);
+	if (ret < 0)
+		return ret;
+	data->gpio_bitnum = bitnum;
+
+	return 0;
+}
+
+static int mma9553_init(struct mma9553_data *data)
+{
+	int ret;
+
+	ret = mma9551_read_version(data->client);
+	if (ret)
+		return ret;
+
+	/*
+	 * Read all the pedometer configuration registers. This is used as
+	 * a device identification command to differentiate the MMA9553L
+	 * from the MMA9550L.
+	 */
+	ret =
+	    mma9551_read_config_words(data->client, MMA9551_APPID_PEDOMETER,
+				      MMA9553_REG_CONF_SLEEPMIN,
+				      sizeof(data->conf), (u16 *) &data->conf);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"device is not MMA9553L: failed to read cfg regs\n");
+		return ret;
+	}
+
+
+	/* Reset gpio */
+	data->gpio_bitnum = -1;
+	ret = mma9553_conf_gpio(data);
+	if (ret < 0)
+		return ret;
+
+	ret = mma9551_app_reset(data->client, MMA9551_RSC_PED);
+	if (ret < 0)
+		return ret;
+
+	/* Init config registers */
+	data->conf.sleepmin = MMA9553_DEFAULT_SLEEPMIN;
+	data->conf.sleepmax = MMA9553_DEFAULT_SLEEPMAX;
+	data->conf.sleepthd = MMA9553_DEFAULT_SLEEPTHD;
+	data->conf.config =
+	    mma9553_set_bits(data->conf.config, 1, MMA9553_MASK_CONF_CONFIG);
+	/*
+	 * Clear the activity debounce counter when the activity level changes,
+	 * so that the confidence level applies for any activity level.
+	 */
+	data->conf.config = mma9553_set_bits(data->conf.config, 1,
+					     MMA9553_MASK_CONF_ACT_DBCNTM);
+	ret =
+	    mma9551_write_config_words(data->client, MMA9551_APPID_PEDOMETER,
+				       MMA9553_REG_CONF_SLEEPMIN,
+				       sizeof(data->conf), (u16 *) &data->conf);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"failed to write configuration registers\n");
+		return ret;
+	}
+
+	return mma9551_set_device_state(data->client, true);
+}
+
+static int mma9553_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val, int *val2, long mask)
+{
+	struct mma9553_data *data = iio_priv(indio_dev);
+	int ret;
+	u16 tmp;
+	u8 activity;
+	bool powered_on;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_PROCESSED:
+		switch (chan->type) {
+		case IIO_STEPS:
+			/*
+			 * The HW only counts steps and other dependent
+			 * parameters (speed, distance, calories, activity)
+			 * if power is on (from enabling an event or the
+			 * step counter */
+			powered_on =
+			    mma9553_is_any_event_enabled(data, false, 0) ||
+			    data->stepcnt_enabled;
+			if (!powered_on) {
+				dev_err(&data->client->dev,
+					"No channels enabled\n");
+				return -EINVAL;
+			}
+			mutex_lock(&data->mutex);
+			ret = mma9551_read_status_word(data->client,
+						       MMA9551_APPID_PEDOMETER,
+						       MMA9553_REG_STEPCNT,
+						       &tmp);
+			mutex_unlock(&data->mutex);
+			if (ret < 0)
+				return ret;
+			*val = tmp;
+			return IIO_VAL_INT;
+		case IIO_DISTANCE:
+			powered_on =
+			    mma9553_is_any_event_enabled(data, false, 0) ||
+			    data->stepcnt_enabled;
+			if (!powered_on) {
+				dev_err(&data->client->dev,
+					"No channels enabled\n");
+				return -EINVAL;
+			}
+			mutex_lock(&data->mutex);
+			ret = mma9551_read_status_word(data->client,
+						       MMA9551_APPID_PEDOMETER,
+						       MMA9553_REG_DISTANCE,
+						       &tmp);
+			mutex_unlock(&data->mutex);
+			if (ret < 0)
+				return ret;
+			*val = tmp;
+			return IIO_VAL_INT;
+		case IIO_ACTIVITY:
+			powered_on =
+			    mma9553_is_any_event_enabled(data, false, 0) ||
+			    data->stepcnt_enabled;
+			if (!powered_on) {
+				dev_err(&data->client->dev,
+					"No channels enabled\n");
+				return -EINVAL;
+			}
+			mutex_lock(&data->mutex);
+			ret = mma9551_read_status_word(data->client,
+						       MMA9551_APPID_PEDOMETER,
+						       MMA9553_REG_STATUS,
+						       &tmp);
+			mutex_unlock(&data->mutex);
+			if (ret < 0)
+				return ret;
+
+			activity =
+			    mma9553_get_bits(tmp, MMA9553_MASK_STATUS_ACTIVITY);
+
+			/*
+			 * The device does not support confidence value levels,
+			 * so we will always have 100% for current activity and
+			 * 0% for the others.
+			 */
+			if (chan->channel2 == mma9553_activity_to_mod(activity))
+				*val = 100;
+			else
+				*val = 0;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_RAW:
+		switch (chan->type) {
+		case IIO_VELOCITY:	/* m/h */
+			if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)
+				return -EINVAL;
+			powered_on =
+			    mma9553_is_any_event_enabled(data, false, 0) ||
+			    data->stepcnt_enabled;
+			if (!powered_on) {
+				dev_err(&data->client->dev,
+					"No channels enabled\n");
+				return -EINVAL;
+			}
+			mutex_lock(&data->mutex);
+			ret = mma9551_read_status_word(data->client,
+						       MMA9551_APPID_PEDOMETER,
+						       MMA9553_REG_SPEED, &tmp);
+			mutex_unlock(&data->mutex);
+			if (ret < 0)
+				return ret;
+			*val = tmp;
+			return IIO_VAL_INT;
+		case IIO_ENERGY:	/* Cal or kcal */
+			powered_on =
+			    mma9553_is_any_event_enabled(data, false, 0) ||
+			    data->stepcnt_enabled;
+			if (!powered_on) {
+				dev_err(&data->client->dev,
+					"No channels enabled\n");
+				return -EINVAL;
+			}
+			mutex_lock(&data->mutex);
+			ret = mma9551_read_status_word(data->client,
+						       MMA9551_APPID_PEDOMETER,
+						       MMA9553_REG_CALORIES,
+						       &tmp);
+			mutex_unlock(&data->mutex);
+			if (ret < 0)
+				return ret;
+			*val = tmp;
+			return IIO_VAL_INT;
+		case IIO_ACCEL:
+			mutex_lock(&data->mutex);
+			ret = mma9551_read_accel_chan(data->client,
+						      chan, val, val2);
+			mutex_unlock(&data->mutex);
+			return ret;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_VELOCITY:	/* m/h to m/s */
+			if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)
+				return -EINVAL;
+			*val = 0;
+			*val2 = 277;	/* 0.000277 */
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ENERGY:	/* Cal or kcal to J */
+			*val = 4184;
+			return IIO_VAL_INT;
+		case IIO_ACCEL:
+			return mma9551_read_accel_scale(val, val2);
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_ENABLE:
+		*val = data->stepcnt_enabled;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_CALIBHEIGHT:
+		tmp = mma9553_get_bits(data->conf.height_weight,
+					MMA9553_MASK_CONF_HEIGHT);
+		*val = tmp / 100;	/* cm to m */
+		*val2 = (tmp % 100) * 10000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	case IIO_CHAN_INFO_CALIBWEIGHT:
+		*val = mma9553_get_bits(data->conf.height_weight,
+					MMA9553_MASK_CONF_WEIGHT);
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_DEBOUNCE_COUNT:
+		switch (chan->type) {
+		case IIO_STEPS:
+			*val = mma9553_get_bits(data->conf.filter,
+						MMA9553_MASK_CONF_FILTSTEP);
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_DEBOUNCE_TIME:
+		switch (chan->type) {
+		case IIO_STEPS:
+			*val = mma9553_get_bits(data->conf.filter,
+						MMA9553_MASK_CONF_FILTTIME);
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_INT_TIME:
+		switch (chan->type) {
+		case IIO_VELOCITY:
+			if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)
+				return -EINVAL;
+			*val = mma9553_get_bits(data->conf.speed_step,
+						MMA9553_MASK_CONF_SPDPRD);
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mma9553_write_raw(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan,
+			     int val, int val2, long mask)
+{
+	struct mma9553_data *data = iio_priv(indio_dev);
+	int ret, tmp;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_ENABLE:
+		if (data->stepcnt_enabled == !!val)
+			return 0;
+		mutex_lock(&data->mutex);
+		ret = mma9551_set_power_state(data->client, val);
+		if (ret < 0) {
+			mutex_unlock(&data->mutex);
+			return ret;
+		}
+		data->stepcnt_enabled = val;
+		mutex_unlock(&data->mutex);
+		return 0;
+	case IIO_CHAN_INFO_CALIBHEIGHT:
+		/* m to cm */
+		tmp = val * 100 + val2 / 10000;
+		if (tmp < 0 || tmp > 255)
+			return -EINVAL;
+		mutex_lock(&data->mutex);
+		ret = mma9553_set_config(data,
+					 MMA9553_REG_CONF_HEIGHT_WEIGHT,
+					 &data->conf.height_weight,
+					 tmp, MMA9553_MASK_CONF_HEIGHT);
+		mutex_unlock(&data->mutex);
+		return ret;
+	case IIO_CHAN_INFO_CALIBWEIGHT:
+		if (val < 0 || val > 255)
+			return -EINVAL;
+		mutex_lock(&data->mutex);
+		ret = mma9553_set_config(data,
+					 MMA9553_REG_CONF_HEIGHT_WEIGHT,
+					 &data->conf.height_weight,
+					 val, MMA9553_MASK_CONF_WEIGHT);
+		mutex_unlock(&data->mutex);
+		return ret;
+	case IIO_CHAN_INFO_DEBOUNCE_COUNT:
+		switch (chan->type) {
+		case IIO_STEPS:
+			/*
+			 * Set to 0 to disable step filtering. If the value
+			 * specified is greater than 6, then 6 will be used.
+			 */
+			if (val < 0)
+				return -EINVAL;
+			if (val > 6)
+				val = 6;
+			mutex_lock(&data->mutex);
+			ret = mma9553_set_config(data, MMA9553_REG_CONF_FILTER,
+						 &data->conf.filter, val,
+						 MMA9553_MASK_CONF_FILTSTEP);
+			mutex_unlock(&data->mutex);
+			return ret;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_DEBOUNCE_TIME:
+		switch (chan->type) {
+		case IIO_STEPS:
+			if (val < 0 || val > 127)
+				return -EINVAL;
+			mutex_lock(&data->mutex);
+			ret = mma9553_set_config(data, MMA9553_REG_CONF_FILTER,
+						 &data->conf.filter, val,
+						 MMA9553_MASK_CONF_FILTTIME);
+			mutex_unlock(&data->mutex);
+			return ret;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_INT_TIME:
+		switch (chan->type) {
+		case IIO_VELOCITY:
+			if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)
+				return -EINVAL;
+			/*
+			 * If set to a value greater than 5, then 5 will be
+			 * used. Warning: Do not set SPDPRD to 0 or 1 as
+			 * this may cause undesirable behavior.
+			 */
+			if (val < 2)
+				return -EINVAL;
+			if (val > 5)
+				val = 5;
+			mutex_lock(&data->mutex);
+			ret = mma9553_set_config(data,
+						 MMA9553_REG_CONF_SPEED_STEP,
+						 &data->conf.speed_step, val,
+						 MMA9553_MASK_CONF_SPDPRD);
+			mutex_unlock(&data->mutex);
+			return ret;
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mma9553_read_event_config(struct iio_dev *indio_dev,
+				     const struct iio_chan_spec *chan,
+				     enum iio_event_type type,
+				     enum iio_event_direction dir)
+{
+
+	struct mma9553_data *data = iio_priv(indio_dev);
+	struct mma9553_event *event;
+
+	event = mma9553_get_event(data, chan->type, chan->channel2, dir);
+	if (!event)
+		return -EINVAL;
+
+	return event->enabled;
+}
+
+static int mma9553_write_event_config(struct iio_dev *indio_dev,
+				      const struct iio_chan_spec *chan,
+				      enum iio_event_type type,
+				      enum iio_event_direction dir, int state)
+{
+	struct mma9553_data *data = iio_priv(indio_dev);
+	struct mma9553_event *event;
+	int ret;
+
+	event = mma9553_get_event(data, chan->type, chan->channel2, dir);
+	if (!event)
+		return -EINVAL;
+
+	if (event->enabled == state)
+		return 0;
+
+	mutex_lock(&data->mutex);
+
+	ret = mma9551_set_power_state(data->client, state);
+	if (ret < 0)
+		goto err_out;
+	event->enabled = state;
+
+	ret = mma9553_conf_gpio(data);
+	if (ret < 0)
+		goto err_conf_gpio;
+
+	mutex_unlock(&data->mutex);
+
+	return ret;
+
+err_conf_gpio:
+	if (state) {
+		event->enabled = false;
+		mma9551_set_power_state(data->client, false);
+	}
+err_out:
+	mutex_unlock(&data->mutex);
+	return ret;
+}
+
+static int mma9553_read_event_value(struct iio_dev *indio_dev,
+				    const struct iio_chan_spec *chan,
+				    enum iio_event_type type,
+				    enum iio_event_direction dir,
+				    enum iio_event_info info,
+				    int *val, int *val2)
+{
+	struct mma9553_data *data = iio_priv(indio_dev);
+
+	*val2 = 0;
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		switch (chan->type) {
+		case IIO_STEPS:
+			*val = mma9553_get_bits(data->conf.speed_step,
+						MMA9553_MASK_CONF_STEPCOALESCE);
+			return IIO_VAL_INT;
+		case IIO_ACTIVITY:
+			/*
+			 * The device does not support confidence value levels.
+			 * We set an average of 50%.
+			 */
+			*val = 50;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+	case IIO_EV_INFO_PERIOD:
+		switch (chan->type) {
+		case IIO_ACTIVITY:
+			*val = MMA9553_ACTIVITY_THD_TO_SEC(data->conf.actthd);
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mma9553_write_event_value(struct iio_dev *indio_dev,
+				     const struct iio_chan_spec *chan,
+				     enum iio_event_type type,
+				     enum iio_event_direction dir,
+				     enum iio_event_info info,
+				     int val, int val2)
+{
+	struct mma9553_data *data = iio_priv(indio_dev);
+	int ret;
+
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		switch (chan->type) {
+		case IIO_STEPS:
+			if (val < 0 || val > 255)
+				return -EINVAL;
+			mutex_lock(&data->mutex);
+			ret = mma9553_set_config(data,
+						MMA9553_REG_CONF_SPEED_STEP,
+						&data->conf.speed_step, val,
+						MMA9553_MASK_CONF_STEPCOALESCE);
+			mutex_unlock(&data->mutex);
+			return ret;
+		default:
+			return -EINVAL;
+		}
+	case IIO_EV_INFO_PERIOD:
+		switch (chan->type) {
+		case IIO_ACTIVITY:
+			mutex_lock(&data->mutex);
+			ret = mma9553_set_config(data, MMA9553_REG_CONF_ACTTHD,
+						 &data->conf.actthd,
+						 MMA9553_ACTIVITY_SEC_TO_THD
+						 (val), MMA9553_MASK_CONF_WORD);
+			mutex_unlock(&data->mutex);
+			return ret;
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mma9553_get_calibgender_mode(struct iio_dev *indio_dev,
+					const struct iio_chan_spec *chan)
+{
+	struct mma9553_data *data = iio_priv(indio_dev);
+	u8 gender;
+
+	gender = mma9553_get_bits(data->conf.filter, MMA9553_MASK_CONF_MALE);
+	/*
+	 * HW expects 0 for female and 1 for male,
+	 * while iio index is 0 for male and 1 for female
+	 */
+	return !gender;
+}
+
+static int mma9553_set_calibgender_mode(struct iio_dev *indio_dev,
+					const struct iio_chan_spec *chan,
+					unsigned int mode)
+{
+	struct mma9553_data *data = iio_priv(indio_dev);
+	u8 gender = !mode;
+	int ret;
+
+	if ((mode != 0) && (mode != 1))
+		return -EINVAL;
+	mutex_lock(&data->mutex);
+	ret = mma9553_set_config(data, MMA9553_REG_CONF_FILTER,
+				 &data->conf.filter, gender,
+				 MMA9553_MASK_CONF_MALE);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static const struct iio_event_spec mma9553_step_event = {
+	.type = IIO_EV_TYPE_CHANGE,
+	.dir = IIO_EV_DIR_NONE,
+	.mask_separate = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_VALUE),
+};
+
+static const struct iio_event_spec mma9553_activity_events[] = {
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_RISING,
+		.mask_separate = BIT(IIO_EV_INFO_ENABLE) |
+				 BIT(IIO_EV_INFO_VALUE) |
+				 BIT(IIO_EV_INFO_PERIOD),
+	 },
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_FALLING,
+		.mask_separate = BIT(IIO_EV_INFO_ENABLE) |
+				 BIT(IIO_EV_INFO_VALUE) |
+				 BIT(IIO_EV_INFO_PERIOD),
+	},
+};
+
+static const char * const calibgender_modes[] = { "male", "female" };
+
+static const struct iio_enum mma9553_calibgender_enum = {
+	.items = calibgender_modes,
+	.num_items = ARRAY_SIZE(calibgender_modes),
+	.get = mma9553_get_calibgender_mode,
+	.set = mma9553_set_calibgender_mode,
+};
+
+static const struct iio_chan_spec_ext_info mma9553_ext_info[] = {
+	IIO_ENUM("calibgender", IIO_SHARED_BY_TYPE, &mma9553_calibgender_enum),
+	IIO_ENUM_AVAILABLE("calibgender", &mma9553_calibgender_enum),
+	{},
+};
+
+#define MMA9553_PEDOMETER_CHANNEL(_type, _mask) {		\
+	.type = _type,						\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_ENABLE)      |	\
+			      BIT(IIO_CHAN_INFO_CALIBHEIGHT) |	\
+			      _mask,				\
+	.ext_info = mma9553_ext_info,				\
+}
+
+#define MMA9553_ACTIVITY_CHANNEL(_chan2) {				\
+	.type = IIO_ACTIVITY,						\
+	.modified = 1,							\
+	.channel2 = _chan2,						\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),		\
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT),	\
+	.event_spec = mma9553_activity_events,				\
+	.num_event_specs = ARRAY_SIZE(mma9553_activity_events),		\
+	.ext_info = mma9553_ext_info,					\
+}
+
+static const struct iio_chan_spec mma9553_channels[] = {
+	MMA9551_ACCEL_CHANNEL(IIO_MOD_X),
+	MMA9551_ACCEL_CHANNEL(IIO_MOD_Y),
+	MMA9551_ACCEL_CHANNEL(IIO_MOD_Z),
+
+	{
+		.type = IIO_STEPS,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
+				     BIT(IIO_CHAN_INFO_ENABLE) |
+				     BIT(IIO_CHAN_INFO_DEBOUNCE_COUNT) |
+				     BIT(IIO_CHAN_INFO_DEBOUNCE_TIME),
+		.event_spec = &mma9553_step_event,
+		.num_event_specs = 1,
+	},
+
+	MMA9553_PEDOMETER_CHANNEL(IIO_DISTANCE, BIT(IIO_CHAN_INFO_PROCESSED)),
+	{
+		.type = IIO_VELOCITY,
+		.modified = 1,
+		.channel2 = IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				      BIT(IIO_CHAN_INFO_SCALE) |
+				      BIT(IIO_CHAN_INFO_INT_TIME) |
+				      BIT(IIO_CHAN_INFO_ENABLE),
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT),
+		.ext_info = mma9553_ext_info,
+	},
+	MMA9553_PEDOMETER_CHANNEL(IIO_ENERGY, BIT(IIO_CHAN_INFO_RAW) |
+				  BIT(IIO_CHAN_INFO_SCALE) |
+				  BIT(IIO_CHAN_INFO_CALIBWEIGHT)),
+
+	MMA9553_ACTIVITY_CHANNEL(IIO_MOD_RUNNING),
+	MMA9553_ACTIVITY_CHANNEL(IIO_MOD_JOGGING),
+	MMA9553_ACTIVITY_CHANNEL(IIO_MOD_WALKING),
+	MMA9553_ACTIVITY_CHANNEL(IIO_MOD_STILL),
+};
+
+static const struct iio_info mma9553_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = mma9553_read_raw,
+	.write_raw = mma9553_write_raw,
+	.read_event_config = mma9553_read_event_config,
+	.write_event_config = mma9553_write_event_config,
+	.read_event_value = mma9553_read_event_value,
+	.write_event_value = mma9553_write_event_value,
+};
+
+static irqreturn_t mma9553_irq_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct mma9553_data *data = iio_priv(indio_dev);
+
+	data->timestamp = iio_get_time_ns();
+	/*
+	 * Since we only configure the interrupt pin when an
+	 * event is enabled, we are sure we have at least
+	 * one event enabled at this point.
+	 */
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mma9553_event_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct mma9553_data *data = iio_priv(indio_dev);
+	u16 stepcnt;
+	u8 activity;
+	struct mma9553_event *ev_activity, *ev_prev_activity, *ev_step_detect;
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = mma9553_read_activity_stepcnt(data, &activity, &stepcnt);
+	if (ret < 0) {
+		mutex_unlock(&data->mutex);
+		return IRQ_HANDLED;
+	}
+
+	ev_prev_activity =
+	    mma9553_get_event(data, IIO_ACTIVITY,
+			      mma9553_activity_to_mod(data->activity),
+			      IIO_EV_DIR_FALLING);
+	ev_activity =
+	    mma9553_get_event(data, IIO_ACTIVITY,
+			      mma9553_activity_to_mod(activity),
+			      IIO_EV_DIR_RISING);
+	ev_step_detect =
+	    mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD, IIO_EV_DIR_NONE);
+
+	if (ev_step_detect->enabled && (stepcnt != data->stepcnt)) {
+		data->stepcnt = stepcnt;
+		iio_push_event(indio_dev,
+			       IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
+			       IIO_EV_DIR_NONE, IIO_EV_TYPE_CHANGE, 0, 0, 0),
+			       data->timestamp);
+	}
+
+	if (activity != data->activity) {
+		data->activity = activity;
+		/* ev_activity can be NULL if activity == ACTIVITY_UNKNOWN */
+		if (ev_prev_activity && ev_prev_activity->enabled)
+			iio_push_event(indio_dev,
+				       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
+				       ev_prev_activity->info->mod,
+				       IIO_EV_DIR_FALLING,
+				       IIO_EV_TYPE_THRESH, 0, 0, 0),
+				       data->timestamp);
+
+		if (ev_activity && ev_activity->enabled)
+			iio_push_event(indio_dev,
+				       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
+				       ev_activity->info->mod,
+				       IIO_EV_DIR_RISING,
+				       IIO_EV_TYPE_THRESH, 0, 0, 0),
+				       data->timestamp);
+	}
+	mutex_unlock(&data->mutex);
+
+	return IRQ_HANDLED;
+}
+
+static int mma9553_gpio_probe(struct i2c_client *client)
+{
+	struct device *dev;
+	struct gpio_desc *gpio;
+	int ret;
+
+	if (!client)
+		return -EINVAL;
+
+	dev = &client->dev;
+
+	/* data ready gpio interrupt pin */
+	gpio = devm_gpiod_get_index(dev, MMA9553_GPIO_NAME, 0);
+	if (IS_ERR(gpio)) {
+		dev_err(dev, "acpi gpio get index failed\n");
+		return PTR_ERR(gpio);
+	}
+
+	ret = gpiod_direction_input(gpio);
+	if (ret)
+		return ret;
+
+	ret = gpiod_to_irq(gpio);
+
+	dev_dbg(dev, "gpio resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
+
+	return ret;
+}
+
+static const char *mma9553_match_acpi_device(struct device *dev)
+{
+	const struct acpi_device_id *id;
+
+	id = acpi_match_device(dev->driver->acpi_match_table, dev);
+	if (!id)
+		return NULL;
+
+	return dev_name(dev);
+}
+
+static int mma9553_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct mma9553_data *data;
+	struct iio_dev *indio_dev;
+	const char *name = NULL;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+
+	if (id)
+		name = id->name;
+	else if (ACPI_HANDLE(&client->dev))
+		name = mma9553_match_acpi_device(&client->dev);
+	else
+		return -ENOSYS;
+
+	mutex_init(&data->mutex);
+	mma9553_init_events(data);
+
+	ret = mma9553_init(data);
+	if (ret < 0)
+		return ret;
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->channels = mma9553_channels;
+	indio_dev->num_channels = ARRAY_SIZE(mma9553_channels);
+	indio_dev->name = name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &mma9553_info;
+
+	if (client->irq < 0)
+		client->irq = mma9553_gpio_probe(client);
+
+	if (client->irq >= 0) {
+		ret = devm_request_threaded_irq(&client->dev, client->irq,
+						mma9553_irq_handler,
+						mma9553_event_handler,
+						IRQF_TRIGGER_RISING,
+						MMA9553_IRQ_NAME, indio_dev);
+		if (ret < 0) {
+			dev_err(&client->dev, "request irq %d failed\n",
+				client->irq);
+			goto out_poweroff;
+		}
+
+	}
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0) {
+		dev_err(&client->dev, "unable to register iio device\n");
+		goto out_poweroff;
+	}
+
+	ret = pm_runtime_set_active(&client->dev);
+	if (ret < 0)
+		goto out_iio_unregister;
+
+	pm_runtime_enable(&client->dev);
+	pm_runtime_set_autosuspend_delay(&client->dev,
+					 MMA9551_AUTO_SUSPEND_DELAY_MS);
+	pm_runtime_use_autosuspend(&client->dev);
+
+	dev_dbg(&indio_dev->dev, "Registered device %s\n", name);
+
+	return 0;
+
+out_iio_unregister:
+	iio_device_unregister(indio_dev);
+out_poweroff:
+	mma9551_set_device_state(client, false);
+	return ret;
+}
+
+static int mma9553_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct mma9553_data *data = iio_priv(indio_dev);
+
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_put_noidle(&client->dev);
+
+	iio_device_unregister(indio_dev);
+	mutex_lock(&data->mutex);
+	mma9551_set_device_state(data->client, false);
+	mutex_unlock(&data->mutex);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mma9553_runtime_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct mma9553_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = mma9551_set_device_state(data->client, false);
+	mutex_unlock(&data->mutex);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "powering off device failed\n");
+		return -EAGAIN;
+	}
+
+	return 0;
+}
+
+static int mma9553_runtime_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct mma9553_data *data = iio_priv(indio_dev);
+	int ret;
+
+	ret = mma9551_set_device_state(data->client, true);
+	if (ret < 0)
+		return ret;
+
+	mma9551_sleep(MMA9553_DEFAULT_SAMPLE_RATE);
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int mma9553_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct mma9553_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = mma9551_set_device_state(data->client, false);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static int mma9553_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct mma9553_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = mma9551_set_device_state(data->client, true);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+#endif
+
+static const struct dev_pm_ops mma9553_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mma9553_suspend, mma9553_resume)
+	SET_RUNTIME_PM_OPS(mma9553_runtime_suspend,
+			   mma9553_runtime_resume, NULL)
+};
+
+static const struct acpi_device_id mma9553_acpi_match[] = {
+	{"MMA9553", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(acpi, mma9553_acpi_match);
+
+static const struct i2c_device_id mma9553_id[] = {
+	{"mma9553", 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, mma9553_id);
+
+static struct i2c_driver mma9553_driver = {
+	.driver = {
+		   .name = MMA9553_DRV_NAME,
+		   .acpi_match_table = ACPI_PTR(mma9553_acpi_match),
+		   .pm = &mma9553_pm_ops,
+		   },
+	.probe = mma9553_probe,
+	.remove = mma9553_remove,
+	.id_table = mma9553_id,
+};
+
+module_i2c_driver(mma9553_driver);
+
+MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MMA9553L pedometer platform driver");
diff --git a/drivers/iio/accel/ssp_accel_sensor.c b/drivers/iio/accel/ssp_accel_sensor.c
new file mode 100644
index 000000000000..4ae05fce9f24
--- /dev/null
+++ b/drivers/iio/accel/ssp_accel_sensor.c
@@ -0,0 +1,169 @@
+/*
+ *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include <linux/iio/common/ssp_sensors.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "../common/ssp_sensors/ssp_iio_sensor.h"
+
+#define SSP_CHANNEL_COUNT 3
+
+#define SSP_ACCEL_NAME "ssp-accelerometer"
+static const char ssp_accel_device_name[] = SSP_ACCEL_NAME;
+
+enum ssp_accel_3d_channel {
+	SSP_CHANNEL_SCAN_INDEX_X,
+	SSP_CHANNEL_SCAN_INDEX_Y,
+	SSP_CHANNEL_SCAN_INDEX_Z,
+	SSP_CHANNEL_SCAN_INDEX_TIME,
+};
+
+static int ssp_accel_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,  int *val,
+			      int *val2, long mask)
+{
+	u32 t;
+	struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		t = ssp_get_sensor_delay(data, SSP_ACCELEROMETER_SENSOR);
+		ssp_convert_to_freq(t, val, val2);
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int ssp_accel_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan, int val,
+			       int val2, long mask)
+{
+	int ret;
+	struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = ssp_convert_to_time(val, val2);
+		ret = ssp_change_delay(data, SSP_ACCELEROMETER_SENSOR, ret);
+		if (ret < 0)
+			dev_err(&indio_dev->dev, "accel sensor enable fail\n");
+
+		return ret;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static struct iio_info ssp_accel_iio_info = {
+	.read_raw = &ssp_accel_read_raw,
+	.write_raw = &ssp_accel_write_raw,
+};
+
+static const unsigned long ssp_accel_scan_mask[] = { 0x7, 0, };
+
+static const struct iio_chan_spec ssp_acc_channels[] = {
+	SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_X, SSP_CHANNEL_SCAN_INDEX_X),
+	SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_Y, SSP_CHANNEL_SCAN_INDEX_Y),
+	SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_Z, SSP_CHANNEL_SCAN_INDEX_Z),
+	SSP_CHAN_TIMESTAMP(SSP_CHANNEL_SCAN_INDEX_TIME),
+};
+
+static int ssp_process_accel_data(struct iio_dev *indio_dev, void *buf,
+				  int64_t timestamp)
+{
+	return ssp_common_process_data(indio_dev, buf, SSP_ACCELEROMETER_SIZE,
+				       timestamp);
+}
+
+static const struct iio_buffer_setup_ops ssp_accel_buffer_ops = {
+	.postenable = &ssp_common_buffer_postenable,
+	.postdisable = &ssp_common_buffer_postdisable,
+};
+
+static int ssp_accel_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct iio_dev *indio_dev;
+	struct ssp_sensor_data *spd;
+	struct iio_buffer *buffer;
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*spd));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	spd = iio_priv(indio_dev);
+
+	spd->process_data = ssp_process_accel_data;
+	spd->type = SSP_ACCELEROMETER_SENSOR;
+
+	indio_dev->name = ssp_accel_device_name;
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->dev.of_node = pdev->dev.of_node;
+	indio_dev->info = &ssp_accel_iio_info;
+	indio_dev->modes = INDIO_BUFFER_SOFTWARE;
+	indio_dev->channels = ssp_acc_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ssp_acc_channels);
+	indio_dev->available_scan_masks = ssp_accel_scan_mask;
+
+	buffer = devm_iio_kfifo_allocate(&pdev->dev);
+	if (!buffer)
+		return -ENOMEM;
+
+	iio_device_attach_buffer(indio_dev, buffer);
+
+	indio_dev->setup_ops = &ssp_accel_buffer_ops;
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		return ret;
+
+	/* ssp registering should be done after all iio setup */
+	ssp_register_consumer(indio_dev, SSP_ACCELEROMETER_SENSOR);
+
+	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);
+
+MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
+MODULE_DESCRIPTION("Samsung sensorhub accelerometers driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 0f79e4725763..202daf889be2 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -135,6 +135,17 @@ config AXP288_ADC
 	  device. Depending on platform configuration, this general purpose ADC can
 	  be used for sampling sensors such as thermal resistors.
 
+config CC10001_ADC
+	tristate "Cosmic Circuits 10001 ADC driver"
+	depends on HAS_IOMEM || HAVE_CLK || REGULATOR
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	  Say yes here to build support for Cosmic Circuits 10001 ADC.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called cc10001_adc.
+
 config EXYNOS_ADC
 	tristate "Exynos ADC driver support"
 	depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST)
@@ -228,6 +239,20 @@ config QCOM_SPMI_IADC
 	  To compile this driver as a module, choose M here: the module will
 	  be called qcom-spmi-iadc.
 
+config QCOM_SPMI_VADC
+	tristate "Qualcomm SPMI PMIC voltage ADC"
+	depends on SPMI
+	select REGMAP_SPMI
+	help
+	  This is the IIO Voltage ADC driver for Qualcomm QPNP VADC Chip.
+
+	  The driver supports multiple channels read. The VADC is a 15-bit
+	  sigma-delta ADC. Some of the channels are internally used for
+	  calibration.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called qcom-spmi-vadc.
+
 config ROCKCHIP_SARADC
 	tristate "Rockchip SARADC driver"
 	depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 701fdb7c96aa..0315af640866 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_AD7887) += ad7887.o
 obj-$(CONFIG_AD799X) += ad799x.o
 obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
+obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1027) += max1027.o
@@ -24,6 +25,7 @@ obj-$(CONFIG_MCP3422) += mcp3422.o
 obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
 obj-$(CONFIG_NAU7802) += nau7802.o
 obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
+obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
 obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o
diff --git a/drivers/iio/adc/cc10001_adc.c b/drivers/iio/adc/cc10001_adc.c
new file mode 100644
index 000000000000..51e2a83c9404
--- /dev/null
+++ b/drivers/iio/adc/cc10001_adc.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2014-2015 Imagination Technologies Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+/* Registers */
+#define CC10001_ADC_CONFIG		0x00
+#define CC10001_ADC_START_CONV		BIT(4)
+#define CC10001_ADC_MODE_SINGLE_CONV	BIT(5)
+
+#define CC10001_ADC_DDATA_OUT		0x04
+#define CC10001_ADC_EOC			0x08
+#define CC10001_ADC_EOC_SET		BIT(0)
+
+#define CC10001_ADC_CHSEL_SAMPLED	0x0c
+#define CC10001_ADC_POWER_UP		0x10
+#define CC10001_ADC_POWER_UP_SET	BIT(0)
+#define CC10001_ADC_DEBUG		0x14
+#define CC10001_ADC_DATA_COUNT		0x20
+
+#define CC10001_ADC_DATA_MASK		GENMASK(9, 0)
+#define CC10001_ADC_NUM_CHANNELS	8
+#define CC10001_ADC_CH_MASK		GENMASK(2, 0)
+
+#define CC10001_INVALID_SAMPLED		0xffff
+#define CC10001_MAX_POLL_COUNT		20
+
+/*
+ * As per device specification, wait six clock cycles after power-up to
+ * activate START. Since adding two more clock cycles delay does not
+ * impact the performance too much, we are adding two additional cycles delay
+ * intentionally here.
+ */
+#define	CC10001_WAIT_CYCLES		8
+
+struct cc10001_adc_device {
+	void __iomem *reg_base;
+	struct clk *adc_clk;
+	struct regulator *reg;
+	u16 *buf;
+
+	struct mutex lock;
+	unsigned long channel_map;
+	unsigned int start_delay_ns;
+	unsigned int eoc_delay_ns;
+};
+
+static inline void cc10001_adc_write_reg(struct cc10001_adc_device *adc_dev,
+					 u32 reg, u32 val)
+{
+	writel(val, adc_dev->reg_base + reg);
+}
+
+static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev,
+				       u32 reg)
+{
+	return readl(adc_dev->reg_base + reg);
+}
+
+static void cc10001_adc_start(struct cc10001_adc_device *adc_dev,
+			      unsigned int channel)
+{
+	u32 val;
+
+	/* Channel selection and mode of operation */
+	val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV;
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
+
+	val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG);
+	val = val | CC10001_ADC_START_CONV;
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val);
+}
+
+static u16 cc10001_adc_poll_done(struct iio_dev *indio_dev,
+				 unsigned int channel,
+				 unsigned int delay)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	unsigned int poll_count = 0;
+
+	while (!(cc10001_adc_read_reg(adc_dev, CC10001_ADC_EOC) &
+			CC10001_ADC_EOC_SET)) {
+
+		ndelay(delay);
+		if (poll_count++ == CC10001_MAX_POLL_COUNT)
+			return CC10001_INVALID_SAMPLED;
+	}
+
+	poll_count = 0;
+	while ((cc10001_adc_read_reg(adc_dev, CC10001_ADC_CHSEL_SAMPLED) &
+			CC10001_ADC_CH_MASK) != channel) {
+
+		ndelay(delay);
+		if (poll_count++ == CC10001_MAX_POLL_COUNT)
+			return CC10001_INVALID_SAMPLED;
+	}
+
+	/* Read the 10 bit output register */
+	return cc10001_adc_read_reg(adc_dev, CC10001_ADC_DDATA_OUT) &
+			       CC10001_ADC_DATA_MASK;
+}
+
+static irqreturn_t cc10001_adc_trigger_h(int irq, void *p)
+{
+	struct cc10001_adc_device *adc_dev;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev;
+	unsigned int delay_ns;
+	unsigned int channel;
+	bool sample_invalid;
+	u16 *data;
+	int i;
+
+	indio_dev = pf->indio_dev;
+	adc_dev = iio_priv(indio_dev);
+	data = adc_dev->buf;
+
+	mutex_lock(&adc_dev->lock);
+
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
+			      CC10001_ADC_POWER_UP_SET);
+
+	/* Wait for 8 (6+2) clock cycles before activating START */
+	ndelay(adc_dev->start_delay_ns);
+
+	/* Calculate delay step for eoc and sampled data */
+	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
+
+	i = 0;
+	sample_invalid = false;
+	for_each_set_bit(channel, indio_dev->active_scan_mask,
+				  indio_dev->masklength) {
+
+		cc10001_adc_start(adc_dev, channel);
+
+		data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns);
+		if (data[i] == CC10001_INVALID_SAMPLED) {
+			dev_warn(&indio_dev->dev,
+				 "invalid sample on channel %d\n", channel);
+			sample_invalid = true;
+			goto done;
+		}
+		i++;
+	}
+
+done:
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
+
+	mutex_unlock(&adc_dev->lock);
+
+	if (!sample_invalid)
+		iio_push_to_buffers_with_timestamp(indio_dev, data,
+						   iio_get_time_ns());
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev,
+					struct iio_chan_spec const *chan)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	unsigned int delay_ns;
+	u16 val;
+
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP,
+			      CC10001_ADC_POWER_UP_SET);
+
+	/* Wait for 8 (6+2) clock cycles before activating START */
+	ndelay(adc_dev->start_delay_ns);
+
+	/* Calculate delay step for eoc and sampled data */
+	delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT;
+
+	cc10001_adc_start(adc_dev, chan->channel);
+
+	val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns);
+
+	cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0);
+
+	return val;
+}
+
+static int cc10001_adc_read_raw(struct iio_dev *indio_dev,
+				 struct iio_chan_spec const *chan,
+				 int *val, int *val2, long mask)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		if (iio_buffer_enabled(indio_dev))
+			return -EBUSY;
+		mutex_lock(&adc_dev->lock);
+		*val = cc10001_adc_read_raw_voltage(indio_dev, chan);
+		mutex_unlock(&adc_dev->lock);
+
+		if (*val == CC10001_INVALID_SAMPLED)
+			return -EIO;
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SCALE:
+		ret = regulator_get_voltage(adc_dev->reg);
+		if (ret)
+			return ret;
+
+		*val = ret / 1000;
+		*val2 = chan->scan_type.realbits;
+		return IIO_VAL_FRACTIONAL_LOG2;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int cc10001_update_scan_mode(struct iio_dev *indio_dev,
+				    const unsigned long *scan_mask)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+
+	kfree(adc_dev->buf);
+	adc_dev->buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+	if (!adc_dev->buf)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static const struct iio_info cc10001_adc_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &cc10001_adc_read_raw,
+	.update_scan_mode = &cc10001_update_scan_mode,
+};
+
+static int cc10001_adc_channel_init(struct iio_dev *indio_dev)
+{
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+	struct iio_chan_spec *chan_array, *timestamp;
+	unsigned int bit, idx = 0;
+
+	indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map,
+						CC10001_ADC_NUM_CHANNELS);
+
+	chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1,
+				  sizeof(struct iio_chan_spec),
+				  GFP_KERNEL);
+	if (!chan_array)
+		return -ENOMEM;
+
+	for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) {
+		struct iio_chan_spec *chan = &chan_array[idx];
+
+		chan->type = IIO_VOLTAGE;
+		chan->indexed = 1;
+		chan->channel = bit;
+		chan->scan_index = idx;
+		chan->scan_type.sign = 'u';
+		chan->scan_type.realbits = 10;
+		chan->scan_type.storagebits = 16;
+		chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
+		chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
+		idx++;
+	}
+
+	timestamp = &chan_array[idx];
+	timestamp->type = IIO_TIMESTAMP;
+	timestamp->channel = -1;
+	timestamp->scan_index = idx;
+	timestamp->scan_type.sign = 's';
+	timestamp->scan_type.realbits = 64;
+	timestamp->scan_type.storagebits = 64;
+
+	indio_dev->channels = chan_array;
+
+	return 0;
+}
+
+static int cc10001_adc_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct cc10001_adc_device *adc_dev;
+	unsigned long adc_clk_rate;
+	struct resource *res;
+	struct iio_dev *indio_dev;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	adc_dev = iio_priv(indio_dev);
+
+	adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0);
+	if (!of_property_read_u32(node, "adc-reserved-channels", &ret))
+		adc_dev->channel_map &= ~ret;
+
+	adc_dev->reg = devm_regulator_get(&pdev->dev, "vref");
+	if (IS_ERR(adc_dev->reg))
+		return PTR_ERR(adc_dev->reg);
+
+	ret = regulator_enable(adc_dev->reg);
+	if (ret)
+		return ret;
+
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->name = dev_name(&pdev->dev);
+	indio_dev->info = &cc10001_adc_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(adc_dev->reg_base)) {
+		ret = PTR_ERR(adc_dev->reg_base);
+		goto err_disable_reg;
+	}
+
+	adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc");
+	if (IS_ERR(adc_dev->adc_clk)) {
+		dev_err(&pdev->dev, "failed to get the clock\n");
+		ret = PTR_ERR(adc_dev->adc_clk);
+		goto err_disable_reg;
+	}
+
+	ret = clk_prepare_enable(adc_dev->adc_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to enable the clock\n");
+		goto err_disable_reg;
+	}
+
+	adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
+	if (!adc_clk_rate) {
+		ret = -EINVAL;
+		dev_err(&pdev->dev, "null clock rate!\n");
+		goto err_disable_clk;
+	}
+
+	adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate;
+	adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES;
+
+	/* Setup the ADC channels available on the device */
+	ret = cc10001_adc_channel_init(indio_dev);
+	if (ret < 0)
+		goto err_disable_clk;
+
+	mutex_init(&adc_dev->lock);
+
+	ret = iio_triggered_buffer_setup(indio_dev, NULL,
+					 &cc10001_adc_trigger_h, NULL);
+	if (ret < 0)
+		goto err_disable_clk;
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		goto err_cleanup_buffer;
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	return 0;
+
+err_cleanup_buffer:
+	iio_triggered_buffer_cleanup(indio_dev);
+err_disable_clk:
+	clk_disable_unprepare(adc_dev->adc_clk);
+err_disable_reg:
+	regulator_disable(adc_dev->reg);
+	return ret;
+}
+
+static int cc10001_adc_remove(struct platform_device *pdev)
+{
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct cc10001_adc_device *adc_dev = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+	clk_disable_unprepare(adc_dev->adc_clk);
+	regulator_disable(adc_dev->reg);
+
+	return 0;
+}
+
+static const struct of_device_id cc10001_adc_dt_ids[] = {
+	{ .compatible = "cosmic,10001-adc", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cc10001_adc_dt_ids);
+
+static struct platform_driver cc10001_adc_driver = {
+	.driver = {
+		.name   = "cc10001-adc",
+		.of_match_table = cc10001_adc_dt_ids,
+	},
+	.probe	= cc10001_adc_probe,
+	.remove	= cc10001_adc_remove,
+};
+module_platform_driver(cc10001_adc_driver);
+
+MODULE_AUTHOR("Phani Movva <Phani.Movva@imgtec.com>");
+MODULE_DESCRIPTION("Cosmic Circuits ADC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/adc/qcom-spmi-vadc.c b/drivers/iio/adc/qcom-spmi-vadc.c
new file mode 100644
index 000000000000..3211729bcb0b
--- /dev/null
+++ b/drivers/iio/adc/qcom-spmi-vadc.c
@@ -0,0 +1,1016 @@
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iio/iio.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/log2.h>
+
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+
+/* VADC register and bit definitions */
+#define VADC_REVISION2				0x1
+#define VADC_REVISION2_SUPPORTED_VADC		1
+
+#define VADC_PERPH_TYPE				0x4
+#define VADC_PERPH_TYPE_ADC			8
+
+#define VADC_PERPH_SUBTYPE			0x5
+#define VADC_PERPH_SUBTYPE_VADC			1
+
+#define VADC_STATUS1				0x8
+#define VADC_STATUS1_OP_MODE			4
+#define VADC_STATUS1_REQ_STS			BIT(1)
+#define VADC_STATUS1_EOC			BIT(0)
+#define VADC_STATUS1_REQ_STS_EOC_MASK		0x3
+
+#define VADC_MODE_CTL				0x40
+#define VADC_OP_MODE_SHIFT			3
+#define VADC_OP_MODE_NORMAL			0
+#define VADC_AMUX_TRIM_EN			BIT(1)
+#define VADC_ADC_TRIM_EN			BIT(0)
+
+#define VADC_EN_CTL1				0x46
+#define VADC_EN_CTL1_SET			BIT(7)
+
+#define VADC_ADC_CH_SEL_CTL			0x48
+
+#define VADC_ADC_DIG_PARAM			0x50
+#define VADC_ADC_DIG_DEC_RATIO_SEL_SHIFT	2
+
+#define VADC_HW_SETTLE_DELAY			0x51
+
+#define VADC_CONV_REQ				0x52
+#define VADC_CONV_REQ_SET			BIT(7)
+
+#define VADC_FAST_AVG_CTL			0x5a
+#define VADC_FAST_AVG_EN			0x5b
+#define VADC_FAST_AVG_EN_SET			BIT(7)
+
+#define VADC_ACCESS				0xd0
+#define VADC_ACCESS_DATA			0xa5
+
+#define VADC_PERH_RESET_CTL3			0xda
+#define VADC_FOLLOW_WARM_RB			BIT(2)
+
+#define VADC_DATA				0x60	/* 16 bits */
+
+#define VADC_CONV_TIME_MIN_US			2000
+#define VADC_CONV_TIME_MAX_US			2100
+
+/* Min ADC code represents 0V */
+#define VADC_MIN_ADC_CODE			0x6000
+/* Max ADC code represents full-scale range of 1.8V */
+#define VADC_MAX_ADC_CODE			0xa800
+
+#define VADC_ABSOLUTE_RANGE_UV			625000
+#define VADC_RATIOMETRIC_RANGE_UV		1800000
+
+#define VADC_DEF_PRESCALING			0 /* 1:1 */
+#define VADC_DEF_DECIMATION			0 /* 512 */
+#define VADC_DEF_HW_SETTLE_TIME			0 /* 0 us */
+#define VADC_DEF_AVG_SAMPLES			0 /* 1 sample */
+#define VADC_DEF_CALIB_TYPE			VADC_CALIB_ABSOLUTE
+
+#define VADC_DECIMATION_MIN			512
+#define VADC_DECIMATION_MAX			4096
+
+#define VADC_HW_SETTLE_DELAY_MAX		10000
+#define VADC_AVG_SAMPLES_MAX			512
+
+#define KELVINMIL_CELSIUSMIL			273150
+
+#define VADC_CHAN_MIN			VADC_USBIN
+#define VADC_CHAN_MAX			VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM
+
+/*
+ * VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels.
+ * VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for
+ * calibration.
+ */
+enum vadc_calibration {
+	VADC_CALIB_ABSOLUTE = 0,
+	VADC_CALIB_RATIOMETRIC
+};
+
+/**
+ * struct vadc_linear_graph - Represent ADC characteristics.
+ * @dy: numerator slope to calculate the gain.
+ * @dx: denominator slope to calculate the gain.
+ * @gnd: A/D word of the ground reference used for the channel.
+ *
+ * Each ADC device has different offset and gain parameters which are
+ * computed to calibrate the device.
+ */
+struct vadc_linear_graph {
+	s32 dy;
+	s32 dx;
+	s32 gnd;
+};
+
+/**
+ * struct vadc_prescale_ratio - Represent scaling ratio for ADC input.
+ * @num: the inverse numerator of the gain applied to the input channel.
+ * @den: the inverse denominator of the gain applied to the input channel.
+ */
+struct vadc_prescale_ratio {
+	u32 num;
+	u32 den;
+};
+
+/**
+ * struct vadc_channel_prop - VADC channel property.
+ * @channel: channel number, refer to the channel list.
+ * @calibration: calibration type.
+ * @decimation: sampling rate supported for the channel.
+ * @prescale: channel scaling performed on the input signal.
+ * @hw_settle_time: the time between AMUX being configured and the
+ *	start of conversion.
+ * @avg_samples: ability to provide single result from the ADC
+ *	that is an average of multiple measurements.
+ */
+struct vadc_channel_prop {
+	unsigned int channel;
+	enum vadc_calibration calibration;
+	unsigned int decimation;
+	unsigned int prescale;
+	unsigned int hw_settle_time;
+	unsigned int avg_samples;
+};
+
+/**
+ * struct vadc_priv - VADC private structure.
+ * @regmap: pointer to struct regmap.
+ * @dev: pointer to struct device.
+ * @base: base address for the ADC peripheral.
+ * @nchannels: number of VADC channels.
+ * @chan_props: array of VADC channel properties.
+ * @iio_chans: array of IIO channels specification.
+ * @are_ref_measured: are reference points measured.
+ * @poll_eoc: use polling instead of interrupt.
+ * @complete: VADC result notification after interrupt is received.
+ * @graph: store parameters for calibration.
+ * @lock: ADC lock for access to the peripheral.
+ */
+struct vadc_priv {
+	struct regmap		 *regmap;
+	struct device		 *dev;
+	u16			 base;
+	unsigned int		 nchannels;
+	struct vadc_channel_prop *chan_props;
+	struct iio_chan_spec	 *iio_chans;
+	bool			 are_ref_measured;
+	bool			 poll_eoc;
+	struct completion	 complete;
+	struct vadc_linear_graph graph[2];
+	struct mutex		 lock;
+};
+
+static const struct vadc_prescale_ratio vadc_prescale_ratios[] = {
+	{.num =  1, .den =  1},
+	{.num =  1, .den =  3},
+	{.num =  1, .den =  4},
+	{.num =  1, .den =  6},
+	{.num =  1, .den = 20},
+	{.num =  1, .den =  8},
+	{.num = 10, .den = 81},
+	{.num =  1, .den = 10}
+};
+
+static int vadc_read(struct vadc_priv *vadc, u16 offset, u8 *data)
+{
+	return regmap_bulk_read(vadc->regmap, vadc->base + offset, data, 1);
+}
+
+static int vadc_write(struct vadc_priv *vadc, u16 offset, u8 data)
+{
+	return regmap_write(vadc->regmap, vadc->base + offset, data);
+}
+
+static int vadc_reset(struct vadc_priv *vadc)
+{
+	u8 data;
+	int ret;
+
+	ret = vadc_write(vadc, VADC_ACCESS, VADC_ACCESS_DATA);
+	if (ret)
+		return ret;
+
+	ret = vadc_read(vadc, VADC_PERH_RESET_CTL3, &data);
+	if (ret)
+		return ret;
+
+	ret = vadc_write(vadc, VADC_ACCESS, VADC_ACCESS_DATA);
+	if (ret)
+		return ret;
+
+	data |= VADC_FOLLOW_WARM_RB;
+
+	return vadc_write(vadc, VADC_PERH_RESET_CTL3, data);
+}
+
+static int vadc_set_state(struct vadc_priv *vadc, bool state)
+{
+	return vadc_write(vadc, VADC_EN_CTL1, state ? VADC_EN_CTL1_SET : 0);
+}
+
+static void vadc_show_status(struct vadc_priv *vadc)
+{
+	u8 mode, sta1, chan, dig, en, req;
+	int ret;
+
+	ret = vadc_read(vadc, VADC_MODE_CTL, &mode);
+	if (ret)
+		return;
+
+	ret = vadc_read(vadc, VADC_ADC_DIG_PARAM, &dig);
+	if (ret)
+		return;
+
+	ret = vadc_read(vadc, VADC_ADC_CH_SEL_CTL, &chan);
+	if (ret)
+		return;
+
+	ret = vadc_read(vadc, VADC_CONV_REQ, &req);
+	if (ret)
+		return;
+
+	ret = vadc_read(vadc, VADC_STATUS1, &sta1);
+	if (ret)
+		return;
+
+	ret = vadc_read(vadc, VADC_EN_CTL1, &en);
+	if (ret)
+		return;
+
+	dev_err(vadc->dev,
+		"mode:%02x en:%02x chan:%02x dig:%02x req:%02x sta1:%02x\n",
+		mode, en, chan, dig, req, sta1);
+}
+
+static int vadc_configure(struct vadc_priv *vadc,
+			  struct vadc_channel_prop *prop)
+{
+	u8 decimation, mode_ctrl;
+	int ret;
+
+	/* Mode selection */
+	mode_ctrl = (VADC_OP_MODE_NORMAL << VADC_OP_MODE_SHIFT) |
+		     VADC_ADC_TRIM_EN | VADC_AMUX_TRIM_EN;
+	ret = vadc_write(vadc, VADC_MODE_CTL, mode_ctrl);
+	if (ret)
+		return ret;
+
+	/* Channel selection */
+	ret = vadc_write(vadc, VADC_ADC_CH_SEL_CTL, prop->channel);
+	if (ret)
+		return ret;
+
+	/* Digital parameter setup */
+	decimation = prop->decimation << VADC_ADC_DIG_DEC_RATIO_SEL_SHIFT;
+	ret = vadc_write(vadc, VADC_ADC_DIG_PARAM, decimation);
+	if (ret)
+		return ret;
+
+	/* HW settle time delay */
+	ret = vadc_write(vadc, VADC_HW_SETTLE_DELAY, prop->hw_settle_time);
+	if (ret)
+		return ret;
+
+	ret = vadc_write(vadc, VADC_FAST_AVG_CTL, prop->avg_samples);
+	if (ret)
+		return ret;
+
+	if (prop->avg_samples)
+		ret = vadc_write(vadc, VADC_FAST_AVG_EN, VADC_FAST_AVG_EN_SET);
+	else
+		ret = vadc_write(vadc, VADC_FAST_AVG_EN, 0);
+
+	return ret;
+}
+
+static int vadc_poll_wait_eoc(struct vadc_priv *vadc, unsigned int interval_us)
+{
+	unsigned int count, retry;
+	u8 sta1;
+	int ret;
+
+	retry = interval_us / VADC_CONV_TIME_MIN_US;
+
+	for (count = 0; count < retry; count++) {
+		ret = vadc_read(vadc, VADC_STATUS1, &sta1);
+		if (ret)
+			return ret;
+
+		sta1 &= VADC_STATUS1_REQ_STS_EOC_MASK;
+		if (sta1 == VADC_STATUS1_EOC)
+			return 0;
+
+		usleep_range(VADC_CONV_TIME_MIN_US, VADC_CONV_TIME_MAX_US);
+	}
+
+	vadc_show_status(vadc);
+
+	return -ETIMEDOUT;
+}
+
+static int vadc_read_result(struct vadc_priv *vadc, u16 *data)
+{
+	int ret;
+
+	ret = regmap_bulk_read(vadc->regmap, vadc->base + VADC_DATA, data, 2);
+	if (ret)
+		return ret;
+
+	*data = clamp_t(u16, *data, VADC_MIN_ADC_CODE, VADC_MAX_ADC_CODE);
+
+	return 0;
+}
+
+static struct vadc_channel_prop *vadc_get_channel(struct vadc_priv *vadc,
+						  unsigned int num)
+{
+	unsigned int i;
+
+	for (i = 0; i < vadc->nchannels; i++)
+		if (vadc->chan_props[i].channel == num)
+			return &vadc->chan_props[i];
+
+	dev_dbg(vadc->dev, "no such channel %02x\n", num);
+
+	return NULL;
+}
+
+static int vadc_do_conversion(struct vadc_priv *vadc,
+			      struct vadc_channel_prop *prop, u16 *data)
+{
+	unsigned int timeout;
+	int ret;
+
+	mutex_lock(&vadc->lock);
+
+	ret = vadc_configure(vadc, prop);
+	if (ret)
+		goto unlock;
+
+	if (!vadc->poll_eoc)
+		reinit_completion(&vadc->complete);
+
+	ret = vadc_set_state(vadc, true);
+	if (ret)
+		goto unlock;
+
+	ret = vadc_write(vadc, VADC_CONV_REQ, VADC_CONV_REQ_SET);
+	if (ret)
+		goto err_disable;
+
+	timeout = BIT(prop->avg_samples) * VADC_CONV_TIME_MIN_US * 2;
+
+	if (vadc->poll_eoc) {
+		ret = vadc_poll_wait_eoc(vadc, timeout);
+	} else {
+		ret = wait_for_completion_timeout(&vadc->complete, timeout);
+		if (!ret) {
+			ret = -ETIMEDOUT;
+			goto err_disable;
+		}
+
+		/* Double check conversion status */
+		ret = vadc_poll_wait_eoc(vadc, VADC_CONV_TIME_MIN_US);
+		if (ret)
+			goto err_disable;
+	}
+
+	ret = vadc_read_result(vadc, data);
+
+err_disable:
+	vadc_set_state(vadc, false);
+	if (ret)
+		dev_err(vadc->dev, "conversion failed\n");
+unlock:
+	mutex_unlock(&vadc->lock);
+	return ret;
+}
+
+static int vadc_measure_ref_points(struct vadc_priv *vadc)
+{
+	struct vadc_channel_prop *prop;
+	u16 read_1, read_2;
+	int ret;
+
+	vadc->graph[VADC_CALIB_RATIOMETRIC].dx = VADC_RATIOMETRIC_RANGE_UV;
+	vadc->graph[VADC_CALIB_ABSOLUTE].dx = VADC_ABSOLUTE_RANGE_UV;
+
+	prop = vadc_get_channel(vadc, VADC_REF_1250MV);
+	ret = vadc_do_conversion(vadc, prop, &read_1);
+	if (ret)
+		goto err;
+
+	/* Try with buffered 625mV channel first */
+	prop = vadc_get_channel(vadc, VADC_SPARE1);
+	if (!prop)
+		prop = vadc_get_channel(vadc, VADC_REF_625MV);
+
+	ret = vadc_do_conversion(vadc, prop, &read_2);
+	if (ret)
+		goto err;
+
+	if (read_1 == read_2) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	vadc->graph[VADC_CALIB_ABSOLUTE].dy = read_1 - read_2;
+	vadc->graph[VADC_CALIB_ABSOLUTE].gnd = read_2;
+
+	/* Ratiometric calibration */
+	prop = vadc_get_channel(vadc, VADC_VDD_VADC);
+	ret = vadc_do_conversion(vadc, prop, &read_1);
+	if (ret)
+		goto err;
+
+	prop = vadc_get_channel(vadc, VADC_GND_REF);
+	ret = vadc_do_conversion(vadc, prop, &read_2);
+	if (ret)
+		goto err;
+
+	if (read_1 == read_2) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	vadc->graph[VADC_CALIB_RATIOMETRIC].dy = read_1 - read_2;
+	vadc->graph[VADC_CALIB_RATIOMETRIC].gnd = read_2;
+err:
+	if (ret)
+		dev_err(vadc->dev, "measure reference points failed\n");
+
+	return ret;
+}
+
+static s32 vadc_calibrate(struct vadc_priv *vadc,
+			  const struct vadc_channel_prop *prop, u16 adc_code)
+{
+	const struct vadc_prescale_ratio *prescale;
+	s32 voltage;
+
+	voltage = adc_code - vadc->graph[prop->calibration].gnd;
+	voltage *= vadc->graph[prop->calibration].dx;
+	voltage = voltage / vadc->graph[prop->calibration].dy;
+
+	if (prop->calibration == VADC_CALIB_ABSOLUTE)
+		voltage += vadc->graph[prop->calibration].dx;
+
+	if (voltage < 0)
+		voltage = 0;
+
+	prescale = &vadc_prescale_ratios[prop->prescale];
+
+	voltage = voltage * prescale->den;
+
+	return voltage / prescale->num;
+}
+
+static int vadc_decimation_from_dt(u32 value)
+{
+	if (!is_power_of_2(value) || value < VADC_DECIMATION_MIN ||
+	    value > VADC_DECIMATION_MAX)
+		return -EINVAL;
+
+	return __ffs64(value / VADC_DECIMATION_MIN);
+}
+
+static int vadc_prescaling_from_dt(u32 num, u32 den)
+{
+	unsigned int pre;
+
+	for (pre = 0; pre < ARRAY_SIZE(vadc_prescale_ratios); pre++)
+		if (vadc_prescale_ratios[pre].num == num &&
+		    vadc_prescale_ratios[pre].den == den)
+			break;
+
+	if (pre == ARRAY_SIZE(vadc_prescale_ratios))
+		return -EINVAL;
+
+	return pre;
+}
+
+static int vadc_hw_settle_time_from_dt(u32 value)
+{
+	if ((value <= 1000 && value % 100) || (value > 1000 && value % 2000))
+		return -EINVAL;
+
+	if (value <= 1000)
+		value /= 100;
+	else
+		value = value / 2000 + 10;
+
+	return value;
+}
+
+static int vadc_avg_samples_from_dt(u32 value)
+{
+	if (!is_power_of_2(value) || value > VADC_AVG_SAMPLES_MAX)
+		return -EINVAL;
+
+	return __ffs64(value);
+}
+
+static int vadc_read_raw(struct iio_dev *indio_dev,
+			 struct iio_chan_spec const *chan, int *val, int *val2,
+			 long mask)
+{
+	struct vadc_priv *vadc = iio_priv(indio_dev);
+	struct vadc_channel_prop *prop;
+	u16 adc_code;
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_PROCESSED:
+		prop = &vadc->chan_props[chan->address];
+		ret = vadc_do_conversion(vadc, prop, &adc_code);
+		if (ret)
+			break;
+
+		*val = vadc_calibrate(vadc, prop, adc_code);
+
+		/* 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];
+		ret = vadc_do_conversion(vadc, prop, &adc_code);
+		if (ret)
+			break;
+
+		*val = vadc_calibrate(vadc, prop, 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;
+	}
+
+	return ret;
+}
+
+static int vadc_of_xlate(struct iio_dev *indio_dev,
+			 const struct of_phandle_args *iiospec)
+{
+	struct vadc_priv *vadc = iio_priv(indio_dev);
+	unsigned int i;
+
+	for (i = 0; i < vadc->nchannels; i++)
+		if (vadc->iio_chans[i].channel == iiospec->args[0])
+			return i;
+
+	return -EINVAL;
+}
+
+static const struct iio_info vadc_info = {
+	.read_raw = vadc_read_raw,
+	.of_xlate = vadc_of_xlate,
+	.driver_module = THIS_MODULE,
+};
+
+struct vadc_channels {
+	const char *datasheet_name;
+	unsigned int prescale_index;
+	enum iio_chan_type type;
+	long info_mask;
+};
+
+#define VADC_CHAN(_dname, _type, _mask, _pre)				\
+	[VADC_##_dname] = {						\
+		.datasheet_name = __stringify(_dname),			\
+		.prescale_index = _pre,					\
+		.type = _type,						\
+		.info_mask = _mask					\
+	},								\
+
+#define VADC_CHAN_TEMP(_dname, _pre)					\
+	VADC_CHAN(_dname, IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED), _pre)	\
+
+#define VADC_CHAN_VOLT(_dname, _pre)					\
+	VADC_CHAN(_dname, IIO_VOLTAGE,					\
+		  BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),	\
+		  _pre)							\
+
+/*
+ * The array represents all possible ADC channels found in the supported PMICs.
+ * Every index in the array is equal to the channel number per datasheet. The
+ * 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)
+};
+
+static int vadc_get_dt_channel_data(struct device *dev,
+				    struct vadc_channel_prop *prop,
+				    struct device_node *node)
+{
+	const char *name = node->name;
+	u32 chan, value, varr[2];
+	int ret;
+
+	ret = of_property_read_u32(node, "reg", &chan);
+	if (ret) {
+		dev_err(dev, "invalid channel number %s\n", name);
+		return ret;
+	}
+
+	if (chan > VADC_CHAN_MAX || chan < VADC_CHAN_MIN) {
+		dev_err(dev, "%s invalid channel number %d\n", name, chan);
+		return -EINVAL;
+	}
+
+	/* the channel has DT description */
+	prop->channel = chan;
+
+	ret = of_property_read_u32(node, "qcom,decimation", &value);
+	if (!ret) {
+		ret = vadc_decimation_from_dt(value);
+		if (ret < 0) {
+			dev_err(dev, "%02x invalid decimation %d\n",
+				chan, value);
+			return ret;
+		}
+		prop->decimation = ret;
+	} else {
+		prop->decimation = VADC_DEF_DECIMATION;
+	}
+
+	ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2);
+	if (!ret) {
+		ret = vadc_prescaling_from_dt(varr[0], varr[1]);
+		if (ret < 0) {
+			dev_err(dev, "%02x invalid pre-scaling <%d %d>\n",
+				chan, varr[0], varr[1]);
+			return ret;
+		}
+		prop->prescale = ret;
+	} else {
+		prop->prescale = vadc_chans[prop->channel].prescale_index;
+	}
+
+	ret = of_property_read_u32(node, "qcom,hw-settle-time", &value);
+	if (!ret) {
+		ret = vadc_hw_settle_time_from_dt(value);
+		if (ret < 0) {
+			dev_err(dev, "%02x invalid hw-settle-time %d us\n",
+				chan, value);
+			return ret;
+		}
+		prop->hw_settle_time = ret;
+	} else {
+		prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME;
+	}
+
+	ret = of_property_read_u32(node, "qcom,avg-samples", &value);
+	if (!ret) {
+		ret = vadc_avg_samples_from_dt(value);
+		if (ret < 0) {
+			dev_err(dev, "%02x invalid avg-samples %d\n",
+				chan, value);
+			return ret;
+		}
+		prop->avg_samples = ret;
+	} else {
+		prop->avg_samples = VADC_DEF_AVG_SAMPLES;
+	}
+
+	if (of_property_read_bool(node, "qcom,ratiometric"))
+		prop->calibration = VADC_CALIB_RATIOMETRIC;
+	else
+		prop->calibration = VADC_CALIB_ABSOLUTE;
+
+	dev_dbg(dev, "%02x name %s\n", chan, name);
+
+	return 0;
+}
+
+static int vadc_get_dt_data(struct vadc_priv *vadc, struct device_node *node)
+{
+	const struct vadc_channels *vadc_chan;
+	struct iio_chan_spec *iio_chan;
+	struct vadc_channel_prop prop;
+	struct device_node *child;
+	unsigned int index = 0;
+	int ret;
+
+	vadc->nchannels = of_get_available_child_count(node);
+	if (!vadc->nchannels)
+		return -EINVAL;
+
+	vadc->iio_chans = devm_kcalloc(vadc->dev, vadc->nchannels,
+				       sizeof(*vadc->iio_chans), GFP_KERNEL);
+	if (!vadc->iio_chans)
+		return -ENOMEM;
+
+	vadc->chan_props = devm_kcalloc(vadc->dev, vadc->nchannels,
+					sizeof(*vadc->chan_props), GFP_KERNEL);
+	if (!vadc->chan_props)
+		return -ENOMEM;
+
+	iio_chan = vadc->iio_chans;
+
+	for_each_available_child_of_node(node, child) {
+		ret = vadc_get_dt_channel_data(vadc->dev, &prop, child);
+		if (ret)
+			return ret;
+
+		vadc->chan_props[index] = prop;
+
+		vadc_chan = &vadc_chans[prop.channel];
+
+		iio_chan->channel = prop.channel;
+		iio_chan->datasheet_name = vadc_chan->datasheet_name;
+		iio_chan->info_mask_separate = vadc_chan->info_mask;
+		iio_chan->type = vadc_chan->type;
+		iio_chan->indexed = 1;
+		iio_chan->address = index++;
+
+		iio_chan++;
+	}
+
+	/* These channels are mandatory, they are used as reference points */
+	if (!vadc_get_channel(vadc, VADC_REF_1250MV)) {
+		dev_err(vadc->dev, "Please define 1.25V channel\n");
+		return -ENODEV;
+	}
+
+	if (!vadc_get_channel(vadc, VADC_REF_625MV)) {
+		dev_err(vadc->dev, "Please define 0.625V channel\n");
+		return -ENODEV;
+	}
+
+	if (!vadc_get_channel(vadc, VADC_VDD_VADC)) {
+		dev_err(vadc->dev, "Please define VDD channel\n");
+		return -ENODEV;
+	}
+
+	if (!vadc_get_channel(vadc, VADC_GND_REF)) {
+		dev_err(vadc->dev, "Please define GND channel\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static irqreturn_t vadc_isr(int irq, void *dev_id)
+{
+	struct vadc_priv *vadc = dev_id;
+
+	complete(&vadc->complete);
+
+	return IRQ_HANDLED;
+}
+
+static int vadc_check_revision(struct vadc_priv *vadc)
+{
+	u8 val;
+	int ret;
+
+	ret = vadc_read(vadc, VADC_PERPH_TYPE, &val);
+	if (ret)
+		return ret;
+
+	if (val < VADC_PERPH_TYPE_ADC) {
+		dev_err(vadc->dev, "%d is not ADC\n", val);
+		return -ENODEV;
+	}
+
+	ret = vadc_read(vadc, VADC_PERPH_SUBTYPE, &val);
+	if (ret)
+		return ret;
+
+	if (val < VADC_PERPH_SUBTYPE_VADC) {
+		dev_err(vadc->dev, "%d is not VADC\n", val);
+		return -ENODEV;
+	}
+
+	ret = vadc_read(vadc, VADC_REVISION2, &val);
+	if (ret)
+		return ret;
+
+	if (val < VADC_REVISION2_SUPPORTED_VADC) {
+		dev_err(vadc->dev, "revision %d not supported\n", val);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int vadc_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct iio_dev *indio_dev;
+	struct vadc_priv *vadc;
+	struct regmap *regmap;
+	int ret, irq_eoc;
+	u32 reg;
+
+	regmap = dev_get_regmap(dev->parent, NULL);
+	if (!regmap)
+		return -ENODEV;
+
+	ret = of_property_read_u32(node, "reg", &reg);
+	if (ret < 0)
+		return ret;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*vadc));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	vadc = iio_priv(indio_dev);
+	vadc->regmap = regmap;
+	vadc->dev = dev;
+	vadc->base = reg;
+	vadc->are_ref_measured = false;
+	init_completion(&vadc->complete);
+	mutex_init(&vadc->lock);
+
+	ret = vadc_check_revision(vadc);
+	if (ret)
+		return ret;
+
+	ret = vadc_get_dt_data(vadc, node);
+	if (ret)
+		return ret;
+
+	irq_eoc = platform_get_irq(pdev, 0);
+	if (irq_eoc < 0) {
+		if (irq_eoc == -EPROBE_DEFER || irq_eoc == -EINVAL)
+			return irq_eoc;
+		vadc->poll_eoc = true;
+	} else {
+		ret = devm_request_irq(dev, irq_eoc, vadc_isr, 0,
+				       "spmi-vadc", vadc);
+		if (ret)
+			return ret;
+	}
+
+	ret = vadc_reset(vadc);
+	if (ret) {
+		dev_err(dev, "reset failed\n");
+		return ret;
+	}
+
+	ret = vadc_measure_ref_points(vadc);
+	if (ret)
+		return ret;
+
+	indio_dev->dev.parent = dev;
+	indio_dev->dev.of_node = node;
+	indio_dev->name = pdev->name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &vadc_info;
+	indio_dev->channels = vadc->iio_chans;
+	indio_dev->num_channels = vadc->nchannels;
+
+	return devm_iio_device_register(dev, indio_dev);
+}
+
+static const struct of_device_id vadc_match_table[] = {
+	{ .compatible = "qcom,spmi-vadc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, vadc_match_table);
+
+static struct platform_driver vadc_driver = {
+	.driver = {
+		   .name = "qcom-spmi-vadc",
+		   .of_match_table = vadc_match_table,
+	},
+	.probe = vadc_probe,
+};
+module_platform_driver(vadc_driver);
+
+MODULE_ALIAS("platform:qcom-spmi-vadc");
+MODULE_DESCRIPTION("Qualcomm SPMI PMIC voltage ADC driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>");
+MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index adba23246474..2e5cc4409f78 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -249,7 +249,7 @@ static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
 	struct iio_buffer *buffer;
 	int ret;
 
-	buffer = iio_kfifo_allocate(indio_dev);
+	buffer = iio_kfifo_allocate();
 	if (!buffer)
 		return -ENOMEM;
 
@@ -263,16 +263,8 @@ static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
 	indio_dev->setup_ops = setup_ops;
 	indio_dev->modes |= INDIO_BUFFER_HARDWARE;
 
-	ret = iio_buffer_register(indio_dev,
-				  indio_dev->channels,
-				  indio_dev->num_channels);
-	if (ret)
-		goto error_free_irq;
-
 	return 0;
 
-error_free_irq:
-	free_irq(irq, indio_dev);
 error_kfifo_free:
 	iio_kfifo_free(indio_dev->buffer);
 	return ret;
@@ -284,7 +276,6 @@ static void tiadc_iio_buffered_hardware_remove(struct iio_dev *indio_dev)
 
 	free_irq(adc_dev->mfd_tscadc->irq, indio_dev);
 	iio_kfifo_free(indio_dev->buffer);
-	iio_buffer_unregister(indio_dev);
 }
 
 
diff --git a/drivers/iio/amplifiers/ad8366.c b/drivers/iio/amplifiers/ad8366.c
index ba6f6a91dfff..c0d364ebaea8 100644
--- a/drivers/iio/amplifiers/ad8366.c
+++ b/drivers/iio/amplifiers/ad8366.c
@@ -31,7 +31,7 @@ struct ad8366_state {
 };
 
 static int ad8366_write(struct iio_dev *indio_dev,
-			unsigned char ch_a, char unsigned ch_b)
+			unsigned char ch_a, unsigned char ch_b)
 {
 	struct ad8366_state *st = iio_priv(indio_dev);
 	int ret;
@@ -166,7 +166,7 @@ static int ad8366_probe(struct spi_device *spi)
 	if (ret)
 		goto error_disable_reg;
 
-	ad8366_write(indio_dev, 0 , 0);
+	ad8366_write(indio_dev, 0, 0);
 
 	return 0;
 
diff --git a/drivers/iio/common/Kconfig b/drivers/iio/common/Kconfig
index 0b6e97d18fa0..790f106d719c 100644
--- a/drivers/iio/common/Kconfig
+++ b/drivers/iio/common/Kconfig
@@ -3,4 +3,5 @@
 #
 
 source "drivers/iio/common/hid-sensors/Kconfig"
+source "drivers/iio/common/ssp_sensors/Kconfig"
 source "drivers/iio/common/st_sensors/Kconfig"
diff --git a/drivers/iio/common/Makefile b/drivers/iio/common/Makefile
index 3112df0060e9..b1e4d9c9591c 100644
--- a/drivers/iio/common/Makefile
+++ b/drivers/iio/common/Makefile
@@ -8,4 +8,5 @@
 
 # When adding new entries keep the list in alphabetical order
 obj-y += hid-sensors/
+obj-y += ssp_sensors/
 obj-y += st_sensors/
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
index 92068cdbf8c7..2f1d535b94c4 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -22,16 +22,18 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 #include <linux/hid-sensor-hub.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/sysfs.h>
 #include "hid-sensor-trigger.h"
 
-int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
+static int _hid_sensor_power_state(struct hid_sensor_common *st, bool state)
 {
 	int state_val;
 	int report_val;
+	s32 poll_value = 0;
 
 	if (state) {
 		if (sensor_hub_device_open(st->hsdev))
@@ -47,6 +49,8 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
 			st->report_state.report_id,
 			st->report_state.index,
 			HID_USAGE_SENSOR_PROP_REPORTING_STATE_ALL_EVENTS_ENUM);
+
+		poll_value = hid_sensor_read_poll_value(st);
 	} else {
 		if (!atomic_dec_and_test(&st->data_ready))
 			return 0;
@@ -78,10 +82,36 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
 	sensor_hub_get_feature(st->hsdev, st->power_state.report_id,
 					st->power_state.index,
 					&state_val);
+	if (state && poll_value)
+		msleep_interruptible(poll_value * 2);
+
 	return 0;
 }
 EXPORT_SYMBOL(hid_sensor_power_state);
 
+int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
+{
+#ifdef CONFIG_PM
+	int ret;
+
+	if (state)
+		ret = pm_runtime_get_sync(&st->pdev->dev);
+	else {
+		pm_runtime_mark_last_busy(&st->pdev->dev);
+		ret = pm_runtime_put_autosuspend(&st->pdev->dev);
+	}
+	if (ret < 0) {
+		if (state)
+			pm_runtime_put_noidle(&st->pdev->dev);
+		return ret;
+	}
+
+ 	return 0;
+#else
+	return _hid_sensor_power_state(st, state);
+#endif
+}
+
 static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
 						bool state)
 {
@@ -125,8 +155,21 @@ int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
 	attrb->trigger = trig;
 	indio_dev->trig = iio_trigger_get(trig);
 
-	return ret;
+	ret = pm_runtime_set_active(&indio_dev->dev);
+	if (ret)
+		goto error_unreg_trigger;
 
+	iio_device_set_drvdata(indio_dev, attrb);
+	pm_suspend_ignore_children(&attrb->pdev->dev, true);
+	pm_runtime_enable(&attrb->pdev->dev);
+	/* Default to 3 seconds, but can be changed from sysfs */
+	pm_runtime_set_autosuspend_delay(&attrb->pdev->dev,
+					 3000);
+	pm_runtime_use_autosuspend(&attrb->pdev->dev);
+
+	return ret;
+error_unreg_trigger:
+	iio_trigger_unregister(trig);
 error_free_trig:
 	iio_trigger_free(trig);
 error_ret:
@@ -134,6 +177,34 @@ error_ret:
 }
 EXPORT_SYMBOL(hid_sensor_setup_trigger);
 
+#ifdef CONFIG_PM
+static int hid_sensor_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
+
+	return _hid_sensor_power_state(attrb, false);
+}
+
+static int hid_sensor_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct hid_sensor_common *attrb = iio_device_get_drvdata(indio_dev);
+
+	return _hid_sensor_power_state(attrb, true);
+}
+
+#endif
+
+const struct dev_pm_ops hid_sensor_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(hid_sensor_suspend, hid_sensor_resume)
+	SET_RUNTIME_PM_OPS(hid_sensor_suspend,
+			   hid_sensor_resume, NULL)
+};
+EXPORT_SYMBOL(hid_sensor_pm_ops);
+
 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>");
 MODULE_DESCRIPTION("HID Sensor trigger processing");
 MODULE_LICENSE("GPL");
diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
index 0f8e78c249d3..9f4713f42ecb 100644
--- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
+++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
@@ -19,6 +19,11 @@
 #ifndef _HID_SENSOR_TRIGGER_H
 #define _HID_SENSOR_TRIGGER_H
 
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+
+extern const struct dev_pm_ops hid_sensor_pm_ops;
+
 int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char *name,
 				struct hid_sensor_common *attrb);
 void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
diff --git a/drivers/iio/common/ssp_sensors/Kconfig b/drivers/iio/common/ssp_sensors/Kconfig
new file mode 100644
index 000000000000..0ea4faf016d8
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/Kconfig
@@ -0,0 +1,26 @@
+#
+# SSP sensor drivers and commons configuration
+#
+menu "SSP Sensor Common"
+
+config IIO_SSP_SENSORS_COMMONS
+	tristate "Commons for all SSP Sensor IIO drivers"
+	depends on IIO_SSP_SENSORHUB
+	select IIO_BUFFER
+	select IIO_KFIFO_BUF
+	help
+	  Say yes here to build commons for SSP sensors.
+	  To compile this as a module, choose M here: the module
+	  will be called ssp_iio.
+
+config IIO_SSP_SENSORHUB
+	tristate "Samsung Sensorhub driver"
+	depends on SPI
+	select MFD_CORE
+	help
+	  SSP driver for sensorhub.
+	  If you say yes here you get ssp support for sensorhub.
+	  To compile this driver as a module, choose M here: the
+	  module will be called sensorhub.
+
+endmenu
diff --git a/drivers/iio/common/ssp_sensors/Makefile b/drivers/iio/common/ssp_sensors/Makefile
new file mode 100644
index 000000000000..1e0389eb0905
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for SSP sensor drivers and commons.
+#
+
+sensorhub-objs				:= ssp_dev.o ssp_spi.o
+obj-$(CONFIG_IIO_SSP_SENSORHUB)		+= sensorhub.o
+
+obj-$(CONFIG_IIO_SSP_SENSORS_COMMONS) 	+= ssp_iio.o
diff --git a/drivers/iio/common/ssp_sensors/ssp.h b/drivers/iio/common/ssp_sensors/ssp.h
new file mode 100644
index 000000000000..b910e91d7c0d
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp.h
@@ -0,0 +1,257 @@
+/*
+ *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#ifndef __SSP_SENSORHUB_H__
+#define __SSP_SENSORHUB_H__
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/iio/common/ssp_sensors.h>
+#include <linux/iio/iio.h>
+#include <linux/spi/spi.h>
+
+#define SSP_DEVICE_ID		0x55
+
+#ifdef SSP_DBG
+#define ssp_dbg(format, ...) pr_info("[SSP] "format, ##__VA_ARGS__)
+#else
+#define ssp_dbg(format, ...)
+#endif
+
+#define SSP_SW_RESET_TIME		3000
+/* Sensor polling in ms */
+#define SSP_DEFAULT_POLLING_DELAY	200
+#define SSP_DEFAULT_RETRIES		3
+#define SSP_DATA_PACKET_SIZE		960
+#define SSP_HEADER_BUFFER_SIZE		4
+
+enum {
+	SSP_KERNEL_BINARY = 0,
+	SSP_KERNEL_CRASHED_BINARY,
+};
+
+enum {
+	SSP_INITIALIZATION_STATE = 0,
+	SSP_NO_SENSOR_STATE,
+	SSP_ADD_SENSOR_STATE,
+	SSP_RUNNING_SENSOR_STATE,
+};
+
+/* Firmware download STATE */
+enum {
+	SSP_FW_DL_STATE_FAIL = -1,
+	SSP_FW_DL_STATE_NONE = 0,
+	SSP_FW_DL_STATE_NEED_TO_SCHEDULE,
+	SSP_FW_DL_STATE_SCHEDULED,
+	SSP_FW_DL_STATE_DOWNLOADING,
+	SSP_FW_DL_STATE_SYNC,
+	SSP_FW_DL_STATE_DONE,
+};
+
+#define SSP_INVALID_REVISION			99999
+#define SSP_INVALID_REVISION2			0xffffff
+
+/* AP -> SSP Instruction */
+#define SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD	0xa1
+#define SSP_MSG2SSP_INST_BYPASS_SENSOR_RM	0xa2
+#define SSP_MSG2SSP_INST_REMOVE_ALL		0xa3
+#define SSP_MSG2SSP_INST_CHANGE_DELAY		0xa4
+#define SSP_MSG2SSP_INST_LIBRARY_ADD		0xb1
+#define SSP_MSG2SSP_INST_LIBRARY_REMOVE		0xb2
+#define SSP_MSG2SSP_INST_LIB_NOTI		0xb4
+#define SSP_MSG2SSP_INST_LIB_DATA		0xc1
+
+#define SSP_MSG2SSP_AP_MCU_SET_GYRO_CAL		0xcd
+#define SSP_MSG2SSP_AP_MCU_SET_ACCEL_CAL	0xce
+#define SSP_MSG2SSP_AP_STATUS_SHUTDOWN		0xd0
+#define SSP_MSG2SSP_AP_STATUS_WAKEUP		0xd1
+#define SSP_MSG2SSP_AP_STATUS_SLEEP		0xd2
+#define SSP_MSG2SSP_AP_STATUS_RESUME		0xd3
+#define SSP_MSG2SSP_AP_STATUS_SUSPEND		0xd4
+#define SSP_MSG2SSP_AP_STATUS_RESET		0xd5
+#define SSP_MSG2SSP_AP_STATUS_POW_CONNECTED	0xd6
+#define SSP_MSG2SSP_AP_STATUS_POW_DISCONNECTED	0xd7
+#define SSP_MSG2SSP_AP_TEMPHUMIDITY_CAL_DONE	0xda
+#define SSP_MSG2SSP_AP_MCU_SET_DUMPMODE		0xdb
+#define SSP_MSG2SSP_AP_MCU_DUMP_CHECK		0xdc
+#define SSP_MSG2SSP_AP_MCU_BATCH_FLUSH		0xdd
+#define SSP_MSG2SSP_AP_MCU_BATCH_COUNT		0xdf
+
+#define SSP_MSG2SSP_AP_WHOAMI				0x0f
+#define SSP_MSG2SSP_AP_FIRMWARE_REV			0xf0
+#define SSP_MSG2SSP_AP_SENSOR_FORMATION			0xf1
+#define SSP_MSG2SSP_AP_SENSOR_PROXTHRESHOLD		0xf2
+#define SSP_MSG2SSP_AP_SENSOR_BARCODE_EMUL		0xf3
+#define SSP_MSG2SSP_AP_SENSOR_SCANNING			0xf4
+#define SSP_MSG2SSP_AP_SET_MAGNETIC_HWOFFSET		0xf5
+#define SSP_MSG2SSP_AP_GET_MAGNETIC_HWOFFSET		0xf6
+#define SSP_MSG2SSP_AP_SENSOR_GESTURE_CURRENT		0xf7
+#define SSP_MSG2SSP_AP_GET_THERM			0xf8
+#define SSP_MSG2SSP_AP_GET_BIG_DATA			0xf9
+#define SSP_MSG2SSP_AP_SET_BIG_DATA			0xfa
+#define SSP_MSG2SSP_AP_START_BIG_DATA			0xfb
+#define SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX	0xfd
+#define SSP_MSG2SSP_AP_SENSOR_TILT			0xea
+#define SSP_MSG2SSP_AP_MCU_SET_TIME			0xfe
+#define SSP_MSG2SSP_AP_MCU_GET_TIME			0xff
+
+#define SSP_MSG2SSP_AP_FUSEROM				0x01
+
+/* voice data */
+#define SSP_TYPE_WAKE_UP_VOICE_SERVICE			0x01
+#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_AM		0x01
+#define SSP_TYPE_WAKE_UP_VOICE_SOUND_SOURCE_GRAMMER	0x02
+
+/* Factory Test */
+#define SSP_ACCELEROMETER_FACTORY			0x80
+#define SSP_GYROSCOPE_FACTORY				0x81
+#define SSP_GEOMAGNETIC_FACTORY				0x82
+#define SSP_PRESSURE_FACTORY				0x85
+#define SSP_GESTURE_FACTORY				0x86
+#define SSP_TEMPHUMIDITY_CRC_FACTORY			0x88
+#define SSP_GYROSCOPE_TEMP_FACTORY			0x8a
+#define SSP_GYROSCOPE_DPS_FACTORY			0x8b
+#define SSP_MCU_FACTORY					0x8c
+#define SSP_MCU_SLEEP_FACTORY				0x8d
+
+/* SSP -> AP ACK about write CMD */
+#define SSP_MSG_ACK		0x80	/* ACK from SSP to AP */
+#define SSP_MSG_NAK		0x70	/* NAK from SSP to AP */
+
+struct ssp_sensorhub_info {
+	char *fw_name;
+	char *fw_crashed_name;
+	unsigned int fw_rev;
+	const u8 * const mag_table;
+	const unsigned int mag_length;
+};
+
+/* ssp_msg options bit */
+#define SSP_RW		0
+#define SSP_INDEX	3
+
+#define SSP_AP2HUB_READ		0
+#define SSP_AP2HUB_WRITE	1
+#define SSP_HUB2AP_WRITE	2
+#define SSP_AP2HUB_READY	3
+#define SSP_AP2HUB_RETURN	4
+
+/**
+ * struct ssp_data - ssp platformdata structure
+ * @spi:		spi device
+ * @sensorhub_info:	info about sensorhub board specific features
+ * @wdt_timer:		watchdog timer
+ * @work_wdt:		watchdog work
+ * @work_firmware:	firmware upgrade work queue
+ * @work_refresh:	refresh work queue for reset request from MCU
+ * @shut_down:		shut down flag
+ * @mcu_dump_mode:	mcu dump mode for debug
+ * @time_syncing:	time syncing indication flag
+ * @timestamp:		previous time in ns calculated for time syncing
+ * @check_status:	status table for each sensor
+ * @com_fail_cnt:	communication fail count
+ * @reset_cnt:		reset count
+ * @timeout_cnt:	timeout count
+ * @available_sensors:	available sensors seen by sensorhub (bit array)
+ * @cur_firm_rev:	cached current firmware revision
+ * @last_resume_state:	last AP resume/suspend state used to handle the PM
+ *                      state of ssp
+ * @last_ap_state:	(obsolete) sleep notification for MCU
+ * @sensor_enable:	sensor enable mask
+ * @delay_buf:		data acquisition intervals table
+ * @batch_latency_buf:	yet unknown but existing in communication protocol
+ * @batch_opt_buf:	yet unknown but existing in communication protocol
+ * @accel_position:	yet unknown but existing in communication protocol
+ * @mag_position:	yet unknown but existing in communication protocol
+ * @fw_dl_state:	firmware download state
+ * @comm_lock:		lock protecting the handshake
+ * @pending_lock:	lock protecting pending list and completion
+ * @mcu_reset_gpio:	mcu reset line
+ * @ap_mcu_gpio:	ap to mcu gpio line
+ * @mcu_ap_gpio:	mcu to ap gpio line
+ * @pending_list:	pending list for messages queued to be sent/read
+ * @sensor_devs:	registered IIO devices table
+ * @enable_refcount:	enable reference count for wdt (watchdog timer)
+ * @header_buffer:	cache aligned buffer for packet header
+ */
+struct ssp_data {
+	struct spi_device *spi;
+	struct ssp_sensorhub_info *sensorhub_info;
+	struct timer_list wdt_timer;
+	struct work_struct work_wdt;
+	struct delayed_work work_refresh;
+
+	bool shut_down;
+	bool mcu_dump_mode;
+	bool time_syncing;
+	int64_t timestamp;
+
+	int check_status[SSP_SENSOR_MAX];
+
+	unsigned int com_fail_cnt;
+	unsigned int reset_cnt;
+	unsigned int timeout_cnt;
+
+	unsigned int available_sensors;
+	unsigned int cur_firm_rev;
+
+	char last_resume_state;
+	char last_ap_state;
+
+	unsigned int sensor_enable;
+	u32 delay_buf[SSP_SENSOR_MAX];
+	s32 batch_latency_buf[SSP_SENSOR_MAX];
+	s8 batch_opt_buf[SSP_SENSOR_MAX];
+
+	int accel_position;
+	int mag_position;
+	int fw_dl_state;
+
+	struct mutex comm_lock;
+	struct mutex pending_lock;
+
+	int mcu_reset_gpio;
+	int ap_mcu_gpio;
+	int mcu_ap_gpio;
+
+	struct list_head pending_list;
+
+	struct iio_dev *sensor_devs[SSP_SENSOR_MAX];
+	atomic_t enable_refcount;
+
+	__le16 header_buffer[SSP_HEADER_BUFFER_SIZE / sizeof(__le16)]
+		____cacheline_aligned;
+};
+
+void ssp_clean_pending_list(struct ssp_data *data);
+
+int ssp_command(struct ssp_data *data, char command, int arg);
+
+int ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type,
+			 u8 *send_buf, u8 length);
+
+int ssp_irq_msg(struct ssp_data *data);
+
+int ssp_get_chipid(struct ssp_data *data);
+
+int ssp_set_magnetic_matrix(struct ssp_data *data);
+
+unsigned int ssp_get_sensor_scanning_info(struct ssp_data *data);
+
+unsigned int ssp_get_firmware_rev(struct ssp_data *data);
+
+int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay);
+
+#endif /* __SSP_SENSORHUB_H__ */
diff --git a/drivers/iio/common/ssp_sensors/ssp_dev.c b/drivers/iio/common/ssp_sensors/ssp_dev.c
new file mode 100644
index 000000000000..52d70435f5a1
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp_dev.c
@@ -0,0 +1,712 @@
+/*
+ *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include <linux/iio/iio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include "ssp.h"
+
+#define SSP_WDT_TIME			10000
+#define SSP_LIMIT_RESET_CNT		20
+#define SSP_LIMIT_TIMEOUT_CNT		3
+
+/* It is possible that it is max clk rate for version 1.0 of bootcode */
+#define SSP_BOOT_SPI_HZ	400000
+
+/*
+ * These fields can look enigmatic but this structure is used mainly to flat
+ * some values and depends on command type.
+ */
+struct ssp_instruction {
+	__le32 a;
+	__le32 b;
+	u8 c;
+} __attribute__((__packed__));
+
+static const u8 ssp_magnitude_table[] = {110, 85, 171, 71, 203, 195, 0, 67,
+	208, 56, 175, 244, 206, 213, 0, 92, 250, 0, 55, 48, 189, 252, 171,
+	243, 13, 45, 250};
+
+static const struct ssp_sensorhub_info ssp_rinato_info = {
+	.fw_name = "ssp_B2.fw",
+	.fw_crashed_name = "ssp_crashed.fw",
+	.fw_rev = 14052300,
+	.mag_table = ssp_magnitude_table,
+	.mag_length = ARRAY_SIZE(ssp_magnitude_table),
+};
+
+static const struct ssp_sensorhub_info ssp_thermostat_info = {
+	.fw_name = "thermostat_B2.fw",
+	.fw_crashed_name = "ssp_crashed.fw",
+	.fw_rev = 14080600,
+	.mag_table = ssp_magnitude_table,
+	.mag_length = ARRAY_SIZE(ssp_magnitude_table),
+};
+
+static const struct mfd_cell sensorhub_sensor_devs[] = {
+	{
+		.name = "ssp-accelerometer",
+	},
+	{
+		.name = "ssp-gyroscope",
+	},
+};
+
+static void ssp_toggle_mcu_reset_gpio(struct ssp_data *data)
+{
+	gpio_set_value(data->mcu_reset_gpio, 0);
+	usleep_range(1000, 1200);
+	gpio_set_value(data->mcu_reset_gpio, 1);
+	msleep(50);
+}
+
+static void ssp_sync_available_sensors(struct ssp_data *data)
+{
+	int i, ret;
+
+	for (i = 0; i < SSP_SENSOR_MAX; ++i) {
+		if (data->available_sensors & BIT(i)) {
+			ret = ssp_enable_sensor(data, i, data->delay_buf[i]);
+			if (ret < 0) {
+				dev_err(&data->spi->dev,
+					"Sync sensor nr: %d fail\n", i);
+				continue;
+			}
+		}
+	}
+
+	ret = ssp_command(data, SSP_MSG2SSP_AP_MCU_SET_DUMPMODE,
+			  data->mcu_dump_mode);
+	if (ret < 0)
+		dev_err(&data->spi->dev,
+			"SSP_MSG2SSP_AP_MCU_SET_DUMPMODE failed\n");
+}
+
+static void ssp_enable_mcu(struct ssp_data *data, bool enable)
+{
+	dev_info(&data->spi->dev, "current shutdown = %d, old = %d\n", enable,
+		 data->shut_down);
+
+	if (enable && data->shut_down) {
+		data->shut_down = false;
+		enable_irq(data->spi->irq);
+		enable_irq_wake(data->spi->irq);
+	} else if (!enable && !data->shut_down) {
+		data->shut_down = true;
+		disable_irq(data->spi->irq);
+		disable_irq_wake(data->spi->irq);
+	} else {
+		dev_warn(&data->spi->dev, "current shutdown = %d, old = %d\n",
+			 enable, data->shut_down);
+	}
+}
+
+/*
+ * This function is the first one which communicates with the mcu so it is
+ * possible that the first attempt will fail
+ */
+static int ssp_check_fwbl(struct ssp_data *data)
+{
+	int retries = 0;
+
+	while (retries++ < 5) {
+		data->cur_firm_rev = ssp_get_firmware_rev(data);
+		if (data->cur_firm_rev == SSP_INVALID_REVISION ||
+		    data->cur_firm_rev == SSP_INVALID_REVISION2) {
+			dev_warn(&data->spi->dev,
+				 "Invalid revision, trying %d time\n", retries);
+		} else {
+			break;
+		}
+	}
+
+	if (data->cur_firm_rev == SSP_INVALID_REVISION ||
+	    data->cur_firm_rev == SSP_INVALID_REVISION2) {
+		dev_err(&data->spi->dev, "SSP_INVALID_REVISION\n");
+		return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
+	}
+
+	dev_info(&data->spi->dev,
+		 "MCU Firm Rev : Old = %8u, New = %8u\n",
+		 data->cur_firm_rev,
+		 data->sensorhub_info->fw_rev);
+
+	if (data->cur_firm_rev != data->sensorhub_info->fw_rev)
+		return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
+
+	return SSP_FW_DL_STATE_NONE;
+}
+
+static void ssp_reset_mcu(struct ssp_data *data)
+{
+	ssp_enable_mcu(data, false);
+	ssp_clean_pending_list(data);
+	ssp_toggle_mcu_reset_gpio(data);
+	ssp_enable_mcu(data, true);
+}
+
+static void ssp_wdt_work_func(struct work_struct *work)
+{
+	struct ssp_data *data = container_of(work, struct ssp_data, work_wdt);
+
+	dev_err(&data->spi->dev, "%s - Sensor state: 0x%x, RC: %u, CC: %u\n",
+		__func__, data->available_sensors, data->reset_cnt,
+		data->com_fail_cnt);
+
+	ssp_reset_mcu(data);
+	data->com_fail_cnt = 0;
+	data->timeout_cnt = 0;
+}
+
+static void ssp_wdt_timer_func(unsigned long ptr)
+{
+	struct ssp_data *data = (struct ssp_data *)ptr;
+
+	switch (data->fw_dl_state) {
+	case SSP_FW_DL_STATE_FAIL:
+	case SSP_FW_DL_STATE_DOWNLOADING:
+	case SSP_FW_DL_STATE_SYNC:
+		goto _mod;
+	}
+
+	if (data->timeout_cnt > SSP_LIMIT_TIMEOUT_CNT ||
+	    data->com_fail_cnt > SSP_LIMIT_RESET_CNT)
+		queue_work(system_power_efficient_wq, &data->work_wdt);
+_mod:
+	mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
+}
+
+static void ssp_enable_wdt_timer(struct ssp_data *data)
+{
+	mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
+}
+
+static void ssp_disable_wdt_timer(struct ssp_data *data)
+{
+	del_timer_sync(&data->wdt_timer);
+	cancel_work_sync(&data->work_wdt);
+}
+
+/**
+ * ssp_get_sensor_delay() - gets sensor data acquisition period
+ * @data:	sensorhub structure
+ * @type:	SSP sensor type
+ *
+ * Returns acquisition period in ms
+ */
+u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type type)
+{
+	return data->delay_buf[type];
+}
+EXPORT_SYMBOL(ssp_get_sensor_delay);
+
+/**
+ * ssp_enable_sensor() - enables data acquisition for sensor
+ * @data:	sensorhub structure
+ * @type:	SSP sensor type
+ * @delay:	delay in ms
+ *
+ * Returns 0 or negative value in case of error
+ */
+int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type,
+		      u32 delay)
+{
+	int ret;
+	struct ssp_instruction to_send;
+
+	to_send.a = cpu_to_le32(delay);
+	to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
+	to_send.c = data->batch_opt_buf[type];
+
+	switch (data->check_status[type]) {
+	case SSP_INITIALIZATION_STATE:
+		/* do calibration step, now just enable */
+	case SSP_ADD_SENSOR_STATE:
+		ret = ssp_send_instruction(data,
+					   SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD,
+					   type,
+					   (u8 *)&to_send, sizeof(to_send));
+		if (ret < 0) {
+			dev_err(&data->spi->dev, "Enabling sensor failed\n");
+			data->check_status[type] = SSP_NO_SENSOR_STATE;
+			goto derror;
+		}
+
+		data->sensor_enable |= BIT(type);
+		data->check_status[type] = SSP_RUNNING_SENSOR_STATE;
+		break;
+	case SSP_RUNNING_SENSOR_STATE:
+		ret = ssp_send_instruction(data,
+					   SSP_MSG2SSP_INST_CHANGE_DELAY, type,
+					   (u8 *)&to_send, sizeof(to_send));
+		if (ret < 0) {
+			dev_err(&data->spi->dev,
+				"Changing sensor delay failed\n");
+			goto derror;
+		}
+		break;
+	default:
+		data->check_status[type] = SSP_ADD_SENSOR_STATE;
+		break;
+	}
+
+	data->delay_buf[type] = delay;
+
+	if (atomic_inc_return(&data->enable_refcount) == 1)
+		ssp_enable_wdt_timer(data);
+
+	return 0;
+
+derror:
+	return ret;
+}
+EXPORT_SYMBOL(ssp_enable_sensor);
+
+/**
+ * ssp_change_delay() - changes data acquisition for sensor
+ * @data:	sensorhub structure
+ * @type:	SSP sensor type
+ * @delay:	delay in ms
+ *
+ * Returns 0 or negative value in case of error
+ */
+int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type,
+		     u32 delay)
+{
+	int ret;
+	struct ssp_instruction to_send;
+
+	to_send.a = cpu_to_le32(delay);
+	to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
+	to_send.c = data->batch_opt_buf[type];
+
+	ret = ssp_send_instruction(data, SSP_MSG2SSP_INST_CHANGE_DELAY, type,
+				   (u8 *)&to_send, sizeof(to_send));
+	if (ret < 0) {
+		dev_err(&data->spi->dev, "Changing sensor delay failed\n");
+		return ret;
+	}
+
+	data->delay_buf[type] = delay;
+
+	return 0;
+}
+EXPORT_SYMBOL(ssp_change_delay);
+
+/**
+ * ssp_disable_sensor() - disables sensor
+ *
+ * @data:	sensorhub structure
+ * @type:	SSP sensor type
+ *
+ * Returns 0 or negative value in case of error
+ */
+int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type)
+{
+	int ret;
+	__le32 command;
+
+	if (data->sensor_enable & BIT(type)) {
+		command = cpu_to_le32(data->delay_buf[type]);
+
+		ret = ssp_send_instruction(data,
+					   SSP_MSG2SSP_INST_BYPASS_SENSOR_RM,
+					   type, (u8 *)&command,
+					   sizeof(command));
+		if (ret < 0) {
+			dev_err(&data->spi->dev, "Remove sensor fail\n");
+			return ret;
+		}
+
+		data->sensor_enable &= ~BIT(type);
+	}
+
+	data->check_status[type] = SSP_ADD_SENSOR_STATE;
+
+	if (atomic_dec_and_test(&data->enable_refcount))
+		ssp_disable_wdt_timer(data);
+
+	return 0;
+}
+EXPORT_SYMBOL(ssp_disable_sensor);
+
+static irqreturn_t ssp_irq_thread_fn(int irq, void *dev_id)
+{
+	struct ssp_data *data = dev_id;
+
+	/*
+	 * This wrapper is done to preserve error path for ssp_irq_msg, also
+	 * it is defined in different file.
+	 */
+	ssp_irq_msg(data);
+
+	return IRQ_HANDLED;
+}
+
+static int ssp_initialize_mcu(struct ssp_data *data)
+{
+	int ret;
+
+	ssp_clean_pending_list(data);
+
+	ret = ssp_get_chipid(data);
+	if (ret != SSP_DEVICE_ID) {
+		dev_err(&data->spi->dev, "%s - MCU %s ret = %d\n", __func__,
+			ret < 0 ? "is not working" : "identification failed",
+			ret);
+		return ret < 0 ? ret : -ENODEV;
+	}
+
+	dev_info(&data->spi->dev, "MCU device ID = %d\n", ret);
+
+	/*
+	 * needs clarification, for now do not want to export all transfer
+	 * methods to sensors' drivers
+	 */
+	ret = ssp_set_magnetic_matrix(data);
+	if (ret < 0) {
+		dev_err(&data->spi->dev,
+			"%s - ssp_set_magnetic_matrix failed\n", __func__);
+		return ret;
+	}
+
+	data->available_sensors = ssp_get_sensor_scanning_info(data);
+	if (data->available_sensors == 0) {
+		dev_err(&data->spi->dev,
+			"%s - ssp_get_sensor_scanning_info failed\n", __func__);
+		return -EIO;
+	}
+
+	data->cur_firm_rev = ssp_get_firmware_rev(data);
+	dev_info(&data->spi->dev, "MCU Firm Rev : New = %8u\n",
+		 data->cur_firm_rev);
+
+	return ssp_command(data, SSP_MSG2SSP_AP_MCU_DUMP_CHECK, 0);
+}
+
+/*
+ * sensorhub can request its reinitialization as some brutal and rare error
+ * handling. It can be requested from the MCU.
+ */
+static void ssp_refresh_task(struct work_struct *work)
+{
+	struct ssp_data *data = container_of((struct delayed_work *)work,
+					     struct ssp_data, work_refresh);
+
+	dev_info(&data->spi->dev, "refreshing\n");
+
+	data->reset_cnt++;
+
+	if (ssp_initialize_mcu(data) >= 0) {
+		ssp_sync_available_sensors(data);
+		if (data->last_ap_state != 0)
+			ssp_command(data, data->last_ap_state, 0);
+
+		if (data->last_resume_state != 0)
+			ssp_command(data, data->last_resume_state, 0);
+
+		data->timeout_cnt = 0;
+		data->com_fail_cnt = 0;
+	}
+}
+
+int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay)
+{
+	cancel_delayed_work_sync(&data->work_refresh);
+
+	return queue_delayed_work(system_power_efficient_wq,
+				  &data->work_refresh,
+				  msecs_to_jiffies(delay));
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id ssp_of_match[] = {
+	{
+		.compatible	= "samsung,sensorhub-rinato",
+		.data		= &ssp_rinato_info,
+	}, {
+		.compatible	= "samsung,sensorhub-thermostat",
+		.data		= &ssp_thermostat_info,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, ssp_of_match);
+
+static struct ssp_data *ssp_parse_dt(struct device *dev)
+{
+	int ret;
+	struct ssp_data *data;
+	struct device_node *node = dev->of_node;
+	const struct of_device_id *match;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return NULL;
+
+	data->mcu_ap_gpio = of_get_named_gpio(node, "mcu-ap-gpios", 0);
+	if (data->mcu_ap_gpio < 0)
+		goto err_free_pd;
+
+	data->ap_mcu_gpio = of_get_named_gpio(node, "ap-mcu-gpios", 0);
+	if (data->ap_mcu_gpio < 0)
+		goto err_free_pd;
+
+	data->mcu_reset_gpio = of_get_named_gpio(node, "mcu-reset-gpios", 0);
+	if (data->mcu_reset_gpio < 0)
+		goto err_free_pd;
+
+	ret = devm_gpio_request_one(dev, data->ap_mcu_gpio, GPIOF_OUT_INIT_HIGH,
+				    "ap-mcu-gpios");
+	if (ret)
+		goto err_free_pd;
+
+	ret = devm_gpio_request_one(dev, data->mcu_reset_gpio,
+				    GPIOF_OUT_INIT_HIGH, "mcu-reset-gpios");
+	if (ret)
+		goto err_ap_mcu;
+
+	match = of_match_node(ssp_of_match, node);
+	if (!match)
+		goto err_mcu_reset_gpio;
+
+	data->sensorhub_info = (struct ssp_sensorhub_info *)match->data;
+
+	dev_set_drvdata(dev, data);
+
+	return data;
+
+err_mcu_reset_gpio:
+	devm_gpio_free(dev, data->mcu_reset_gpio);
+err_ap_mcu:
+	devm_gpio_free(dev, data->ap_mcu_gpio);
+err_free_pd:
+	devm_kfree(dev, data);
+	return NULL;
+}
+#else
+static struct ssp_data *ssp_parse_dt(struct device *pdev)
+{
+	return NULL;
+}
+#endif
+
+/**
+ * ssp_register_consumer() - registers iio consumer in ssp framework
+ *
+ * @indio_dev:	consumer iio device
+ * @type:	ssp sensor type
+ */
+void ssp_register_consumer(struct iio_dev *indio_dev, enum ssp_sensor_type type)
+{
+	struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
+
+	data->sensor_devs[type] = indio_dev;
+}
+EXPORT_SYMBOL(ssp_register_consumer);
+
+static int ssp_probe(struct spi_device *spi)
+{
+	int ret, i;
+	struct ssp_data *data;
+
+	data = ssp_parse_dt(&spi->dev);
+	if (!data) {
+		dev_err(&spi->dev, "Failed to find platform data\n");
+		return -ENODEV;
+	}
+
+	ret = mfd_add_devices(&spi->dev, -1, sensorhub_sensor_devs,
+			      ARRAY_SIZE(sensorhub_sensor_devs), NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(&spi->dev, "mfd add devices fail\n");
+		return ret;
+	}
+
+	spi->mode = SPI_MODE_1;
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(&spi->dev, "Failed to setup spi\n");
+		return ret;
+	}
+
+	data->fw_dl_state = SSP_FW_DL_STATE_NONE;
+	data->spi = spi;
+	spi_set_drvdata(spi, data);
+
+	mutex_init(&data->comm_lock);
+
+	for (i = 0; i < SSP_SENSOR_MAX; ++i) {
+		data->delay_buf[i] = SSP_DEFAULT_POLLING_DELAY;
+		data->batch_latency_buf[i] = 0;
+		data->batch_opt_buf[i] = 0;
+		data->check_status[i] = SSP_INITIALIZATION_STATE;
+	}
+
+	data->delay_buf[SSP_BIO_HRM_LIB] = 100;
+
+	data->time_syncing = true;
+
+	mutex_init(&data->pending_lock);
+	INIT_LIST_HEAD(&data->pending_list);
+
+	atomic_set(&data->enable_refcount, 0);
+
+	INIT_WORK(&data->work_wdt, ssp_wdt_work_func);
+	INIT_DELAYED_WORK(&data->work_refresh, ssp_refresh_task);
+
+	setup_timer(&data->wdt_timer, ssp_wdt_timer_func, (unsigned long)data);
+
+	ret = request_threaded_irq(data->spi->irq, NULL,
+				   ssp_irq_thread_fn,
+				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+				   "SSP_Int", data);
+	if (ret < 0) {
+		dev_err(&spi->dev, "Irq request fail\n");
+		goto err_setup_irq;
+	}
+
+	/* Let's start with enabled one so irq balance could be ok */
+	data->shut_down = false;
+
+	/* just to avoid unbalanced irq set wake up */
+	enable_irq_wake(data->spi->irq);
+
+	data->fw_dl_state = ssp_check_fwbl(data);
+	if (data->fw_dl_state == SSP_FW_DL_STATE_NONE) {
+		ret = ssp_initialize_mcu(data);
+		if (ret < 0) {
+			dev_err(&spi->dev, "Initialize_mcu failed\n");
+			goto err_read_reg;
+		}
+	} else {
+		dev_err(&spi->dev, "Firmware version not supported\n");
+		ret = -EPERM;
+		goto err_read_reg;
+	}
+
+	return 0;
+
+err_read_reg:
+	free_irq(data->spi->irq, data);
+err_setup_irq:
+	mutex_destroy(&data->pending_lock);
+	mutex_destroy(&data->comm_lock);
+
+	dev_err(&spi->dev, "Probe failed!\n");
+
+	return ret;
+}
+
+static int ssp_remove(struct spi_device *spi)
+{
+	struct ssp_data *data = spi_get_drvdata(spi);
+
+	if (ssp_command(data, SSP_MSG2SSP_AP_STATUS_SHUTDOWN, 0) < 0)
+		dev_err(&data->spi->dev,
+			"SSP_MSG2SSP_AP_STATUS_SHUTDOWN failed\n");
+
+	ssp_enable_mcu(data, false);
+	ssp_disable_wdt_timer(data);
+
+	ssp_clean_pending_list(data);
+
+	free_irq(data->spi->irq, data);
+
+	del_timer_sync(&data->wdt_timer);
+	cancel_work_sync(&data->work_wdt);
+
+	mutex_destroy(&data->comm_lock);
+	mutex_destroy(&data->pending_lock);
+
+	mfd_remove_devices(&spi->dev);
+
+	return 0;
+}
+
+static int ssp_suspend(struct device *dev)
+{
+	int ret;
+	struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
+
+	data->last_resume_state = SSP_MSG2SSP_AP_STATUS_SUSPEND;
+
+	if (atomic_read(&data->enable_refcount) > 0)
+		ssp_disable_wdt_timer(data);
+
+	ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_SUSPEND, 0);
+	if (ret < 0) {
+		dev_err(&data->spi->dev,
+			"%s SSP_MSG2SSP_AP_STATUS_SUSPEND failed\n", __func__);
+
+		ssp_enable_wdt_timer(data);
+		return ret;
+	}
+
+	data->time_syncing = false;
+	disable_irq(data->spi->irq);
+
+	return 0;
+}
+
+static int ssp_resume(struct device *dev)
+{
+	int ret;
+	struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
+
+	enable_irq(data->spi->irq);
+
+	if (atomic_read(&data->enable_refcount) > 0)
+		ssp_enable_wdt_timer(data);
+
+	ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_RESUME, 0);
+	if (ret < 0) {
+		dev_err(&data->spi->dev,
+			"%s SSP_MSG2SSP_AP_STATUS_RESUME failed\n", __func__);
+		ssp_disable_wdt_timer(data);
+		return ret;
+	}
+
+	/* timesyncing is set by MCU */
+	data->last_resume_state = SSP_MSG2SSP_AP_STATUS_RESUME;
+
+	return 0;
+}
+
+static const struct dev_pm_ops ssp_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(ssp_suspend, ssp_resume)
+};
+
+static struct spi_driver ssp_driver = {
+	.probe = ssp_probe,
+	.remove = ssp_remove,
+	.driver = {
+		.pm = &ssp_pm_ops,
+		.bus = &spi_bus_type,
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(ssp_of_match),
+		.name = "sensorhub"
+	},
+};
+
+module_spi_driver(ssp_driver);
+
+MODULE_DESCRIPTION("ssp sensorhub driver");
+MODULE_AUTHOR("Samsung Electronics");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio.c b/drivers/iio/common/ssp_sensors/ssp_iio.c
new file mode 100644
index 000000000000..a3ae165f8d9f
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp_iio.c
@@ -0,0 +1,107 @@
+/*
+ *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include <linux/iio/common/ssp_sensors.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include "ssp_iio_sensor.h"
+
+/**
+ * ssp_common_buffer_postenable() - generic postenable callback for ssp buffer
+ *
+ * @indio_dev:		iio device
+ *
+ * Returns 0 or negative value in case of error
+ */
+int ssp_common_buffer_postenable(struct iio_dev *indio_dev)
+{
+	struct ssp_sensor_data *spd = iio_priv(indio_dev);
+	struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
+
+	/* the allocation is made in post because scan size is known in this
+	 * moment
+	 * */
+	spd->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL | GFP_DMA);
+	if (!spd->buffer)
+		return -ENOMEM;
+
+	return ssp_enable_sensor(data, spd->type,
+				 ssp_get_sensor_delay(data, spd->type));
+}
+EXPORT_SYMBOL(ssp_common_buffer_postenable);
+
+/**
+ * ssp_common_buffer_postdisable() - generic postdisable callback for ssp buffer
+ *
+ * @indio_dev:		iio device
+ *
+ * Returns 0 or negative value in case of error
+ */
+int ssp_common_buffer_postdisable(struct iio_dev *indio_dev)
+{
+	int ret;
+	struct ssp_sensor_data *spd = iio_priv(indio_dev);
+	struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
+
+	ret = ssp_disable_sensor(data, spd->type);
+	if (ret < 0)
+		return ret;
+
+	kfree(spd->buffer);
+
+	return ret;
+}
+EXPORT_SYMBOL(ssp_common_buffer_postdisable);
+
+/**
+ * ssp_common_process_data() - Common process data callback for ssp sensors
+ *
+ * @indio_dev:		iio device
+ * @buf:		source buffer
+ * @len:		sensor data length
+ * @timestamp:		system timestamp
+ *
+ * Returns 0 or negative value in case of error
+ */
+int ssp_common_process_data(struct iio_dev *indio_dev, void *buf,
+			    unsigned int len, int64_t timestamp)
+{
+	__le32 time;
+	int64_t calculated_time;
+	struct ssp_sensor_data *spd = iio_priv(indio_dev);
+
+	if (indio_dev->scan_bytes == 0)
+		return 0;
+
+	/*
+	 * it always sends full set of samples, remember about available masks
+	 */
+	memcpy(spd->buffer, buf, len);
+
+	if (indio_dev->scan_timestamp) {
+		memcpy(&time, &((char *)buf)[len], SSP_TIME_SIZE);
+		calculated_time =
+			timestamp + (int64_t)le32_to_cpu(time) * 1000000;
+	}
+
+	return iio_push_to_buffers_with_timestamp(indio_dev, spd->buffer,
+						  calculated_time);
+}
+EXPORT_SYMBOL(ssp_common_process_data);
+
+MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
+MODULE_DESCRIPTION("Samsung sensorhub commons");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h b/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h
new file mode 100644
index 000000000000..541c6590d69c
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp_iio_sensor.h
@@ -0,0 +1,71 @@
+#ifndef __SSP_IIO_SENSOR_H__
+#define __SSP_IIO_SENSOR_H__
+
+#define SSP_CHANNEL_AG(_type, _mod, _index) \
+{ \
+		.type = _type,\
+		.modified = 1,\
+		.channel2 = _mod,\
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
+		.scan_index = _index,\
+		.scan_type = {\
+			.sign = 's',\
+			.realbits = 16,\
+			.storagebits = 16,\
+			.shift = 0,\
+			.endianness = IIO_LE,\
+		},\
+}
+
+/* It is defined here as it is a mixed timestamp */
+#define SSP_CHAN_TIMESTAMP(_si) {					\
+	.type = IIO_TIMESTAMP,						\
+	.channel = -1,							\
+	.scan_index = _si,						\
+	.scan_type = {							\
+		.sign = 's',						\
+		.realbits = 64,						\
+		.storagebits = 64,					\
+		},							\
+}
+
+#define SSP_MS_PER_S			1000
+#define SSP_INVERTED_SCALING_FACTOR	1000000U
+
+#define SSP_FACTOR_WITH_MS \
+	(SSP_INVERTED_SCALING_FACTOR * SSP_MS_PER_S)
+
+int ssp_common_buffer_postenable(struct iio_dev *indio_dev);
+
+int ssp_common_buffer_postdisable(struct iio_dev *indio_dev);
+
+int ssp_common_process_data(struct iio_dev *indio_dev, void *buf,
+			    unsigned int len, int64_t timestamp);
+
+/* Converts time in ms to frequency */
+static inline void ssp_convert_to_freq(u32 time, int *integer_part,
+				       int *fractional)
+{
+	if (time == 0) {
+		*fractional = 0;
+		*integer_part = 0;
+		return;
+	}
+
+	*integer_part = SSP_FACTOR_WITH_MS / time;
+	*fractional = *integer_part % SSP_INVERTED_SCALING_FACTOR;
+	*integer_part = *integer_part / SSP_INVERTED_SCALING_FACTOR;
+}
+
+/* Converts frequency to time in ms */
+static inline int ssp_convert_to_time(int integer_part, int fractional)
+{
+	u64 value;
+
+	value = (u64)integer_part * SSP_INVERTED_SCALING_FACTOR + fractional;
+	if (value == 0)
+		return 0;
+
+	return div64_u64((u64)SSP_FACTOR_WITH_MS, value);
+}
+#endif /* __SSP_IIO_SENSOR_H__ */
diff --git a/drivers/iio/common/ssp_sensors/ssp_spi.c b/drivers/iio/common/ssp_sensors/ssp_spi.c
new file mode 100644
index 000000000000..704284a475ae
--- /dev/null
+++ b/drivers/iio/common/ssp_sensors/ssp_spi.c
@@ -0,0 +1,608 @@
+/*
+ *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include "ssp.h"
+
+#define SSP_DEV (&data->spi->dev)
+#define SSP_GET_MESSAGE_TYPE(data) (data & (3 << SSP_RW))
+
+/*
+ * SSP -> AP Instruction
+ * They tell what packet type can be expected. In the future there will
+ * be less of them. BYPASS means common sensor packets with accel, gyro,
+ * hrm etc. data. LIBRARY and META are mock-up's for now.
+ */
+#define SSP_MSG2AP_INST_BYPASS_DATA		0x37
+#define SSP_MSG2AP_INST_LIBRARY_DATA		0x01
+#define SSP_MSG2AP_INST_DEBUG_DATA		0x03
+#define SSP_MSG2AP_INST_BIG_DATA		0x04
+#define SSP_MSG2AP_INST_META_DATA		0x05
+#define SSP_MSG2AP_INST_TIME_SYNC		0x06
+#define SSP_MSG2AP_INST_RESET			0x07
+
+#define SSP_UNIMPLEMENTED -1
+
+struct ssp_msg_header {
+	u8 cmd;
+	__le16 length;
+	__le16 options;
+	__le32 data;
+} __attribute__((__packed__));
+
+struct ssp_msg {
+	u16 length;
+	u16 options;
+	struct list_head list;
+	struct completion *done;
+	struct ssp_msg_header *h;
+	char *buffer;
+};
+
+static const int ssp_offset_map[SSP_SENSOR_MAX] = {
+	[SSP_ACCELEROMETER_SENSOR] =		SSP_ACCELEROMETER_SIZE +
+						SSP_TIME_SIZE,
+	[SSP_GYROSCOPE_SENSOR] =		SSP_GYROSCOPE_SIZE +
+						SSP_TIME_SIZE,
+	[SSP_GEOMAGNETIC_UNCALIB_SENSOR] =	SSP_UNIMPLEMENTED,
+	[SSP_GEOMAGNETIC_RAW] =			SSP_UNIMPLEMENTED,
+	[SSP_GEOMAGNETIC_SENSOR] =		SSP_UNIMPLEMENTED,
+	[SSP_PRESSURE_SENSOR] =			SSP_UNIMPLEMENTED,
+	[SSP_GESTURE_SENSOR] =			SSP_UNIMPLEMENTED,
+	[SSP_PROXIMITY_SENSOR] =		SSP_UNIMPLEMENTED,
+	[SSP_TEMPERATURE_HUMIDITY_SENSOR] =	SSP_UNIMPLEMENTED,
+	[SSP_LIGHT_SENSOR] =			SSP_UNIMPLEMENTED,
+	[SSP_PROXIMITY_RAW] =			SSP_UNIMPLEMENTED,
+	[SSP_ORIENTATION_SENSOR] =		SSP_UNIMPLEMENTED,
+	[SSP_STEP_DETECTOR] =			SSP_UNIMPLEMENTED,
+	[SSP_SIG_MOTION_SENSOR] =		SSP_UNIMPLEMENTED,
+	[SSP_GYRO_UNCALIB_SENSOR] =		SSP_UNIMPLEMENTED,
+	[SSP_GAME_ROTATION_VECTOR] =		SSP_UNIMPLEMENTED,
+	[SSP_ROTATION_VECTOR] =			SSP_UNIMPLEMENTED,
+	[SSP_STEP_COUNTER] =			SSP_UNIMPLEMENTED,
+	[SSP_BIO_HRM_RAW] =			SSP_BIO_HRM_RAW_SIZE +
+						SSP_TIME_SIZE,
+	[SSP_BIO_HRM_RAW_FAC] =			SSP_BIO_HRM_RAW_FAC_SIZE +
+						SSP_TIME_SIZE,
+	[SSP_BIO_HRM_LIB] =			SSP_BIO_HRM_LIB_SIZE +
+						SSP_TIME_SIZE,
+};
+
+#define SSP_HEADER_SIZE		(sizeof(struct ssp_msg_header))
+#define SSP_HEADER_SIZE_ALIGNED	(ALIGN(SSP_HEADER_SIZE, 4))
+
+static struct ssp_msg *ssp_create_msg(u8 cmd, u16 len, u16 opt, u32 data)
+{
+	struct ssp_msg_header h;
+	struct ssp_msg *msg;
+
+	msg = kzalloc(sizeof(*msg), GFP_KERNEL);
+	if (!msg)
+		return NULL;
+
+	h.cmd = cmd;
+	h.length = cpu_to_le16(len);
+	h.options = cpu_to_le16(opt);
+	h.data = cpu_to_le32(data);
+
+	msg->buffer = kzalloc(SSP_HEADER_SIZE_ALIGNED + len,
+			      GFP_KERNEL | GFP_DMA);
+	if (!msg->buffer) {
+		kfree(msg);
+		return NULL;
+	}
+
+	msg->length = len;
+	msg->options = opt;
+
+	memcpy(msg->buffer, &h, SSP_HEADER_SIZE);
+
+	return msg;
+}
+
+/*
+ * It is a bit heavy to do it this way but often the function is used to compose
+ * the message from smaller chunks which are placed on the stack.  Often the
+ * chunks are small so memcpy should be optimalized.
+ */
+static inline void ssp_fill_buffer(struct ssp_msg *m, unsigned int offset,
+				   const void *src, unsigned int len)
+{
+	memcpy(&m->buffer[SSP_HEADER_SIZE_ALIGNED + offset], src, len);
+}
+
+static inline void ssp_get_buffer(struct ssp_msg *m, unsigned int offset,
+				  void *dest, unsigned int len)
+{
+	memcpy(dest, &m->buffer[SSP_HEADER_SIZE_ALIGNED + offset],  len);
+}
+
+#define SSP_GET_BUFFER_AT_INDEX(m, index) \
+	(m->buffer[SSP_HEADER_SIZE_ALIGNED + index])
+#define SSP_SET_BUFFER_AT_INDEX(m, index, val) \
+	(m->buffer[SSP_HEADER_SIZE_ALIGNED + index] = val)
+
+static void ssp_clean_msg(struct ssp_msg *m)
+{
+	kfree(m->buffer);
+	kfree(m);
+}
+
+static int ssp_print_mcu_debug(char *data_frame, int *data_index,
+			       int received_len)
+{
+	int length = data_frame[(*data_index)++];
+
+	if (length > received_len - *data_index || length <= 0) {
+		ssp_dbg("[SSP]: MSG From MCU-invalid debug length(%d/%d)\n",
+			length, received_len);
+		return length ? length : -EPROTO;
+	}
+
+	ssp_dbg("[SSP]: MSG From MCU - %s\n", &data_frame[*data_index]);
+
+	*data_index += length;
+
+	return 0;
+}
+
+/*
+ * It was designed that way - additional lines to some kind of handshake,
+ * please do not ask why - only the firmware guy can know it.
+ */
+static int ssp_check_lines(struct ssp_data *data, bool state)
+{
+	int delay_cnt = 0;
+
+	gpio_set_value_cansleep(data->ap_mcu_gpio, state);
+
+	while (gpio_get_value_cansleep(data->mcu_ap_gpio) != state) {
+		usleep_range(3000, 3500);
+
+		if (data->shut_down || delay_cnt++ > 500) {
+			dev_err(SSP_DEV, "%s:timeout, hw ack wait fail %d\n",
+				__func__, state);
+
+			if (!state)
+				gpio_set_value_cansleep(data->ap_mcu_gpio, 1);
+
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static int ssp_do_transfer(struct ssp_data *data, struct ssp_msg *msg,
+			   struct completion *done, int timeout)
+{
+	int status;
+	/*
+	 * check if this is a short one way message or the whole transfer has
+	 * second part after an interrupt
+	 */
+	const bool use_no_irq = msg->length == 0;
+
+	if (data->shut_down)
+		return -EPERM;
+
+	msg->done = done;
+
+	mutex_lock(&data->comm_lock);
+
+	status = ssp_check_lines(data, false);
+	if (status < 0)
+		goto _error_locked;
+
+	status = spi_write(data->spi, msg->buffer, SSP_HEADER_SIZE);
+	if (status < 0) {
+		gpio_set_value_cansleep(data->ap_mcu_gpio, 1);
+		dev_err(SSP_DEV, "%s spi_write fail\n", __func__);
+		goto _error_locked;
+	}
+
+	if (!use_no_irq) {
+		mutex_lock(&data->pending_lock);
+		list_add_tail(&msg->list, &data->pending_list);
+		mutex_unlock(&data->pending_lock);
+	}
+
+	status = ssp_check_lines(data, true);
+	if (status < 0) {
+		if (!use_no_irq) {
+			mutex_lock(&data->pending_lock);
+			list_del(&msg->list);
+			mutex_unlock(&data->pending_lock);
+		}
+		goto _error_locked;
+	}
+
+	mutex_unlock(&data->comm_lock);
+
+	if (!use_no_irq && done)
+		if (wait_for_completion_timeout(done,
+						msecs_to_jiffies(timeout)) ==
+		    0) {
+			mutex_lock(&data->pending_lock);
+			list_del(&msg->list);
+			mutex_unlock(&data->pending_lock);
+
+			data->timeout_cnt++;
+			return -ETIMEDOUT;
+		}
+
+	return 0;
+
+_error_locked:
+	mutex_unlock(&data->comm_lock);
+	data->timeout_cnt++;
+	return status;
+}
+
+static inline int ssp_spi_sync_command(struct ssp_data *data,
+				       struct ssp_msg *msg)
+{
+	return ssp_do_transfer(data, msg, NULL, 0);
+}
+
+static int ssp_spi_sync(struct ssp_data *data, struct ssp_msg *msg,
+			int timeout)
+{
+	DECLARE_COMPLETION_ONSTACK(done);
+
+	if (WARN_ON(!msg->length))
+		return -EPERM;
+
+	return ssp_do_transfer(data, msg, &done, timeout);
+}
+
+static int ssp_handle_big_data(struct ssp_data *data, char *dataframe, int *idx)
+{
+	/* mock-up, it will be changed with adding another sensor types */
+	*idx += 8;
+	return 0;
+}
+
+static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len)
+{
+	int idx, sd;
+	struct timespec ts;
+	struct ssp_sensor_data *spd;
+	struct iio_dev **indio_devs = data->sensor_devs;
+
+	getnstimeofday(&ts);
+
+	for (idx = 0; idx < len;) {
+		switch (dataframe[idx++]) {
+		case SSP_MSG2AP_INST_BYPASS_DATA:
+			sd = dataframe[idx++];
+			if (sd < 0 || sd >= SSP_SENSOR_MAX) {
+				dev_err(SSP_DEV,
+					"Mcu data frame1 error %d\n", sd);
+				return -EPROTO;
+			}
+
+			if (indio_devs[sd]) {
+				spd = iio_priv(indio_devs[sd]);
+				if (spd->process_data)
+					spd->process_data(indio_devs[sd],
+							  &dataframe[idx],
+							  data->timestamp);
+			} else {
+				dev_err(SSP_DEV, "no client for frame\n");
+			}
+
+			idx += ssp_offset_map[sd];
+			break;
+		case SSP_MSG2AP_INST_DEBUG_DATA:
+			sd = ssp_print_mcu_debug(dataframe, &idx, len);
+			if (sd) {
+				dev_err(SSP_DEV,
+					"Mcu data frame3 error %d\n", sd);
+				return sd;
+			}
+			break;
+		case SSP_MSG2AP_INST_LIBRARY_DATA:
+			idx += len;
+			break;
+		case SSP_MSG2AP_INST_BIG_DATA:
+			ssp_handle_big_data(data, dataframe, &idx);
+			break;
+		case SSP_MSG2AP_INST_TIME_SYNC:
+			data->time_syncing = true;
+			break;
+		case SSP_MSG2AP_INST_RESET:
+			ssp_queue_ssp_refresh_task(data, 0);
+			break;
+		}
+	}
+
+	if (data->time_syncing)
+		data->timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
+
+	return 0;
+}
+
+/* threaded irq */
+int ssp_irq_msg(struct ssp_data *data)
+{
+	bool found = false;
+	char *buffer;
+	u8 msg_type;
+	int ret;
+	u16 length, msg_options;
+	struct ssp_msg *msg, *n;
+
+	ret = spi_read(data->spi, data->header_buffer, SSP_HEADER_BUFFER_SIZE);
+	if (ret < 0) {
+		dev_err(SSP_DEV, "header read fail\n");
+		return ret;
+	}
+
+	length = le16_to_cpu(data->header_buffer[1]);
+	msg_options = le16_to_cpu(data->header_buffer[0]);
+
+	if (length == 0) {
+		dev_err(SSP_DEV, "length received from mcu is 0\n");
+		return -EINVAL;
+	}
+
+	msg_type = SSP_GET_MESSAGE_TYPE(msg_options);
+
+	switch (msg_type) {
+	case SSP_AP2HUB_READ:
+	case SSP_AP2HUB_WRITE:
+		/*
+		 * this is a small list, a few elements - the packets can be
+		 * received with no order
+		 */
+		mutex_lock(&data->pending_lock);
+		list_for_each_entry_safe(msg, n, &data->pending_list, list) {
+			if (msg->options == msg_options) {
+				list_del(&msg->list);
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			/*
+			 * here can be implemented dead messages handling
+			 * but the slave should not send such ones - it is to
+			 * check but let's handle this
+			 */
+			buffer = kmalloc(length, GFP_KERNEL | GFP_DMA);
+			if (!buffer) {
+				ret = -ENOMEM;
+				goto _unlock;
+			}
+
+			/* got dead packet so it is always an error */
+			ret = spi_read(data->spi, buffer, length);
+			if (ret >= 0)
+				ret = -EPROTO;
+
+			kfree(buffer);
+
+			dev_err(SSP_DEV, "No match error %x\n",
+				msg_options);
+
+			goto _unlock;
+		}
+
+		if (msg_type == SSP_AP2HUB_READ)
+			ret = spi_read(data->spi,
+				       &msg->buffer[SSP_HEADER_SIZE_ALIGNED],
+				       msg->length);
+
+		if (msg_type == SSP_AP2HUB_WRITE) {
+			ret = spi_write(data->spi,
+					&msg->buffer[SSP_HEADER_SIZE_ALIGNED],
+					msg->length);
+			if (msg_options & SSP_AP2HUB_RETURN) {
+				msg->options =
+					SSP_AP2HUB_READ | SSP_AP2HUB_RETURN;
+				msg->length = 1;
+
+				list_add_tail(&msg->list, &data->pending_list);
+				goto _unlock;
+			}
+		}
+
+		if (msg->done)
+			if (!completion_done(msg->done))
+				complete(msg->done);
+_unlock:
+		mutex_unlock(&data->pending_lock);
+		break;
+	case SSP_HUB2AP_WRITE:
+		buffer = kzalloc(length, GFP_KERNEL | GFP_DMA);
+		if (!buffer)
+			return -ENOMEM;
+
+		ret = spi_read(data->spi, buffer, length);
+		if (ret < 0) {
+			dev_err(SSP_DEV, "spi read fail\n");
+			kfree(buffer);
+			break;
+		}
+
+		ret = ssp_parse_dataframe(data, buffer, length);
+
+		kfree(buffer);
+		break;
+
+	default:
+		dev_err(SSP_DEV, "unknown msg type\n");
+		return -EPROTO;
+	}
+
+	return ret;
+}
+
+void ssp_clean_pending_list(struct ssp_data *data)
+{
+	struct ssp_msg *msg, *n;
+
+	mutex_lock(&data->pending_lock);
+	list_for_each_entry_safe(msg, n, &data->pending_list, list) {
+		list_del(&msg->list);
+
+		if (msg->done)
+			if (!completion_done(msg->done))
+				complete(msg->done);
+	}
+	mutex_unlock(&data->pending_lock);
+}
+
+int ssp_command(struct ssp_data *data, char command, int arg)
+{
+	int ret;
+	struct ssp_msg *msg;
+
+	msg = ssp_create_msg(command, 0, SSP_AP2HUB_WRITE, arg);
+	if (!msg)
+		return -ENOMEM;
+
+	ssp_dbg("%s - command 0x%x %d\n", __func__, command, arg);
+
+	ret = ssp_spi_sync_command(data, msg);
+	ssp_clean_msg(msg);
+
+	return ret;
+}
+
+int ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type,
+			 u8 *send_buf, u8 length)
+{
+	int ret;
+	struct ssp_msg *msg;
+
+	if (data->fw_dl_state == SSP_FW_DL_STATE_DOWNLOADING) {
+		dev_err(SSP_DEV, "%s - Skip Inst! DL state = %d\n",
+			__func__, data->fw_dl_state);
+		return -EBUSY;
+	} else if (!(data->available_sensors & BIT(sensor_type)) &&
+		   (inst <= SSP_MSG2SSP_INST_CHANGE_DELAY)) {
+		dev_err(SSP_DEV, "%s - Bypass Inst Skip! - %u\n",
+			__func__, sensor_type);
+		return -EIO; /* just fail */
+	}
+
+	msg = ssp_create_msg(inst, length + 2, SSP_AP2HUB_WRITE, 0);
+	if (!msg)
+		return -ENOMEM;
+
+	ssp_fill_buffer(msg, 0, &sensor_type, 1);
+	ssp_fill_buffer(msg, 1, send_buf, length);
+
+	ssp_dbg("%s - Inst = 0x%x, Sensor Type = 0x%x, data = %u\n",
+		__func__, inst, sensor_type, send_buf[1]);
+
+	ret = ssp_spi_sync(data, msg, 1000);
+	ssp_clean_msg(msg);
+
+	return ret;
+}
+
+int ssp_get_chipid(struct ssp_data *data)
+{
+	int ret;
+	char buffer;
+	struct ssp_msg *msg;
+
+	msg = ssp_create_msg(SSP_MSG2SSP_AP_WHOAMI, 1, SSP_AP2HUB_READ, 0);
+	if (!msg)
+		return -ENOMEM;
+
+	ret = ssp_spi_sync(data, msg, 1000);
+
+	buffer = SSP_GET_BUFFER_AT_INDEX(msg, 0);
+
+	ssp_clean_msg(msg);
+
+	return ret < 0 ? ret : buffer;
+}
+
+int ssp_set_magnetic_matrix(struct ssp_data *data)
+{
+	int ret;
+	struct ssp_msg *msg;
+
+	msg = ssp_create_msg(SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX,
+			     data->sensorhub_info->mag_length, SSP_AP2HUB_WRITE,
+			     0);
+	if (!msg)
+		return -ENOMEM;
+
+	ssp_fill_buffer(msg, 0, data->sensorhub_info->mag_table,
+			data->sensorhub_info->mag_length);
+
+	ret = ssp_spi_sync(data, msg, 1000);
+	ssp_clean_msg(msg);
+
+	return ret;
+}
+
+unsigned int ssp_get_sensor_scanning_info(struct ssp_data *data)
+{
+	int ret;
+	__le32 result;
+	u32 cpu_result = 0;
+
+	struct ssp_msg *msg = ssp_create_msg(SSP_MSG2SSP_AP_SENSOR_SCANNING, 4,
+					     SSP_AP2HUB_READ, 0);
+	if (!msg)
+		return 0;
+
+	ret = ssp_spi_sync(data, msg, 1000);
+	if (ret < 0) {
+		dev_err(SSP_DEV, "%s - spi read fail %d\n", __func__, ret);
+		goto _exit;
+	}
+
+	ssp_get_buffer(msg, 0, &result, 4);
+	cpu_result = le32_to_cpu(result);
+
+	dev_info(SSP_DEV, "%s state: 0x%08x\n", __func__, cpu_result);
+
+_exit:
+	ssp_clean_msg(msg);
+	return cpu_result;
+}
+
+unsigned int ssp_get_firmware_rev(struct ssp_data *data)
+{
+	int ret;
+	__le32 result;
+
+	struct ssp_msg *msg = ssp_create_msg(SSP_MSG2SSP_AP_FIRMWARE_REV, 4,
+					     SSP_AP2HUB_READ, 0);
+	if (!msg)
+		return SSP_INVALID_REVISION;
+
+	ret = ssp_spi_sync(data, msg, 1000);
+	if (ret < 0) {
+		dev_err(SSP_DEV, "%s - transfer fail %d\n", __func__, ret);
+		ret = SSP_INVALID_REVISION;
+		goto _exit;
+	}
+
+	ssp_get_buffer(msg, 0, &result, 4);
+	ret = le32_to_cpu(result);
+
+_exit:
+	ssp_clean_msg(msg);
+	return ret;
+}
diff --git a/drivers/iio/common/st_sensors/st_sensors_spi.c b/drivers/iio/common/st_sensors/st_sensors_spi.c
index 78a6a1ab3ece..5b377373f48d 100644
--- a/drivers/iio/common/st_sensors/st_sensors_spi.c
+++ b/drivers/iio/common/st_sensors/st_sensors_spi.c
@@ -54,7 +54,7 @@ static int st_sensors_spi_read(struct st_sensor_transfer_buffer *tb,
 	if (err)
 		goto acc_spi_read_error;
 
-	memcpy(data, tb->rx_buf, len*sizeof(u8));
+	memcpy(data, tb->rx_buf, len);
 	mutex_unlock(&tb->buf_lock);
 	return len;
 
diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c
index 7c5245d9f99c..50ed8d1ca45a 100644
--- a/drivers/iio/frequency/ad9523.c
+++ b/drivers/iio/frequency/ad9523.c
@@ -445,7 +445,7 @@ static int ad9523_store_eeprom(struct iio_dev *indio_dev)
 
 	tmp = 4;
 	do {
-		msleep(16);
+		msleep(20);
 		ret = ad9523_read(indio_dev,
 				  AD9523_EEPROM_DATA_XFER_STATUS);
 		if (ret < 0)
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c
index 63a25d9e1204..10a0dfc3b01f 100644
--- a/drivers/iio/frequency/adf4350.c
+++ b/drivers/iio/frequency/adf4350.c
@@ -387,10 +387,8 @@ static struct adf4350_platform_data *adf4350_parse_dt(struct device *dev)
 	int ret;
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
-	if (!pdata) {
-		dev_err(dev, "could not allocate memory for platform data\n");
+	if (!pdata)
 		return NULL;
-	}
 
 	strncpy(&pdata->name[0], np->name, SPI_NAME_SIZE - 1);
 
@@ -613,9 +611,8 @@ static int adf4350_remove(struct spi_device *spi)
 	if (st->clk)
 		clk_disable_unprepare(st->clk);
 
-	if (!IS_ERR(reg)) {
+	if (!IS_ERR(reg))
 		regulator_disable(reg);
-	}
 
 	return 0;
 }
diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile
index 36a38776f739..f46341b39139 100644
--- a/drivers/iio/gyro/Makefile
+++ b/drivers/iio/gyro/Makefile
@@ -16,6 +16,8 @@ itg3200-y               := itg3200_core.o
 itg3200-$(CONFIG_IIO_BUFFER) += itg3200_buffer.o
 obj-$(CONFIG_ITG3200)   += itg3200.o
 
+obj-$(CONFIG_IIO_SSP_SENSORS_COMMONS) += ssp_gyro_sensor.o
+
 obj-$(CONFIG_IIO_ST_GYRO_3AXIS) += st_gyro.o
 st_gyro-y := st_gyro_core.o
 st_gyro-$(CONFIG_IIO_BUFFER) += st_gyro_buffer.o
diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
index a3ea1e8785d7..a3c3e19de527 100644
--- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
+++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
@@ -111,19 +111,12 @@ static int gyro_3d_read_raw(struct iio_dev *indio_dev,
 	int report_id = -1;
 	u32 address;
 	int ret_type;
-	s32 poll_value;
 
 	*val = 0;
 	*val2 = 0;
 	switch (mask) {
 	case 0:
-		poll_value = hid_sensor_read_poll_value(
-					&gyro_state->common_attributes);
-		if (poll_value < 0)
-			return -EINVAL;
-
 		hid_sensor_power_state(&gyro_state->common_attributes, true);
-		msleep_interruptible(poll_value * 2);
 		report_id = gyro_state->gyro[chan->scan_index].report_id;
 		address = gyro_3d_addresses[chan->scan_index];
 		if (report_id >= 0)
@@ -416,6 +409,7 @@ static struct platform_driver hid_gyro_3d_platform_driver = {
 	.id_table = hid_gyro_3d_ids,
 	.driver = {
 		.name	= KBUILD_MODNAME,
+		.pm	= &hid_sensor_pm_ops,
 	},
 	.probe		= hid_gyro_3d_probe,
 	.remove		= hid_gyro_3d_remove,
diff --git a/drivers/iio/gyro/ssp_gyro_sensor.c b/drivers/iio/gyro/ssp_gyro_sensor.c
new file mode 100644
index 000000000000..0a8afdd21728
--- /dev/null
+++ b/drivers/iio/gyro/ssp_gyro_sensor.c
@@ -0,0 +1,168 @@
+/*
+ *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+
+#include <linux/iio/common/ssp_sensors.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/kfifo_buf.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "../common/ssp_sensors/ssp_iio_sensor.h"
+
+#define SSP_CHANNEL_COUNT 3
+
+#define SSP_GYROSCOPE_NAME "ssp-gyroscope"
+static const char ssp_gyro_name[] = SSP_GYROSCOPE_NAME;
+
+enum ssp_gyro_3d_channel {
+	SSP_CHANNEL_SCAN_INDEX_X,
+	SSP_CHANNEL_SCAN_INDEX_Y,
+	SSP_CHANNEL_SCAN_INDEX_Z,
+	SSP_CHANNEL_SCAN_INDEX_TIME,
+};
+
+static int ssp_gyro_read_raw(struct iio_dev *indio_dev,
+			     struct iio_chan_spec const *chan, int *val,
+			     int *val2, long mask)
+{
+	u32 t;
+	struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		t = ssp_get_sensor_delay(data, SSP_GYROSCOPE_SENSOR);
+		ssp_convert_to_freq(t, val, val2);
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static int ssp_gyro_write_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan, int val,
+			      int val2, long mask)
+{
+	int ret;
+	struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		ret = ssp_convert_to_time(val, val2);
+		ret = ssp_change_delay(data, SSP_GYROSCOPE_SENSOR, ret);
+		if (ret < 0)
+			dev_err(&indio_dev->dev, "gyro sensor enable fail\n");
+
+		return ret;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static struct iio_info ssp_gyro_iio_info = {
+	.read_raw = &ssp_gyro_read_raw,
+	.write_raw = &ssp_gyro_write_raw,
+};
+
+static const unsigned long ssp_gyro_scan_mask[] = { 0x07, 0, };
+
+static const struct iio_chan_spec ssp_gyro_channels[] = {
+	SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_X, SSP_CHANNEL_SCAN_INDEX_X),
+	SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_Y, SSP_CHANNEL_SCAN_INDEX_Y),
+	SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_Z, SSP_CHANNEL_SCAN_INDEX_Z),
+	SSP_CHAN_TIMESTAMP(SSP_CHANNEL_SCAN_INDEX_TIME),
+};
+
+static int ssp_process_gyro_data(struct iio_dev *indio_dev, void *buf,
+				 int64_t timestamp)
+{
+	return ssp_common_process_data(indio_dev, buf, SSP_GYROSCOPE_SIZE,
+				       timestamp);
+}
+
+static const struct iio_buffer_setup_ops ssp_gyro_buffer_ops = {
+	.postenable = &ssp_common_buffer_postenable,
+	.postdisable = &ssp_common_buffer_postdisable,
+};
+
+static int ssp_gyro_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct iio_dev *indio_dev;
+	struct ssp_sensor_data *spd;
+	struct iio_buffer *buffer;
+
+	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*spd));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	spd = iio_priv(indio_dev);
+
+	spd->process_data = ssp_process_gyro_data;
+	spd->type = SSP_GYROSCOPE_SENSOR;
+
+	indio_dev->name = ssp_gyro_name;
+	indio_dev->dev.parent = &pdev->dev;
+	indio_dev->info = &ssp_gyro_iio_info;
+	indio_dev->modes = INDIO_BUFFER_SOFTWARE;
+	indio_dev->channels = ssp_gyro_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ssp_gyro_channels);
+	indio_dev->available_scan_masks = ssp_gyro_scan_mask;
+
+	buffer = devm_iio_kfifo_allocate(&pdev->dev);
+	if (!buffer)
+		return -ENOMEM;
+
+	iio_device_attach_buffer(indio_dev, buffer);
+
+	indio_dev->setup_ops = &ssp_gyro_buffer_ops;
+
+	platform_set_drvdata(pdev, indio_dev);
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		return ret;
+
+	/* ssp registering should be done after all iio setup */
+	ssp_register_consumer(indio_dev, SSP_GYROSCOPE_SENSOR);
+
+	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);
+
+MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
+MODULE_DESCRIPTION("Samsung sensorhub gyroscopes driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h
index 5f0ea77fe717..359883525ab7 100644
--- a/drivers/iio/iio_core.h
+++ b/drivers/iio/iio_core.h
@@ -48,6 +48,8 @@ unsigned int iio_buffer_poll(struct file *filp,
 ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 				      size_t n, loff_t *f_ps);
 
+int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev);
+void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev);
 
 #define iio_buffer_poll_addr (&iio_buffer_poll)
 #define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer)
@@ -60,6 +62,13 @@ void iio_buffer_wakeup_poll(struct iio_dev *indio_dev);
 #define iio_buffer_poll_addr NULL
 #define iio_buffer_read_first_n_outer_addr NULL
 
+static inline int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
+{
+	return 0;
+}
+
+static inline void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev) {}
+
 static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {}
 static inline void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) {}
 
diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig
index 2b0e45133e9d..5e610f7de5aa 100644
--- a/drivers/iio/imu/Kconfig
+++ b/drivers/iio/imu/Kconfig
@@ -25,6 +25,17 @@ config ADIS16480
 	  Say yes here to build support for Analog Devices ADIS16375, ADIS16480,
 	  ADIS16485, ADIS16488 inertial sensors.
 
+config KMX61
+	tristate "Kionix KMX61 6-axis accelerometer and magnetometer"
+	depends on I2C
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	help
+	  Say Y here if you want to build a driver for Kionix KMX61 6-axis
+	  accelerometer and magnetometer.
+	  To compile this driver as module, choose M here: the module will
+	  be called kmx61.
+
 source "drivers/iio/imu/inv_mpu6050/Kconfig"
 
 endmenu
diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile
index 114d2c17cbe2..e1e6e3d70e26 100644
--- a/drivers/iio/imu/Makefile
+++ b/drivers/iio/imu/Makefile
@@ -14,3 +14,5 @@ adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o
 obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o
 
 obj-y += inv_mpu6050/
+
+obj-$(CONFIG_KMX61) += kmx61.o
diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig
index 2d0608ba88d7..48fbc0bc7e2a 100644
--- a/drivers/iio/imu/inv_mpu6050/Kconfig
+++ b/drivers/iio/imu/inv_mpu6050/Kconfig
@@ -7,6 +7,7 @@ config INV_MPU6050_IIO
 	depends on I2C && SYSFS
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
+	select I2C_MUX
 	help
 	  This driver supports the Invensense MPU6050 devices.
 	  This driver can also support MPU6500 in MPU6050 compatibility mode
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index b75519deac1a..f73e60b7a796 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -23,6 +23,8 @@
 #include <linux/kfifo.h>
 #include <linux/spinlock.h>
 #include <linux/iio/iio.h>
+#include <linux/i2c-mux.h>
+#include <linux/acpi.h>
 #include "inv_mpu_iio.h"
 
 /*
@@ -52,6 +54,7 @@ static const struct inv_mpu6050_reg_map reg_set_6050 = {
 	.int_enable             = INV_MPU6050_REG_INT_ENABLE,
 	.pwr_mgmt_1             = INV_MPU6050_REG_PWR_MGMT_1,
 	.pwr_mgmt_2             = INV_MPU6050_REG_PWR_MGMT_2,
+	.int_pin_cfg		= INV_MPU6050_REG_INT_PIN_CFG,
 };
 
 static const struct inv_mpu6050_chip_config chip_config_6050 = {
@@ -77,6 +80,83 @@ int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 d)
 	return i2c_smbus_write_i2c_block_data(st->client, reg, 1, &d);
 }
 
+/*
+ * The i2c read/write needs to happen in unlocked mode. As the parent
+ * adapter is common. If we use locked versions, it will fail as
+ * the mux adapter will lock the parent i2c adapter, while calling
+ * select/deselect functions.
+ */
+static int inv_mpu6050_write_reg_unlocked(struct inv_mpu6050_state *st,
+					  u8 reg, u8 d)
+{
+	int ret;
+	u8 buf[2];
+	struct i2c_msg msg[1] = {
+		{
+			.addr = st->client->addr,
+			.flags = 0,
+			.len = sizeof(buf),
+			.buf = buf,
+		}
+	};
+
+	buf[0] = reg;
+	buf[1] = d;
+	ret = __i2c_transfer(st->client->adapter, msg, 1);
+	if (ret != 1)
+		return ret;
+
+	return 0;
+}
+
+static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv,
+				     u32 chan_id)
+{
+	struct iio_dev *indio_dev = mux_priv;
+	struct inv_mpu6050_state *st = iio_priv(indio_dev);
+	int ret = 0;
+
+	/* Use the same mutex which was used everywhere to protect power-op */
+	mutex_lock(&indio_dev->mlock);
+	if (!st->powerup_count) {
+		ret = inv_mpu6050_write_reg_unlocked(st, st->reg->pwr_mgmt_1,
+						     0);
+		if (ret)
+			goto write_error;
+
+		msleep(INV_MPU6050_REG_UP_TIME);
+	}
+	if (!ret) {
+		st->powerup_count++;
+		ret = inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg,
+						     st->client->irq |
+						     INV_MPU6050_BIT_BYPASS_EN);
+	}
+write_error:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap,
+				       void *mux_priv, u32 chan_id)
+{
+	struct iio_dev *indio_dev = mux_priv;
+	struct inv_mpu6050_state *st = iio_priv(indio_dev);
+
+	mutex_lock(&indio_dev->mlock);
+	/* It doesn't really mattter, if any of the calls fails */
+	inv_mpu6050_write_reg_unlocked(st, st->reg->int_pin_cfg,
+				       st->client->irq);
+	st->powerup_count--;
+	if (!st->powerup_count)
+		inv_mpu6050_write_reg_unlocked(st, st->reg->pwr_mgmt_1,
+					       INV_MPU6050_BIT_SLEEP);
+	mutex_unlock(&indio_dev->mlock);
+
+	return 0;
+}
+
 int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
 {
 	u8 d, mgmt_1;
@@ -133,13 +213,22 @@ int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask)
 
 int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on)
 {
-	int result;
+	int result = 0;
+
+	if (power_on) {
+		/* Already under indio-dev->mlock mutex */
+		if (!st->powerup_count)
+			result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
+						       0);
+		if (!result)
+			st->powerup_count++;
+	} else {
+		st->powerup_count--;
+		if (!st->powerup_count)
+			result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
+						       INV_MPU6050_BIT_SLEEP);
+	}
 
-	if (power_on)
-		result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1, 0);
-	else
-		result = inv_mpu6050_write_reg(st, st->reg->pwr_mgmt_1,
-						INV_MPU6050_BIT_SLEEP);
 	if (result)
 		return result;
 
@@ -673,6 +762,7 @@ static int inv_mpu_probe(struct i2c_client *client,
 
 	st = iio_priv(indio_dev);
 	st->client = client;
+	st->powerup_count = 0;
 	pdata = dev_get_platdata(&client->dev);
 	if (pdata)
 		st->plat_data = *pdata;
@@ -720,8 +810,21 @@ static int inv_mpu_probe(struct i2c_client *client,
 		goto out_remove_trigger;
 	}
 
+	st->mux_adapter = i2c_add_mux_adapter(client->adapter,
+					      &client->dev,
+					      indio_dev,
+					      0, 0, 0,
+					      inv_mpu6050_select_bypass,
+					      inv_mpu6050_deselect_bypass);
+	if (!st->mux_adapter) {
+		result = -ENODEV;
+		goto out_unreg_device;
+	}
+
 	return 0;
 
+out_unreg_device:
+	iio_device_unregister(indio_dev);
 out_remove_trigger:
 	inv_mpu6050_remove_trigger(st);
 out_unreg_ring:
@@ -734,6 +837,7 @@ static int inv_mpu_remove(struct i2c_client *client)
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 	struct inv_mpu6050_state *st = iio_priv(indio_dev);
 
+	i2c_del_mux_adapter(st->mux_adapter);
 	iio_device_unregister(indio_dev);
 	inv_mpu6050_remove_trigger(st);
 	iio_triggered_buffer_cleanup(indio_dev);
@@ -772,6 +876,13 @@ static const struct i2c_device_id inv_mpu_id[] = {
 
 MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
 
+static const struct acpi_device_id inv_acpi_match[] = {
+	{"INVN6500", 0},
+	{ },
+};
+
+MODULE_DEVICE_TABLE(acpi, inv_acpi_match);
+
 static struct i2c_driver inv_mpu_driver = {
 	.probe		=	inv_mpu_probe,
 	.remove		=	inv_mpu_remove,
@@ -780,6 +891,7 @@ static struct i2c_driver inv_mpu_driver = {
 		.owner	=	THIS_MODULE,
 		.name	=	"inv-mpu6050",
 		.pm     =       INV_MPU6050_PMOPS,
+		.acpi_match_table = ACPI_PTR(inv_acpi_match),
 	},
 };
 
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index e7799315d4dc..aa837de57079 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
@@ -54,6 +54,7 @@ struct inv_mpu6050_reg_map {
 	u8 int_enable;
 	u8 pwr_mgmt_1;
 	u8 pwr_mgmt_2;
+	u8 int_pin_cfg;
 };
 
 /*device enum */
@@ -119,6 +120,8 @@ struct inv_mpu6050_state {
 	enum   inv_devices chip_type;
 	spinlock_t time_stamp_lock;
 	struct i2c_client *client;
+	struct i2c_adapter *mux_adapter;
+	unsigned int powerup_count;
 	struct inv_mpu6050_platform_data plat_data;
 	DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
 };
@@ -179,6 +182,9 @@ struct inv_mpu6050_state {
 /* 6 + 6 round up and plus 8 */
 #define INV_MPU6050_OUTPUT_DATA_SIZE         24
 
+#define INV_MPU6050_REG_INT_PIN_CFG	0x37
+#define INV_MPU6050_BIT_BYPASS_EN	0x2
+
 /* init parameters */
 #define INV_MPU6050_INIT_FIFO_RATE           50
 #define INV_MPU6050_TIME_STAMP_TOR           5
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
index 926fccea8de0..844610c3a3a9 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
@@ -116,40 +116,35 @@ int inv_mpu6050_probe_trigger(struct iio_dev *indio_dev)
 	int ret;
 	struct inv_mpu6050_state *st = iio_priv(indio_dev);
 
-	st->trig = iio_trigger_alloc("%s-dev%d",
-					indio_dev->name,
-					indio_dev->id);
-	if (st->trig == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	ret = request_irq(st->client->irq, &iio_trigger_generic_data_rdy_poll,
-				IRQF_TRIGGER_RISING,
-				"inv_mpu",
-				st->trig);
+	st->trig = devm_iio_trigger_alloc(&indio_dev->dev,
+					  "%s-dev%d",
+					  indio_dev->name,
+					  indio_dev->id);
+	if (!st->trig)
+		return -ENOMEM;
+
+	ret = devm_request_irq(&indio_dev->dev, st->client->irq,
+			       &iio_trigger_generic_data_rdy_poll,
+			       IRQF_TRIGGER_RISING,
+			       "inv_mpu",
+			       st->trig);
 	if (ret)
-		goto error_free_trig;
+		return ret;
+
 	st->trig->dev.parent = &st->client->dev;
 	st->trig->ops = &inv_mpu_trigger_ops;
 	iio_trigger_set_drvdata(st->trig, indio_dev);
+
 	ret = iio_trigger_register(st->trig);
 	if (ret)
-		goto error_free_irq;
+		return ret;
+
 	indio_dev->trig = iio_trigger_get(st->trig);
 
 	return 0;
-
-error_free_irq:
-	free_irq(st->client->irq, st->trig);
-error_free_trig:
-	iio_trigger_free(st->trig);
-error_ret:
-	return ret;
 }
 
 void inv_mpu6050_remove_trigger(struct inv_mpu6050_state *st)
 {
 	iio_trigger_unregister(st->trig);
-	free_irq(st->client->irq, st->trig);
-	iio_trigger_free(st->trig);
 }
diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c
new file mode 100644
index 000000000000..5cc3692acf37
--- /dev/null
+++ b/drivers/iio/imu/kmx61.c
@@ -0,0 +1,1595 @@
+/*
+ * KMX61 - Kionix 6-axis Accelerometer/Magnetometer
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * IIO driver for KMX61 (7-bit I2C slave address 0x0E or 0x0F).
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+
+#define KMX61_DRV_NAME "kmx61"
+#define KMX61_GPIO_NAME "kmx61_int"
+#define KMX61_IRQ_NAME "kmx61_event"
+
+#define KMX61_REG_WHO_AM_I	0x00
+#define KMX61_REG_INS1		0x01
+#define KMX61_REG_INS2		0x02
+
+/*
+ * three 16-bit accelerometer output registers for X/Y/Z axis
+ * we use only XOUT_L as a base register, all other addresses
+ * can be obtained by applying an offset and are provided here
+ * only for clarity.
+ */
+#define KMX61_ACC_XOUT_L	0x0A
+#define KMX61_ACC_XOUT_H	0x0B
+#define KMX61_ACC_YOUT_L	0x0C
+#define KMX61_ACC_YOUT_H	0x0D
+#define KMX61_ACC_ZOUT_L	0x0E
+#define KMX61_ACC_ZOUT_H	0x0F
+
+/*
+ * one 16-bit temperature output register
+ */
+#define KMX61_TEMP_L		0x10
+#define KMX61_TEMP_H		0x11
+
+/*
+ * three 16-bit magnetometer output registers for X/Y/Z axis
+ */
+#define KMX61_MAG_XOUT_L	0x12
+#define KMX61_MAG_XOUT_H	0x13
+#define KMX61_MAG_YOUT_L	0x14
+#define KMX61_MAG_YOUT_H	0x15
+#define KMX61_MAG_ZOUT_L	0x16
+#define KMX61_MAG_ZOUT_H	0x17
+
+#define KMX61_REG_INL		0x28
+#define KMX61_REG_STBY		0x29
+#define KMX61_REG_CTRL1		0x2A
+#define KMX61_REG_CTRL2		0x2B
+#define KMX61_REG_ODCNTL	0x2C
+#define KMX61_REG_INC1		0x2D
+
+#define KMX61_REG_WUF_THRESH	0x3D
+#define KMX61_REG_WUF_TIMER	0x3E
+
+#define KMX61_ACC_STBY_BIT	BIT(0)
+#define KMX61_MAG_STBY_BIT	BIT(1)
+#define KMX61_ACT_STBY_BIT	BIT(7)
+
+#define KMX61_ALL_STBY		(KMX61_ACC_STBY_BIT | KMX61_MAG_STBY_BIT)
+
+#define KMX61_REG_INS1_BIT_WUFS		BIT(1)
+
+#define KMX61_REG_INS2_BIT_ZP		BIT(0)
+#define KMX61_REG_INS2_BIT_ZN		BIT(1)
+#define KMX61_REG_INS2_BIT_YP		BIT(2)
+#define KMX61_REG_INS2_BIT_YN		BIT(3)
+#define KMX61_REG_INS2_BIT_XP		BIT(4)
+#define KMX61_REG_INS2_BIT_XN		BIT(5)
+
+#define KMX61_REG_CTRL1_GSEL_MASK	0x03
+
+#define KMX61_REG_CTRL1_BIT_RES		BIT(4)
+#define KMX61_REG_CTRL1_BIT_DRDYE	BIT(5)
+#define KMX61_REG_CTRL1_BIT_WUFE	BIT(6)
+#define KMX61_REG_CTRL1_BIT_BTSE	BIT(7)
+
+#define KMX61_REG_INC1_BIT_WUFS		BIT(0)
+#define KMX61_REG_INC1_BIT_DRDYM	BIT(1)
+#define KMX61_REG_INC1_BIT_DRDYA	BIT(2)
+#define KMX61_REG_INC1_BIT_IEN		BIT(5)
+
+#define KMX61_ACC_ODR_SHIFT	0
+#define KMX61_MAG_ODR_SHIFT	4
+#define KMX61_ACC_ODR_MASK	0x0F
+#define KMX61_MAG_ODR_MASK	0xF0
+
+#define KMX61_OWUF_MASK		0x7
+
+#define KMX61_DEFAULT_WAKE_THRESH	1
+#define KMX61_DEFAULT_WAKE_DURATION	1
+
+#define KMX61_SLEEP_DELAY_MS	2000
+
+#define KMX61_CHIP_ID		0x12
+
+/* KMX61 devices */
+#define KMX61_ACC	0x01
+#define KMX61_MAG	0x02
+
+struct kmx61_data {
+	struct i2c_client *client;
+
+	/* serialize access to non-atomic ops, e.g set_mode */
+	struct mutex lock;
+
+	/* standby state */
+	bool acc_stby;
+	bool mag_stby;
+
+	/* power state */
+	bool acc_ps;
+	bool mag_ps;
+
+	/* config bits */
+	u8 range;
+	u8 odr_bits;
+	u8 wake_thresh;
+	u8 wake_duration;
+
+	/* accelerometer specific data */
+	struct iio_dev *acc_indio_dev;
+	struct iio_trigger *acc_dready_trig;
+	struct iio_trigger *motion_trig;
+	bool acc_dready_trig_on;
+	bool motion_trig_on;
+	bool ev_enable_state;
+
+	/* magnetometer specific data */
+	struct iio_dev *mag_indio_dev;
+	struct iio_trigger *mag_dready_trig;
+	bool mag_dready_trig_on;
+};
+
+enum kmx61_range {
+	KMX61_RANGE_2G,
+	KMX61_RANGE_4G,
+	KMX61_RANGE_8G,
+};
+
+enum kmx61_axis {
+	KMX61_AXIS_X,
+	KMX61_AXIS_Y,
+	KMX61_AXIS_Z,
+};
+
+static const u16 kmx61_uscale_table[] = {9582, 19163, 38326};
+
+static const struct {
+	int val;
+	int val2;
+	u8 odr_bits;
+} kmx61_samp_freq_table[] = { {12, 500000, 0x00},
+			{25, 0, 0x01},
+			{50, 0, 0x02},
+			{100, 0, 0x03},
+			{200, 0, 0x04},
+			{400, 0, 0x05},
+			{800, 0, 0x06},
+			{1600, 0, 0x07},
+			{0, 781000, 0x08},
+			{1, 563000, 0x09},
+			{3, 125000, 0x0A},
+			{6, 250000, 0x0B} };
+
+static const struct {
+	int val;
+	int val2;
+	int odr_bits;
+} kmx61_wake_up_odr_table[] = { {0, 781000, 0x00},
+				 {1, 563000, 0x01},
+				 {3, 125000, 0x02},
+				 {6, 250000, 0x03},
+				 {12, 500000, 0x04},
+				 {25, 0, 0x05},
+				 {50, 0, 0x06},
+				 {100, 0, 0x06},
+				 {200, 0, 0x06},
+				 {400, 0, 0x06},
+				 {800, 0, 0x06},
+				 {1600, 0, 0x06} };
+
+static IIO_CONST_ATTR(accel_scale_available, "0.009582 0.019163 0.038326");
+static IIO_CONST_ATTR(magn_scale_available, "0.001465");
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
+	"0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800");
+
+static struct attribute *kmx61_acc_attributes[] = {
+	&iio_const_attr_accel_scale_available.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute *kmx61_mag_attributes[] = {
+	&iio_const_attr_magn_scale_available.dev_attr.attr,
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group kmx61_acc_attribute_group = {
+	.attrs = kmx61_acc_attributes,
+};
+
+static const struct attribute_group kmx61_mag_attribute_group = {
+	.attrs = kmx61_mag_attributes,
+};
+
+static const struct iio_event_spec kmx61_event = {
+	.type = IIO_EV_TYPE_THRESH,
+	.dir = IIO_EV_DIR_EITHER,
+	.mask_separate = BIT(IIO_EV_INFO_VALUE) |
+			 BIT(IIO_EV_INFO_ENABLE) |
+			 BIT(IIO_EV_INFO_PERIOD),
+};
+
+#define KMX61_ACC_CHAN(_axis) { \
+	.type = IIO_ACCEL, \
+	.modified = 1, \
+	.channel2 = IIO_MOD_ ## _axis, \
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+				BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	.address = KMX61_ACC, \
+	.scan_index = KMX61_AXIS_ ## _axis, \
+	.scan_type = { \
+		.sign = 's', \
+		.realbits = 12, \
+		.storagebits = 16, \
+		.shift = 4, \
+		.endianness = IIO_LE, \
+	}, \
+	.event_spec = &kmx61_event, \
+	.num_event_specs = 1 \
+}
+
+#define KMX61_MAG_CHAN(_axis) { \
+	.type = IIO_MAGN, \
+	.modified = 1, \
+	.channel2 = IIO_MOD_ ## _axis, \
+	.address = KMX61_MAG, \
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+				BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+	.scan_index = KMX61_AXIS_ ## _axis, \
+	.scan_type = { \
+		.sign = 's', \
+		.realbits = 14, \
+		.storagebits = 16, \
+		.shift = 2, \
+		.endianness = IIO_LE, \
+	}, \
+}
+
+static const struct iio_chan_spec kmx61_acc_channels[] = {
+	KMX61_ACC_CHAN(X),
+	KMX61_ACC_CHAN(Y),
+	KMX61_ACC_CHAN(Z),
+};
+
+static const struct iio_chan_spec kmx61_mag_channels[] = {
+	KMX61_MAG_CHAN(X),
+	KMX61_MAG_CHAN(Y),
+	KMX61_MAG_CHAN(Z),
+};
+
+static void kmx61_set_data(struct iio_dev *indio_dev, struct kmx61_data *data)
+{
+	struct kmx61_data **priv = iio_priv(indio_dev);
+
+	*priv = data;
+}
+
+static struct kmx61_data *kmx61_get_data(struct iio_dev *indio_dev)
+{
+	return *(struct kmx61_data **)iio_priv(indio_dev);
+}
+
+static int kmx61_convert_freq_to_bit(int val, int val2)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
+		if (val == kmx61_samp_freq_table[i].val &&
+		    val2 == kmx61_samp_freq_table[i].val2)
+			return kmx61_samp_freq_table[i].odr_bits;
+	return -EINVAL;
+}
+
+static int kmx61_convert_bit_to_freq(u8 odr_bits, int *val, int *val2)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
+		if (odr_bits == kmx61_samp_freq_table[i].odr_bits) {
+			*val = kmx61_samp_freq_table[i].val;
+			*val2 = kmx61_samp_freq_table[i].val2;
+			return 0;
+		}
+	return -EINVAL;
+}
+
+
+static int kmx61_convert_wake_up_odr_to_bit(int val, int val2)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(kmx61_wake_up_odr_table); ++i)
+		if (kmx61_wake_up_odr_table[i].val == val &&
+			kmx61_wake_up_odr_table[i].val2 == val2)
+				return kmx61_wake_up_odr_table[i].odr_bits;
+	return -EINVAL;
+}
+
+/**
+ * kmx61_set_mode() - set KMX61 device operating mode
+ * @data - kmx61 device private data pointer
+ * @mode - bitmask, indicating operating mode for @device
+ * @device - bitmask, indicating device for which @mode needs to be set
+ * @update - update stby bits stored in device's private  @data
+ *
+ * For each sensor (accelerometer/magnetometer) there are two operating modes
+ * STANDBY and OPERATION. Neither accel nor magn can be disabled independently
+ * if they are both enabled. Internal sensors state is saved in acc_stby and
+ * mag_stby members of driver's private @data.
+ */
+static int kmx61_set_mode(struct kmx61_data *data, u8 mode, u8 device,
+			  bool update)
+{
+	int ret;
+	int acc_stby = -1, mag_stby = -1;
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_stby\n");
+		return ret;
+	}
+	if (device & KMX61_ACC) {
+		if (mode & KMX61_ACC_STBY_BIT) {
+			ret |= KMX61_ACC_STBY_BIT;
+			acc_stby = 1;
+		} else {
+			ret &= ~KMX61_ACC_STBY_BIT;
+			acc_stby = 0;
+		}
+	}
+
+	if (device & KMX61_MAG) {
+		if (mode & KMX61_MAG_STBY_BIT) {
+			ret |= KMX61_MAG_STBY_BIT;
+			mag_stby = 1;
+		} else {
+			ret &= ~KMX61_MAG_STBY_BIT;
+			mag_stby = 0;
+		}
+	}
+
+	if (mode & KMX61_ACT_STBY_BIT)
+		ret |= KMX61_ACT_STBY_BIT;
+
+	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_STBY, ret);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_stby\n");
+		return ret;
+	}
+
+	if (acc_stby != -1 && update)
+		data->acc_stby = acc_stby;
+	if (mag_stby != -1 && update)
+		data->mag_stby = mag_stby;
+
+	return 0;
+}
+
+static int kmx61_get_mode(struct kmx61_data *data, u8 *mode, u8 device)
+{
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_STBY);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_stby\n");
+		return ret;
+	}
+	*mode = 0;
+
+	if (device & KMX61_ACC) {
+		if (ret & KMX61_ACC_STBY_BIT)
+			*mode |= KMX61_ACC_STBY_BIT;
+		else
+			*mode &= ~KMX61_ACC_STBY_BIT;
+	}
+
+	if (device & KMX61_MAG) {
+		if (ret & KMX61_MAG_STBY_BIT)
+			*mode |= KMX61_MAG_STBY_BIT;
+		else
+			*mode &= ~KMX61_MAG_STBY_BIT;
+	}
+
+	return 0;
+}
+
+static int kmx61_set_wake_up_odr(struct kmx61_data *data, int val, int val2)
+{
+	int ret, odr_bits;
+
+	odr_bits = kmx61_convert_wake_up_odr_to_bit(val, val2);
+	if (odr_bits < 0)
+		return odr_bits;
+
+	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL2,
+					odr_bits);
+	if (ret < 0)
+		dev_err(&data->client->dev, "Error writing reg_ctrl2\n");
+	return ret;
+}
+
+static int kmx61_set_odr(struct kmx61_data *data, int val, int val2, u8 device)
+{
+	int ret;
+	u8 mode;
+	int lodr_bits, odr_bits;
+
+	ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG);
+	if (ret < 0)
+		return ret;
+
+	lodr_bits = kmx61_convert_freq_to_bit(val, val2);
+	if (lodr_bits < 0)
+		return lodr_bits;
+
+	/* To change ODR, accel and magn must be in STDBY */
+	ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG,
+			     true);
+	if (ret < 0)
+		return ret;
+
+	odr_bits = 0;
+	if (device & KMX61_ACC)
+		odr_bits |= lodr_bits << KMX61_ACC_ODR_SHIFT;
+	if (device & KMX61_MAG)
+		odr_bits |= lodr_bits << KMX61_MAG_ODR_SHIFT;
+
+	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_ODCNTL,
+					odr_bits);
+	if (ret < 0)
+		return ret;
+
+	data->odr_bits = odr_bits;
+
+	if (device & KMX61_ACC) {
+		ret = kmx61_set_wake_up_odr(data, val, val2);
+		if (ret)
+			return ret;
+	}
+
+	return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true);
+}
+
+static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2,
+			 u8 device)
+{	int i;
+	u8 lodr_bits;
+
+	if (device & KMX61_ACC)
+		lodr_bits = (data->odr_bits >> KMX61_ACC_ODR_SHIFT) &
+			     KMX61_ACC_ODR_MASK;
+	else if (device & KMX61_MAG)
+		lodr_bits = (data->odr_bits >> KMX61_MAG_ODR_SHIFT) &
+			     KMX61_MAG_ODR_MASK;
+	else
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
+		if (lodr_bits == kmx61_samp_freq_table[i].odr_bits) {
+			*val = kmx61_samp_freq_table[i].val;
+			*val2 = kmx61_samp_freq_table[i].val2;
+			return 0;
+		}
+	return -EINVAL;
+}
+
+static int kmx61_set_range(struct kmx61_data *data, u8 range)
+{
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+		return ret;
+	}
+
+	ret &= ~KMX61_REG_CTRL1_GSEL_MASK;
+	ret |= range & KMX61_REG_CTRL1_GSEL_MASK;
+
+	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+		return ret;
+	}
+
+	data->range = range;
+
+	return 0;
+}
+
+static int kmx61_set_scale(struct kmx61_data *data, u16 uscale)
+{
+	int ret, i;
+	u8  mode;
+
+	for (i = 0; i < ARRAY_SIZE(kmx61_uscale_table); i++) {
+		if (kmx61_uscale_table[i] == uscale) {
+			ret = kmx61_get_mode(data, &mode,
+					     KMX61_ACC | KMX61_MAG);
+			if (ret < 0)
+				return ret;
+
+			ret = kmx61_set_mode(data, KMX61_ALL_STBY,
+					     KMX61_ACC | KMX61_MAG, true);
+			if (ret < 0)
+				return ret;
+
+			ret = kmx61_set_range(data, i);
+			if (ret < 0)
+				return ret;
+
+			return  kmx61_set_mode(data, mode,
+					       KMX61_ACC | KMX61_MAG, true);
+		}
+	}
+	return -EINVAL;
+}
+
+static int kmx61_chip_init(struct kmx61_data *data)
+{
+	int ret, val, val2;
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_WHO_AM_I);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading who_am_i\n");
+		return ret;
+	}
+
+	if (ret != KMX61_CHIP_ID) {
+		dev_err(&data->client->dev,
+			"Wrong chip id, got %x expected %x\n",
+			 ret, KMX61_CHIP_ID);
+		return -EINVAL;
+	}
+
+	/* set accel 12bit, 4g range */
+	ret = kmx61_set_range(data, KMX61_RANGE_4G);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_ODCNTL);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_odcntl\n");
+		return ret;
+	}
+	data->odr_bits = ret;
+
+	/* set output data rate for wake up (motion detection) function */
+	ret = kmx61_convert_bit_to_freq(data->odr_bits, &val, &val2);
+	if (ret < 0)
+		return ret;
+
+	ret = kmx61_set_wake_up_odr(data, val, val2);
+	if (ret < 0)
+		return ret;
+
+	/* set acc/magn to OPERATION mode */
+	ret = kmx61_set_mode(data, 0, KMX61_ACC | KMX61_MAG, true);
+	if (ret < 0)
+		return ret;
+
+	data->wake_thresh = KMX61_DEFAULT_WAKE_THRESH;
+	data->wake_duration = KMX61_DEFAULT_WAKE_DURATION;
+
+	return 0;
+}
+
+static int kmx61_setup_new_data_interrupt(struct kmx61_data *data,
+					  bool status, u8 device)
+{
+	u8 mode;
+	int ret;
+
+	ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG);
+	if (ret < 0)
+		return ret;
+
+	ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INC1);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+		return ret;
+	}
+
+	if (status) {
+		ret |= KMX61_REG_INC1_BIT_IEN;
+		if (device & KMX61_ACC)
+			ret |= KMX61_REG_INC1_BIT_DRDYA;
+		if (device & KMX61_MAG)
+			ret |=  KMX61_REG_INC1_BIT_DRDYM;
+	} else {
+		ret &= ~KMX61_REG_INC1_BIT_IEN;
+		if (device & KMX61_ACC)
+			ret &= ~KMX61_REG_INC1_BIT_DRDYA;
+		if (device & KMX61_MAG)
+			ret &= ~KMX61_REG_INC1_BIT_DRDYM;
+	}
+	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_INC1, ret);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_int_ctrl1\n");
+		return ret;
+	}
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+		return ret;
+	}
+
+	if (status)
+		ret |= KMX61_REG_CTRL1_BIT_DRDYE;
+	else
+		ret &= ~KMX61_REG_CTRL1_BIT_DRDYE;
+
+	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+		return ret;
+	}
+
+	return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true);
+}
+
+static int kmx61_chip_update_thresholds(struct kmx61_data *data)
+{
+	int ret;
+
+	ret = i2c_smbus_write_byte_data(data->client,
+					KMX61_REG_WUF_TIMER,
+					data->wake_duration);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Errow writing reg_wuf_timer\n");
+		return ret;
+	}
+
+	ret = i2c_smbus_write_byte_data(data->client,
+					KMX61_REG_WUF_THRESH,
+					data->wake_thresh);
+	if (ret < 0)
+		dev_err(&data->client->dev, "Error writing reg_wuf_thresh\n");
+
+	return ret;
+}
+
+static int kmx61_setup_any_motion_interrupt(struct kmx61_data *data,
+					    bool status)
+{
+	u8 mode;
+	int ret;
+
+	ret = kmx61_get_mode(data, &mode, KMX61_ACC | KMX61_MAG);
+	if (ret < 0)
+		return ret;
+
+	ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
+	if (ret < 0)
+		return ret;
+
+	ret = kmx61_chip_update_thresholds(data);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INC1);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_inc1\n");
+		return ret;
+	}
+	if (status)
+		ret |= (KMX61_REG_INC1_BIT_IEN | KMX61_REG_INC1_BIT_WUFS);
+	else
+		ret &= ~(KMX61_REG_INC1_BIT_IEN | KMX61_REG_INC1_BIT_WUFS);
+
+	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_INC1, ret);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_inc1\n");
+		return ret;
+	}
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+		return ret;
+	}
+
+	if (status)
+		ret |= KMX61_REG_CTRL1_BIT_WUFE | KMX61_REG_CTRL1_BIT_BTSE;
+	else
+		ret &= ~(KMX61_REG_CTRL1_BIT_WUFE | KMX61_REG_CTRL1_BIT_BTSE);
+
+	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+		return ret;
+	}
+	mode |= KMX61_ACT_STBY_BIT;
+	return kmx61_set_mode(data, mode, KMX61_ACC | KMX61_MAG, true);
+}
+
+/**
+ * kmx61_set_power_state() - set power state for kmx61 @device
+ * @data - kmx61 device private pointer
+ * @on - power state to be set for @device
+ * @device - bitmask indicating device for which @on state needs to be set
+ *
+ * Notice that when ACC power state needs to be set to ON and MAG is in
+ * OPERATION then we know that kmx61_runtime_resume was already called
+ * so we must set ACC OPERATION mode here. The same happens when MAG power
+ * state needs to be set to ON and ACC is in OPERATION.
+ */
+static int kmx61_set_power_state(struct kmx61_data *data, bool on, u8 device)
+{
+#ifdef CONFIG_PM
+	int ret;
+
+	if (device & KMX61_ACC) {
+		if (on && !data->acc_ps && !data->mag_stby) {
+			ret = kmx61_set_mode(data, 0, KMX61_ACC, true);
+			if (ret < 0)
+				return ret;
+		}
+		data->acc_ps = on;
+	}
+	if (device & KMX61_MAG) {
+		if (on && !data->mag_ps && !data->acc_stby) {
+			ret = kmx61_set_mode(data, 0, KMX61_MAG, true);
+			if (ret < 0)
+				return ret;
+		}
+		data->mag_ps = on;
+	}
+
+	if (on) {
+		ret = pm_runtime_get_sync(&data->client->dev);
+	} else {
+		pm_runtime_mark_last_busy(&data->client->dev);
+		ret = pm_runtime_put_autosuspend(&data->client->dev);
+	}
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"Failed: kmx61_set_power_state for %d, ret %d\n",
+			on, ret);
+		if (on)
+			pm_runtime_put_noidle(&data->client->dev);
+
+		return ret;
+	}
+#endif
+	return 0;
+}
+
+static int kmx61_read_measurement(struct kmx61_data *data, u8 base, u8 offset)
+{
+	int ret;
+	u8 reg = base + offset * 2;
+
+	ret = i2c_smbus_read_word_data(data->client, reg);
+	if (ret < 0)
+		dev_err(&data->client->dev, "failed to read reg at %x\n", reg);
+
+	return ret;
+}
+
+static int kmx61_read_raw(struct iio_dev *indio_dev,
+			  struct iio_chan_spec const *chan, int *val,
+			  int *val2, long mask)
+{
+	int ret;
+	u8 base_reg;
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		switch (chan->type) {
+		case IIO_ACCEL:
+			base_reg = KMX61_ACC_XOUT_L;
+			break;
+		case IIO_MAGN:
+			base_reg = KMX61_MAG_XOUT_L;
+			break;
+		default:
+			return -EINVAL;
+		}
+		mutex_lock(&data->lock);
+
+		ret = kmx61_set_power_state(data, true, chan->address);
+		if (ret) {
+			mutex_unlock(&data->lock);
+			return ret;
+		}
+
+		ret = kmx61_read_measurement(data, base_reg, chan->scan_index);
+		if (ret < 0) {
+			kmx61_set_power_state(data, false, chan->address);
+			mutex_unlock(&data->lock);
+			return ret;
+		}
+		*val = sign_extend32(ret >> chan->scan_type.shift,
+				     chan->scan_type.realbits - 1);
+		ret = kmx61_set_power_state(data, false, chan->address);
+
+		mutex_unlock(&data->lock);
+		if (ret)
+			return ret;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_ACCEL:
+			*val = 0;
+			*val2 = kmx61_uscale_table[data->range];
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_MAGN:
+			/* 14 bits res, 1465 microGauss per magn count */
+			*val = 0;
+			*val2 = 1465;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
+			return -EINVAL;
+
+		mutex_lock(&data->lock);
+		ret = kmx61_get_odr(data, val, val2, chan->address);
+		mutex_unlock(&data->lock);
+		if (ret)
+			return -EINVAL;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
+}
+
+static int kmx61_write_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan, int val,
+			   int val2, long mask)
+{
+	int ret;
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_SAMP_FREQ:
+		if (chan->type != IIO_ACCEL && chan->type != IIO_MAGN)
+			return -EINVAL;
+
+		mutex_lock(&data->lock);
+		ret = kmx61_set_odr(data, val, val2, chan->address);
+		mutex_unlock(&data->lock);
+		return ret;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_ACCEL:
+			if (val != 0)
+				return -EINVAL;
+			mutex_lock(&data->lock);
+			ret = kmx61_set_scale(data, val2);
+			mutex_unlock(&data->lock);
+			return ret;
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static int kmx61_read_event(struct iio_dev *indio_dev,
+			    const struct iio_chan_spec *chan,
+			    enum iio_event_type type,
+			    enum iio_event_direction dir,
+			    enum iio_event_info info,
+			    int *val, int *val2)
+{
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+
+	*val2 = 0;
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		*val = data->wake_thresh;
+		return IIO_VAL_INT;
+	case IIO_EV_INFO_PERIOD:
+		*val = data->wake_duration;
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int kmx61_write_event(struct iio_dev *indio_dev,
+			     const struct iio_chan_spec *chan,
+			     enum iio_event_type type,
+			     enum iio_event_direction dir,
+			     enum iio_event_info info,
+			     int val, int val2)
+{
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+
+	if (data->ev_enable_state)
+		return -EBUSY;
+
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		data->wake_thresh = val;
+		return IIO_VAL_INT;
+	case IIO_EV_INFO_PERIOD:
+		data->wake_duration = val;
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int kmx61_read_event_config(struct iio_dev *indio_dev,
+				   const struct iio_chan_spec *chan,
+				   enum iio_event_type type,
+				   enum iio_event_direction dir)
+{
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+
+	return data->ev_enable_state;
+}
+
+static int kmx61_write_event_config(struct iio_dev *indio_dev,
+				    const struct iio_chan_spec *chan,
+				    enum iio_event_type type,
+				    enum iio_event_direction dir,
+				    int state)
+{
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+	int ret = 0;
+
+	if (state && data->ev_enable_state)
+		return 0;
+
+	mutex_lock(&data->lock);
+
+	if (!state && data->motion_trig_on) {
+		data->ev_enable_state = false;
+		goto err_unlock;
+	}
+
+	ret = kmx61_set_power_state(data, state, KMX61_ACC);
+	if (ret < 0)
+		goto err_unlock;
+
+	ret = kmx61_setup_any_motion_interrupt(data, state);
+	if (ret < 0) {
+		kmx61_set_power_state(data, false, KMX61_ACC);
+		goto err_unlock;
+	}
+
+	data->ev_enable_state = state;
+
+err_unlock:
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int kmx61_acc_validate_trigger(struct iio_dev *indio_dev,
+				      struct iio_trigger *trig)
+{
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+
+	if (data->acc_dready_trig != trig && data->motion_trig != trig)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int kmx61_mag_validate_trigger(struct iio_dev *indio_dev,
+				      struct iio_trigger *trig)
+{
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+
+	if (data->mag_dready_trig != trig)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const struct iio_info kmx61_acc_info = {
+	.driver_module		= THIS_MODULE,
+	.read_raw		= kmx61_read_raw,
+	.write_raw		= kmx61_write_raw,
+	.attrs			= &kmx61_acc_attribute_group,
+	.read_event_value	= kmx61_read_event,
+	.write_event_value	= kmx61_write_event,
+	.read_event_config	= kmx61_read_event_config,
+	.write_event_config	= kmx61_write_event_config,
+	.validate_trigger	= kmx61_acc_validate_trigger,
+};
+
+static const struct iio_info kmx61_mag_info = {
+	.driver_module		= THIS_MODULE,
+	.read_raw		= kmx61_read_raw,
+	.write_raw		= kmx61_write_raw,
+	.attrs			= &kmx61_mag_attribute_group,
+	.validate_trigger	= kmx61_mag_validate_trigger,
+};
+
+
+static int kmx61_data_rdy_trigger_set_state(struct iio_trigger *trig,
+					    bool state)
+{
+	int ret = 0;
+	u8 device;
+
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+
+	mutex_lock(&data->lock);
+
+	if (!state && data->ev_enable_state && data->motion_trig_on) {
+		data->motion_trig_on = false;
+		goto err_unlock;
+	}
+
+	if (data->acc_dready_trig == trig || data->motion_trig == trig)
+		device = KMX61_ACC;
+	else
+		device = KMX61_MAG;
+
+	ret = kmx61_set_power_state(data, state, device);
+	if (ret < 0)
+		goto err_unlock;
+
+	if (data->acc_dready_trig == trig || data->mag_dready_trig == trig)
+		ret = kmx61_setup_new_data_interrupt(data, state, device);
+	else
+		ret = kmx61_setup_any_motion_interrupt(data, state);
+	if (ret < 0) {
+		kmx61_set_power_state(data, false, device);
+		goto err_unlock;
+	}
+
+	if (data->acc_dready_trig == trig)
+		data->acc_dready_trig_on = state;
+	else if (data->mag_dready_trig == trig)
+		data->mag_dready_trig_on = state;
+	else
+		data->motion_trig_on = state;
+err_unlock:
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int kmx61_trig_try_reenable(struct iio_trigger *trig)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INL);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_inl\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct iio_trigger_ops kmx61_trigger_ops = {
+	.set_trigger_state = kmx61_data_rdy_trigger_set_state,
+	.try_reenable = kmx61_trig_try_reenable,
+	.owner = THIS_MODULE,
+};
+
+static irqreturn_t kmx61_event_handler(int irq, void *private)
+{
+	struct kmx61_data *data = private;
+	struct iio_dev *indio_dev = data->acc_indio_dev;
+	int ret;
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INS1);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "Error reading reg_ins1\n");
+		goto ack_intr;
+	}
+
+	if (ret & KMX61_REG_INS1_BIT_WUFS) {
+		ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INS2);
+		if (ret < 0) {
+			dev_err(&data->client->dev, "Error reading reg_ins2\n");
+			goto ack_intr;
+		}
+
+		if (ret & KMX61_REG_INS2_BIT_XN)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_X,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_FALLING),
+				       0);
+
+		if (ret & KMX61_REG_INS2_BIT_XP)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_X,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_RISING),
+				       0);
+
+		if (ret & KMX61_REG_INS2_BIT_YN)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_Y,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_FALLING),
+				       0);
+
+		if (ret & KMX61_REG_INS2_BIT_YP)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_Y,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_RISING),
+				       0);
+
+		if (ret & KMX61_REG_INS2_BIT_ZN)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_Z,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_FALLING),
+				       0);
+
+		if (ret & KMX61_REG_INS2_BIT_ZP)
+			iio_push_event(indio_dev,
+				       IIO_MOD_EVENT_CODE(IIO_ACCEL,
+				       0,
+				       IIO_MOD_Z,
+				       IIO_EV_TYPE_THRESH,
+				       IIO_EV_DIR_RISING),
+				       0);
+	}
+
+ack_intr:
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_CTRL1);
+	if (ret < 0)
+		dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
+
+	ret |= KMX61_REG_CTRL1_BIT_RES;
+	ret = i2c_smbus_write_byte_data(data->client, KMX61_REG_CTRL1, ret);
+	if (ret < 0)
+		dev_err(&data->client->dev, "Error writing reg_ctrl1\n");
+
+	ret = i2c_smbus_read_byte_data(data->client, KMX61_REG_INL);
+	if (ret < 0)
+		dev_err(&data->client->dev, "Error reading reg_inl\n");
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t kmx61_data_rdy_trig_poll(int irq, void *private)
+{
+	struct kmx61_data *data = private;
+
+	if (data->acc_dready_trig_on)
+		iio_trigger_poll(data->acc_dready_trig);
+	if (data->mag_dready_trig_on)
+		iio_trigger_poll(data->mag_dready_trig);
+
+	if (data->motion_trig_on)
+		iio_trigger_poll(data->motion_trig);
+
+	if (data->ev_enable_state)
+		return IRQ_WAKE_THREAD;
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t kmx61_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct kmx61_data *data = kmx61_get_data(indio_dev);
+	int bit, ret, i = 0;
+	u8 base;
+	s16 buffer[8];
+
+	if (indio_dev == data->acc_indio_dev)
+		base = KMX61_ACC_XOUT_L;
+	else
+		base = KMX61_MAG_XOUT_L;
+
+	mutex_lock(&data->lock);
+	for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+			 indio_dev->masklength) {
+		ret = kmx61_read_measurement(data, base, bit);
+		if (ret < 0) {
+			mutex_unlock(&data->lock);
+			goto err;
+		}
+		buffer[i++] = ret;
+	}
+	mutex_unlock(&data->lock);
+
+	iio_push_to_buffers(indio_dev, buffer);
+err:
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+static const char *kmx61_match_acpi_device(struct device *dev)
+{
+	const struct acpi_device_id *id;
+
+	id = acpi_match_device(dev->driver->acpi_match_table, dev);
+	if (!id)
+		return NULL;
+	return dev_name(dev);
+}
+
+static int kmx61_gpio_probe(struct i2c_client *client, struct kmx61_data *data)
+{
+	struct device *dev;
+	struct gpio_desc *gpio;
+	int ret;
+
+	if (!client)
+		return -EINVAL;
+
+	dev = &client->dev;
+
+	/* data ready gpio interrupt pin */
+	gpio = devm_gpiod_get_index(dev, KMX61_GPIO_NAME, 0);
+	if (IS_ERR(gpio)) {
+		dev_err(dev, "acpi gpio get index failed\n");
+		return PTR_ERR(gpio);
+	}
+
+	ret = gpiod_direction_input(gpio);
+	if (ret)
+		return ret;
+
+	ret = gpiod_to_irq(gpio);
+
+	dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
+	return ret;
+}
+
+static struct iio_dev *kmx61_indiodev_setup(struct kmx61_data *data,
+					    const struct iio_info *info,
+					    const struct iio_chan_spec *chan,
+					    int num_channels,
+					    const char *name)
+{
+	struct iio_dev *indio_dev;
+
+	indio_dev = devm_iio_device_alloc(&data->client->dev, sizeof(data));
+	if (!indio_dev)
+		return ERR_PTR(-ENOMEM);
+
+	kmx61_set_data(indio_dev, data);
+
+	indio_dev->dev.parent = &data->client->dev;
+	indio_dev->channels = chan;
+	indio_dev->num_channels = num_channels;
+	indio_dev->name = name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = info;
+
+	return indio_dev;
+}
+
+static struct iio_trigger *kmx61_trigger_setup(struct kmx61_data *data,
+					       struct iio_dev *indio_dev,
+					       const char *tag)
+{
+	struct iio_trigger *trig;
+	int ret;
+
+	trig = devm_iio_trigger_alloc(&data->client->dev,
+				      "%s-%s-dev%d",
+				      indio_dev->name,
+				      tag,
+				      indio_dev->id);
+	if (!trig)
+		return ERR_PTR(-ENOMEM);
+
+	trig->dev.parent = &data->client->dev;
+	trig->ops = &kmx61_trigger_ops;
+	iio_trigger_set_drvdata(trig, indio_dev);
+
+	ret = iio_trigger_register(trig);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return trig;
+}
+
+static int kmx61_probe(struct i2c_client *client,
+		       const struct i2c_device_id *id)
+{
+	int ret;
+	struct kmx61_data *data;
+	const char *name = NULL;
+
+	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	data->client = client;
+
+	mutex_init(&data->lock);
+
+	if (id)
+		name = id->name;
+	else if (ACPI_HANDLE(&client->dev))
+		name = kmx61_match_acpi_device(&client->dev);
+	else
+		return -ENODEV;
+
+	data->acc_indio_dev =
+		kmx61_indiodev_setup(data, &kmx61_acc_info,
+				     kmx61_acc_channels,
+				     ARRAY_SIZE(kmx61_acc_channels),
+				     name);
+	if (IS_ERR(data->acc_indio_dev))
+		return PTR_ERR(data->acc_indio_dev);
+
+	data->mag_indio_dev =
+		kmx61_indiodev_setup(data, &kmx61_mag_info,
+				     kmx61_mag_channels,
+				     ARRAY_SIZE(kmx61_mag_channels),
+				     name);
+	if (IS_ERR(data->mag_indio_dev))
+		return PTR_ERR(data->mag_indio_dev);
+
+	ret = kmx61_chip_init(data);
+	if (ret < 0)
+		return ret;
+
+	if (client->irq < 0)
+		client->irq = kmx61_gpio_probe(client, data);
+
+	if (client->irq >= 0) {
+		ret = devm_request_threaded_irq(&client->dev, client->irq,
+						kmx61_data_rdy_trig_poll,
+						kmx61_event_handler,
+						IRQF_TRIGGER_RISING,
+						KMX61_IRQ_NAME,
+						data);
+		if (ret)
+			goto err_chip_uninit;
+
+		data->acc_dready_trig =
+			kmx61_trigger_setup(data, data->acc_indio_dev,
+					    "dready");
+		if (IS_ERR(data->acc_dready_trig)) {
+			ret = PTR_ERR(data->acc_dready_trig);
+			goto err_chip_uninit;
+		}
+
+		data->mag_dready_trig =
+			kmx61_trigger_setup(data, data->mag_indio_dev,
+					    "dready");
+		if (IS_ERR(data->mag_dready_trig)) {
+			ret = PTR_ERR(data->mag_dready_trig);
+			goto err_trigger_unregister_acc_dready;
+		}
+
+		data->motion_trig =
+			kmx61_trigger_setup(data, data->acc_indio_dev,
+					    "any-motion");
+		if (IS_ERR(data->motion_trig)) {
+			ret = PTR_ERR(data->motion_trig);
+			goto err_trigger_unregister_mag_dready;
+		}
+
+		ret = iio_triggered_buffer_setup(data->acc_indio_dev,
+						 &iio_pollfunc_store_time,
+						 kmx61_trigger_handler,
+						 NULL);
+		if (ret < 0) {
+			dev_err(&data->client->dev,
+				"Failed to setup acc triggered buffer\n");
+			goto err_trigger_unregister_motion;
+		}
+
+		ret = iio_triggered_buffer_setup(data->mag_indio_dev,
+						 &iio_pollfunc_store_time,
+						 kmx61_trigger_handler,
+						 NULL);
+		if (ret < 0) {
+			dev_err(&data->client->dev,
+				"Failed to setup mag triggered buffer\n");
+			goto err_buffer_cleanup_acc;
+		}
+	}
+
+	ret = iio_device_register(data->acc_indio_dev);
+	if (ret < 0) {
+		dev_err(&client->dev, "Failed to register acc iio device\n");
+		goto err_buffer_cleanup_mag;
+	}
+
+	ret = iio_device_register(data->mag_indio_dev);
+	if (ret < 0) {
+		dev_err(&client->dev, "Failed to register mag iio device\n");
+		goto err_iio_unregister_acc;
+	}
+
+	ret = pm_runtime_set_active(&client->dev);
+	if (ret < 0)
+		goto err_iio_unregister_mag;
+
+	pm_runtime_enable(&client->dev);
+	pm_runtime_set_autosuspend_delay(&client->dev, KMX61_SLEEP_DELAY_MS);
+	pm_runtime_use_autosuspend(&client->dev);
+
+	return 0;
+
+err_iio_unregister_mag:
+	iio_device_unregister(data->mag_indio_dev);
+err_iio_unregister_acc:
+	iio_device_unregister(data->acc_indio_dev);
+err_buffer_cleanup_mag:
+	if (client->irq >= 0)
+		iio_triggered_buffer_cleanup(data->mag_indio_dev);
+err_buffer_cleanup_acc:
+	if (client->irq >= 0)
+		iio_triggered_buffer_cleanup(data->acc_indio_dev);
+err_trigger_unregister_motion:
+	iio_trigger_unregister(data->motion_trig);
+err_trigger_unregister_mag_dready:
+	iio_trigger_unregister(data->mag_dready_trig);
+err_trigger_unregister_acc_dready:
+	iio_trigger_unregister(data->acc_dready_trig);
+err_chip_uninit:
+	kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
+	return ret;
+}
+
+static int kmx61_remove(struct i2c_client *client)
+{
+	struct kmx61_data *data = i2c_get_clientdata(client);
+
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_put_noidle(&client->dev);
+
+	iio_device_unregister(data->acc_indio_dev);
+	iio_device_unregister(data->mag_indio_dev);
+
+	if (client->irq >= 0) {
+		iio_triggered_buffer_cleanup(data->acc_indio_dev);
+		iio_triggered_buffer_cleanup(data->mag_indio_dev);
+		iio_trigger_unregister(data->acc_dready_trig);
+		iio_trigger_unregister(data->mag_dready_trig);
+		iio_trigger_unregister(data->motion_trig);
+	}
+
+	mutex_lock(&data->lock);
+	kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
+	mutex_unlock(&data->lock);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int kmx61_suspend(struct device *dev)
+{
+	int ret;
+	struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	mutex_lock(&data->lock);
+	ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG,
+			     false);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int kmx61_resume(struct device *dev)
+{
+	u8 stby = 0;
+	struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
+
+	if (data->acc_stby)
+		stby |= KMX61_ACC_STBY_BIT;
+	if (data->mag_stby)
+		stby |= KMX61_MAG_STBY_BIT;
+
+	return kmx61_set_mode(data, stby, KMX61_ACC | KMX61_MAG, true);
+}
+#endif
+
+#ifdef CONFIG_PM
+static int kmx61_runtime_suspend(struct device *dev)
+{
+	struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
+	int ret;
+
+	mutex_lock(&data->lock);
+	ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int kmx61_runtime_resume(struct device *dev)
+{
+	struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
+	u8 stby = 0;
+
+	if (!data->acc_ps)
+		stby |= KMX61_ACC_STBY_BIT;
+	if (!data->mag_ps)
+		stby |= KMX61_MAG_STBY_BIT;
+
+	return kmx61_set_mode(data, stby, KMX61_ACC | KMX61_MAG, true);
+}
+#endif
+
+static const struct dev_pm_ops kmx61_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(kmx61_suspend, kmx61_resume)
+	SET_RUNTIME_PM_OPS(kmx61_runtime_suspend, kmx61_runtime_resume, NULL)
+};
+
+static const struct acpi_device_id kmx61_acpi_match[] = {
+	{"KMX61021", 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(acpi, kmx61_acpi_match);
+
+static const struct i2c_device_id kmx61_id[] = {
+	{"kmx611021", 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, kmx61_id);
+
+static struct i2c_driver kmx61_driver = {
+	.driver = {
+		.name = KMX61_DRV_NAME,
+		.acpi_match_table = ACPI_PTR(kmx61_acpi_match),
+		.pm = &kmx61_pm_ops,
+	},
+	.probe		= kmx61_probe,
+	.remove		= kmx61_remove,
+	.id_table	= kmx61_id,
+};
+
+module_i2c_driver(kmx61_driver);
+
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
+MODULE_DESCRIPTION("KMX61 accelerometer/magnetometer driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c
index f971f79103ec..71333140d42c 100644
--- a/drivers/iio/industrialio-buffer.c
+++ b/drivers/iio/industrialio-buffer.c
@@ -178,6 +178,80 @@ static ssize_t iio_scan_el_show(struct device *dev,
 	return sprintf(buf, "%d\n", ret);
 }
 
+/* Note NULL used as error indicator as it doesn't make sense. */
+static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
+					  unsigned int masklength,
+					  const unsigned long *mask)
+{
+	if (bitmap_empty(mask, masklength))
+		return NULL;
+	while (*av_masks) {
+		if (bitmap_subset(mask, av_masks, masklength))
+			return av_masks;
+		av_masks += BITS_TO_LONGS(masklength);
+	}
+	return NULL;
+}
+
+static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
+	const unsigned long *mask)
+{
+	if (!indio_dev->setup_ops->validate_scan_mask)
+		return true;
+
+	return indio_dev->setup_ops->validate_scan_mask(indio_dev, mask);
+}
+
+/**
+ * iio_scan_mask_set() - set particular bit in the scan mask
+ * @indio_dev: the iio device
+ * @buffer: the buffer whose scan mask we are interested in
+ * @bit: the bit to be set.
+ *
+ * Note that at this point we have no way of knowing what other
+ * buffers might request, hence this code only verifies that the
+ * individual buffers request is plausible.
+ */
+static int iio_scan_mask_set(struct iio_dev *indio_dev,
+		      struct iio_buffer *buffer, int bit)
+{
+	const unsigned long *mask;
+	unsigned long *trialmask;
+
+	trialmask = kmalloc(sizeof(*trialmask)*
+			    BITS_TO_LONGS(indio_dev->masklength),
+			    GFP_KERNEL);
+
+	if (trialmask == NULL)
+		return -ENOMEM;
+	if (!indio_dev->masklength) {
+		WARN_ON("Trying to set scanmask prior to registering buffer\n");
+		goto err_invalid_mask;
+	}
+	bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
+	set_bit(bit, trialmask);
+
+	if (!iio_validate_scan_mask(indio_dev, trialmask))
+		goto err_invalid_mask;
+
+	if (indio_dev->available_scan_masks) {
+		mask = iio_scan_mask_match(indio_dev->available_scan_masks,
+					   indio_dev->masklength,
+					   trialmask);
+		if (!mask)
+			goto err_invalid_mask;
+	}
+	bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength);
+
+	kfree(trialmask);
+
+	return 0;
+
+err_invalid_mask:
+	kfree(trialmask);
+	return -EINVAL;
+}
+
 static int iio_scan_mask_clear(struct iio_buffer *buffer, int bit)
 {
 	clear_bit(bit, buffer->scan_mask);
@@ -309,115 +383,19 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
 	return ret;
 }
 
-static const char * const iio_scan_elements_group_name = "scan_elements";
-
-int iio_buffer_register(struct iio_dev *indio_dev,
-			const struct iio_chan_spec *channels,
-			int num_channels)
-{
-	struct iio_dev_attr *p;
-	struct attribute **attr;
-	struct iio_buffer *buffer = indio_dev->buffer;
-	int ret, i, attrn, attrcount, attrcount_orig = 0;
-
-	if (buffer->attrs)
-		indio_dev->groups[indio_dev->groupcounter++] = buffer->attrs;
-
-	if (buffer->scan_el_attrs != NULL) {
-		attr = buffer->scan_el_attrs->attrs;
-		while (*attr++ != NULL)
-			attrcount_orig++;
-	}
-	attrcount = attrcount_orig;
-	INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list);
-	if (channels) {
-		/* new magic */
-		for (i = 0; i < num_channels; i++) {
-			if (channels[i].scan_index < 0)
-				continue;
-
-			/* Establish necessary mask length */
-			if (channels[i].scan_index >
-			    (int)indio_dev->masklength - 1)
-				indio_dev->masklength
-					= channels[i].scan_index + 1;
-
-			ret = iio_buffer_add_channel_sysfs(indio_dev,
-							 &channels[i]);
-			if (ret < 0)
-				goto error_cleanup_dynamic;
-			attrcount += ret;
-			if (channels[i].type == IIO_TIMESTAMP)
-				indio_dev->scan_index_timestamp =
-					channels[i].scan_index;
-		}
-		if (indio_dev->masklength && buffer->scan_mask == NULL) {
-			buffer->scan_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
-						    sizeof(*buffer->scan_mask),
-						    GFP_KERNEL);
-			if (buffer->scan_mask == NULL) {
-				ret = -ENOMEM;
-				goto error_cleanup_dynamic;
-			}
-		}
-	}
-
-	buffer->scan_el_group.name = iio_scan_elements_group_name;
-
-	buffer->scan_el_group.attrs = kcalloc(attrcount + 1,
-					      sizeof(buffer->scan_el_group.attrs[0]),
-					      GFP_KERNEL);
-	if (buffer->scan_el_group.attrs == NULL) {
-		ret = -ENOMEM;
-		goto error_free_scan_mask;
-	}
-	if (buffer->scan_el_attrs)
-		memcpy(buffer->scan_el_group.attrs, buffer->scan_el_attrs,
-		       sizeof(buffer->scan_el_group.attrs[0])*attrcount_orig);
-	attrn = attrcount_orig;
-
-	list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l)
-		buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr;
-	indio_dev->groups[indio_dev->groupcounter++] = &buffer->scan_el_group;
-
-	return 0;
-
-error_free_scan_mask:
-	kfree(buffer->scan_mask);
-error_cleanup_dynamic:
-	iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
-
-	return ret;
-}
-EXPORT_SYMBOL(iio_buffer_register);
-
-void iio_buffer_unregister(struct iio_dev *indio_dev)
-{
-	kfree(indio_dev->buffer->scan_mask);
-	kfree(indio_dev->buffer->scan_el_group.attrs);
-	iio_free_chan_devattr_list(&indio_dev->buffer->scan_el_dev_attr_list);
-}
-EXPORT_SYMBOL(iio_buffer_unregister);
-
-ssize_t iio_buffer_read_length(struct device *dev,
-			       struct device_attribute *attr,
-			       char *buf)
+static ssize_t iio_buffer_read_length(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	struct iio_buffer *buffer = indio_dev->buffer;
 
-	if (buffer->access->get_length)
-		return sprintf(buf, "%d\n",
-			       buffer->access->get_length(buffer));
-
-	return 0;
+	return sprintf(buf, "%d\n", buffer->length);
 }
-EXPORT_SYMBOL(iio_buffer_read_length);
 
-ssize_t iio_buffer_write_length(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf,
-				size_t len)
+static ssize_t iio_buffer_write_length(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t len)
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	struct iio_buffer *buffer = indio_dev->buffer;
@@ -428,47 +406,28 @@ ssize_t iio_buffer_write_length(struct device *dev,
 	if (ret)
 		return ret;
 
-	if (buffer->access->get_length)
-		if (val == buffer->access->get_length(buffer))
-			return len;
+	if (val == buffer->length)
+		return len;
 
 	mutex_lock(&indio_dev->mlock);
 	if (iio_buffer_is_active(indio_dev->buffer)) {
 		ret = -EBUSY;
 	} else {
-		if (buffer->access->set_length)
-			buffer->access->set_length(buffer, val);
+		buffer->access->set_length(buffer, val);
 		ret = 0;
 	}
 	mutex_unlock(&indio_dev->mlock);
 
 	return ret ? ret : len;
 }
-EXPORT_SYMBOL(iio_buffer_write_length);
 
-ssize_t iio_buffer_show_enable(struct device *dev,
-			       struct device_attribute *attr,
-			       char *buf)
+static ssize_t iio_buffer_show_enable(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
 {
 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 	return sprintf(buf, "%d\n", iio_buffer_is_active(indio_dev->buffer));
 }
-EXPORT_SYMBOL(iio_buffer_show_enable);
-
-/* Note NULL used as error indicator as it doesn't make sense. */
-static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
-					  unsigned int masklength,
-					  const unsigned long *mask)
-{
-	if (bitmap_empty(mask, masklength))
-		return NULL;
-	while (*av_masks) {
-		if (bitmap_subset(mask, av_masks, masklength))
-			return av_masks;
-		av_masks += BITS_TO_LONGS(masklength);
-	}
-	return NULL;
-}
 
 static int iio_compute_scan_bytes(struct iio_dev *indio_dev,
 				const unsigned long *mask, bool timestamp)
@@ -680,6 +639,8 @@ static int __iio_update_buffers(struct iio_dev *indio_dev,
 		indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
 	} else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
 		indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
+	} else if (indio_dev->modes & INDIO_BUFFER_SOFTWARE) {
+		indio_dev->currentmode = INDIO_BUFFER_SOFTWARE;
 	} else { /* Should never be reached */
 		ret = -EINVAL;
 		goto error_run_postdisable;
@@ -755,10 +716,10 @@ out_unlock:
 }
 EXPORT_SYMBOL_GPL(iio_update_buffers);
 
-ssize_t iio_buffer_store_enable(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf,
-				size_t len)
+static ssize_t iio_buffer_store_enable(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf,
+				       size_t len)
 {
 	int ret;
 	bool requested_state;
@@ -790,83 +751,146 @@ done:
 	mutex_unlock(&indio_dev->mlock);
 	return (ret < 0) ? ret : len;
 }
-EXPORT_SYMBOL(iio_buffer_store_enable);
 
-/**
- * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected
- * @indio_dev: the iio device
- * @mask: scan mask to be checked
- *
- * Return true if exactly one bit is set in the scan mask, false otherwise. It
- * can be used for devices where only one channel can be active for sampling at
- * a time.
- */
-bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
-	const unsigned long *mask)
-{
-	return bitmap_weight(mask, indio_dev->masklength) == 1;
-}
-EXPORT_SYMBOL_GPL(iio_validate_scan_mask_onehot);
-
-static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
-	const unsigned long *mask)
-{
-	if (!indio_dev->setup_ops->validate_scan_mask)
-		return true;
+static const char * const iio_scan_elements_group_name = "scan_elements";
 
-	return indio_dev->setup_ops->validate_scan_mask(indio_dev, mask);
-}
+static DEVICE_ATTR(length, S_IRUGO | S_IWUSR, iio_buffer_read_length,
+		   iio_buffer_write_length);
+static struct device_attribute dev_attr_length_ro = __ATTR(length,
+	S_IRUGO, iio_buffer_read_length, NULL);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
+		   iio_buffer_show_enable, iio_buffer_store_enable);
 
-/**
- * iio_scan_mask_set() - set particular bit in the scan mask
- * @indio_dev: the iio device
- * @buffer: the buffer whose scan mask we are interested in
- * @bit: the bit to be set.
- *
- * Note that at this point we have no way of knowing what other
- * buffers might request, hence this code only verifies that the
- * individual buffers request is plausible.
- */
-int iio_scan_mask_set(struct iio_dev *indio_dev,
-		      struct iio_buffer *buffer, int bit)
+int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
 {
-	const unsigned long *mask;
-	unsigned long *trialmask;
+	struct iio_dev_attr *p;
+	struct attribute **attr;
+	struct iio_buffer *buffer = indio_dev->buffer;
+	int ret, i, attrn, attrcount, attrcount_orig = 0;
+	const struct iio_chan_spec *channels;
 
-	trialmask = kmalloc(sizeof(*trialmask)*
-			    BITS_TO_LONGS(indio_dev->masklength),
-			    GFP_KERNEL);
+	if (!buffer)
+		return 0;
 
-	if (trialmask == NULL)
+	attrcount = 0;
+	if (buffer->attrs) {
+		while (buffer->attrs[attrcount] != NULL)
+			attrcount++;
+	}
+
+	buffer->buffer_group.name = "buffer";
+	buffer->buffer_group.attrs = kcalloc(attrcount + 3,
+			sizeof(*buffer->buffer_group.attrs), GFP_KERNEL);
+	if (!buffer->buffer_group.attrs)
 		return -ENOMEM;
-	if (!indio_dev->masklength) {
-		WARN_ON("Trying to set scanmask prior to registering buffer\n");
-		goto err_invalid_mask;
+
+	if (buffer->access->set_length)
+		buffer->buffer_group.attrs[0] = &dev_attr_length.attr;
+	else
+		buffer->buffer_group.attrs[0] = &dev_attr_length_ro.attr;
+	buffer->buffer_group.attrs[1] = &dev_attr_enable.attr;
+	if (buffer->attrs)
+		memcpy(&buffer->buffer_group.attrs[2], buffer->attrs,
+			sizeof(*&buffer->buffer_group.attrs) * attrcount);
+	buffer->buffer_group.attrs[attrcount+2] = NULL;
+
+	indio_dev->groups[indio_dev->groupcounter++] = &buffer->buffer_group;
+
+	if (buffer->scan_el_attrs != NULL) {
+		attr = buffer->scan_el_attrs->attrs;
+		while (*attr++ != NULL)
+			attrcount_orig++;
 	}
-	bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
-	set_bit(bit, trialmask);
+	attrcount = attrcount_orig;
+	INIT_LIST_HEAD(&buffer->scan_el_dev_attr_list);
+	channels = indio_dev->channels;
+	if (channels) {
+		/* new magic */
+		for (i = 0; i < indio_dev->num_channels; i++) {
+			if (channels[i].scan_index < 0)
+				continue;
 
-	if (!iio_validate_scan_mask(indio_dev, trialmask))
-		goto err_invalid_mask;
+			/* Establish necessary mask length */
+			if (channels[i].scan_index >
+			    (int)indio_dev->masklength - 1)
+				indio_dev->masklength
+					= channels[i].scan_index + 1;
 
-	if (indio_dev->available_scan_masks) {
-		mask = iio_scan_mask_match(indio_dev->available_scan_masks,
-					   indio_dev->masklength,
-					   trialmask);
-		if (!mask)
-			goto err_invalid_mask;
+			ret = iio_buffer_add_channel_sysfs(indio_dev,
+							 &channels[i]);
+			if (ret < 0)
+				goto error_cleanup_dynamic;
+			attrcount += ret;
+			if (channels[i].type == IIO_TIMESTAMP)
+				indio_dev->scan_index_timestamp =
+					channels[i].scan_index;
+		}
+		if (indio_dev->masklength && buffer->scan_mask == NULL) {
+			buffer->scan_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
+						    sizeof(*buffer->scan_mask),
+						    GFP_KERNEL);
+			if (buffer->scan_mask == NULL) {
+				ret = -ENOMEM;
+				goto error_cleanup_dynamic;
+			}
+		}
 	}
-	bitmap_copy(buffer->scan_mask, trialmask, indio_dev->masklength);
 
-	kfree(trialmask);
+	buffer->scan_el_group.name = iio_scan_elements_group_name;
+
+	buffer->scan_el_group.attrs = kcalloc(attrcount + 1,
+					      sizeof(buffer->scan_el_group.attrs[0]),
+					      GFP_KERNEL);
+	if (buffer->scan_el_group.attrs == NULL) {
+		ret = -ENOMEM;
+		goto error_free_scan_mask;
+	}
+	if (buffer->scan_el_attrs)
+		memcpy(buffer->scan_el_group.attrs, buffer->scan_el_attrs,
+		       sizeof(buffer->scan_el_group.attrs[0])*attrcount_orig);
+	attrn = attrcount_orig;
+
+	list_for_each_entry(p, &buffer->scan_el_dev_attr_list, l)
+		buffer->scan_el_group.attrs[attrn++] = &p->dev_attr.attr;
+	indio_dev->groups[indio_dev->groupcounter++] = &buffer->scan_el_group;
 
 	return 0;
 
-err_invalid_mask:
-	kfree(trialmask);
-	return -EINVAL;
+error_free_scan_mask:
+	kfree(buffer->scan_mask);
+error_cleanup_dynamic:
+	iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
+	kfree(indio_dev->buffer->buffer_group.attrs);
+
+	return ret;
+}
+
+void iio_buffer_free_sysfs_and_mask(struct iio_dev *indio_dev)
+{
+	if (!indio_dev->buffer)
+		return;
+
+	kfree(indio_dev->buffer->scan_mask);
+	kfree(indio_dev->buffer->buffer_group.attrs);
+	kfree(indio_dev->buffer->scan_el_group.attrs);
+	iio_free_chan_devattr_list(&indio_dev->buffer->scan_el_dev_attr_list);
+}
+
+/**
+ * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected
+ * @indio_dev: the iio device
+ * @mask: scan mask to be checked
+ *
+ * Return true if exactly one bit is set in the scan mask, false otherwise. It
+ * can be used for devices where only one channel can be active for sampling at
+ * a time.
+ */
+bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
+	const unsigned long *mask)
+{
+	return bitmap_weight(mask, indio_dev->masklength) == 1;
 }
-EXPORT_SYMBOL_GPL(iio_scan_mask_set);
+EXPORT_SYMBOL_GPL(iio_validate_scan_mask_onehot);
 
 int iio_scan_mask_query(struct iio_dev *indio_dev,
 			struct iio_buffer *buffer, int bit)
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index af3e76d652ba..aaba9d3d980e 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -70,6 +70,11 @@ static const char * const iio_chan_type_name_spec[] = {
 	[IIO_CCT] = "cct",
 	[IIO_PRESSURE] = "pressure",
 	[IIO_HUMIDITYRELATIVE] = "humidityrelative",
+	[IIO_ACTIVITY] = "activity",
+	[IIO_STEPS] = "steps",
+	[IIO_ENERGY] = "energy",
+	[IIO_DISTANCE] = "distance",
+	[IIO_VELOCITY] = "velocity",
 };
 
 static const char * const iio_modifier_names[] = {
@@ -91,6 +96,11 @@ static const char * const iio_modifier_names[] = {
 	[IIO_MOD_NORTH_TRUE] = "from_north_true",
 	[IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
 	[IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
+	[IIO_MOD_RUNNING] = "running",
+	[IIO_MOD_JOGGING] = "jogging",
+	[IIO_MOD_WALKING] = "walking",
+	[IIO_MOD_STILL] = "still",
+	[IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z] = "sqrt(x^2+y^2+z^2)",
 };
 
 /* relies on pairs of these shared then separate */
@@ -113,6 +123,11 @@ static const char * const iio_chan_info_postfix[] = {
 	[IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
 	[IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
 	[IIO_CHAN_INFO_INT_TIME] = "integration_time",
+	[IIO_CHAN_INFO_ENABLE] = "en",
+	[IIO_CHAN_INFO_CALIBHEIGHT] = "calibheight",
+	[IIO_CHAN_INFO_CALIBWEIGHT] = "calibweight",
+	[IIO_CHAN_INFO_DEBOUNCE_COUNT] = "debounce_count",
+	[IIO_CHAN_INFO_DEBOUNCE_TIME] = "debounce_time",
 };
 
 /**
@@ -1035,7 +1050,6 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv)
 	if (!ptr)
 		return NULL;
 
-	/* use raw alloc_dr for kmalloc caller tracing */
 	iio_dev = iio_device_alloc(sizeof_priv);
 	if (iio_dev) {
 		*ptr = iio_dev;
@@ -1127,6 +1141,29 @@ static const struct file_operations iio_buffer_fileops = {
 	.compat_ioctl = iio_ioctl,
 };
 
+static int iio_check_unique_scan_index(struct iio_dev *indio_dev)
+{
+	int i, j;
+	const struct iio_chan_spec *channels = indio_dev->channels;
+
+	if (!(indio_dev->modes & INDIO_ALL_BUFFER_MODES))
+		return 0;
+
+	for (i = 0; i < indio_dev->num_channels - 1; i++) {
+		if (channels[i].scan_index < 0)
+			continue;
+		for (j = i + 1; j < indio_dev->num_channels; j++)
+			if (channels[i].scan_index == channels[j].scan_index) {
+				dev_err(&indio_dev->dev,
+					"Duplicate scan index %d\n",
+					channels[i].scan_index);
+				return -EINVAL;
+			}
+	}
+
+	return 0;
+}
+
 static const struct iio_buffer_setup_ops noop_ring_setup_ops;
 
 /**
@@ -1141,6 +1178,10 @@ int iio_device_register(struct iio_dev *indio_dev)
 	if (!indio_dev->dev.of_node && indio_dev->dev.parent)
 		indio_dev->dev.of_node = indio_dev->dev.parent->of_node;
 
+	ret = iio_check_unique_scan_index(indio_dev);
+	if (ret < 0)
+		return ret;
+
 	/* configure elements for the chrdev */
 	indio_dev->dev.devt = MKDEV(MAJOR(iio_devt), indio_dev->id);
 
@@ -1150,11 +1191,19 @@ int iio_device_register(struct iio_dev *indio_dev)
 			"Failed to register debugfs interfaces\n");
 		return ret;
 	}
+
+	ret = iio_buffer_alloc_sysfs_and_mask(indio_dev);
+	if (ret) {
+		dev_err(indio_dev->dev.parent,
+			"Failed to create buffer sysfs interfaces\n");
+		goto error_unreg_debugfs;
+	}
+
 	ret = iio_device_register_sysfs(indio_dev);
 	if (ret) {
 		dev_err(indio_dev->dev.parent,
 			"Failed to register sysfs interfaces\n");
-		goto error_unreg_debugfs;
+		goto error_buffer_free_sysfs;
 	}
 	ret = iio_device_register_eventset(indio_dev);
 	if (ret) {
@@ -1187,6 +1236,8 @@ error_unreg_eventset:
 	iio_device_unregister_eventset(indio_dev);
 error_free_sysfs:
 	iio_device_unregister_sysfs(indio_dev);
+error_buffer_free_sysfs:
+	iio_buffer_free_sysfs_and_mask(indio_dev);
 error_unreg_debugfs:
 	iio_device_unregister_debugfs(indio_dev);
 	return ret;
@@ -1215,6 +1266,8 @@ void iio_device_unregister(struct iio_dev *indio_dev)
 	iio_buffer_wakeup_poll(indio_dev);
 
 	mutex_unlock(&indio_dev->info_exist_lock);
+
+	iio_buffer_free_sysfs_and_mask(indio_dev);
 }
 EXPORT_SYMBOL(iio_device_unregister);
 
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index 0c1e37e3120a..a4b397048f71 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -197,6 +197,7 @@ static const char * const iio_ev_type_text[] = {
 	[IIO_EV_TYPE_ROC] = "roc",
 	[IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
 	[IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
+	[IIO_EV_TYPE_CHANGE] = "change",
 };
 
 static const char * const iio_ev_dir_text[] = {
@@ -327,9 +328,15 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
 	for_each_set_bit(i, mask, sizeof(*mask)*8) {
 		if (i >= ARRAY_SIZE(iio_ev_info_text))
 			return -EINVAL;
-		postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
-				iio_ev_type_text[type], iio_ev_dir_text[dir],
-				iio_ev_info_text[i]);
+		if (dir != IIO_EV_DIR_NONE)
+			postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
+					iio_ev_type_text[type],
+					iio_ev_dir_text[dir],
+					iio_ev_info_text[i]);
+		else
+			postfix = kasprintf(GFP_KERNEL, "%s_%s",
+					iio_ev_type_text[type],
+					iio_ev_info_text[i]);
 		if (postfix == NULL)
 			return -ENOMEM;
 
@@ -404,7 +411,7 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)
 {
 	int j, ret, attrcount = 0;
 
-	/* Dynically created from the channels array */
+	/* Dynamically created from the channels array */
 	for (j = 0; j < indio_dev->num_channels; j++) {
 		ret = iio_device_add_event_sysfs(indio_dev,
 						 &indio_dev->channels[j]);
diff --git a/drivers/iio/industrialio-triggered-buffer.c b/drivers/iio/industrialio-triggered-buffer.c
index d6f54930b34a..15a5341b5e7b 100644
--- a/drivers/iio/industrialio-triggered-buffer.c
+++ b/drivers/iio/industrialio-triggered-buffer.c
@@ -32,7 +32,7 @@ static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
  *
  * This function combines some common tasks which will normally be performed
  * when setting up a triggered buffer. It will allocate the buffer and the
- * pollfunc, as well as register the buffer with the IIO core.
+ * pollfunc.
  *
  * Before calling this function the indio_dev structure should already be
  * completely initialized, but not yet registered. In practice this means that
@@ -49,7 +49,7 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
 	struct iio_buffer *buffer;
 	int ret;
 
-	buffer = iio_kfifo_allocate(indio_dev);
+	buffer = iio_kfifo_allocate();
 	if (!buffer) {
 		ret = -ENOMEM;
 		goto error_ret;
@@ -78,16 +78,8 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
 
-	ret = iio_buffer_register(indio_dev,
-				  indio_dev->channels,
-				  indio_dev->num_channels);
-	if (ret)
-		goto error_dealloc_pollfunc;
-
 	return 0;
 
-error_dealloc_pollfunc:
-	iio_dealloc_pollfunc(indio_dev->pollfunc);
 error_kfifo_free:
 	iio_kfifo_free(indio_dev->buffer);
 error_ret:
@@ -101,7 +93,6 @@ EXPORT_SYMBOL(iio_triggered_buffer_setup);
  */
 void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev)
 {
-	iio_buffer_unregister(indio_dev);
 	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_kfifo_free(indio_dev->buffer);
 }
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 90c8cb727cc7..c8bad3cf891d 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -116,8 +116,11 @@ static int __of_iio_simple_xlate(struct iio_dev *indio_dev,
 	if (!iiospec->args_count)
 		return 0;
 
-	if (iiospec->args[0] >= indio_dev->num_channels)
+	if (iiospec->args[0] >= indio_dev->num_channels) {
+		dev_err(&indio_dev->dev, "invalid channel index %u\n",
+			iiospec->args[0]);
 		return -EINVAL;
+	}
 
 	return iiospec->args[0];
 }
@@ -634,3 +637,28 @@ err_unlock:
 	return ret;
 }
 EXPORT_SYMBOL_GPL(iio_get_channel_type);
+
+static int iio_channel_write(struct iio_channel *chan, int val, int val2,
+			     enum iio_chan_info_enum info)
+{
+	return chan->indio_dev->info->write_raw(chan->indio_dev,
+						chan->channel, val, val2, info);
+}
+
+int iio_write_channel_raw(struct iio_channel *chan, int val)
+{
+	int ret;
+
+	mutex_lock(&chan->indio_dev->info_exist_lock);
+	if (chan->indio_dev->info == NULL) {
+		ret = -ENODEV;
+		goto err_unlock;
+	}
+
+	ret = iio_channel_write(chan, val, 0, IIO_CHAN_INFO_RAW);
+err_unlock:
+	mutex_unlock(&chan->indio_dev->info_exist_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(iio_write_channel_raw);
diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c
index 7134e8ada09a..b2beea01c49b 100644
--- a/drivers/iio/kfifo_buf.c
+++ b/drivers/iio/kfifo_buf.c
@@ -47,30 +47,6 @@ static int iio_request_update_kfifo(struct iio_buffer *r)
 	return ret;
 }
 
-static int iio_get_length_kfifo(struct iio_buffer *r)
-{
-	return r->length;
-}
-
-static IIO_BUFFER_ENABLE_ATTR;
-static IIO_BUFFER_LENGTH_ATTR;
-
-static struct attribute *iio_kfifo_attributes[] = {
-	&dev_attr_length.attr,
-	&dev_attr_enable.attr,
-	NULL,
-};
-
-static struct attribute_group iio_kfifo_attribute_group = {
-	.attrs = iio_kfifo_attributes,
-	.name = "buffer",
-};
-
-static int iio_get_bytes_per_datum_kfifo(struct iio_buffer *r)
-{
-	return r->bytes_per_datum;
-}
-
 static int iio_mark_update_needed_kfifo(struct iio_buffer *r)
 {
 	struct iio_kfifo *kf = iio_to_kfifo(r);
@@ -159,26 +135,25 @@ static const struct iio_buffer_access_funcs kfifo_access_funcs = {
 	.read_first_n = &iio_read_first_n_kfifo,
 	.data_available = iio_kfifo_buf_data_available,
 	.request_update = &iio_request_update_kfifo,
-	.get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo,
 	.set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
-	.get_length = &iio_get_length_kfifo,
 	.set_length = &iio_set_length_kfifo,
 	.release = &iio_kfifo_buffer_release,
 };
 
-struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
+struct iio_buffer *iio_kfifo_allocate(void)
 {
 	struct iio_kfifo *kf;
 
-	kf = kzalloc(sizeof *kf, GFP_KERNEL);
+	kf = kzalloc(sizeof(*kf), GFP_KERNEL);
 	if (!kf)
 		return NULL;
+
 	kf->update_needed = true;
 	iio_buffer_init(&kf->buffer);
-	kf->buffer.attrs = &iio_kfifo_attribute_group;
 	kf->buffer.access = &kfifo_access_funcs;
 	kf->buffer.length = 2;
 	mutex_init(&kf->user_lock);
+
 	return &kf->buffer;
 }
 EXPORT_SYMBOL(iio_kfifo_allocate);
@@ -189,4 +164,58 @@ void iio_kfifo_free(struct iio_buffer *r)
 }
 EXPORT_SYMBOL(iio_kfifo_free);
 
+static void devm_iio_kfifo_release(struct device *dev, void *res)
+{
+	iio_kfifo_free(*(struct iio_buffer **)res);
+}
+
+static int devm_iio_kfifo_match(struct device *dev, void *res, void *data)
+{
+	struct iio_buffer **r = res;
+
+	if (WARN_ON(!r || !*r))
+		return 0;
+
+	return *r == data;
+}
+
+/**
+ * devm_iio_fifo_allocate - Resource-managed iio_kfifo_allocate()
+ * @dev:		Device to allocate kfifo buffer for
+ *
+ * RETURNS:
+ * Pointer to allocated iio_buffer on success, NULL on failure.
+ */
+struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev)
+{
+	struct iio_buffer **ptr, *r;
+
+	ptr = devres_alloc(devm_iio_kfifo_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return NULL;
+
+	r = iio_kfifo_allocate();
+	if (r) {
+		*ptr = r;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return r;
+}
+EXPORT_SYMBOL(devm_iio_kfifo_allocate);
+
+/**
+ * devm_iio_fifo_free - Resource-managed iio_kfifo_free()
+ * @dev:		Device the buffer belongs to
+ * @r:			The buffer associated with the device
+ */
+void devm_iio_kfifo_free(struct device *dev, struct iio_buffer *r)
+{
+	WARN_ON(devres_release(dev, devm_iio_kfifo_release,
+			       devm_iio_kfifo_match, r));
+}
+EXPORT_SYMBOL(devm_iio_kfifo_free);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index 5bea821adcae..ae68c64bdad3 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -48,6 +48,17 @@ config CM32181
 	 To compile this driver as a module, choose M here:
 	 the module will be called cm32181.
 
+config CM3232
+	depends on I2C
+	tristate "CM3232 ambient light sensor"
+	help
+	 Say Y here if you use cm3232.
+	 This option enables ambient light sensor using
+	 Capella Microsystems cm3232 device driver.
+
+	 To compile this driver as a module, choose M here:
+	 the module will be called cm3232.
+
 config CM36651
 	depends on I2C
 	tristate "CM36651 driver"
@@ -95,6 +106,9 @@ config HID_SENSOR_ALS
 	  Say yes here to build support for the HID SENSOR
 	  Ambient light sensor.
 
+	  To compile this driver as a module, choose M here: the
+	  module will be called hid-sensor-als.
+
 config HID_SENSOR_PROX
 	depends on HID_SENSOR_HUB
 	select IIO_BUFFER
@@ -109,6 +123,16 @@ config HID_SENSOR_PROX
 	  To compile this driver as a module, choose M here: the
 	  module will be called hid-sensor-prox.
 
+config JSA1212
+	tristate "JSA1212 ALS and proximity sensor driver"
+	depends on I2C
+	help
+	 Say Y here if you want to build a IIO driver for JSA1212
+	 proximity & ALS sensor device.
+
+	 To compile this driver as a module, choose M here:
+	 the module will be called jsa1212.
+
 config SENSORS_LM3533
 	tristate "LM3533 ambient light sensor"
 	depends on MFD_LM3533
diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
index 47877a36cc12..b12a5160d9e0 100644
--- a/drivers/iio/light/Makefile
+++ b/drivers/iio/light/Makefile
@@ -7,11 +7,13 @@ obj-$(CONFIG_ADJD_S311)		+= adjd_s311.o
 obj-$(CONFIG_AL3320A)		+= al3320a.o
 obj-$(CONFIG_APDS9300)		+= apds9300.o
 obj-$(CONFIG_CM32181)		+= cm32181.o
+obj-$(CONFIG_CM3232)		+= cm3232.o
 obj-$(CONFIG_CM36651)		+= cm36651.o
 obj-$(CONFIG_GP2AP020A00F)	+= gp2ap020a00f.o
 obj-$(CONFIG_HID_SENSOR_ALS)	+= hid-sensor-als.o
 obj-$(CONFIG_HID_SENSOR_PROX)	+= hid-sensor-prox.o
 obj-$(CONFIG_ISL29125)		+= isl29125.o
+obj-$(CONFIG_JSA1212)		+= jsa1212.o
 obj-$(CONFIG_SENSORS_LM3533)	+= lm3533-als.o
 obj-$(CONFIG_LTR501)		+= ltr501.o
 obj-$(CONFIG_SENSORS_TSL2563)	+= tsl2563.o
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index ad36b294e4d5..5d12ae54d088 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -169,7 +169,7 @@ static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
  * @cm32181:	pointer of struct cm32181.
  *
  * Convert sensor raw data to lux.  It depends on integration
- * time and claibscale variable.
+ * time and calibscale variable.
  *
  * Return: Positive value is lux, otherwise is error code.
  */
diff --git a/drivers/iio/light/cm3232.c b/drivers/iio/light/cm3232.c
new file mode 100644
index 000000000000..90e3519a91de
--- /dev/null
+++ b/drivers/iio/light/cm3232.c
@@ -0,0 +1,403 @@
+/*
+ * CM3232 Ambient Light Sensor
+ *
+ * Copyright (C) 2014-2015 Capella Microsystems Inc.
+ * Author: Kevin Tsai <ktsai@capellamicro.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.
+ *
+ * IIO driver for CM3232 (7-bit I2C slave address 0x10).
+ */
+
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/init.h>
+
+/* Registers Address */
+#define CM3232_REG_ADDR_CMD		0x00
+#define CM3232_REG_ADDR_ALS		0x50
+#define CM3232_REG_ADDR_ID		0x53
+
+#define CM3232_CMD_ALS_DISABLE		BIT(0)
+
+#define CM3232_CMD_ALS_IT_SHIFT		2
+#define CM3232_CMD_ALS_IT_MASK		(BIT(2) | BIT(3) | BIT(4))
+#define CM3232_CMD_ALS_IT_DEFAULT	(0x01 << CM3232_CMD_ALS_IT_SHIFT)
+
+#define CM3232_CMD_ALS_RESET		BIT(6)
+
+#define CM3232_CMD_DEFAULT		CM3232_CMD_ALS_IT_DEFAULT
+
+#define CM3232_HW_ID			0x32
+#define CM3232_CALIBSCALE_DEFAULT	100000
+#define CM3232_CALIBSCALE_RESOLUTION	100000
+#define CM3232_MLUX_PER_LUX		1000
+
+#define CM3232_MLUX_PER_BIT_DEFAULT	64
+#define CM3232_MLUX_PER_BIT_BASE_IT	100000
+
+static const struct {
+	int val;
+	int val2;
+	u8 it;
+} cm3232_als_it_scales[] = {
+	{0, 100000, 0},	/* 0.100000 */
+	{0, 200000, 1},	/* 0.200000 */
+	{0, 400000, 2},	/* 0.400000 */
+	{0, 800000, 3},	/* 0.800000 */
+	{1, 600000, 4},	/* 1.600000 */
+	{3, 200000, 5},	/* 3.200000 */
+};
+
+struct cm3232_als_info {
+	u8 regs_cmd_default;
+	u8 hw_id;
+	int calibscale;
+	int mlux_per_bit;
+	int mlux_per_bit_base_it;
+};
+
+static struct cm3232_als_info cm3232_als_info_default = {
+	.regs_cmd_default = CM3232_CMD_DEFAULT,
+	.hw_id = CM3232_HW_ID,
+	.calibscale = CM3232_CALIBSCALE_DEFAULT,
+	.mlux_per_bit = CM3232_MLUX_PER_BIT_DEFAULT,
+	.mlux_per_bit_base_it = CM3232_MLUX_PER_BIT_BASE_IT,
+};
+
+struct cm3232_chip {
+	struct i2c_client *client;
+	struct cm3232_als_info *als_info;
+	u8 regs_cmd;
+	u16 regs_als;
+};
+
+/**
+ * cm3232_reg_init() - Initialize CM3232
+ * @chip:	pointer of struct cm3232_chip.
+ *
+ * Check and initialize CM3232 ambient light sensor.
+ *
+ * Return: 0 for success; otherwise for error code.
+ */
+static int cm3232_reg_init(struct cm3232_chip *chip)
+{
+	struct i2c_client *client = chip->client;
+	s32 ret;
+
+	chip->als_info = &cm3232_als_info_default;
+
+	/* Identify device */
+	ret = i2c_smbus_read_word_data(client, CM3232_REG_ADDR_ID);
+	if (ret < 0) {
+		dev_err(&chip->client->dev, "Error reading addr_id\n");
+		return ret;
+	}
+
+	if ((ret & 0xFF) != chip->als_info->hw_id)
+		return -ENODEV;
+
+	/* Disable and reset device */
+	chip->regs_cmd = CM3232_CMD_ALS_DISABLE | CM3232_CMD_ALS_RESET;
+	ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
+					chip->regs_cmd);
+	if (ret < 0) {
+		dev_err(&chip->client->dev, "Error writing reg_cmd\n");
+		return ret;
+	}
+
+	/* Register default value */
+	chip->regs_cmd = chip->als_info->regs_cmd_default;
+
+	/* Configure register */
+	ret = i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
+					chip->regs_cmd);
+	if (ret < 0)
+		dev_err(&chip->client->dev, "Error writing reg_cmd\n");
+
+	return 0;
+}
+
+/**
+ *  cm3232_read_als_it() - Get sensor integration time
+ *  @chip:	pointer of struct cm3232_chip
+ *  @val:	pointer of int to load the integration (sec).
+ *  @val2:	pointer of int to load the integration time (microsecond).
+ *
+ *  Report the current integration time.
+ *
+ *  Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
+ */
+static int cm3232_read_als_it(struct cm3232_chip *chip, int *val, int *val2)
+{
+	u16 als_it;
+	int i;
+
+	als_it = chip->regs_cmd;
+	als_it &= CM3232_CMD_ALS_IT_MASK;
+	als_it >>= CM3232_CMD_ALS_IT_SHIFT;
+	for (i = 0; i < ARRAY_SIZE(cm3232_als_it_scales); i++) {
+		if (als_it == cm3232_als_it_scales[i].it) {
+			*val = cm3232_als_it_scales[i].val;
+			*val2 = cm3232_als_it_scales[i].val2;
+			return IIO_VAL_INT_PLUS_MICRO;
+		}
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * cm3232_write_als_it() - Write sensor integration time
+ * @chip:	pointer of struct cm3232_chip.
+ * @val:	integration time in second.
+ * @val2:	integration time in microsecond.
+ *
+ * Convert integration time to sensor value.
+ *
+ * Return: i2c_smbus_write_byte_data command return value.
+ */
+static int cm3232_write_als_it(struct cm3232_chip *chip, int val, int val2)
+{
+	struct i2c_client *client = chip->client;
+	u16 als_it, cmd;
+	int i;
+	s32 ret;
+
+	for (i = 0; i < ARRAY_SIZE(cm3232_als_it_scales); i++) {
+		if (val == cm3232_als_it_scales[i].val &&
+			val2 == cm3232_als_it_scales[i].val2) {
+
+			als_it = cm3232_als_it_scales[i].it;
+			als_it <<= CM3232_CMD_ALS_IT_SHIFT;
+
+			cmd = chip->regs_cmd & ~CM3232_CMD_ALS_IT_MASK;
+			cmd |= als_it;
+			ret = i2c_smbus_write_byte_data(client,
+							CM3232_REG_ADDR_CMD,
+							cmd);
+			if (ret < 0)
+				return ret;
+			chip->regs_cmd = cmd;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+/**
+ * cm3232_get_lux() - report current lux value
+ * @chip:	pointer of struct cm3232_chip.
+ *
+ * Convert sensor data to lux.  It depends on integration
+ * time and calibscale variable.
+ *
+ * Return: Zero or positive value is lux, otherwise error code.
+ */
+static int cm3232_get_lux(struct cm3232_chip *chip)
+{
+	struct i2c_client *client = chip->client;
+	struct cm3232_als_info *als_info = chip->als_info;
+	int ret;
+	int val, val2;
+	int als_it;
+	u64 lux;
+
+	/* Calculate mlux per bit based on als_it */
+	ret = cm3232_read_als_it(chip, &val, &val2);
+	if (ret < 0)
+		return -EINVAL;
+	als_it = val * 1000000 + val2;
+	lux = (__force u64)als_info->mlux_per_bit;
+	lux *= als_info->mlux_per_bit_base_it;
+	lux = div_u64(lux, als_it);
+
+	ret = i2c_smbus_read_word_data(client, CM3232_REG_ADDR_ALS);
+	if (ret < 0) {
+		dev_err(&client->dev, "Error reading reg_addr_als\n");
+		return ret;
+	}
+
+	chip->regs_als = (u16)ret;
+	lux *= chip->regs_als;
+	lux *= als_info->calibscale;
+	lux = div_u64(lux, CM3232_CALIBSCALE_RESOLUTION);
+	lux = div_u64(lux, CM3232_MLUX_PER_LUX);
+
+	if (lux > 0xFFFF)
+		lux = 0xFFFF;
+
+	return (int)lux;
+}
+
+static int cm3232_read_raw(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int *val, int *val2, long mask)
+{
+	struct cm3232_chip *chip = iio_priv(indio_dev);
+	struct cm3232_als_info *als_info = chip->als_info;
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_PROCESSED:
+		ret = cm3232_get_lux(chip);
+		if (ret < 0)
+			return ret;
+		*val = ret;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_CALIBSCALE:
+		*val = als_info->calibscale;
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_INT_TIME:
+		return cm3232_read_als_it(chip, val, val2);
+	}
+
+	return -EINVAL;
+}
+
+static int cm3232_write_raw(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int val, int val2, long mask)
+{
+	struct cm3232_chip *chip = iio_priv(indio_dev);
+	struct cm3232_als_info *als_info = chip->als_info;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_CALIBSCALE:
+		als_info->calibscale = val;
+		return 0;
+	case IIO_CHAN_INFO_INT_TIME:
+		return cm3232_write_als_it(chip, val, val2);
+	}
+
+	return -EINVAL;
+}
+
+/**
+ * cm3232_get_it_available() - Get available ALS IT value
+ * @dev:	pointer of struct device.
+ * @attr:	pointer of struct device_attribute.
+ * @buf:	pointer of return string buffer.
+ *
+ * Display the available integration time in second.
+ *
+ * Return: string length.
+ */
+static ssize_t cm3232_get_it_available(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	int i, len;
+
+	for (i = 0, len = 0; i < ARRAY_SIZE(cm3232_als_it_scales); i++)
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ",
+			cm3232_als_it_scales[i].val,
+			cm3232_als_it_scales[i].val2);
+	return len + scnprintf(buf + len, PAGE_SIZE - len, "\n");
+}
+
+static const struct iio_chan_spec cm3232_channels[] = {
+	{
+		.type = IIO_LIGHT,
+		.info_mask_separate =
+			BIT(IIO_CHAN_INFO_PROCESSED) |
+			BIT(IIO_CHAN_INFO_CALIBSCALE) |
+			BIT(IIO_CHAN_INFO_INT_TIME),
+	}
+};
+
+static IIO_DEVICE_ATTR(in_illuminance_integration_time_available,
+			S_IRUGO, cm3232_get_it_available, NULL, 0);
+
+static struct attribute *cm3232_attributes[] = {
+	&iio_dev_attr_in_illuminance_integration_time_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group cm3232_attribute_group = {
+	.attrs = cm3232_attributes
+};
+
+static const struct iio_info cm3232_info = {
+	.driver_module		= THIS_MODULE,
+	.read_raw		= &cm3232_read_raw,
+	.write_raw		= &cm3232_write_raw,
+	.attrs			= &cm3232_attribute_group,
+};
+
+static int cm3232_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct cm3232_chip *chip;
+	struct iio_dev *indio_dev;
+	int ret;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	chip = iio_priv(indio_dev);
+	i2c_set_clientdata(client, indio_dev);
+	chip->client = client;
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->channels = cm3232_channels;
+	indio_dev->num_channels = ARRAY_SIZE(cm3232_channels);
+	indio_dev->info = &cm3232_info;
+	indio_dev->name = id->name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = cm3232_reg_init(chip);
+	if (ret) {
+		dev_err(&client->dev,
+			"%s: register init failed\n",
+			__func__);
+		return ret;
+	}
+
+	return iio_device_register(indio_dev);
+}
+
+static int cm3232_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+	i2c_smbus_write_byte_data(client, CM3232_REG_ADDR_CMD,
+		CM3232_CMD_ALS_DISABLE);
+
+	iio_device_unregister(indio_dev);
+
+	return 0;
+}
+
+static const struct i2c_device_id cm3232_id[] = {
+	{"cm3232", 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, cm3232_id);
+
+static const struct of_device_id cm3232_of_match[] = {
+	{.compatible = "capella,cm3232"},
+	{}
+};
+
+static struct i2c_driver cm3232_driver = {
+	.driver = {
+		.name	= "cm3232",
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(cm3232_of_match),
+	},
+	.id_table	= cm3232_id,
+	.probe		= cm3232_probe,
+	.remove		= cm3232_remove,
+};
+
+module_i2c_driver(cm3232_driver);
+
+MODULE_AUTHOR("Kevin Tsai <ktsai@capellamicro.com>");
+MODULE_DESCRIPTION("CM3232 ambient light sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c
index a5283d75c096..948acfc38b8c 100644
--- a/drivers/iio/light/hid-sensor-als.c
+++ b/drivers/iio/light/hid-sensor-als.c
@@ -80,7 +80,6 @@ static int als_read_raw(struct iio_dev *indio_dev,
 	int report_id = -1;
 	u32 address;
 	int ret_type;
-	s32 poll_value;
 
 	*val = 0;
 	*val2 = 0;
@@ -97,15 +96,8 @@ static int als_read_raw(struct iio_dev *indio_dev,
 			break;
 		}
 		if (report_id >= 0) {
-			poll_value = hid_sensor_read_poll_value(
-						&als_state->common_attributes);
-			if (poll_value < 0)
-				return -EINVAL;
-
 			hid_sensor_power_state(&als_state->common_attributes,
 						true);
-			msleep_interruptible(poll_value * 2);
-
 			*val = sensor_hub_input_attr_get_raw_value(
 					als_state->common_attributes.hsdev,
 					HID_USAGE_SENSOR_ALS, address,
@@ -381,6 +373,7 @@ static struct platform_driver hid_als_platform_driver = {
 	.id_table = hid_als_ids,
 	.driver = {
 		.name	= KBUILD_MODNAME,
+		.pm	= &hid_sensor_pm_ops,
 	},
 	.probe		= hid_als_probe,
 	.remove		= hid_als_remove,
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c
index f5a514698fd8..3ecf79ed08ac 100644
--- a/drivers/iio/light/hid-sensor-prox.c
+++ b/drivers/iio/light/hid-sensor-prox.c
@@ -75,7 +75,6 @@ static int prox_read_raw(struct iio_dev *indio_dev,
 	int report_id = -1;
 	u32 address;
 	int ret_type;
-	s32 poll_value;
 
 	*val = 0;
 	*val2 = 0;
@@ -92,16 +91,8 @@ static int prox_read_raw(struct iio_dev *indio_dev,
 			break;
 		}
 		if (report_id >= 0) {
-			poll_value = hid_sensor_read_poll_value(
-					&prox_state->common_attributes);
-			if (poll_value < 0)
-				return -EINVAL;
-
 			hid_sensor_power_state(&prox_state->common_attributes,
 						true);
-
-			msleep_interruptible(poll_value * 2);
-
 			*val = sensor_hub_input_attr_get_raw_value(
 				prox_state->common_attributes.hsdev,
 				HID_USAGE_SENSOR_PROX, address,
@@ -373,6 +364,7 @@ static struct platform_driver hid_prox_platform_driver = {
 	.id_table = hid_prox_ids,
 	.driver = {
 		.name	= KBUILD_MODNAME,
+		.pm	= &hid_sensor_pm_ops,
 	},
 	.probe		= hid_prox_probe,
 	.remove		= hid_prox_remove,
diff --git a/drivers/iio/light/jsa1212.c b/drivers/iio/light/jsa1212.c
new file mode 100644
index 000000000000..29de7e7d9562
--- /dev/null
+++ b/drivers/iio/light/jsa1212.c
@@ -0,0 +1,471 @@
+/*
+ * JSA1212 Ambient Light & Proximity Sensor Driver
+ *
+ * Copyright (c) 2014, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * JSA1212 I2C slave address: 0x44(ADDR tied to GND), 0x45(ADDR tied to VDD)
+ *
+ * TODO: Interrupt support, thresholds, range support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/acpi.h>
+#include <linux/regmap.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+/* JSA1212 reg address */
+#define JSA1212_CONF_REG		0x01
+#define JSA1212_INT_REG			0x02
+#define JSA1212_PXS_LT_REG		0x03
+#define JSA1212_PXS_HT_REG		0x04
+#define JSA1212_ALS_TH1_REG		0x05
+#define JSA1212_ALS_TH2_REG		0x06
+#define JSA1212_ALS_TH3_REG		0x07
+#define JSA1212_PXS_DATA_REG		0x08
+#define JSA1212_ALS_DT1_REG		0x09
+#define JSA1212_ALS_DT2_REG		0x0A
+#define JSA1212_ALS_RNG_REG		0x0B
+#define JSA1212_MAX_REG			0x0C
+
+/* JSA1212 reg masks */
+#define JSA1212_CONF_MASK		0xFF
+#define JSA1212_INT_MASK		0xFF
+#define JSA1212_PXS_LT_MASK		0xFF
+#define JSA1212_PXS_HT_MASK		0xFF
+#define JSA1212_ALS_TH1_MASK		0xFF
+#define JSA1212_ALS_TH2_LT_MASK		0x0F
+#define JSA1212_ALS_TH2_HT_MASK		0xF0
+#define JSA1212_ALS_TH3_MASK		0xFF
+#define JSA1212_PXS_DATA_MASK		0xFF
+#define JSA1212_ALS_DATA_MASK		0x0FFF
+#define JSA1212_ALS_DT1_MASK		0xFF
+#define JSA1212_ALS_DT2_MASK		0x0F
+#define JSA1212_ALS_RNG_MASK		0x07
+
+/* JSA1212 CONF REG bits */
+#define JSA1212_CONF_PXS_MASK		0x80
+#define JSA1212_CONF_PXS_ENABLE		0x80
+#define JSA1212_CONF_PXS_DISABLE	0x00
+#define JSA1212_CONF_ALS_MASK		0x04
+#define JSA1212_CONF_ALS_ENABLE		0x04
+#define JSA1212_CONF_ALS_DISABLE	0x00
+#define JSA1212_CONF_IRDR_MASK		0x08
+/* Proxmity sensing IRDR current sink settings */
+#define JSA1212_CONF_IRDR_200MA		0x08
+#define JSA1212_CONF_IRDR_100MA		0x00
+#define JSA1212_CONF_PXS_SLP_MASK	0x70
+#define JSA1212_CONF_PXS_SLP_0MS	0x70
+#define JSA1212_CONF_PXS_SLP_12MS	0x60
+#define JSA1212_CONF_PXS_SLP_50MS	0x50
+#define JSA1212_CONF_PXS_SLP_75MS	0x40
+#define JSA1212_CONF_PXS_SLP_100MS	0x30
+#define JSA1212_CONF_PXS_SLP_200MS	0x20
+#define JSA1212_CONF_PXS_SLP_400MS	0x10
+#define JSA1212_CONF_PXS_SLP_800MS	0x00
+
+/* JSA1212 INT REG bits */
+#define JSA1212_INT_CTRL_MASK		0x01
+#define JSA1212_INT_CTRL_EITHER		0x00
+#define JSA1212_INT_CTRL_BOTH		0x01
+#define JSA1212_INT_ALS_PRST_MASK	0x06
+#define JSA1212_INT_ALS_PRST_1CONV	0x00
+#define JSA1212_INT_ALS_PRST_4CONV	0x02
+#define JSA1212_INT_ALS_PRST_8CONV	0x04
+#define JSA1212_INT_ALS_PRST_16CONV	0x06
+#define JSA1212_INT_ALS_FLAG_MASK	0x08
+#define JSA1212_INT_ALS_FLAG_CLR	0x00
+#define JSA1212_INT_PXS_PRST_MASK	0x60
+#define JSA1212_INT_PXS_PRST_1CONV	0x00
+#define JSA1212_INT_PXS_PRST_4CONV	0x20
+#define JSA1212_INT_PXS_PRST_8CONV	0x40
+#define JSA1212_INT_PXS_PRST_16CONV	0x60
+#define JSA1212_INT_PXS_FLAG_MASK	0x80
+#define JSA1212_INT_PXS_FLAG_CLR	0x00
+
+/* JSA1212 ALS RNG REG bits */
+#define JSA1212_ALS_RNG_0_2048		0x00
+#define JSA1212_ALS_RNG_0_1024		0x01
+#define JSA1212_ALS_RNG_0_512		0x02
+#define JSA1212_ALS_RNG_0_256		0x03
+#define JSA1212_ALS_RNG_0_128		0x04
+
+/* JSA1212 INT threshold range */
+#define JSA1212_ALS_TH_MIN	0x0000
+#define JSA1212_ALS_TH_MAX	0x0FFF
+#define JSA1212_PXS_TH_MIN	0x00
+#define JSA1212_PXS_TH_MAX	0xFF
+
+#define JSA1212_ALS_DELAY_MS	200
+#define JSA1212_PXS_DELAY_MS	100
+
+#define JSA1212_DRIVER_NAME	"jsa1212"
+#define JSA1212_REGMAP_NAME	"jsa1212_regmap"
+
+enum jsa1212_op_mode {
+	JSA1212_OPMODE_ALS_EN,
+	JSA1212_OPMODE_PXS_EN,
+};
+
+struct jsa1212_data {
+	struct i2c_client *client;
+	struct mutex lock;
+	u8 als_rng_idx;
+	bool als_en; /* ALS enable status */
+	bool pxs_en; /* proximity enable status */
+	struct regmap *regmap;
+};
+
+/* ALS range idx to val mapping */
+static const int jsa1212_als_range_val[] = {2048, 1024, 512, 256, 128,
+						128, 128, 128};
+
+/* Enables or disables ALS function based on status */
+static int jsa1212_als_enable(struct jsa1212_data *data, u8 status)
+{
+	int ret;
+
+	ret = regmap_update_bits(data->regmap, JSA1212_CONF_REG,
+				JSA1212_CONF_ALS_MASK,
+				status);
+	if (ret < 0)
+		return ret;
+
+	data->als_en = !!status;
+
+	return 0;
+}
+
+/* Enables or disables PXS function based on status */
+static int jsa1212_pxs_enable(struct jsa1212_data *data, u8 status)
+{
+	int ret;
+
+	ret = regmap_update_bits(data->regmap, JSA1212_CONF_REG,
+				JSA1212_CONF_PXS_MASK,
+				status);
+	if (ret < 0)
+		return ret;
+
+	data->pxs_en = !!status;
+
+	return 0;
+}
+
+static int jsa1212_read_als_data(struct jsa1212_data *data,
+				unsigned int *val)
+{
+	int ret;
+	__le16 als_data;
+
+	ret = jsa1212_als_enable(data, JSA1212_CONF_ALS_ENABLE);
+	if (ret < 0)
+		return ret;
+
+	/* Delay for data output */
+	msleep(JSA1212_ALS_DELAY_MS);
+
+	/* Read 12 bit data */
+	ret = regmap_bulk_read(data->regmap, JSA1212_ALS_DT1_REG, &als_data, 2);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "als data read err\n");
+		goto als_data_read_err;
+	}
+
+	*val = le16_to_cpu(als_data);
+
+als_data_read_err:
+	return jsa1212_als_enable(data, JSA1212_CONF_ALS_DISABLE);
+}
+
+static int jsa1212_read_pxs_data(struct jsa1212_data *data,
+				unsigned int *val)
+{
+	int ret;
+	unsigned int pxs_data;
+
+	ret = jsa1212_pxs_enable(data, JSA1212_CONF_PXS_ENABLE);
+	if (ret < 0)
+		return ret;
+
+	/* Delay for data output */
+	msleep(JSA1212_PXS_DELAY_MS);
+
+	/* Read out all data */
+	ret = regmap_read(data->regmap, JSA1212_PXS_DATA_REG, &pxs_data);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "pxs data read err\n");
+		goto pxs_data_read_err;
+	}
+
+	*val = pxs_data & JSA1212_PXS_DATA_MASK;
+
+pxs_data_read_err:
+	return jsa1212_pxs_enable(data, JSA1212_CONF_PXS_DISABLE);
+}
+
+static int jsa1212_read_raw(struct iio_dev *indio_dev,
+				struct iio_chan_spec const *chan,
+				int *val, int *val2, long mask)
+{
+	int ret;
+	struct jsa1212_data *data = iio_priv(indio_dev);
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		mutex_lock(&data->lock);
+		switch (chan->type) {
+		case IIO_LIGHT:
+			ret = jsa1212_read_als_data(data, val);
+			break;
+		case IIO_PROXIMITY:
+			ret = jsa1212_read_pxs_data(data, val);
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+		mutex_unlock(&data->lock);
+		return ret < 0 ? ret : IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->type) {
+		case IIO_LIGHT:
+			*val = jsa1212_als_range_val[data->als_rng_idx];
+			*val2 = BIT(12); /* Max 12 bit value */
+			return IIO_VAL_FRACTIONAL;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	return -EINVAL;
+}
+
+static const struct iio_chan_spec jsa1212_channels[] = {
+	{
+		.type = IIO_LIGHT,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE),
+	},
+	{
+		.type = IIO_PROXIMITY,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+	}
+};
+
+static const struct iio_info jsa1212_info = {
+	.driver_module		= THIS_MODULE,
+	.read_raw		= &jsa1212_read_raw,
+};
+
+static int jsa1212_chip_init(struct jsa1212_data *data)
+{
+	int ret;
+
+	ret = regmap_write(data->regmap, JSA1212_CONF_REG,
+				(JSA1212_CONF_PXS_SLP_50MS |
+				JSA1212_CONF_IRDR_200MA));
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_write(data->regmap, JSA1212_INT_REG,
+				JSA1212_INT_ALS_PRST_4CONV);
+	if (ret < 0)
+		return ret;
+
+	data->als_rng_idx = JSA1212_ALS_RNG_0_2048;
+
+	return 0;
+}
+
+static bool jsa1212_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case JSA1212_PXS_DATA_REG:
+	case JSA1212_ALS_DT1_REG:
+	case JSA1212_ALS_DT2_REG:
+	case JSA1212_INT_REG:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static struct regmap_config jsa1212_regmap_config = {
+	.name =  JSA1212_REGMAP_NAME,
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = JSA1212_MAX_REG,
+	.cache_type = REGCACHE_RBTREE,
+	.volatile_reg = jsa1212_is_volatile_reg,
+};
+
+static int jsa1212_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct jsa1212_data *data;
+	struct iio_dev *indio_dev;
+	struct regmap *regmap;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	regmap = devm_regmap_init_i2c(client, &jsa1212_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "Regmap initialization failed.\n");
+		return PTR_ERR(regmap);
+	}
+
+	data = iio_priv(indio_dev);
+
+	i2c_set_clientdata(client, indio_dev);
+	data->client = client;
+	data->regmap = regmap;
+
+	mutex_init(&data->lock);
+
+	ret = jsa1212_chip_init(data);
+	if (ret < 0)
+		return ret;
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->channels = jsa1212_channels;
+	indio_dev->num_channels = ARRAY_SIZE(jsa1212_channels);
+	indio_dev->name = JSA1212_DRIVER_NAME;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+
+	indio_dev->info = &jsa1212_info;
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		dev_err(&client->dev, "%s: register device failed\n", __func__);
+
+	return ret;
+}
+
+ /* power off the device */
+static int jsa1212_power_off(struct jsa1212_data *data)
+{
+	int ret;
+
+	mutex_lock(&data->lock);
+
+	ret = regmap_update_bits(data->regmap, JSA1212_CONF_REG,
+				JSA1212_CONF_ALS_MASK |
+				JSA1212_CONF_PXS_MASK,
+				JSA1212_CONF_ALS_DISABLE |
+				JSA1212_CONF_PXS_DISABLE);
+
+	if (ret < 0)
+		dev_err(&data->client->dev, "power off cmd failed\n");
+
+	mutex_unlock(&data->lock);
+
+	return ret;
+}
+
+static int jsa1212_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct jsa1212_data *data = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+
+	return jsa1212_power_off(data);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int jsa1212_suspend(struct device *dev)
+{
+	struct jsa1212_data *data;
+
+	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+
+	return jsa1212_power_off(data);
+}
+
+static int jsa1212_resume(struct device *dev)
+{
+	int ret = 0;
+	struct jsa1212_data *data;
+
+	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
+
+	mutex_lock(&data->lock);
+
+	if (data->als_en) {
+		ret = jsa1212_als_enable(data, JSA1212_CONF_ALS_ENABLE);
+		if (ret < 0) {
+			dev_err(dev, "als resume failed\n");
+			goto unlock_and_ret;
+		}
+	}
+
+	if (data->pxs_en) {
+		ret = jsa1212_pxs_enable(data, JSA1212_CONF_PXS_ENABLE);
+		if (ret < 0)
+			dev_err(dev, "pxs resume failed\n");
+	}
+
+unlock_and_ret:
+	mutex_unlock(&data->lock);
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(jsa1212_pm_ops, jsa1212_suspend, jsa1212_resume);
+
+#define JSA1212_PM_OPS (&jsa1212_pm_ops)
+#else
+#define JSA1212_PM_OPS NULL
+#endif
+
+static const struct acpi_device_id jsa1212_acpi_match[] = {
+	{"JSA1212", 0},
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, jsa1212_acpi_match);
+
+static const struct i2c_device_id jsa1212_id[] = {
+	{ JSA1212_DRIVER_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, jsa1212_id);
+
+static struct i2c_driver jsa1212_driver = {
+	.driver = {
+		.name	= JSA1212_DRIVER_NAME,
+		.pm	= JSA1212_PM_OPS,
+		.owner	= THIS_MODULE,
+		.acpi_match_table = ACPI_PTR(jsa1212_acpi_match),
+	},
+	.probe		= jsa1212_probe,
+	.remove		= jsa1212_remove,
+	.id_table	= jsa1212_id,
+};
+module_i2c_driver(jsa1212_driver);
+
+MODULE_AUTHOR("Sathya Kuppuswamy <sathyanarayanan.kuppuswamy@linux.intel.com>");
+MODULE_DESCRIPTION("JSA1212 proximity/ambient light sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c
index ae3c71bdd6c6..076bc46fad03 100644
--- a/drivers/iio/light/lm3533-als.c
+++ b/drivers/iio/light/lm3533-als.c
@@ -657,7 +657,7 @@ static ALS_HYSTERESIS_ATTR_RO(3);
 #define ILLUMINANCE_ATTR_RO(_name) \
 	DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO, show_##_name, NULL)
 #define ILLUMINANCE_ATTR_RW(_name) \
-	DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO | S_IWUSR , \
+	DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO | S_IWUSR, \
 						show_##_name, store_##_name)
 /*
  * ALS Zone threshold-event enable
diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c
index a9e449b0be0c..71c2bde275aa 100644
--- a/drivers/iio/light/tcs3414.c
+++ b/drivers/iio/light/tcs3414.c
@@ -149,8 +149,8 @@ static int tcs3414_read_raw(struct iio_dev *indio_dev,
 		*val = ret;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
-	i = (data->gain & TCS3414_GAIN_MASK) >> TCS3414_GAIN_SHIFT;
-	*val = tcs3414_scales[i][0];
+		i = (data->gain & TCS3414_GAIN_MASK) >> TCS3414_GAIN_SHIFT;
+		*val = tcs3414_scales[i][0];
 		*val2 = tcs3414_scales[i][1];
 		return IIO_VAL_INT_PLUS_MICRO;
 	case IIO_CHAN_INFO_INT_TIME:
diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig
index b2dba9e506ab..4c7a4c52dd06 100644
--- a/drivers/iio/magnetometer/Kconfig
+++ b/drivers/iio/magnetometer/Kconfig
@@ -6,26 +6,21 @@
 menu "Magnetometer sensors"
 
 config AK8975
-	tristate "Asahi Kasei AK8975 3-Axis Magnetometer"
+	tristate "Asahi Kasei AK 3-Axis Magnetometer"
 	depends on I2C
 	depends on GPIOLIB
 	help
-	  Say yes here to build support for Asahi Kasei AK8975 3-Axis
-	  Magnetometer. This driver can also support AK8963, if i2c
-	  device name is identified as ak8963.
+	  Say yes here to build support for Asahi Kasei AK8975, AK8963,
+	  AK09911 or AK09912 3-Axis Magnetometer.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called ak8975.
 
 config AK09911
 	tristate "Asahi Kasei AK09911 3-axis Compass"
-	depends on I2C
+	select AK8975
 	help
-	  Say yes here to build support for Asahi Kasei AK09911 3-Axis
-	  Magnetometer.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called ak09911.
+	  Deprecated: AK09911 is now supported by AK8975 driver.
 
 config MAG3110
 	tristate "Freescale MAG3110 3-Axis Magnetometer"
diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile
index b91315e0b826..0f5d3c985799 100644
--- a/drivers/iio/magnetometer/Makefile
+++ b/drivers/iio/magnetometer/Makefile
@@ -3,7 +3,6 @@
 #
 
 # When adding new entries keep the list in alphabetical order
-obj-$(CONFIG_AK09911)	+= ak09911.o
 obj-$(CONFIG_AK8975)	+= ak8975.o
 obj-$(CONFIG_MAG3110)	+= mag3110.o
 obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o
diff --git a/drivers/iio/magnetometer/ak09911.c b/drivers/iio/magnetometer/ak09911.c
deleted file mode 100644
index b2bc942ff6b8..000000000000
--- a/drivers/iio/magnetometer/ak09911.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * AK09911 3-axis compass driver
- * Copyright (c) 2014, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/acpi.h>
-#include <linux/iio/iio.h>
-
-#define AK09911_REG_WIA1		0x00
-#define AK09911_REG_WIA2		0x01
-#define AK09911_WIA1_VALUE		0x48
-#define AK09911_WIA2_VALUE		0x05
-
-#define AK09911_REG_ST1			0x10
-#define AK09911_REG_HXL			0x11
-#define AK09911_REG_HXH			0x12
-#define AK09911_REG_HYL			0x13
-#define AK09911_REG_HYH			0x14
-#define AK09911_REG_HZL			0x15
-#define AK09911_REG_HZH			0x16
-
-#define AK09911_REG_ASAX		0x60
-#define AK09911_REG_ASAY		0x61
-#define AK09911_REG_ASAZ		0x62
-
-#define AK09911_REG_CNTL1		0x30
-#define AK09911_REG_CNTL2		0x31
-#define AK09911_REG_CNTL3		0x32
-
-#define AK09911_MODE_SNG_MEASURE	0x01
-#define AK09911_MODE_SELF_TEST		0x10
-#define AK09911_MODE_FUSE_ACCESS	0x1F
-#define AK09911_MODE_POWERDOWN		0x00
-#define AK09911_RESET_DATA		0x01
-
-#define AK09911_REG_CNTL1		0x30
-#define AK09911_REG_CNTL2		0x31
-#define AK09911_REG_CNTL3		0x32
-
-#define AK09911_RAW_TO_GAUSS(asa)	((((asa) + 128) * 6000) / 256)
-
-#define AK09911_MAX_CONVERSION_TIMEOUT_MS	500
-#define AK09911_CONVERSION_DONE_POLL_TIME_MS	10
-
-struct ak09911_data {
-	struct i2c_client	*client;
-	struct mutex		lock;
-	u8			asa[3];
-	long			raw_to_gauss[3];
-};
-
-static const int ak09911_index_to_reg[] = {
-	AK09911_REG_HXL, AK09911_REG_HYL, AK09911_REG_HZL,
-};
-
-static int ak09911_set_mode(struct i2c_client *client, u8 mode)
-{
-	int ret;
-
-	switch (mode) {
-	case AK09911_MODE_SNG_MEASURE:
-	case AK09911_MODE_SELF_TEST:
-	case AK09911_MODE_FUSE_ACCESS:
-	case AK09911_MODE_POWERDOWN:
-		ret = i2c_smbus_write_byte_data(client,
-						AK09911_REG_CNTL2, mode);
-		if (ret < 0) {
-			dev_err(&client->dev, "set_mode error\n");
-			return ret;
-		}
-		/* After mode change wait atleast 100us */
-		usleep_range(100, 500);
-		break;
-	default:
-		dev_err(&client->dev,
-			"%s: Unknown mode(%d).", __func__, mode);
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-/* Get Sensitivity Adjustment value */
-static int ak09911_get_asa(struct i2c_client *client)
-{
-	struct iio_dev *indio_dev = i2c_get_clientdata(client);
-	struct ak09911_data *data = iio_priv(indio_dev);
-	int ret;
-
-	ret = ak09911_set_mode(client, AK09911_MODE_FUSE_ACCESS);
-	if (ret < 0)
-		return ret;
-
-	/* Get asa data and store in the device data. */
-	ret = i2c_smbus_read_i2c_block_data(client, AK09911_REG_ASAX,
-					    3, data->asa);
-	if (ret < 0) {
-		dev_err(&client->dev, "Not able to read asa data\n");
-		return ret;
-	}
-
-	ret = ak09911_set_mode(client,  AK09911_MODE_POWERDOWN);
-	if (ret < 0)
-		return ret;
-
-	data->raw_to_gauss[0] = AK09911_RAW_TO_GAUSS(data->asa[0]);
-	data->raw_to_gauss[1] = AK09911_RAW_TO_GAUSS(data->asa[1]);
-	data->raw_to_gauss[2] = AK09911_RAW_TO_GAUSS(data->asa[2]);
-
-	return 0;
-}
-
-static int ak09911_verify_chip_id(struct i2c_client *client)
-{
-	u8 wia_val[2];
-	int ret;
-
-	ret = i2c_smbus_read_i2c_block_data(client, AK09911_REG_WIA1,
-					    2, wia_val);
-	if (ret < 0) {
-		dev_err(&client->dev, "Error reading WIA\n");
-		return ret;
-	}
-
-	dev_dbg(&client->dev, "WIA %02x %02x\n", wia_val[0], wia_val[1]);
-
-	if (wia_val[0] != AK09911_WIA1_VALUE ||
-		wia_val[1] != AK09911_WIA2_VALUE) {
-		dev_err(&client->dev, "Device ak09911 not found\n");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-static int wait_conversion_complete_polled(struct ak09911_data *data)
-{
-	struct i2c_client *client = data->client;
-	u8 read_status;
-	u32 timeout_ms = AK09911_MAX_CONVERSION_TIMEOUT_MS;
-	int ret;
-
-	/* Wait for the conversion to complete. */
-	while (timeout_ms) {
-		msleep_interruptible(AK09911_CONVERSION_DONE_POLL_TIME_MS);
-		ret = i2c_smbus_read_byte_data(client, AK09911_REG_ST1);
-		if (ret < 0) {
-			dev_err(&client->dev, "Error in reading ST1\n");
-			return ret;
-		}
-		read_status = ret & 0x01;
-		if (read_status)
-			break;
-		timeout_ms -= AK09911_CONVERSION_DONE_POLL_TIME_MS;
-	}
-	if (!timeout_ms) {
-		dev_err(&client->dev, "Conversion timeout happened\n");
-		return -EIO;
-	}
-
-	return read_status;
-}
-
-static int ak09911_read_axis(struct iio_dev *indio_dev, int index, int *val)
-{
-	struct ak09911_data *data = iio_priv(indio_dev);
-	struct i2c_client *client = data->client;
-	int ret;
-
-	mutex_lock(&data->lock);
-
-	ret = ak09911_set_mode(client, AK09911_MODE_SNG_MEASURE);
-	if (ret < 0)
-		goto fn_exit;
-
-	ret = wait_conversion_complete_polled(data);
-	if (ret < 0)
-		goto fn_exit;
-
-	/* Read data */
-	ret = i2c_smbus_read_word_data(client, ak09911_index_to_reg[index]);
-	if (ret < 0) {
-		dev_err(&client->dev, "Read axis data fails\n");
-		goto fn_exit;
-	}
-
-	mutex_unlock(&data->lock);
-
-	/* Clamp to valid range. */
-	*val = sign_extend32(clamp_t(s16, ret, -8192, 8191), 13);
-
-	return IIO_VAL_INT;
-
-fn_exit:
-	mutex_unlock(&data->lock);
-
-	return ret;
-}
-
-static int ak09911_read_raw(struct iio_dev *indio_dev,
-			    struct iio_chan_spec const *chan,
-			    int *val, int *val2,
-			    long mask)
-{
-	struct ak09911_data *data = iio_priv(indio_dev);
-
-	switch (mask) {
-	case IIO_CHAN_INFO_RAW:
-		return ak09911_read_axis(indio_dev, chan->address, val);
-	case IIO_CHAN_INFO_SCALE:
-		*val = 0;
-		*val2 = data->raw_to_gauss[chan->address];
-		return IIO_VAL_INT_PLUS_MICRO;
-	}
-
-	return -EINVAL;
-}
-
-#define AK09911_CHANNEL(axis, index)					\
-	{								\
-		.type = IIO_MAGN,					\
-		.modified = 1,						\
-		.channel2 = IIO_MOD_##axis,				\
-		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
-			     BIT(IIO_CHAN_INFO_SCALE),			\
-		.address = index,					\
-	}
-
-static const struct iio_chan_spec ak09911_channels[] = {
-	AK09911_CHANNEL(X, 0), AK09911_CHANNEL(Y, 1), AK09911_CHANNEL(Z, 2),
-};
-
-static const struct iio_info ak09911_info = {
-	.read_raw = &ak09911_read_raw,
-	.driver_module = THIS_MODULE,
-};
-
-static const struct acpi_device_id ak_acpi_match[] = {
-	{"AK009911", 0},
-	{ },
-};
-MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
-
-static int ak09911_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
-{
-	struct iio_dev *indio_dev;
-	struct ak09911_data *data;
-	const char *name;
-	int ret;
-
-	ret = ak09911_verify_chip_id(client);
-	if (ret) {
-		dev_err(&client->dev, "AK00911 not detected\n");
-		return -ENODEV;
-	}
-
-	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
-	if (indio_dev == NULL)
-		return -ENOMEM;
-
-	data = iio_priv(indio_dev);
-	i2c_set_clientdata(client, indio_dev);
-
-	data->client = client;
-	mutex_init(&data->lock);
-
-	ret = ak09911_get_asa(client);
-	if (ret)
-		return ret;
-
-	if (id)
-		name = id->name;
-	else if (ACPI_HANDLE(&client->dev))
-		name = dev_name(&client->dev);
-	else
-		return -ENODEV;
-
-	dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
-
-	indio_dev->dev.parent = &client->dev;
-	indio_dev->channels = ak09911_channels;
-	indio_dev->num_channels = ARRAY_SIZE(ak09911_channels);
-	indio_dev->info = &ak09911_info;
-	indio_dev->modes = INDIO_DIRECT_MODE;
-	indio_dev->name = name;
-
-	return devm_iio_device_register(&client->dev, indio_dev);
-}
-
-static const struct i2c_device_id ak09911_id[] = {
-	{"ak09911", 0},
-	{}
-};
-
-MODULE_DEVICE_TABLE(i2c, ak09911_id);
-
-static struct i2c_driver ak09911_driver = {
-	.driver = {
-		.name	= "ak09911",
-		.acpi_match_table = ACPI_PTR(ak_acpi_match),
-	},
-	.probe		= ak09911_probe,
-	.id_table	= ak09911_id,
-};
-module_i2c_driver(ak09911_driver);
-
-MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("AK09911 Compass driver");
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c
index bf5ef077e791..b13936dacc78 100644
--- a/drivers/iio/magnetometer/ak8975.c
+++ b/drivers/iio/magnetometer/ak8975.c
@@ -64,10 +64,10 @@
 #define AK8975_REG_CNTL			0x0A
 #define AK8975_REG_CNTL_MODE_SHIFT	0
 #define AK8975_REG_CNTL_MODE_MASK	(0xF << AK8975_REG_CNTL_MODE_SHIFT)
-#define AK8975_REG_CNTL_MODE_POWER_DOWN	0
-#define AK8975_REG_CNTL_MODE_ONCE	1
-#define AK8975_REG_CNTL_MODE_SELF_TEST	8
-#define AK8975_REG_CNTL_MODE_FUSE_ROM	0xF
+#define AK8975_REG_CNTL_MODE_POWER_DOWN	0x00
+#define AK8975_REG_CNTL_MODE_ONCE	0x01
+#define AK8975_REG_CNTL_MODE_SELF_TEST	0x08
+#define AK8975_REG_CNTL_MODE_FUSE_ROM	0x0F
 
 #define AK8975_REG_RSVC			0x0B
 #define AK8975_REG_ASTC			0x0C
@@ -81,18 +81,278 @@
 #define AK8975_MAX_REGS			AK8975_REG_ASAZ
 
 /*
+ * AK09912 Register definitions
+ */
+#define AK09912_REG_WIA1		0x00
+#define AK09912_REG_WIA2		0x01
+#define AK09912_DEVICE_ID		0x04
+#define AK09911_DEVICE_ID		0x05
+
+#define AK09911_REG_INFO1		0x02
+#define AK09911_REG_INFO2		0x03
+
+#define AK09912_REG_ST1			0x10
+
+#define AK09912_REG_ST1_DRDY_SHIFT	0
+#define AK09912_REG_ST1_DRDY_MASK	(1 << AK09912_REG_ST1_DRDY_SHIFT)
+
+#define AK09912_REG_HXL			0x11
+#define AK09912_REG_HXH			0x12
+#define AK09912_REG_HYL			0x13
+#define AK09912_REG_HYH			0x14
+#define AK09912_REG_HZL			0x15
+#define AK09912_REG_HZH			0x16
+#define AK09912_REG_TMPS		0x17
+
+#define AK09912_REG_ST2			0x18
+#define AK09912_REG_ST2_HOFL_SHIFT	3
+#define AK09912_REG_ST2_HOFL_MASK	(1 << AK09912_REG_ST2_HOFL_SHIFT)
+
+#define AK09912_REG_CNTL1		0x30
+
+#define AK09912_REG_CNTL2		0x31
+#define AK09912_REG_CNTL_MODE_POWER_DOWN	0x00
+#define AK09912_REG_CNTL_MODE_ONCE	0x01
+#define AK09912_REG_CNTL_MODE_SELF_TEST	0x10
+#define AK09912_REG_CNTL_MODE_FUSE_ROM	0x1F
+#define AK09912_REG_CNTL2_MODE_SHIFT	0
+#define AK09912_REG_CNTL2_MODE_MASK	(0x1F << AK09912_REG_CNTL2_MODE_SHIFT)
+
+#define AK09912_REG_CNTL3		0x32
+
+#define AK09912_REG_TS1			0x33
+#define AK09912_REG_TS2			0x34
+#define AK09912_REG_TS3			0x35
+#define AK09912_REG_I2CDIS		0x36
+#define AK09912_REG_TS4			0x37
+
+#define AK09912_REG_ASAX		0x60
+#define AK09912_REG_ASAY		0x61
+#define AK09912_REG_ASAZ		0x62
+
+#define AK09912_MAX_REGS		AK09912_REG_ASAZ
+
+/*
  * Miscellaneous values.
  */
 #define AK8975_MAX_CONVERSION_TIMEOUT	500
 #define AK8975_CONVERSION_DONE_POLL_TIME 10
 #define AK8975_DATA_READY_TIMEOUT	((100*HZ)/1000)
-#define RAW_TO_GAUSS_8975(asa) ((((asa) + 128) * 3000) / 256)
-#define RAW_TO_GAUSS_8963(asa) ((((asa) + 128) * 6000) / 256)
+
+/*
+ * Precalculate scale factor (in Gauss units) for each axis and
+ * store in the device data.
+ *
+ * This scale factor is axis-dependent, and is derived from 3 calibration
+ * factors ASA(x), ASA(y), and ASA(z).
+ *
+ * These ASA values are read from the sensor device at start of day, and
+ * cached in the device context struct.
+ *
+ * Adjusting the flux value with the sensitivity adjustment value should be
+ * done via the following formula:
+ *
+ * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
+ * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
+ * is the resultant adjusted value.
+ *
+ * We reduce the formula to:
+ *
+ * Hadj = H * (ASA + 128) / 256
+ *
+ * H is in the range of -4096 to 4095.  The magnetometer has a range of
+ * +-1229uT.  To go from the raw value to uT is:
+ *
+ * HuT = H * 1229/4096, or roughly, 3/10.
+ *
+ * Since 1uT = 0.01 gauss, our final scale factor becomes:
+ *
+ * Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100
+ * Hadj = H * ((ASA + 128) * 0.003) / 256
+ *
+ * Since ASA doesn't change, we cache the resultant scale factor into the
+ * device context in ak8975_setup().
+ *
+ * Given we use IIO_VAL_INT_PLUS_MICRO bit when displaying the scale, we
+ * multiply the stored scale value by 1e6.
+ */
+static long ak8975_raw_to_gauss(u16 data)
+{
+	return (((long)data + 128) * 3000) / 256;
+}
+
+/*
+ * For AK8963 and AK09911, same calculation, but the device is less sensitive:
+ *
+ * H is in the range of +-8190.  The magnetometer has a range of
+ * +-4912uT.  To go from the raw value to uT is:
+ *
+ * HuT = H * 4912/8190, or roughly, 6/10, instead of 3/10.
+ */
+
+static long ak8963_09911_raw_to_gauss(u16 data)
+{
+	return (((long)data + 128) * 6000) / 256;
+}
+
+/*
+ * For AK09912, same calculation, except the device is more sensitive:
+ *
+ * H is in the range of -32752 to 32752.  The magnetometer has a range of
+ * +-4912uT.  To go from the raw value to uT is:
+ *
+ * HuT = H * 4912/32752, or roughly, 3/20, instead of 3/10.
+ */
+static long ak09912_raw_to_gauss(u16 data)
+{
+	return (((long)data + 128) * 1500) / 256;
+}
 
 /* Compatible Asahi Kasei Compass parts */
 enum asahi_compass_chipset {
 	AK8975,
 	AK8963,
+	AK09911,
+	AK09912,
+	AK_MAX_TYPE
+};
+
+enum ak_ctrl_reg_addr {
+	ST1,
+	ST2,
+	CNTL,
+	ASA_BASE,
+	MAX_REGS,
+	REGS_END,
+};
+
+enum ak_ctrl_reg_mask {
+	ST1_DRDY,
+	ST2_HOFL,
+	ST2_DERR,
+	CNTL_MODE,
+	MASK_END,
+};
+
+enum ak_ctrl_mode {
+	POWER_DOWN,
+	MODE_ONCE,
+	SELF_TEST,
+	FUSE_ROM,
+	MODE_END,
+};
+
+struct ak_def {
+	enum asahi_compass_chipset type;
+	long (*raw_to_gauss)(u16 data);
+	u16 range;
+	u8 ctrl_regs[REGS_END];
+	u8 ctrl_masks[MASK_END];
+	u8 ctrl_modes[MODE_END];
+	u8 data_regs[3];
+};
+
+static struct ak_def ak_def_array[AK_MAX_TYPE] = {
+	{
+		.type = AK8975,
+		.raw_to_gauss = ak8975_raw_to_gauss,
+		.range = 4096,
+		.ctrl_regs = {
+			AK8975_REG_ST1,
+			AK8975_REG_ST2,
+			AK8975_REG_CNTL,
+			AK8975_REG_ASAX,
+			AK8975_MAX_REGS},
+		.ctrl_masks = {
+			AK8975_REG_ST1_DRDY_MASK,
+			AK8975_REG_ST2_HOFL_MASK,
+			AK8975_REG_ST2_DERR_MASK,
+			AK8975_REG_CNTL_MODE_MASK},
+		.ctrl_modes = {
+			AK8975_REG_CNTL_MODE_POWER_DOWN,
+			AK8975_REG_CNTL_MODE_ONCE,
+			AK8975_REG_CNTL_MODE_SELF_TEST,
+			AK8975_REG_CNTL_MODE_FUSE_ROM},
+		.data_regs = {
+			AK8975_REG_HXL,
+			AK8975_REG_HYL,
+			AK8975_REG_HZL},
+	},
+	{
+		.type = AK8963,
+		.raw_to_gauss = ak8963_09911_raw_to_gauss,
+		.range = 8190,
+		.ctrl_regs = {
+			AK8975_REG_ST1,
+			AK8975_REG_ST2,
+			AK8975_REG_CNTL,
+			AK8975_REG_ASAX,
+			AK8975_MAX_REGS},
+		.ctrl_masks = {
+			AK8975_REG_ST1_DRDY_MASK,
+			AK8975_REG_ST2_HOFL_MASK,
+			0,
+			AK8975_REG_CNTL_MODE_MASK},
+		.ctrl_modes = {
+			AK8975_REG_CNTL_MODE_POWER_DOWN,
+			AK8975_REG_CNTL_MODE_ONCE,
+			AK8975_REG_CNTL_MODE_SELF_TEST,
+			AK8975_REG_CNTL_MODE_FUSE_ROM},
+		.data_regs = {
+			AK8975_REG_HXL,
+			AK8975_REG_HYL,
+			AK8975_REG_HZL},
+	},
+	{
+		.type = AK09911,
+		.raw_to_gauss = ak8963_09911_raw_to_gauss,
+		.range = 8192,
+		.ctrl_regs = {
+			AK09912_REG_ST1,
+			AK09912_REG_ST2,
+			AK09912_REG_CNTL2,
+			AK09912_REG_ASAX,
+			AK09912_MAX_REGS},
+		.ctrl_masks = {
+			AK09912_REG_ST1_DRDY_MASK,
+			AK09912_REG_ST2_HOFL_MASK,
+			0,
+			AK09912_REG_CNTL2_MODE_MASK},
+		.ctrl_modes = {
+			AK09912_REG_CNTL_MODE_POWER_DOWN,
+			AK09912_REG_CNTL_MODE_ONCE,
+			AK09912_REG_CNTL_MODE_SELF_TEST,
+			AK09912_REG_CNTL_MODE_FUSE_ROM},
+		.data_regs = {
+			AK09912_REG_HXL,
+			AK09912_REG_HYL,
+			AK09912_REG_HZL},
+	},
+	{
+		.type = AK09912,
+		.raw_to_gauss = ak09912_raw_to_gauss,
+		.range = 32752,
+		.ctrl_regs = {
+			AK09912_REG_ST1,
+			AK09912_REG_ST2,
+			AK09912_REG_CNTL2,
+			AK09912_REG_ASAX,
+			AK09912_MAX_REGS},
+		.ctrl_masks = {
+			AK09912_REG_ST1_DRDY_MASK,
+			AK09912_REG_ST2_HOFL_MASK,
+			0,
+			AK09912_REG_CNTL2_MODE_MASK},
+		.ctrl_modes = {
+			AK09912_REG_CNTL_MODE_POWER_DOWN,
+			AK09912_REG_CNTL_MODE_ONCE,
+			AK09912_REG_CNTL_MODE_SELF_TEST,
+			AK09912_REG_CNTL_MODE_FUSE_ROM},
+		.data_regs = {
+			AK09912_REG_HXL,
+			AK09912_REG_HYL,
+			AK09912_REG_HZL},
+	}
 };
 
 /*
@@ -100,40 +360,82 @@ enum asahi_compass_chipset {
  */
 struct ak8975_data {
 	struct i2c_client	*client;
+	struct ak_def		*def;
 	struct attribute_group	attrs;
 	struct mutex		lock;
 	u8			asa[3];
 	long			raw_to_gauss[3];
-	u8			reg_cache[AK8975_MAX_REGS];
 	int			eoc_gpio;
 	int			eoc_irq;
 	wait_queue_head_t	data_ready_queue;
 	unsigned long		flags;
-	enum asahi_compass_chipset chipset;
+	u8			cntl_cache;
 };
 
-static const int ak8975_index_to_reg[] = {
-	AK8975_REG_HXL, AK8975_REG_HYL, AK8975_REG_HZL,
-};
+/*
+ * Return 0 if the i2c device is the one we expect.
+ * return a negative error number otherwise
+ */
+static int ak8975_who_i_am(struct i2c_client *client,
+			   enum asahi_compass_chipset type)
+{
+	u8 wia_val[2];
+	int ret;
+
+	/*
+	 * Signature for each device:
+	 * Device   |  WIA1      |  WIA2
+	 * AK09912  |  DEVICE_ID |  AK09912_DEVICE_ID
+	 * AK09911  |  DEVICE_ID |  AK09911_DEVICE_ID
+	 * AK8975   |  DEVICE_ID |  NA
+	 * AK8963   |  DEVICE_ID |  NA
+	 */
+	ret = i2c_smbus_read_i2c_block_data(client, AK09912_REG_WIA1,
+					    2, wia_val);
+	if (ret < 0) {
+		dev_err(&client->dev, "Error reading WIA\n");
+		return ret;
+	}
+
+	if (wia_val[0] != AK8975_DEVICE_ID)
+		return -ENODEV;
+
+	switch (type) {
+	case AK8975:
+	case AK8963:
+		return 0;
+	case AK09911:
+		if (wia_val[1] == AK09911_DEVICE_ID)
+			return 0;
+		break;
+	case AK09912:
+		if (wia_val[1] == AK09912_DEVICE_ID)
+			return 0;
+		break;
+	default:
+		dev_err(&client->dev, "Type %d unknown\n", type);
+	}
+	return -ENODEV;
+}
 
 /*
- * Helper function to write to the I2C device's registers.
+ * Helper function to write to CNTL register.
  */
-static int ak8975_write_data(struct i2c_client *client,
-			     u8 reg, u8 val, u8 mask, u8 shift)
+static int ak8975_set_mode(struct ak8975_data *data, enum ak_ctrl_mode mode)
 {
-	struct iio_dev *indio_dev = i2c_get_clientdata(client);
-	struct ak8975_data *data = iio_priv(indio_dev);
 	u8 regval;
 	int ret;
 
-	regval = (data->reg_cache[reg] & ~mask) | (val << shift);
-	ret = i2c_smbus_write_byte_data(client, reg, regval);
+	regval = (data->cntl_cache & ~data->def->ctrl_masks[CNTL_MODE]) |
+		 data->def->ctrl_modes[mode];
+	ret = i2c_smbus_write_byte_data(data->client,
+					data->def->ctrl_regs[CNTL], regval);
 	if (ret < 0) {
-		dev_err(&client->dev, "Write to device fails status %x\n", ret);
 		return ret;
 	}
-	data->reg_cache[reg] = regval;
+	data->cntl_cache = regval;
+	/* After mode change wait atleast 100us */
+	usleep_range(100, 500);
 
 	return 0;
 }
@@ -166,8 +468,8 @@ static int ak8975_setup_irq(struct ak8975_data *data)
 		irq = gpio_to_irq(data->eoc_gpio);
 
 	rc = devm_request_irq(&client->dev, irq, ak8975_irq_handler,
-			 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-			 dev_name(&client->dev), data);
+			      IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+			      dev_name(&client->dev), data);
 	if (rc < 0) {
 		dev_err(&client->dev,
 			"irq %d request failed, (gpio %d): %d\n",
@@ -191,34 +493,18 @@ static int ak8975_setup(struct i2c_client *client)
 {
 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
 	struct ak8975_data *data = iio_priv(indio_dev);
-	u8 device_id;
 	int ret;
 
-	/* Confirm that the device we're talking to is really an AK8975. */
-	ret = i2c_smbus_read_byte_data(client, AK8975_REG_WIA);
-	if (ret < 0) {
-		dev_err(&client->dev, "Error reading WIA\n");
-		return ret;
-	}
-	device_id = ret;
-	if (device_id != AK8975_DEVICE_ID) {
-		dev_err(&client->dev, "Device ak8975 not found\n");
-		return -ENODEV;
-	}
-
 	/* Write the fused rom access mode. */
-	ret = ak8975_write_data(client,
-				AK8975_REG_CNTL,
-				AK8975_REG_CNTL_MODE_FUSE_ROM,
-				AK8975_REG_CNTL_MODE_MASK,
-				AK8975_REG_CNTL_MODE_SHIFT);
+	ret = ak8975_set_mode(data, FUSE_ROM);
 	if (ret < 0) {
 		dev_err(&client->dev, "Error in setting fuse access mode\n");
 		return ret;
 	}
 
 	/* Get asa data and store in the device data. */
-	ret = i2c_smbus_read_i2c_block_data(client, AK8975_REG_ASAX,
+	ret = i2c_smbus_read_i2c_block_data(client,
+					    data->def->ctrl_regs[ASA_BASE],
 					    3, data->asa);
 	if (ret < 0) {
 		dev_err(&client->dev, "Not able to read asa data\n");
@@ -226,13 +512,13 @@ static int ak8975_setup(struct i2c_client *client)
 	}
 
 	/* After reading fuse ROM data set power-down mode */
-	ret = ak8975_write_data(client,
-				AK8975_REG_CNTL,
-				AK8975_REG_CNTL_MODE_POWER_DOWN,
-				AK8975_REG_CNTL_MODE_MASK,
-				AK8975_REG_CNTL_MODE_SHIFT);
+	ret = ak8975_set_mode(data, POWER_DOWN);
+	if (ret < 0) {
+		dev_err(&client->dev, "Error in setting power-down mode\n");
+		return ret;
+	}
 
-	if (data->eoc_gpio > 0 || client->irq) {
+	if (data->eoc_gpio > 0 || client->irq > 0) {
 		ret = ak8975_setup_irq(data);
 		if (ret < 0) {
 			dev_err(&client->dev,
@@ -241,61 +527,9 @@ static int ak8975_setup(struct i2c_client *client)
 		}
 	}
 
-	if (ret < 0) {
-		dev_err(&client->dev, "Error in setting power-down mode\n");
-		return ret;
-	}
-
-/*
- * Precalculate scale factor (in Gauss units) for each axis and
- * store in the device data.
- *
- * This scale factor is axis-dependent, and is derived from 3 calibration
- * factors ASA(x), ASA(y), and ASA(z).
- *
- * These ASA values are read from the sensor device at start of day, and
- * cached in the device context struct.
- *
- * Adjusting the flux value with the sensitivity adjustment value should be
- * done via the following formula:
- *
- * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 )
- *
- * where H is the raw value, ASA is the sensitivity adjustment, and Hadj
- * is the resultant adjusted value.
- *
- * We reduce the formula to:
- *
- * Hadj = H * (ASA + 128) / 256
- *
- * H is in the range of -4096 to 4095.  The magnetometer has a range of
- * +-1229uT.  To go from the raw value to uT is:
- *
- * HuT = H * 1229/4096, or roughly, 3/10.
- *
- * Since 1uT = 0.01 gauss, our final scale factor becomes:
- *
- * Hadj = H * ((ASA + 128) / 256) * 3/10 * 1/100
- * Hadj = H * ((ASA + 128) * 0.003) / 256
- *
- * Since ASA doesn't change, we cache the resultant scale factor into the
- * device context in ak8975_setup().
- */
-	if (data->chipset == AK8963) {
-		/*
-		 * H range is +-8190 and magnetometer range is +-4912.
-		 * So HuT using the above explanation for 8975,
-		 * 4912/8190 = ~ 6/10.
-		 * So the Hadj should use 6/10 instead of 3/10.
-		 */
-		data->raw_to_gauss[0] = RAW_TO_GAUSS_8963(data->asa[0]);
-		data->raw_to_gauss[1] = RAW_TO_GAUSS_8963(data->asa[1]);
-		data->raw_to_gauss[2] = RAW_TO_GAUSS_8963(data->asa[2]);
-	} else {
-		data->raw_to_gauss[0] = RAW_TO_GAUSS_8975(data->asa[0]);
-		data->raw_to_gauss[1] = RAW_TO_GAUSS_8975(data->asa[1]);
-		data->raw_to_gauss[2] = RAW_TO_GAUSS_8975(data->asa[2]);
-	}
+	data->raw_to_gauss[0] = data->def->raw_to_gauss(data->asa[0]);
+	data->raw_to_gauss[1] = data->def->raw_to_gauss(data->asa[1]);
+	data->raw_to_gauss[2] = data->def->raw_to_gauss(data->asa[2]);
 
 	return 0;
 }
@@ -318,7 +552,7 @@ static int wait_conversion_complete_gpio(struct ak8975_data *data)
 		return -EINVAL;
 	}
 
-	ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
+	ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST1]);
 	if (ret < 0)
 		dev_err(&client->dev, "Error in reading ST1\n");
 
@@ -335,7 +569,8 @@ static int wait_conversion_complete_polled(struct ak8975_data *data)
 	/* Wait for the conversion to complete. */
 	while (timeout_ms) {
 		msleep(AK8975_CONVERSION_DONE_POLL_TIME);
-		ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
+		ret = i2c_smbus_read_byte_data(client,
+					       data->def->ctrl_regs[ST1]);
 		if (ret < 0) {
 			dev_err(&client->dev, "Error in reading ST1\n");
 			return ret;
@@ -378,11 +613,7 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
 	mutex_lock(&data->lock);
 
 	/* Set up the device for taking a sample. */
-	ret = ak8975_write_data(client,
-				AK8975_REG_CNTL,
-				AK8975_REG_CNTL_MODE_ONCE,
-				AK8975_REG_CNTL_MODE_MASK,
-				AK8975_REG_CNTL_MODE_SHIFT);
+	ret = ak8975_set_mode(data, MODE_ONCE);
 	if (ret < 0) {
 		dev_err(&client->dev, "Error in setting operating mode\n");
 		goto exit;
@@ -399,14 +630,15 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
 		goto exit;
 
 	/* This will be executed only for non-interrupt based waiting case */
-	if (ret & AK8975_REG_ST1_DRDY_MASK) {
-		ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2);
+	if (ret & data->def->ctrl_masks[ST1_DRDY]) {
+		ret = i2c_smbus_read_byte_data(client,
+					       data->def->ctrl_regs[ST2]);
 		if (ret < 0) {
 			dev_err(&client->dev, "Error in reading ST2\n");
 			goto exit;
 		}
-		if (ret & (AK8975_REG_ST2_DERR_MASK |
-			   AK8975_REG_ST2_HOFL_MASK)) {
+		if (ret & (data->def->ctrl_masks[ST2_DERR] |
+			   data->def->ctrl_masks[ST2_HOFL])) {
 			dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
 			ret = -EINVAL;
 			goto exit;
@@ -415,7 +647,7 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
 
 	/* Read the flux value from the appropriate register
 	   (the register is specified in the iio device attributes). */
-	ret = i2c_smbus_read_word_data(client, ak8975_index_to_reg[index]);
+	ret = i2c_smbus_read_word_data(client, data->def->data_regs[index]);
 	if (ret < 0) {
 		dev_err(&client->dev, "Read axis data fails\n");
 		goto exit;
@@ -424,7 +656,7 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
 	mutex_unlock(&data->lock);
 
 	/* Clamp to valid range. */
-	*val = clamp_t(s16, ret, -4096, 4095);
+	*val = clamp_t(s16, ret, -data->def->range, data->def->range);
 	return IIO_VAL_INT;
 
 exit:
@@ -473,6 +705,8 @@ static const struct acpi_device_id ak_acpi_match[] = {
 	{"AK8975", AK8975},
 	{"AK8963", AK8963},
 	{"INVN6500", AK8963},
+	{"AK09911", AK09911},
+	{"AK09912", AK09912},
 	{ },
 };
 MODULE_DEVICE_TABLE(acpi, ak_acpi_match);
@@ -498,6 +732,7 @@ static int ak8975_probe(struct i2c_client *client,
 	int eoc_gpio;
 	int err;
 	const char *name = NULL;
+	enum asahi_compass_chipset chipset;
 
 	/* Grab and set up the supplied GPIO. */
 	if (client->dev.platform_data)
@@ -537,42 +772,50 @@ static int ak8975_probe(struct i2c_client *client,
 
 	/* id will be NULL when enumerated via ACPI */
 	if (id) {
-		data->chipset =
-			(enum asahi_compass_chipset)(id->driver_data);
+		chipset = (enum asahi_compass_chipset)(id->driver_data);
 		name = id->name;
 	} else if (ACPI_HANDLE(&client->dev))
-		name = ak8975_match_acpi_device(&client->dev, &data->chipset);
+		name = ak8975_match_acpi_device(&client->dev, &chipset);
 	else
 		return -ENOSYS;
 
+	if (chipset >= AK_MAX_TYPE) {
+		dev_err(&client->dev, "AKM device type unsupported: %d\n",
+			chipset);
+		return -ENODEV;
+	}
+
+	data->def = &ak_def_array[chipset];
+	err = ak8975_who_i_am(client, data->def->type);
+	if (err < 0) {
+		dev_err(&client->dev, "Unexpected device\n");
+		return err;
+	}
 	dev_dbg(&client->dev, "Asahi compass chip %s\n", name);
 
 	/* Perform some basic start-of-day setup of the device. */
 	err = ak8975_setup(client);
 	if (err < 0) {
-		dev_err(&client->dev, "AK8975 initialization fails\n");
+		dev_err(&client->dev, "%s initialization fails\n", name);
 		return err;
 	}
 
-	data->client = client;
 	mutex_init(&data->lock);
-	data->eoc_gpio = eoc_gpio;
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->channels = ak8975_channels;
 	indio_dev->num_channels = ARRAY_SIZE(ak8975_channels);
 	indio_dev->info = &ak8975_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->name = name;
-	err = devm_iio_device_register(&client->dev, indio_dev);
-	if (err < 0)
-		return err;
-
-	return 0;
+	return devm_iio_device_register(&client->dev, indio_dev);
 }
 
 static const struct i2c_device_id ak8975_id[] = {
 	{"ak8975", AK8975},
 	{"ak8963", AK8963},
+	{"AK8963", AK8963},
+	{"ak09911", AK09911},
+	{"ak09912", AK09912},
 	{}
 };
 
@@ -581,14 +824,20 @@ MODULE_DEVICE_TABLE(i2c, ak8975_id);
 static const struct of_device_id ak8975_of_match[] = {
 	{ .compatible = "asahi-kasei,ak8975", },
 	{ .compatible = "ak8975", },
-	{ }
+	{ .compatible = "asahi-kasei,ak8963", },
+	{ .compatible = "ak8963", },
+	{ .compatible = "asahi-kasei,ak09911", },
+	{ .compatible = "ak09911", },
+	{ .compatible = "asahi-kasei,ak09912", },
+	{ .compatible = "ak09912", },
+	{}
 };
 MODULE_DEVICE_TABLE(of, ak8975_of_match);
 
 static struct i2c_driver ak8975_driver = {
 	.driver = {
 		.name	= "ak8975",
-		.of_match_table = ak8975_of_match,
+		.of_match_table = of_match_ptr(ak8975_of_match),
 		.acpi_match_table = ACPI_PTR(ak_acpi_match),
 	},
 	.probe		= ak8975_probe,
diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
index 6294575d2777..d22993b4066a 100644
--- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
+++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
@@ -157,20 +157,12 @@ static int magn_3d_read_raw(struct iio_dev *indio_dev,
 	int report_id = -1;
 	u32 address;
 	int ret_type;
-	s32 poll_value;
 
 	*val = 0;
 	*val2 = 0;
 	switch (mask) {
 	case 0:
-		poll_value = hid_sensor_read_poll_value(
-					&magn_state->common_attributes);
-		if (poll_value < 0)
-				return -EINVAL;
-
 		hid_sensor_power_state(&magn_state->common_attributes, true);
-		msleep_interruptible(poll_value * 2);
-
 		report_id =
 			magn_state->magn[chan->address].report_id;
 		address = magn_3d_addresses[chan->address];
@@ -530,6 +522,7 @@ static struct platform_driver hid_magn_3d_platform_driver = {
 	.id_table = hid_magn_3d_ids,
 	.driver = {
 		.name	= KBUILD_MODNAME,
+		.pm	= &hid_sensor_pm_ops,
 	},
 	.probe		= hid_magn_3d_probe,
 	.remove		= hid_magn_3d_remove,
diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c
index 1ff181bbbcef..73854460bb2c 100644
--- a/drivers/iio/orientation/hid-sensor-incl-3d.c
+++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
@@ -111,20 +111,12 @@ static int incl_3d_read_raw(struct iio_dev *indio_dev,
 	int report_id = -1;
 	u32 address;
 	int ret_type;
-	s32 poll_value;
 
 	*val = 0;
 	*val2 = 0;
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
-		poll_value = hid_sensor_read_poll_value(
-					&incl_state->common_attributes);
-		if (poll_value < 0)
-			return -EINVAL;
-
 		hid_sensor_power_state(&incl_state->common_attributes, true);
-		msleep_interruptible(poll_value * 2);
-
 		report_id =
 			incl_state->incl[chan->scan_index].report_id;
 		address = incl_3d_addresses[chan->scan_index];
@@ -437,6 +429,7 @@ static struct platform_driver hid_incl_3d_platform_driver = {
 	.id_table = hid_incl_3d_ids,
 	.driver = {
 		.name	= KBUILD_MODNAME,
+		.pm	= &hid_sensor_pm_ops,
 	},
 	.probe		= hid_incl_3d_probe,
 	.remove		= hid_incl_3d_remove,
diff --git a/drivers/iio/pressure/bmp280.c b/drivers/iio/pressure/bmp280.c
index 75038dacfff1..7c623e2bd633 100644
--- a/drivers/iio/pressure/bmp280.c
+++ b/drivers/iio/pressure/bmp280.c
@@ -80,16 +80,12 @@ struct bmp280_data {
 	s32 t_fine;
 };
 
-/* Compensation parameters. */
-struct bmp280_comp_temp {
-	u16 dig_t1;
-	s16 dig_t2, dig_t3;
-};
-
-struct bmp280_comp_press {
-	u16 dig_p1;
-	s16 dig_p2, dig_p3, dig_p4, dig_p5, dig_p6, dig_p7, dig_p8, dig_p9;
-};
+/*
+ * These enums are used for indexing into the array of compensation
+ * parameters.
+ */
+enum { T1, T2, T3 };
+enum { P1, P2, P3, P4, P5, P6, P7, P8, P9 };
 
 static const struct iio_chan_spec bmp280_channels[] = {
 	{
@@ -141,54 +137,6 @@ static const struct regmap_config bmp280_regmap_config = {
 	.volatile_reg = bmp280_is_volatile_reg,
 };
 
-static int bmp280_read_compensation_temp(struct bmp280_data *data,
-					 struct bmp280_comp_temp *comp)
-{
-	int ret;
-	__le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
-
-	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
-			       buf, BMP280_COMP_TEMP_REG_COUNT);
-	if (ret < 0) {
-		dev_err(&data->client->dev,
-			"failed to read temperature calibration parameters\n");
-		return ret;
-	}
-
-	comp->dig_t1 = (u16) le16_to_cpu(buf[0]);
-	comp->dig_t2 = (s16) le16_to_cpu(buf[1]);
-	comp->dig_t3 = (s16) le16_to_cpu(buf[2]);
-
-	return 0;
-}
-
-static int bmp280_read_compensation_press(struct bmp280_data *data,
-					  struct bmp280_comp_press *comp)
-{
-	int ret;
-	__le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
-
-	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
-			       buf, BMP280_COMP_PRESS_REG_COUNT);
-	if (ret < 0) {
-		dev_err(&data->client->dev,
-			"failed to read pressure calibration parameters\n");
-		return ret;
-	}
-
-	comp->dig_p1 = (u16) le16_to_cpu(buf[0]);
-	comp->dig_p2 = (s16) le16_to_cpu(buf[1]);
-	comp->dig_p3 = (s16) le16_to_cpu(buf[2]);
-	comp->dig_p4 = (s16) le16_to_cpu(buf[3]);
-	comp->dig_p5 = (s16) le16_to_cpu(buf[4]);
-	comp->dig_p6 = (s16) le16_to_cpu(buf[5]);
-	comp->dig_p7 = (s16) le16_to_cpu(buf[6]);
-	comp->dig_p8 = (s16) le16_to_cpu(buf[7]);
-	comp->dig_p9 = (s16) le16_to_cpu(buf[8]);
-
-	return 0;
-}
-
 /*
  * Returns temperature in DegC, resolution is 0.01 DegC.  Output value of
  * "5123" equals 51.23 DegC.  t_fine carries fine temperature as global
@@ -197,21 +145,35 @@ static int bmp280_read_compensation_press(struct bmp280_data *data,
  * Taken from datasheet, Section 3.11.3, "Compensation formula".
  */
 static s32 bmp280_compensate_temp(struct bmp280_data *data,
-				  struct bmp280_comp_temp *comp,
 				  s32 adc_temp)
 {
-	s32 var1, var2, t;
+	int ret;
+	s32 var1, var2;
+	__le16 buf[BMP280_COMP_TEMP_REG_COUNT / 2];
 
-	var1 = (((adc_temp >> 3) - ((s32) comp->dig_t1 << 1)) *
-		((s32) comp->dig_t2)) >> 11;
-	var2 = (((((adc_temp >> 4) - ((s32) comp->dig_t1)) *
-		  ((adc_temp >> 4) - ((s32) comp->dig_t1))) >> 12) *
-		((s32) comp->dig_t3)) >> 14;
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
+			       buf, BMP280_COMP_TEMP_REG_COUNT);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"failed to read temperature calibration parameters\n");
+		return ret;
+	}
 
-	data->t_fine = var1 + var2;
-	t = (data->t_fine * 5 + 128) >> 8;
+	/*
+	 * The double casts are necessary because le16_to_cpu returns an
+	 * unsigned 16-bit value.  Casting that value directly to a
+	 * signed 32-bit will not do proper sign extension.
+	 *
+	 * Conversely, T1 and P1 are unsigned values, so they can be
+	 * cast straight to the larger type.
+	 */
+	var1 = (((adc_temp >> 3) - ((s32)le16_to_cpu(buf[T1]) << 1)) *
+		((s32)(s16)le16_to_cpu(buf[T2]))) >> 11;
+	var2 = (((((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1]))) *
+		  ((adc_temp >> 4) - ((s32)le16_to_cpu(buf[T1])))) >> 12) *
+		((s32)(s16)le16_to_cpu(buf[T3]))) >> 14;
 
-	return t;
+	return (data->t_fine * 5 + 128) >> 8;
 }
 
 /*
@@ -222,29 +184,38 @@ static s32 bmp280_compensate_temp(struct bmp280_data *data,
  * Taken from datasheet, Section 3.11.3, "Compensation formula".
  */
 static u32 bmp280_compensate_press(struct bmp280_data *data,
-				   struct bmp280_comp_press *comp,
 				   s32 adc_press)
 {
+	int ret;
 	s64 var1, var2, p;
+	__le16 buf[BMP280_COMP_PRESS_REG_COUNT / 2];
+
+	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_PRESS_START,
+			       buf, BMP280_COMP_PRESS_REG_COUNT);
+	if (ret < 0) {
+		dev_err(&data->client->dev,
+			"failed to read pressure calibration parameters\n");
+		return ret;
+	}
 
-	var1 = ((s64) data->t_fine) - 128000;
-	var2 = var1 * var1 * (s64) comp->dig_p6;
-	var2 = var2 + ((var1 * (s64) comp->dig_p5) << 17);
-	var2 = var2 + (((s64) comp->dig_p4) << 35);
-	var1 = ((var1 * var1 * (s64) comp->dig_p3) >> 8) +
-		((var1 * (s64) comp->dig_p2) << 12);
-	var1 = (((((s64) 1) << 47) + var1)) * ((s64) comp->dig_p1) >> 33;
+	var1 = ((s64)data->t_fine) - 128000;
+	var2 = var1 * var1 * (s64)(s16)le16_to_cpu(buf[P6]);
+	var2 += (var1 * (s64)(s16)le16_to_cpu(buf[P5])) << 17;
+	var2 += ((s64)(s16)le16_to_cpu(buf[P4])) << 35;
+	var1 = ((var1 * var1 * (s64)(s16)le16_to_cpu(buf[P3])) >> 8) +
+		((var1 * (s64)(s16)le16_to_cpu(buf[P2])) << 12);
+	var1 = ((((s64)1) << 47) + var1) * ((s64)le16_to_cpu(buf[P1])) >> 33;
 
 	if (var1 == 0)
 		return 0;
 
-	p = ((((s64) 1048576 - adc_press) << 31) - var2) * 3125;
+	p = ((((s64)1048576 - adc_press) << 31) - var2) * 3125;
 	p = div64_s64(p, var1);
-	var1 = (((s64) comp->dig_p9) * (p >> 13) * (p >> 13)) >> 25;
-	var2 = (((s64) comp->dig_p8) * p) >> 19;
-	p = ((p + var1 + var2) >> 8) + (((s64) comp->dig_p7) << 4);
+	var1 = (((s64)(s16)le16_to_cpu(buf[P9])) * (p >> 13) * (p >> 13)) >> 25;
+	var2 = (((s64)(s16)le16_to_cpu(buf[P8])) * p) >> 19;
+	p = ((p + var1 + var2) >> 8) + (((s64)(s16)le16_to_cpu(buf[P7])) << 4);
 
-	return (u32) p;
+	return (u32)p;
 }
 
 static int bmp280_read_temp(struct bmp280_data *data,
@@ -253,11 +224,6 @@ static int bmp280_read_temp(struct bmp280_data *data,
 	int ret;
 	__be32 tmp = 0;
 	s32 adc_temp, comp_temp;
-	struct bmp280_comp_temp comp;
-
-	ret = bmp280_read_compensation_temp(data, &comp);
-	if (ret < 0)
-		return ret;
 
 	ret = regmap_bulk_read(data->regmap, BMP280_REG_TEMP_MSB,
 			       (u8 *) &tmp, 3);
@@ -267,7 +233,7 @@ static int bmp280_read_temp(struct bmp280_data *data,
 	}
 
 	adc_temp = be32_to_cpu(tmp) >> 12;
-	comp_temp = bmp280_compensate_temp(data, &comp, adc_temp);
+	comp_temp = bmp280_compensate_temp(data, adc_temp);
 
 	/*
 	 * val might be NULL if we're called by the read_press routine,
@@ -288,11 +254,6 @@ static int bmp280_read_press(struct bmp280_data *data,
 	__be32 tmp = 0;
 	s32 adc_press;
 	u32 comp_press;
-	struct bmp280_comp_press comp;
-
-	ret = bmp280_read_compensation_press(data, &comp);
-	if (ret < 0)
-		return ret;
 
 	/* Read and compensate temperature so we get a reading of t_fine. */
 	ret = bmp280_read_temp(data, NULL);
@@ -307,7 +268,7 @@ static int bmp280_read_press(struct bmp280_data *data,
 	}
 
 	adc_press = be32_to_cpu(tmp) >> 12;
-	comp_press = bmp280_compensate_press(data, &comp, adc_press);
+	comp_press = bmp280_compensate_press(data, adc_press);
 
 	*val = comp_press;
 	*val2 = 256000;
@@ -366,7 +327,7 @@ static int bmp280_chip_init(struct bmp280_data *data)
 				 BMP280_MODE_NORMAL);
 	if (ret < 0) {
 		dev_err(&data->client->dev,
-			"failed to write config register\n");
+			"failed to write ctrl_meas register\n");
 		return ret;
 	}
 
@@ -394,7 +355,6 @@ static int bmp280_probe(struct i2c_client *client,
 	if (!indio_dev)
 		return -ENOMEM;
 
-	i2c_set_clientdata(client, indio_dev);
 	data = iio_priv(indio_dev);
 	mutex_init(&data->lock);
 	data->client = client;
diff --git a/drivers/iio/pressure/hid-sensor-press.c b/drivers/iio/pressure/hid-sensor-press.c
index 764928682df2..1af314926ebd 100644
--- a/drivers/iio/pressure/hid-sensor-press.c
+++ b/drivers/iio/pressure/hid-sensor-press.c
@@ -79,7 +79,6 @@ static int press_read_raw(struct iio_dev *indio_dev,
 	int report_id = -1;
 	u32 address;
 	int ret_type;
-	s32 poll_value;
 
 	*val = 0;
 	*val2 = 0;
@@ -96,15 +95,8 @@ static int press_read_raw(struct iio_dev *indio_dev,
 			break;
 		}
 		if (report_id >= 0) {
-			poll_value = hid_sensor_read_poll_value(
-					&press_state->common_attributes);
-			if (poll_value < 0)
-				return -EINVAL;
 			hid_sensor_power_state(&press_state->common_attributes,
 						true);
-
-			msleep_interruptible(poll_value * 2);
-
 			*val = sensor_hub_input_attr_get_raw_value(
 				press_state->common_attributes.hsdev,
 				HID_USAGE_SENSOR_PRESSURE, address,
@@ -382,6 +374,7 @@ static struct platform_driver hid_press_platform_driver = {
 	.id_table = hid_press_ids,
 	.driver = {
 		.name	= KBUILD_MODNAME,
+		.pm	= &hid_sensor_pm_ops,
 	},
 	.probe		= hid_press_probe,
 	.remove		= hid_press_remove,
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
index 0c8cdf58f6a1..41a8d8ffa0de 100644
--- a/drivers/iio/proximity/Kconfig
+++ b/drivers/iio/proximity/Kconfig
@@ -17,3 +17,20 @@ config AS3935
 	  module will be called as3935
 
 endmenu
+
+menu "Proximity sensors"
+
+config SX9500
+	tristate "SX9500 Semtech proximity sensor"
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
+	select REGMAP_I2C
+	depends on I2C
+	help
+	  Say Y here to build a driver for Semtech's SX9500 capacitive
+	  proximity/button sensor.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sx9500.
+
+endmenu
diff --git a/drivers/iio/proximity/Makefile b/drivers/iio/proximity/Makefile
index 743adee1c8bf..9818dc562abd 100644
--- a/drivers/iio/proximity/Makefile
+++ b/drivers/iio/proximity/Makefile
@@ -4,3 +4,4 @@
 
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_AS3935)		+= as3935.o
+obj-$(CONFIG_SX9500)		+= sx9500.o
diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c
index 466aa4314667..bc0d68efd455 100644
--- a/drivers/iio/proximity/as3935.c
+++ b/drivers/iio/proximity/as3935.c
@@ -273,9 +273,9 @@ static void calibrate_as3935(struct as3935_state *st)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int as3935_suspend(struct spi_device *spi, pm_message_t msg)
+static int as3935_suspend(struct device *dev)
 {
-	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct as3935_state *st = iio_priv(indio_dev);
 	int val, ret;
 
@@ -293,9 +293,9 @@ err_suspend:
 	return ret;
 }
 
-static int as3935_resume(struct spi_device *spi)
+static int as3935_resume(struct device *dev)
 {
-	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct as3935_state *st = iio_priv(indio_dev);
 	int val, ret;
 
@@ -311,9 +311,12 @@ err_resume:
 
 	return ret;
 }
+
+static SIMPLE_DEV_PM_OPS(as3935_pm_ops, as3935_suspend, as3935_resume);
+#define AS3935_PM_OPS (&as3935_pm_ops)
+
 #else
-#define as3935_suspend	NULL
-#define as3935_resume	NULL
+#define AS3935_PM_OPS NULL
 #endif
 
 static int as3935_probe(struct spi_device *spi)
@@ -441,12 +444,11 @@ static struct spi_driver as3935_driver = {
 	.driver = {
 		.name	= "as3935",
 		.owner	= THIS_MODULE,
+		.pm	= AS3935_PM_OPS,
 	},
 	.probe		= as3935_probe,
 	.remove		= as3935_remove,
 	.id_table	= as3935_id,
-	.suspend	= as3935_suspend,
-	.resume		= as3935_resume,
 };
 module_spi_driver(as3935_driver);
 
diff --git a/drivers/iio/proximity/sx9500.c b/drivers/iio/proximity/sx9500.c
new file mode 100644
index 000000000000..74dff4e4a11a
--- /dev/null
+++ b/drivers/iio/proximity/sx9500.c
@@ -0,0 +1,752 @@
+/*
+ * Copyright (c) 2014 Intel Corporation
+ *
+ * Driver for Semtech's SX9500 capacitive proximity/button solution.
+ * Datasheet available at
+ * <http://www.semtech.com/images/datasheet/sx9500.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/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regmap.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/iio/trigger_consumer.h>
+
+#define SX9500_DRIVER_NAME		"sx9500"
+#define SX9500_IRQ_NAME			"sx9500_event"
+#define SX9500_GPIO_NAME		"sx9500_gpio"
+
+/* Register definitions. */
+#define SX9500_REG_IRQ_SRC		0x00
+#define SX9500_REG_STAT			0x01
+#define SX9500_REG_IRQ_MSK		0x03
+
+#define SX9500_REG_PROX_CTRL0		0x06
+#define SX9500_REG_PROX_CTRL1		0x07
+#define SX9500_REG_PROX_CTRL2		0x08
+#define SX9500_REG_PROX_CTRL3		0x09
+#define SX9500_REG_PROX_CTRL4		0x0a
+#define SX9500_REG_PROX_CTRL5		0x0b
+#define SX9500_REG_PROX_CTRL6		0x0c
+#define SX9500_REG_PROX_CTRL7		0x0d
+#define SX9500_REG_PROX_CTRL8		0x0e
+
+#define SX9500_REG_SENSOR_SEL		0x20
+#define SX9500_REG_USE_MSB		0x21
+#define SX9500_REG_USE_LSB		0x22
+#define SX9500_REG_AVG_MSB		0x23
+#define SX9500_REG_AVG_LSB		0x24
+#define SX9500_REG_DIFF_MSB		0x25
+#define SX9500_REG_DIFF_LSB		0x26
+#define SX9500_REG_OFFSET_MSB		0x27
+#define SX9500_REG_OFFSET_LSB		0x28
+
+#define SX9500_REG_RESET		0x7f
+
+/* Write this to REG_RESET to do a soft reset. */
+#define SX9500_SOFT_RESET		0xde
+
+#define SX9500_SCAN_PERIOD_MASK		GENMASK(6, 4)
+#define SX9500_SCAN_PERIOD_SHIFT	4
+
+/*
+ * These serve for identifying IRQ source in the IRQ_SRC register, and
+ * also for masking the IRQs in the IRQ_MSK register.
+ */
+#define SX9500_CLOSE_IRQ		BIT(6)
+#define SX9500_FAR_IRQ			BIT(5)
+#define SX9500_CONVDONE_IRQ		BIT(3)
+
+#define SX9500_PROXSTAT_SHIFT		4
+
+#define SX9500_NUM_CHANNELS		4
+
+struct sx9500_data {
+	struct mutex mutex;
+	struct i2c_client *client;
+	struct iio_trigger *trig;
+	struct regmap *regmap;
+	/*
+	 * Last reading of the proximity status for each channel.  We
+	 * only send an event to user space when this changes.
+	 */
+	bool prox_stat[SX9500_NUM_CHANNELS];
+	bool event_enabled[SX9500_NUM_CHANNELS];
+	bool trigger_enabled;
+	u16 *buffer;
+};
+
+static const struct iio_event_spec sx9500_events[] = {
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_EITHER,
+		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
+	},
+};
+
+#define SX9500_CHANNEL(idx)					\
+	{							\
+		.type = IIO_PROXIMITY,				\
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
+		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+		.indexed = 1,					\
+		.channel = idx,					\
+		.event_spec = sx9500_events,			\
+		.num_event_specs = ARRAY_SIZE(sx9500_events),	\
+		.scan_index = idx,				\
+		.scan_type = {					\
+			.sign = 'u',				\
+			.realbits = 16,				\
+			.storagebits = 16,			\
+			.shift = 0,				\
+		},						\
+	}
+
+static const struct iio_chan_spec sx9500_channels[] = {
+	SX9500_CHANNEL(0),
+	SX9500_CHANNEL(1),
+	SX9500_CHANNEL(2),
+	SX9500_CHANNEL(3),
+	IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static const struct {
+	int val;
+	int val2;
+} sx9500_samp_freq_table[] = {
+	{33, 333333},
+	{16, 666666},
+	{11, 111111},
+	{8, 333333},
+	{6, 666666},
+	{5, 0},
+	{3, 333333},
+	{2, 500000},
+};
+
+static const struct regmap_range sx9500_writable_reg_ranges[] = {
+	regmap_reg_range(SX9500_REG_IRQ_MSK, SX9500_REG_IRQ_MSK),
+	regmap_reg_range(SX9500_REG_PROX_CTRL0, SX9500_REG_PROX_CTRL8),
+	regmap_reg_range(SX9500_REG_SENSOR_SEL, SX9500_REG_SENSOR_SEL),
+	regmap_reg_range(SX9500_REG_OFFSET_MSB, SX9500_REG_OFFSET_LSB),
+	regmap_reg_range(SX9500_REG_RESET, SX9500_REG_RESET),
+};
+
+static const struct regmap_access_table sx9500_writeable_regs = {
+	.yes_ranges = sx9500_writable_reg_ranges,
+	.n_yes_ranges = ARRAY_SIZE(sx9500_writable_reg_ranges),
+};
+
+/*
+ * All allocated registers are readable, so we just list unallocated
+ * ones.
+ */
+static const struct regmap_range sx9500_non_readable_reg_ranges[] = {
+	regmap_reg_range(SX9500_REG_STAT + 1, SX9500_REG_STAT + 1),
+	regmap_reg_range(SX9500_REG_IRQ_MSK + 1, SX9500_REG_PROX_CTRL0 - 1),
+	regmap_reg_range(SX9500_REG_PROX_CTRL8 + 1, SX9500_REG_SENSOR_SEL - 1),
+	regmap_reg_range(SX9500_REG_OFFSET_LSB + 1, SX9500_REG_RESET - 1),
+};
+
+static const struct regmap_access_table sx9500_readable_regs = {
+	.no_ranges = sx9500_non_readable_reg_ranges,
+	.n_no_ranges = ARRAY_SIZE(sx9500_non_readable_reg_ranges),
+};
+
+static const struct regmap_range sx9500_volatile_reg_ranges[] = {
+	regmap_reg_range(SX9500_REG_IRQ_SRC, SX9500_REG_STAT),
+	regmap_reg_range(SX9500_REG_USE_MSB, SX9500_REG_OFFSET_LSB),
+	regmap_reg_range(SX9500_REG_RESET, SX9500_REG_RESET),
+};
+
+static const struct regmap_access_table sx9500_volatile_regs = {
+	.yes_ranges = sx9500_volatile_reg_ranges,
+	.n_yes_ranges = ARRAY_SIZE(sx9500_volatile_reg_ranges),
+};
+
+static const struct regmap_config sx9500_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = SX9500_REG_RESET,
+	.cache_type = REGCACHE_RBTREE,
+
+	.wr_table = &sx9500_writeable_regs,
+	.rd_table = &sx9500_readable_regs,
+	.volatile_table = &sx9500_volatile_regs,
+};
+
+static int sx9500_read_proximity(struct sx9500_data *data,
+				 const struct iio_chan_spec *chan,
+				 int *val)
+{
+	int ret;
+	__be16 regval;
+
+	ret = regmap_write(data->regmap, SX9500_REG_SENSOR_SEL, chan->channel);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_bulk_read(data->regmap, SX9500_REG_USE_MSB, &regval, 2);
+	if (ret < 0)
+		return ret;
+
+	*val = 32767 - (s16)be16_to_cpu(regval);
+
+	return IIO_VAL_INT;
+}
+
+static int sx9500_read_samp_freq(struct sx9500_data *data,
+				 int *val, int *val2)
+{
+	int ret;
+	unsigned int regval;
+
+	mutex_lock(&data->mutex);
+	ret = regmap_read(data->regmap, SX9500_REG_PROX_CTRL0, &regval);
+	mutex_unlock(&data->mutex);
+
+	if (ret < 0)
+		return ret;
+
+	regval = (regval & SX9500_SCAN_PERIOD_MASK) >> SX9500_SCAN_PERIOD_SHIFT;
+	*val = sx9500_samp_freq_table[regval].val;
+	*val2 = sx9500_samp_freq_table[regval].val2;
+
+	return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int sx9500_read_raw(struct iio_dev *indio_dev,
+			   const struct iio_chan_spec *chan,
+			   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;
+			mutex_lock(&data->mutex);
+			ret = sx9500_read_proximity(data, chan, val);
+			mutex_unlock(&data->mutex);
+			return ret;
+		case IIO_CHAN_INFO_SAMP_FREQ:
+			return sx9500_read_samp_freq(data, val, val2);
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static int sx9500_set_samp_freq(struct sx9500_data *data,
+				int val, int val2)
+{
+	int i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(sx9500_samp_freq_table); i++)
+		if (val == sx9500_samp_freq_table[i].val &&
+		    val2 == sx9500_samp_freq_table[i].val2)
+			break;
+
+	if (i == ARRAY_SIZE(sx9500_samp_freq_table))
+		return -EINVAL;
+
+	mutex_lock(&data->mutex);
+
+	ret = regmap_update_bits(data->regmap, SX9500_REG_PROX_CTRL0,
+				 SX9500_SCAN_PERIOD_MASK,
+				 i << SX9500_SCAN_PERIOD_SHIFT);
+
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static int sx9500_write_raw(struct iio_dev *indio_dev,
+			    const struct iio_chan_spec *chan,
+			    int val, int val2, long mask)
+{
+	struct sx9500_data *data = iio_priv(indio_dev);
+
+	switch (chan->type) {
+	case IIO_PROXIMITY:
+		switch (mask) {
+		case IIO_CHAN_INFO_SAMP_FREQ:
+			return sx9500_set_samp_freq(data, val, val2);
+		default:
+			return -EINVAL;
+		}
+	default:
+		return -EINVAL;
+	}
+}
+
+static irqreturn_t sx9500_irq_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct sx9500_data *data = iio_priv(indio_dev);
+
+	if (data->trigger_enabled)
+		iio_trigger_poll(data->trig);
+
+	/*
+	 * Even if no event is enabled, we need to wake the thread to
+	 * clear the interrupt state by reading SX9500_REG_IRQ_SRC.  It
+	 * is not possible to do that here because regmap_read takes a
+	 * mutex.
+	 */
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t sx9500_irq_thread_handler(int irq, void *private)
+{
+	struct iio_dev *indio_dev = private;
+	struct sx9500_data *data = iio_priv(indio_dev);
+	int ret;
+	unsigned int val, chan;
+
+	mutex_lock(&data->mutex);
+
+	ret = regmap_read(data->regmap, SX9500_REG_IRQ_SRC, &val);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "i2c transfer error in irq\n");
+		goto out;
+	}
+
+	if (!(val & (SX9500_CLOSE_IRQ | SX9500_FAR_IRQ)))
+		goto out;
+
+	ret = regmap_read(data->regmap, SX9500_REG_STAT, &val);
+	if (ret < 0) {
+		dev_err(&data->client->dev, "i2c transfer error in irq\n");
+		goto out;
+	}
+
+	val >>= SX9500_PROXSTAT_SHIFT;
+	for (chan = 0; chan < SX9500_NUM_CHANNELS; chan++) {
+		int dir;
+		u64 ev;
+		bool new_prox = val & BIT(chan);
+
+		if (!data->event_enabled[chan])
+			continue;
+		if (new_prox == data->prox_stat[chan])
+			/* No change on this channel. */
+			continue;
+
+		dir = new_prox ? IIO_EV_DIR_FALLING :
+			IIO_EV_DIR_RISING;
+		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
+					  chan,
+					  IIO_EV_TYPE_THRESH,
+					  dir);
+		iio_push_event(indio_dev, ev, iio_get_time_ns());
+		data->prox_stat[chan] = new_prox;
+	}
+
+out:
+	mutex_unlock(&data->mutex);
+
+	return IRQ_HANDLED;
+}
+
+static int sx9500_read_event_config(struct iio_dev *indio_dev,
+				    const struct iio_chan_spec *chan,
+				    enum iio_event_type type,
+				    enum iio_event_direction dir)
+{
+	struct sx9500_data *data = iio_priv(indio_dev);
+
+	if (chan->type != IIO_PROXIMITY || type != IIO_EV_TYPE_THRESH ||
+	    dir != IIO_EV_DIR_EITHER)
+		return -EINVAL;
+
+	return data->event_enabled[chan->channel];
+}
+
+static int sx9500_write_event_config(struct iio_dev *indio_dev,
+				     const struct iio_chan_spec *chan,
+				     enum iio_event_type type,
+				     enum iio_event_direction dir,
+				     int state)
+{
+	struct sx9500_data *data = iio_priv(indio_dev);
+	int ret, i;
+	bool any_active = false;
+	unsigned int irqmask;
+
+	if (chan->type != IIO_PROXIMITY || type != IIO_EV_TYPE_THRESH ||
+	    dir != IIO_EV_DIR_EITHER)
+		return -EINVAL;
+
+	mutex_lock(&data->mutex);
+
+	data->event_enabled[chan->channel] = state;
+
+	for (i = 0; i < SX9500_NUM_CHANNELS; i++)
+		if (data->event_enabled[i]) {
+			any_active = true;
+			break;
+		}
+
+	irqmask = SX9500_CLOSE_IRQ | SX9500_FAR_IRQ;
+	if (any_active)
+		ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
+					 irqmask, irqmask);
+	else
+		ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
+					 irqmask, 0);
+
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static int sx9500_update_scan_mode(struct iio_dev *indio_dev,
+				   const unsigned long *scan_mask)
+{
+	struct sx9500_data *data = iio_priv(indio_dev);
+
+	mutex_lock(&data->mutex);
+	kfree(data->buffer);
+	data->buffer = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
+	mutex_unlock(&data->mutex);
+
+	if (data->buffer == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
+	"2.500000 3.333333 5 6.666666 8.333333 11.111111 16.666666 33.333333");
+
+static struct attribute *sx9500_attributes[] = {
+	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group sx9500_attribute_group = {
+	.attrs = sx9500_attributes,
+};
+
+static const struct iio_info sx9500_info = {
+	.driver_module = THIS_MODULE,
+	.attrs = &sx9500_attribute_group,
+	.read_raw = &sx9500_read_raw,
+	.write_raw = &sx9500_write_raw,
+	.read_event_config = &sx9500_read_event_config,
+	.write_event_config = &sx9500_write_event_config,
+	.update_scan_mode = &sx9500_update_scan_mode,
+};
+
+static int sx9500_set_trigger_state(struct iio_trigger *trig,
+				    bool state)
+{
+	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
+	struct sx9500_data *data = iio_priv(indio_dev);
+	int ret;
+
+	mutex_lock(&data->mutex);
+
+	ret = regmap_update_bits(data->regmap, SX9500_REG_IRQ_MSK,
+				 SX9500_CONVDONE_IRQ,
+				 state ? SX9500_CONVDONE_IRQ : 0);
+	if (ret == 0)
+		data->trigger_enabled = state;
+
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
+static const struct iio_trigger_ops sx9500_trigger_ops = {
+	.set_trigger_state = sx9500_set_trigger_state,
+	.owner = THIS_MODULE,
+};
+
+static irqreturn_t sx9500_trigger_handler(int irq, void *private)
+{
+	struct iio_poll_func *pf = private;
+	struct iio_dev *indio_dev = pf->indio_dev;
+	struct sx9500_data *data = iio_priv(indio_dev);
+	int val, bit, ret, i = 0;
+
+	mutex_lock(&data->mutex);
+
+	for_each_set_bit(bit, indio_dev->buffer->scan_mask,
+			 indio_dev->masklength) {
+		ret = sx9500_read_proximity(data, &indio_dev->channels[bit],
+					    &val);
+		if (ret < 0)
+			goto out;
+
+		data->buffer[i++] = val;
+	}
+
+	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+					   iio_get_time_ns());
+
+out:
+	mutex_unlock(&data->mutex);
+
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
+}
+
+struct sx9500_reg_default {
+	u8 reg;
+	u8 def;
+};
+
+static const struct sx9500_reg_default sx9500_default_regs[] = {
+	{
+		.reg = SX9500_REG_PROX_CTRL1,
+		/* Shield enabled, small range. */
+		.def = 0x43,
+	},
+	{
+		.reg = SX9500_REG_PROX_CTRL2,
+		/* x8 gain, 167kHz frequency, finest resolution. */
+		.def = 0x77,
+	},
+	{
+		.reg = SX9500_REG_PROX_CTRL3,
+		/* Doze enabled, 2x scan period doze, no raw filter. */
+		.def = 0x40,
+	},
+	{
+		.reg = SX9500_REG_PROX_CTRL4,
+		/* Average threshold. */
+		.def = 0x30,
+	},
+	{
+		.reg = SX9500_REG_PROX_CTRL5,
+		/*
+		 * Debouncer off, lowest average negative filter,
+		 * highest average postive filter.
+		 */
+		.def = 0x0f,
+	},
+	{
+		.reg = SX9500_REG_PROX_CTRL6,
+		/* Proximity detection threshold: 280 */
+		.def = 0x0e,
+	},
+	{
+		.reg = SX9500_REG_PROX_CTRL7,
+		/*
+		 * No automatic compensation, compensate each pin
+		 * independently, proximity hysteresis: 32, close
+		 * debouncer off, far debouncer off.
+		 */
+		.def = 0x00,
+	},
+	{
+		.reg = SX9500_REG_PROX_CTRL8,
+		/* No stuck timeout, no periodic compensation. */
+		.def = 0x00,
+	},
+	{
+		.reg = SX9500_REG_PROX_CTRL0,
+		/* Scan period: 30ms, all sensors enabled. */
+		.def = 0x0f,
+	},
+};
+
+static int sx9500_init_device(struct iio_dev *indio_dev)
+{
+	struct sx9500_data *data = iio_priv(indio_dev);
+	int ret, i;
+	unsigned int val;
+
+	ret = regmap_write(data->regmap, SX9500_REG_IRQ_MSK, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_write(data->regmap, SX9500_REG_RESET,
+			   SX9500_SOFT_RESET);
+	if (ret < 0)
+		return ret;
+
+	ret = regmap_read(data->regmap, SX9500_REG_IRQ_SRC, &val);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(sx9500_default_regs); i++) {
+		ret = regmap_write(data->regmap,
+				   sx9500_default_regs[i].reg,
+				   sx9500_default_regs[i].def);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int sx9500_gpio_probe(struct i2c_client *client,
+			     struct sx9500_data *data)
+{
+	struct device *dev;
+	struct gpio_desc *gpio;
+	int ret;
+
+	if (!client)
+		return -EINVAL;
+
+	dev = &client->dev;
+
+	/* data ready gpio interrupt pin */
+	gpio = devm_gpiod_get_index(dev, SX9500_GPIO_NAME, 0);
+	if (IS_ERR(gpio)) {
+		dev_err(dev, "acpi gpio get index failed\n");
+		return PTR_ERR(gpio);
+	}
+
+	ret = gpiod_direction_input(gpio);
+	if (ret)
+		return ret;
+
+	ret = gpiod_to_irq(gpio);
+
+	dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
+
+	return ret;
+}
+
+static int sx9500_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	int ret;
+	struct iio_dev *indio_dev;
+	struct sx9500_data *data;
+
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	data = iio_priv(indio_dev);
+	data->client = client;
+	mutex_init(&data->mutex);
+	data->trigger_enabled = false;
+
+	data->regmap = devm_regmap_init_i2c(client, &sx9500_regmap_config);
+	if (IS_ERR(data->regmap))
+		return PTR_ERR(data->regmap);
+
+	sx9500_init_device(indio_dev);
+
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = SX9500_DRIVER_NAME;
+	indio_dev->channels = sx9500_channels;
+	indio_dev->num_channels = ARRAY_SIZE(sx9500_channels);
+	indio_dev->info = &sx9500_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	i2c_set_clientdata(client, indio_dev);
+
+	if (client->irq <= 0)
+		client->irq = sx9500_gpio_probe(client, data);
+
+	if (client->irq > 0) {
+		ret = devm_request_threaded_irq(&client->dev, client->irq,
+				sx9500_irq_handler, sx9500_irq_thread_handler,
+				IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+				SX9500_IRQ_NAME, indio_dev);
+		if (ret < 0)
+			return ret;
+
+		data->trig = devm_iio_trigger_alloc(&client->dev,
+				"%s-dev%d", indio_dev->name, indio_dev->id);
+		if (!data->trig)
+			return -ENOMEM;
+
+		data->trig->dev.parent = &client->dev;
+		data->trig->ops = &sx9500_trigger_ops;
+		iio_trigger_set_drvdata(data->trig, indio_dev);
+
+		ret = iio_trigger_register(data->trig);
+		if (ret)
+			return ret;
+	}
+
+	ret = iio_triggered_buffer_setup(indio_dev, NULL,
+					 sx9500_trigger_handler, NULL);
+	if (ret < 0)
+		goto out_trigger_unregister;
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		goto out_buffer_cleanup;
+
+	return 0;
+
+out_buffer_cleanup:
+	iio_triggered_buffer_cleanup(indio_dev);
+out_trigger_unregister:
+	if (client->irq > 0)
+		iio_trigger_unregister(data->trig);
+
+	return ret;
+}
+
+static int sx9500_remove(struct i2c_client *client)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct sx9500_data *data = iio_priv(indio_dev);
+
+	iio_device_unregister(indio_dev);
+	iio_triggered_buffer_cleanup(indio_dev);
+	if (client->irq > 0)
+		iio_trigger_unregister(data->trig);
+	kfree(data->buffer);
+
+	return 0;
+}
+
+static const struct acpi_device_id sx9500_acpi_match[] = {
+	{"SSX9500", 0},
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, sx9500_acpi_match);
+
+static const struct i2c_device_id sx9500_id[] = {
+	{"sx9500", 0},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, sx9500_id);
+
+static struct i2c_driver sx9500_driver = {
+	.driver = {
+		.name	= SX9500_DRIVER_NAME,
+		.acpi_match_table = ACPI_PTR(sx9500_acpi_match),
+	},
+	.probe		= sx9500_probe,
+	.remove		= sx9500_remove,
+	.id_table	= sx9500_id,
+};
+module_i2c_driver(sx9500_driver);
+
+MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
+MODULE_DESCRIPTION("Driver for Semtech SX9500 proximity sensor");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c
index 254c7e906127..3dfab2bc6d69 100644
--- a/drivers/iio/trigger/iio-trig-sysfs.c
+++ b/drivers/iio/trigger/iio-trig-sysfs.c
@@ -135,6 +135,7 @@ static int iio_sysfs_trigger_probe(int id)
 	struct iio_sysfs_trig *t;
 	int ret;
 	bool foundit = false;
+
 	mutex_lock(&iio_sysfs_trig_list_mut);
 	list_for_each_entry(t, &iio_sysfs_trig_list, l)
 		if (id == t->id) {
@@ -185,6 +186,7 @@ static int iio_sysfs_trigger_remove(int id)
 {
 	bool foundit = false;
 	struct iio_sysfs_trig *t;
+
 	mutex_lock(&iio_sysfs_trig_list_mut);
 	list_for_each_entry(t, &iio_sysfs_trig_list, l)
 		if (id == t->id) {
diff --git a/drivers/message/Makefile b/drivers/message/Makefile
index 97ef5a01ad11..755676ded67c 100644
--- a/drivers/message/Makefile
+++ b/drivers/message/Makefile
@@ -2,5 +2,4 @@
 # Makefile for MPT based block devices
 #
 
-obj-$(CONFIG_I2O)	+= i2o/
 obj-$(CONFIG_FUSION)	+= fusion/
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 9049dd91b569..45baa83be7ce 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -56,6 +56,8 @@ source "drivers/staging/vt6656/Kconfig"
 
 source "drivers/staging/iio/Kconfig"
 
+source "drivers/staging/sm7xxfb/Kconfig"
+
 source "drivers/staging/xgifb/Kconfig"
 
 source "drivers/staging/emxx_udc/Kconfig"
@@ -64,8 +66,6 @@ source "drivers/staging/ft1000/Kconfig"
 
 source "drivers/staging/speakup/Kconfig"
 
-source "drivers/staging/cptm1217/Kconfig"
-
 source "drivers/staging/ste_rmi4/Kconfig"
 
 source "drivers/staging/nvec/Kconfig"
@@ -104,4 +104,8 @@ source "drivers/staging/unisys/Kconfig"
 
 source "drivers/staging/clocking-wizard/Kconfig"
 
+source "drivers/staging/fbtft/Kconfig"
+
+source "drivers/staging/i2o/Kconfig"
+
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index fe26ff162b42..29160790841f 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -22,11 +22,11 @@ obj-$(CONFIG_VT6655)		+= vt6655/
 obj-$(CONFIG_VT6656)		+= vt6656/
 obj-$(CONFIG_VME_BUS)		+= vme/
 obj-$(CONFIG_IIO)		+= iio/
+obj-$(CONFIG_FB_SM7XX)		+= sm7xxfb/
 obj-$(CONFIG_FB_XGI)		+= xgifb/
 obj-$(CONFIG_USB_EMXX)		+= emxx_udc/
 obj-$(CONFIG_FT1000)		+= ft1000/
 obj-$(CONFIG_SPEAKUP)		+= speakup/
-obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217)	+= cptm1217/
 obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)	+= ste_rmi4/
 obj-$(CONFIG_MFD_NVEC)		+= nvec/
 obj-$(CONFIG_ANDROID)		+= android/
@@ -44,3 +44,5 @@ obj-$(CONFIG_GS_FPGABOOT)	+= gs_fpgaboot/
 obj-$(CONFIG_CRYPTO_SKEIN)	+= skein/
 obj-$(CONFIG_UNISYSSPAR)	+= unisys/
 obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)	+= clocking-wizard/
+obj-$(CONFIG_FB_TFT)		+= fbtft/
+obj-$(CONFIG_I2O)		+= i2o/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 7e012f37792b..8feb9048e62f 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -14,23 +14,6 @@ config ASHMEM
 	  It is, in theory, a good memory allocator for low-memory devices,
 	  because it can discard shared memory units when under memory pressure.
 
-config ANDROID_LOGGER
-	tristate "Android log driver"
-	default n
-	---help---
-	  This adds support for system-wide logging using four log buffers.
-
-	  These are:
-
-	      1: main
-	      2: events
-	      3: radio
-	      4: system
-
-	  Log reading and writing is performed via normal Linux reads and
-	  optimized writes. This optimization avoids logging having too
-	  much overhead in the system.
-
 config ANDROID_TIMED_OUTPUT
 	bool "Timed output class driver"
 	default y
@@ -45,15 +28,6 @@ config ANDROID_LOW_MEMORY_KILLER
 	---help---
 	  Registers processes to be killed when memory is low
 
-config ANDROID_INTF_ALARM_DEV
-	tristate "Android alarm driver"
-	depends on RTC_CLASS
-	default n
-	---help---
-	  Provides non-wakeup and rtc backed wakeup alarms based on rtc or
-	  elapsed realtime, and a non-wakeup alarm on the monotonic clock.
-	  Also exports the alarm interface to user-space.
-
 config SYNC
 	bool "Synchronization framework"
 	default n
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile
index 479b2b86f8c8..c7b6c99cc5ce 100644
--- a/drivers/staging/android/Makefile
+++ b/drivers/staging/android/Makefile
@@ -3,10 +3,8 @@ ccflags-y += -I$(src)			# needed for trace events
 obj-y					+= ion/
 
 obj-$(CONFIG_ASHMEM)			+= ashmem.o
-obj-$(CONFIG_ANDROID_LOGGER)		+= logger.o
 obj-$(CONFIG_ANDROID_TIMED_OUTPUT)	+= timed_output.o
 obj-$(CONFIG_ANDROID_TIMED_GPIO)	+= timed_gpio.o
 obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER)	+= lowmemorykiller.o
-obj-$(CONFIG_ANDROID_INTF_ALARM_DEV)	+= alarm-dev.o
 obj-$(CONFIG_SYNC)			+= sync.o sync_debug.o
 obj-$(CONFIG_SW_SYNC)			+= sw_sync.o
diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c
deleted file mode 100644
index ff4b3e8758a7..000000000000
--- a/drivers/staging/android/alarm-dev.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/* drivers/rtc/alarm-dev.c
- *
- * Copyright (C) 2007-2009 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/time.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/uaccess.h>
-#include <linux/alarmtimer.h>
-#include "android_alarm.h"
-
-#define ANDROID_ALARM_PRINT_INFO (1U << 0)
-#define ANDROID_ALARM_PRINT_IO (1U << 1)
-#define ANDROID_ALARM_PRINT_INT (1U << 2)
-
-static int debug_mask = ANDROID_ALARM_PRINT_INFO;
-module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
-
-#define alarm_dbg(debug_level_mask, fmt, ...)				\
-do {									\
-	if (debug_mask & ANDROID_ALARM_PRINT_##debug_level_mask)	\
-		pr_info(fmt, ##__VA_ARGS__);				\
-} while (0)
-
-#define ANDROID_ALARM_WAKEUP_MASK ( \
-	ANDROID_ALARM_RTC_WAKEUP_MASK | \
-	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK)
-
-static int alarm_opened;
-static DEFINE_SPINLOCK(alarm_slock);
-static struct wakeup_source alarm_wake_lock;
-static DECLARE_WAIT_QUEUE_HEAD(alarm_wait_queue);
-static uint32_t alarm_pending;
-static uint32_t alarm_enabled;
-static uint32_t wait_pending;
-
-struct devalarm {
-	union {
-		struct hrtimer hrt;
-		struct alarm alrm;
-	} u;
-	enum android_alarm_type type;
-};
-
-static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT];
-
-/**
- * is_wakeup() - Checks to see if this alarm can wake the device
- * @type:	 The type of alarm being checked
- *
- * Return: 1 if this is a wakeup alarm, otherwise 0
- */
-static int is_wakeup(enum android_alarm_type type)
-{
-	return type == ANDROID_ALARM_RTC_WAKEUP ||
-		type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP;
-}
-
-static void devalarm_start(struct devalarm *alrm, ktime_t exp)
-{
-	if (is_wakeup(alrm->type))
-		alarm_start(&alrm->u.alrm, exp);
-	else
-		hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS);
-}
-
-static int devalarm_try_to_cancel(struct devalarm *alrm)
-{
-	if (is_wakeup(alrm->type))
-		return alarm_try_to_cancel(&alrm->u.alrm);
-	return hrtimer_try_to_cancel(&alrm->u.hrt);
-}
-
-static void devalarm_cancel(struct devalarm *alrm)
-{
-	if (is_wakeup(alrm->type))
-		alarm_cancel(&alrm->u.alrm);
-	else
-		hrtimer_cancel(&alrm->u.hrt);
-}
-
-static void alarm_clear(enum android_alarm_type alarm_type)
-{
-	uint32_t alarm_type_mask = 1U << alarm_type;
-	unsigned long flags;
-
-	spin_lock_irqsave(&alarm_slock, flags);
-	alarm_dbg(IO, "alarm %d clear\n", alarm_type);
-	devalarm_try_to_cancel(&alarms[alarm_type]);
-	if (alarm_pending) {
-		alarm_pending &= ~alarm_type_mask;
-		if (!alarm_pending && !wait_pending)
-			__pm_relax(&alarm_wake_lock);
-	}
-	alarm_enabled &= ~alarm_type_mask;
-	spin_unlock_irqrestore(&alarm_slock, flags);
-}
-
-static void alarm_set(enum android_alarm_type alarm_type,
-							struct timespec *ts)
-{
-	uint32_t alarm_type_mask = 1U << alarm_type;
-	unsigned long flags;
-
-	spin_lock_irqsave(&alarm_slock, flags);
-	alarm_dbg(IO, "alarm %d set %ld.%09ld\n",
-			alarm_type, ts->tv_sec, ts->tv_nsec);
-	alarm_enabled |= alarm_type_mask;
-	devalarm_start(&alarms[alarm_type], timespec_to_ktime(*ts));
-	spin_unlock_irqrestore(&alarm_slock, flags);
-}
-
-static int alarm_wait(void)
-{
-	unsigned long flags;
-	int rv = 0;
-
-	spin_lock_irqsave(&alarm_slock, flags);
-	alarm_dbg(IO, "alarm wait\n");
-	if (!alarm_pending && wait_pending) {
-		__pm_relax(&alarm_wake_lock);
-		wait_pending = 0;
-	}
-	spin_unlock_irqrestore(&alarm_slock, flags);
-
-	rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
-	if (rv)
-		return rv;
-
-	spin_lock_irqsave(&alarm_slock, flags);
-	rv = alarm_pending;
-	wait_pending = 1;
-	alarm_pending = 0;
-	spin_unlock_irqrestore(&alarm_slock, flags);
-
-	return rv;
-}
-
-static int alarm_set_rtc(struct timespec *ts)
-{
-	struct rtc_time new_rtc_tm;
-	struct rtc_device *rtc_dev;
-	unsigned long flags;
-	int rv = 0;
-
-	rtc_time_to_tm(ts->tv_sec, &new_rtc_tm);
-	rtc_dev = alarmtimer_get_rtcdev();
-	rv = do_settimeofday(ts);
-	if (rv < 0)
-		return rv;
-	if (rtc_dev)
-		rv = rtc_set_time(rtc_dev, &new_rtc_tm);
-
-	spin_lock_irqsave(&alarm_slock, flags);
-	alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
-	wake_up(&alarm_wait_queue);
-	spin_unlock_irqrestore(&alarm_slock, flags);
-
-	return rv;
-}
-
-static int alarm_get_time(enum android_alarm_type alarm_type,
-							struct timespec *ts)
-{
-	int rv = 0;
-
-	switch (alarm_type) {
-	case ANDROID_ALARM_RTC_WAKEUP:
-	case ANDROID_ALARM_RTC:
-		getnstimeofday(ts);
-		break;
-	case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
-	case ANDROID_ALARM_ELAPSED_REALTIME:
-		get_monotonic_boottime(ts);
-		break;
-	case ANDROID_ALARM_SYSTEMTIME:
-		ktime_get_ts(ts);
-		break;
-	default:
-		rv = -EINVAL;
-	}
-	return rv;
-}
-
-static long alarm_do_ioctl(struct file *file, unsigned int cmd,
-							struct timespec *ts)
-{
-	int rv = 0;
-	unsigned long flags;
-	enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
-
-	if (alarm_type >= ANDROID_ALARM_TYPE_COUNT)
-		return -EINVAL;
-
-	if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) {
-		if ((file->f_flags & O_ACCMODE) == O_RDONLY)
-			return -EPERM;
-		if (file->private_data == NULL &&
-		    cmd != ANDROID_ALARM_SET_RTC) {
-			spin_lock_irqsave(&alarm_slock, flags);
-			if (alarm_opened) {
-				spin_unlock_irqrestore(&alarm_slock, flags);
-				return -EBUSY;
-			}
-			alarm_opened = 1;
-			file->private_data = (void *)1;
-			spin_unlock_irqrestore(&alarm_slock, flags);
-		}
-	}
-
-	switch (ANDROID_ALARM_BASE_CMD(cmd)) {
-	case ANDROID_ALARM_CLEAR(0):
-		alarm_clear(alarm_type);
-		break;
-	case ANDROID_ALARM_SET(0):
-		alarm_set(alarm_type, ts);
-		break;
-	case ANDROID_ALARM_SET_AND_WAIT(0):
-		alarm_set(alarm_type, ts);
-		/* fall though */
-	case ANDROID_ALARM_WAIT:
-		rv = alarm_wait();
-		break;
-	case ANDROID_ALARM_SET_RTC:
-		rv = alarm_set_rtc(ts);
-		break;
-	case ANDROID_ALARM_GET_TIME(0):
-		rv = alarm_get_time(alarm_type, ts);
-		break;
-
-	default:
-		rv = -EINVAL;
-	}
-	return rv;
-}
-
-static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-
-	struct timespec ts;
-	int rv;
-
-	switch (ANDROID_ALARM_BASE_CMD(cmd)) {
-	case ANDROID_ALARM_SET_AND_WAIT(0):
-	case ANDROID_ALARM_SET(0):
-	case ANDROID_ALARM_SET_RTC:
-		if (copy_from_user(&ts, (void __user *)arg, sizeof(ts)))
-			return -EFAULT;
-		break;
-	}
-
-	rv = alarm_do_ioctl(file, cmd, &ts);
-	if (rv)
-		return rv;
-
-	switch (ANDROID_ALARM_BASE_CMD(cmd)) {
-	case ANDROID_ALARM_GET_TIME(0):
-		if (copy_to_user((void __user *)arg, &ts, sizeof(ts)))
-			return -EFAULT;
-		break;
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_COMPAT
-static long alarm_compat_ioctl(struct file *file, unsigned int cmd,
-							unsigned long arg)
-{
-
-	struct timespec ts;
-	int rv;
-
-	switch (ANDROID_ALARM_BASE_CMD(cmd)) {
-	case ANDROID_ALARM_SET_AND_WAIT_COMPAT(0):
-	case ANDROID_ALARM_SET_COMPAT(0):
-	case ANDROID_ALARM_SET_RTC_COMPAT:
-		if (compat_get_timespec(&ts, (void __user *)arg))
-			return -EFAULT;
-		/* fall through */
-	case ANDROID_ALARM_GET_TIME_COMPAT(0):
-		cmd = ANDROID_ALARM_COMPAT_TO_NORM(cmd);
-		break;
-	}
-
-	rv = alarm_do_ioctl(file, cmd, &ts);
-	if (rv)
-		return rv;
-
-	switch (ANDROID_ALARM_BASE_CMD(cmd)) {
-	case ANDROID_ALARM_GET_TIME(0): /* NOTE: we modified cmd above */
-		if (compat_put_timespec(&ts, (void __user *)arg))
-			return -EFAULT;
-		break;
-	}
-
-	return 0;
-}
-#endif
-
-static int alarm_open(struct inode *inode, struct file *file)
-{
-	file->private_data = NULL;
-	return 0;
-}
-
-static int alarm_release(struct inode *inode, struct file *file)
-{
-	int i;
-	unsigned long flags;
-
-	spin_lock_irqsave(&alarm_slock, flags);
-	if (file->private_data) {
-		for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
-			uint32_t alarm_type_mask = 1U << i;
-
-			if (alarm_enabled & alarm_type_mask) {
-				alarm_dbg(INFO,
-					  "%s: clear alarm, pending %d\n",
-					  __func__,
-					  !!(alarm_pending & alarm_type_mask));
-				alarm_enabled &= ~alarm_type_mask;
-			}
-			spin_unlock_irqrestore(&alarm_slock, flags);
-			devalarm_cancel(&alarms[i]);
-			spin_lock_irqsave(&alarm_slock, flags);
-		}
-		if (alarm_pending | wait_pending) {
-			if (alarm_pending)
-				alarm_dbg(INFO, "%s: clear pending alarms %x\n",
-					  __func__, alarm_pending);
-			__pm_relax(&alarm_wake_lock);
-			wait_pending = 0;
-			alarm_pending = 0;
-		}
-		alarm_opened = 0;
-	}
-	spin_unlock_irqrestore(&alarm_slock, flags);
-	return 0;
-}
-
-static void devalarm_triggered(struct devalarm *alarm)
-{
-	unsigned long flags;
-	uint32_t alarm_type_mask = 1U << alarm->type;
-
-	alarm_dbg(INT, "%s: type %d\n", __func__, alarm->type);
-	spin_lock_irqsave(&alarm_slock, flags);
-	if (alarm_enabled & alarm_type_mask) {
-		__pm_wakeup_event(&alarm_wake_lock, 5000); /* 5secs */
-		alarm_enabled &= ~alarm_type_mask;
-		alarm_pending |= alarm_type_mask;
-		wake_up(&alarm_wait_queue);
-	}
-	spin_unlock_irqrestore(&alarm_slock, flags);
-}
-
-static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt)
-{
-	struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt);
-
-	devalarm_triggered(devalrm);
-	return HRTIMER_NORESTART;
-}
-
-static enum alarmtimer_restart devalarm_alarmhandler(struct alarm *alrm,
-							ktime_t now)
-{
-	struct devalarm *devalrm = container_of(alrm, struct devalarm, u.alrm);
-
-	devalarm_triggered(devalrm);
-	return ALARMTIMER_NORESTART;
-}
-
-
-static const struct file_operations alarm_fops = {
-	.owner = THIS_MODULE,
-	.unlocked_ioctl = alarm_ioctl,
-	.open = alarm_open,
-	.release = alarm_release,
-#ifdef CONFIG_COMPAT
-	.compat_ioctl = alarm_compat_ioctl,
-#endif
-};
-
-static struct miscdevice alarm_device = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = "alarm",
-	.fops = &alarm_fops,
-};
-
-static int __init alarm_dev_init(void)
-{
-	int err;
-	int i;
-
-	err = misc_register(&alarm_device);
-	if (err)
-		return err;
-
-	alarm_init(&alarms[ANDROID_ALARM_RTC_WAKEUP].u.alrm,
-			ALARM_REALTIME, devalarm_alarmhandler);
-	hrtimer_init(&alarms[ANDROID_ALARM_RTC].u.hrt,
-			CLOCK_REALTIME, HRTIMER_MODE_ABS);
-	alarm_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].u.alrm,
-			ALARM_BOOTTIME, devalarm_alarmhandler);
-	hrtimer_init(&alarms[ANDROID_ALARM_ELAPSED_REALTIME].u.hrt,
-			CLOCK_BOOTTIME, HRTIMER_MODE_ABS);
-	hrtimer_init(&alarms[ANDROID_ALARM_SYSTEMTIME].u.hrt,
-			CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-
-	for (i = 0; i < ANDROID_ALARM_TYPE_COUNT; i++) {
-		alarms[i].type = i;
-		if (!is_wakeup(i))
-			alarms[i].u.hrt.function = devalarm_hrthandler;
-	}
-
-	wakeup_source_init(&alarm_wake_lock, "alarm");
-	return 0;
-}
-
-static void  __exit alarm_dev_exit(void)
-{
-	misc_deregister(&alarm_device);
-	wakeup_source_trash(&alarm_wake_lock);
-}
-
-module_init(alarm_dev_init);
-module_exit(alarm_dev_exit);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h
deleted file mode 100644
index 495b20cf3bf6..000000000000
--- a/drivers/staging/android/android_alarm.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* include/linux/android_alarm.h
- *
- * Copyright (C) 2006-2007 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.
- *
- */
-
-#ifndef _LINUX_ANDROID_ALARM_H
-#define _LINUX_ANDROID_ALARM_H
-
-#include <linux/compat.h>
-#include <linux/ioctl.h>
-
-#include "uapi/android_alarm.h"
-
-#ifdef CONFIG_COMPAT
-#define ANDROID_ALARM_SET_COMPAT(type)		ALARM_IOW(2, type, \
-							struct compat_timespec)
-#define ANDROID_ALARM_SET_AND_WAIT_COMPAT(type)	ALARM_IOW(3, type, \
-							struct compat_timespec)
-#define ANDROID_ALARM_GET_TIME_COMPAT(type)	ALARM_IOW(4, type, \
-							struct compat_timespec)
-#define ANDROID_ALARM_SET_RTC_COMPAT		_IOW('a', 5, \
-							struct compat_timespec)
-#define ANDROID_ALARM_IOCTL_NR(cmd)		(_IOC_NR(cmd) & ((1<<4)-1))
-#define ANDROID_ALARM_COMPAT_TO_NORM(cmd)  \
-				ALARM_IOW(ANDROID_ALARM_IOCTL_NR(cmd), \
-					ANDROID_ALARM_IOCTL_TO_TYPE(cmd), \
-					struct timespec)
-
-#endif
-
-#endif
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 8c7852742f4b..d140b733940c 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -447,8 +447,8 @@ ashmem_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
 		loff_t end = (range->pgend + 1) * PAGE_SIZE;
 
 		vfs_fallocate(range->asma->file,
-				FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
-				start, end - start);
+			      FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+			      start, end - start);
 		range->purged = ASHMEM_WAS_PURGED;
 		lru_del(range);
 
@@ -549,7 +549,6 @@ static int get_name(struct ashmem_area *asma, void __user *name)
 
 	mutex_lock(&ashmem_mutex);
 	if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0') {
-
 		/*
 		 * Copying only `len', instead of ASHMEM_NAME_LEN, bytes
 		 * prevents us from revealing one user's stack to another.
@@ -751,10 +750,10 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 
 	switch (cmd) {
 	case ASHMEM_SET_NAME:
-		ret = set_name(asma, (void __user *) arg);
+		ret = set_name(asma, (void __user *)arg);
 		break;
 	case ASHMEM_GET_NAME:
-		ret = get_name(asma, (void __user *) arg);
+		ret = get_name(asma, (void __user *)arg);
 		break;
 	case ASHMEM_SET_SIZE:
 		ret = -EINVAL;
@@ -775,7 +774,7 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	case ASHMEM_PIN:
 	case ASHMEM_UNPIN:
 	case ASHMEM_GET_PIN_STATUS:
-		ret = ashmem_pin_unpin(asma, cmd, (void __user *) arg);
+		ret = ashmem_pin_unpin(asma, cmd, (void __user *)arg);
 		break;
 	case ASHMEM_PURGE_ALL_CACHES:
 		ret = -EPERM;
@@ -798,7 +797,6 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 static long compat_ashmem_ioctl(struct file *file, unsigned int cmd,
 				unsigned long arg)
 {
-
 	switch (cmd) {
 	case COMPAT_ASHMEM_SET_SIZE:
 		cmd = ASHMEM_SET_SIZE;
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 296d347660fc..b8f1c491553e 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -1508,6 +1508,9 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
 		pr_err("%s: can not add heap with invalid ops struct.\n",
 		       __func__);
 
+	spin_lock_init(&heap->free_lock);
+	heap->free_list_size = 0;
+
 	if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
 		ion_heap_init_deferred_free(heap);
 
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index f8cabcbc39e5..f4211f1be488 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -39,24 +39,6 @@ struct ion_cma_buffer_info {
 	struct sg_table *table;
 };
 
-/*
- * Create scatter-list for the already allocated DMA buffer.
- * This function could be replaced by dma_common_get_sgtable
- * as soon as it will avalaible.
- */
-static int ion_cma_get_sgtable(struct device *dev, struct sg_table *sgt,
-			       void *cpu_addr, dma_addr_t handle, size_t size)
-{
-	struct page *page = virt_to_page(cpu_addr);
-	int ret;
-
-	ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
-	if (unlikely(ret))
-		return ret;
-
-	sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
-	return 0;
-}
 
 /* ION CMA heap operations functions */
 static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
@@ -91,7 +73,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
 	if (!info->table)
 		goto free_mem;
 
-	if (ion_cma_get_sgtable
+	if (dma_common_get_sgtable
 	    (dev, info->table, info->cpu_addr, info->handle, len))
 		goto free_table;
 	/* keep this for memory release */
diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c
index 4605e04712aa..fd13d05b538a 100644
--- a/drivers/staging/android/ion/ion_heap.c
+++ b/drivers/staging/android/ion/ion_heap.c
@@ -253,8 +253,6 @@ int ion_heap_init_deferred_free(struct ion_heap *heap)
 	struct sched_param param = { .sched_priority = 0 };
 
 	INIT_LIST_HEAD(&heap->free_list);
-	heap->free_list_size = 0;
-	spin_lock_init(&heap->free_lock);
 	init_waitqueue_head(&heap->waitqueue);
 	heap->task = kthread_run(ion_heap_deferred_free, heap,
 				 "%s", heap->name);
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
deleted file mode 100644
index a673ffa34aa3..000000000000
--- a/drivers/staging/android/logger.c
+++ /dev/null
@@ -1,808 +0,0 @@
-/*
- * drivers/misc/logger.c
- *
- * A Logging Subsystem
- *
- * Copyright (C) 2007-2008 Google, Inc.
- *
- * Robert Love <rlove@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#define pr_fmt(fmt) "logger: " fmt
-
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/vmalloc.h>
-#include <linux/aio.h>
-#include "logger.h"
-
-#include <asm/ioctls.h>
-
-/**
- * struct logger_log - represents a specific log, such as 'main' or 'radio'
- * @buffer:	The actual ring buffer
- * @misc:	The "misc" device representing the log
- * @wq:		The wait queue for @readers
- * @readers:	This log's readers
- * @mutex:	The mutex that protects the @buffer
- * @w_off:	The current write head offset
- * @head:	The head, or location that readers start reading at.
- * @size:	The size of the log
- * @logs:	The list of log channels
- *
- * This structure lives from module insertion until module removal, so it does
- * not need additional reference counting. The structure is protected by the
- * mutex 'mutex'.
- */
-struct logger_log {
-	unsigned char		*buffer;
-	struct miscdevice	misc;
-	wait_queue_head_t	wq;
-	struct list_head	readers;
-	struct mutex		mutex;
-	size_t			w_off;
-	size_t			head;
-	size_t			size;
-	struct list_head	logs;
-};
-
-static LIST_HEAD(log_list);
-
-
-/**
- * struct logger_reader - a logging device open for reading
- * @log:	The associated log
- * @list:	The associated entry in @logger_log's list
- * @r_off:	The current read head offset.
- * @r_all:	Reader can read all entries
- * @r_ver:	Reader ABI version
- *
- * This object lives from open to release, so we don't need additional
- * reference counting. The structure is protected by log->mutex.
- */
-struct logger_reader {
-	struct logger_log	*log;
-	struct list_head	list;
-	size_t			r_off;
-	bool			r_all;
-	int			r_ver;
-};
-
-/* logger_offset - returns index 'n' into the log via (optimized) modulus */
-static size_t logger_offset(struct logger_log *log, size_t n)
-{
-	return n & (log->size - 1);
-}
-
-
-/*
- * file_get_log - Given a file structure, return the associated log
- *
- * This isn't aesthetic. We have several goals:
- *
- *	1) Need to quickly obtain the associated log during an I/O operation
- *	2) Readers need to maintain state (logger_reader)
- *	3) Writers need to be very fast (open() should be a near no-op)
- *
- * In the reader case, we can trivially go file->logger_reader->logger_log.
- * For a writer, we don't want to maintain a logger_reader, so we just go
- * file->logger_log. Thus what file->private_data points at depends on whether
- * or not the file was opened for reading. This function hides that dirtiness.
- */
-static inline struct logger_log *file_get_log(struct file *file)
-{
-	if (file->f_mode & FMODE_READ) {
-		struct logger_reader *reader = file->private_data;
-
-		return reader->log;
-	}
-	return file->private_data;
-}
-
-/*
- * get_entry_header - returns a pointer to the logger_entry header within
- * 'log' starting at offset 'off'. A temporary logger_entry 'scratch' must
- * be provided. Typically the return value will be a pointer within
- * 'logger->buf'.  However, a pointer to 'scratch' may be returned if
- * the log entry spans the end and beginning of the circular buffer.
- */
-static struct logger_entry *get_entry_header(struct logger_log *log,
-		size_t off, struct logger_entry *scratch)
-{
-	size_t len = min(sizeof(struct logger_entry), log->size - off);
-
-	if (len != sizeof(struct logger_entry)) {
-		memcpy(((void *) scratch), log->buffer + off, len);
-		memcpy(((void *) scratch) + len, log->buffer,
-			sizeof(struct logger_entry) - len);
-		return scratch;
-	}
-
-	return (struct logger_entry *) (log->buffer + off);
-}
-
-/*
- * get_entry_msg_len - Grabs the length of the message of the entry
- * starting from from 'off'.
- *
- * An entry length is 2 bytes (16 bits) in host endian order.
- * In the log, the length does not include the size of the log entry structure.
- * This function returns the size including the log entry structure.
- *
- * Caller needs to hold log->mutex.
- */
-static __u32 get_entry_msg_len(struct logger_log *log, size_t off)
-{
-	struct logger_entry scratch;
-	struct logger_entry *entry;
-
-	entry = get_entry_header(log, off, &scratch);
-	return entry->len;
-}
-
-static size_t get_user_hdr_len(int ver)
-{
-	if (ver < 2)
-		return sizeof(struct user_logger_entry_compat);
-	return sizeof(struct logger_entry);
-}
-
-static ssize_t copy_header_to_user(int ver, struct logger_entry *entry,
-					 char __user *buf)
-{
-	void *hdr;
-	size_t hdr_len;
-	struct user_logger_entry_compat v1;
-
-	if (ver < 2) {
-		v1.len      = entry->len;
-		v1.__pad    = 0;
-		v1.pid      = entry->pid;
-		v1.tid      = entry->tid;
-		v1.sec      = entry->sec;
-		v1.nsec     = entry->nsec;
-		hdr         = &v1;
-		hdr_len     = sizeof(struct user_logger_entry_compat);
-	} else {
-		hdr         = entry;
-		hdr_len     = sizeof(struct logger_entry);
-	}
-
-	return copy_to_user(buf, hdr, hdr_len);
-}
-
-/*
- * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the
- * user-space buffer 'buf'. Returns 'count' on success.
- *
- * Caller must hold log->mutex.
- */
-static ssize_t do_read_log_to_user(struct logger_log *log,
-				   struct logger_reader *reader,
-				   char __user *buf,
-				   size_t count)
-{
-	struct logger_entry scratch;
-	struct logger_entry *entry;
-	size_t len;
-	size_t msg_start;
-
-	/*
-	 * First, copy the header to userspace, using the version of
-	 * the header requested
-	 */
-	entry = get_entry_header(log, reader->r_off, &scratch);
-	if (copy_header_to_user(reader->r_ver, entry, buf))
-		return -EFAULT;
-
-	count -= get_user_hdr_len(reader->r_ver);
-	buf += get_user_hdr_len(reader->r_ver);
-	msg_start = logger_offset(log,
-		reader->r_off + sizeof(struct logger_entry));
-
-	/*
-	 * We read from the msg in two disjoint operations. First, we read from
-	 * the current msg head offset up to 'count' bytes or to the end of
-	 * the log, whichever comes first.
-	 */
-	len = min(count, log->size - msg_start);
-	if (copy_to_user(buf, log->buffer + msg_start, len))
-		return -EFAULT;
-
-	/*
-	 * Second, we read any remaining bytes, starting back at the head of
-	 * the log.
-	 */
-	if (count != len)
-		if (copy_to_user(buf + len, log->buffer, count - len))
-			return -EFAULT;
-
-	reader->r_off = logger_offset(log, reader->r_off +
-		sizeof(struct logger_entry) + count);
-
-	return count + get_user_hdr_len(reader->r_ver);
-}
-
-/*
- * get_next_entry_by_uid - Starting at 'off', returns an offset into
- * 'log->buffer' which contains the first entry readable by 'euid'
- */
-static size_t get_next_entry_by_uid(struct logger_log *log,
-		size_t off, kuid_t euid)
-{
-	while (off != log->w_off) {
-		struct logger_entry *entry;
-		struct logger_entry scratch;
-		size_t next_len;
-
-		entry = get_entry_header(log, off, &scratch);
-
-		if (uid_eq(entry->euid, euid))
-			return off;
-
-		next_len = sizeof(struct logger_entry) + entry->len;
-		off = logger_offset(log, off + next_len);
-	}
-
-	return off;
-}
-
-/*
- * logger_read - our log's read() method
- *
- * Behavior:
- *
- *	- O_NONBLOCK works
- *	- If there are no log entries to read, blocks until log is written to
- *	- Atomically reads exactly one log entry
- *
- * Will set errno to EINVAL if read
- * buffer is insufficient to hold next entry.
- */
-static ssize_t logger_read(struct file *file, char __user *buf,
-			   size_t count, loff_t *pos)
-{
-	struct logger_reader *reader = file->private_data;
-	struct logger_log *log = reader->log;
-	ssize_t ret;
-	DEFINE_WAIT(wait);
-
-start:
-	while (1) {
-		mutex_lock(&log->mutex);
-
-		prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE);
-
-		ret = (log->w_off == reader->r_off);
-		mutex_unlock(&log->mutex);
-		if (!ret)
-			break;
-
-		if (file->f_flags & O_NONBLOCK) {
-			ret = -EAGAIN;
-			break;
-		}
-
-		if (signal_pending(current)) {
-			ret = -EINTR;
-			break;
-		}
-
-		schedule();
-	}
-
-	finish_wait(&log->wq, &wait);
-	if (ret)
-		return ret;
-
-	mutex_lock(&log->mutex);
-
-	if (!reader->r_all)
-		reader->r_off = get_next_entry_by_uid(log,
-			reader->r_off, current_euid());
-
-	/* is there still something to read or did we race? */
-	if (unlikely(log->w_off == reader->r_off)) {
-		mutex_unlock(&log->mutex);
-		goto start;
-	}
-
-	/* get the size of the next entry */
-	ret = get_user_hdr_len(reader->r_ver) +
-		get_entry_msg_len(log, reader->r_off);
-	if (count < ret) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	/* get exactly one entry from the log */
-	ret = do_read_log_to_user(log, reader, buf, ret);
-
-out:
-	mutex_unlock(&log->mutex);
-
-	return ret;
-}
-
-/*
- * get_next_entry - return the offset of the first valid entry at least 'len'
- * bytes after 'off'.
- *
- * Caller must hold log->mutex.
- */
-static size_t get_next_entry(struct logger_log *log, size_t off, size_t len)
-{
-	size_t count = 0;
-
-	do {
-		size_t nr = sizeof(struct logger_entry) +
-			get_entry_msg_len(log, off);
-		off = logger_offset(log, off + nr);
-		count += nr;
-	} while (count < len);
-
-	return off;
-}
-
-/*
- * is_between - is a < c < b, accounting for wrapping of a, b, and c
- *    positions in the buffer
- *
- * That is, if a<b, check for c between a and b
- * and if a>b, check for c outside (not between) a and b
- *
- * |------- a xxxxxxxx b --------|
- *               c^
- *
- * |xxxxx b --------- a xxxxxxxxx|
- *    c^
- *  or                    c^
- */
-static inline int is_between(size_t a, size_t b, size_t c)
-{
-	if (a < b) {
-		/* is c between a and b? */
-		if (a < c && c <= b)
-			return 1;
-	} else {
-		/* is c outside of b through a? */
-		if (c <= b || a < c)
-			return 1;
-	}
-
-	return 0;
-}
-
-/*
- * fix_up_readers - walk the list of all readers and "fix up" any who were
- * lapped by the writer; also do the same for the default "start head".
- * We do this by "pulling forward" the readers and start head to the first
- * entry after the new write head.
- *
- * The caller needs to hold log->mutex.
- */
-static void fix_up_readers(struct logger_log *log, size_t len)
-{
-	size_t old = log->w_off;
-	size_t new = logger_offset(log, old + len);
-	struct logger_reader *reader;
-
-	if (is_between(old, new, log->head))
-		log->head = get_next_entry(log, log->head, len);
-
-	list_for_each_entry(reader, &log->readers, list)
-		if (is_between(old, new, reader->r_off))
-			reader->r_off = get_next_entry(log, reader->r_off, len);
-}
-
-/*
- * logger_write_iter - our write method, implementing support for write(),
- * writev(), and aio_write(). Writes are our fast path, and we try to optimize
- * them above all else.
- */
-static ssize_t logger_write_iter(struct kiocb *iocb, struct iov_iter *from)
-{
-	struct logger_log *log = file_get_log(iocb->ki_filp);
-	struct logger_entry header;
-	struct timespec now;
-	size_t len, count, w_off;
-
-	count = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD);
-
-	now = current_kernel_time();
-
-	header.pid = current->tgid;
-	header.tid = current->pid;
-	header.sec = now.tv_sec;
-	header.nsec = now.tv_nsec;
-	header.euid = current_euid();
-	header.len = count;
-	header.hdr_size = sizeof(struct logger_entry);
-
-	/* null writes succeed, return zero */
-	if (unlikely(!header.len))
-		return 0;
-
-	mutex_lock(&log->mutex);
-
-	/*
-	 * Fix up any readers, pulling them forward to the first readable
-	 * entry after (what will be) the new write offset. We do this now
-	 * because if we partially fail, we can end up with clobbered log
-	 * entries that encroach on readable buffer.
-	 */
-	fix_up_readers(log, sizeof(struct logger_entry) + header.len);
-
-	len = min(sizeof(header), log->size - log->w_off);
-	memcpy(log->buffer + log->w_off, &header, len);
-	memcpy(log->buffer, (char *)&header + len, sizeof(header) - len);
-
-	/* Work with a copy until we are ready to commit the whole entry */
-	w_off =  logger_offset(log, log->w_off + sizeof(struct logger_entry));
-
-	len = min(count, log->size - w_off);
-
-	if (copy_from_iter(log->buffer + w_off, len, from) != len) {
-		/*
-		 * Note that by not updating log->w_off, this abandons the
-		 * portion of the new entry that *was* successfully
-		 * copied, just above.  This is intentional to avoid
-		 * message corruption from missing fragments.
-		 */
-		mutex_unlock(&log->mutex);
-		return -EFAULT;
-	}
-
-	if (copy_from_iter(log->buffer, count - len, from) != count - len) {
-		mutex_unlock(&log->mutex);
-		return -EFAULT;
-	}
-
-	log->w_off = logger_offset(log, w_off + count);
-	mutex_unlock(&log->mutex);
-
-	/* wake up any blocked readers */
-	wake_up_interruptible(&log->wq);
-
-	return len;
-}
-
-static struct logger_log *get_log_from_minor(int minor)
-{
-	struct logger_log *log;
-
-	list_for_each_entry(log, &log_list, logs)
-		if (log->misc.minor == minor)
-			return log;
-	return NULL;
-}
-
-/*
- * logger_open - the log's open() file operation
- *
- * Note how near a no-op this is in the write-only case. Keep it that way!
- */
-static int logger_open(struct inode *inode, struct file *file)
-{
-	struct logger_log *log;
-	int ret;
-
-	ret = nonseekable_open(inode, file);
-	if (ret)
-		return ret;
-
-	log = get_log_from_minor(MINOR(inode->i_rdev));
-	if (!log)
-		return -ENODEV;
-
-	if (file->f_mode & FMODE_READ) {
-		struct logger_reader *reader;
-
-		reader = kmalloc(sizeof(struct logger_reader), GFP_KERNEL);
-		if (!reader)
-			return -ENOMEM;
-
-		reader->log = log;
-		reader->r_ver = 1;
-		reader->r_all = in_egroup_p(inode->i_gid) ||
-			capable(CAP_SYSLOG);
-
-		INIT_LIST_HEAD(&reader->list);
-
-		mutex_lock(&log->mutex);
-		reader->r_off = log->head;
-		list_add_tail(&reader->list, &log->readers);
-		mutex_unlock(&log->mutex);
-
-		file->private_data = reader;
-	} else
-		file->private_data = log;
-
-	return 0;
-}
-
-/*
- * logger_release - the log's release file operation
- *
- * Note this is a total no-op in the write-only case. Keep it that way!
- */
-static int logger_release(struct inode *ignored, struct file *file)
-{
-	if (file->f_mode & FMODE_READ) {
-		struct logger_reader *reader = file->private_data;
-		struct logger_log *log = reader->log;
-
-		mutex_lock(&log->mutex);
-		list_del(&reader->list);
-		mutex_unlock(&log->mutex);
-
-		kfree(reader);
-	}
-
-	return 0;
-}
-
-/*
- * logger_poll - the log's poll file operation, for poll/select/epoll
- *
- * Note we always return POLLOUT, because you can always write() to the log.
- * Note also that, strictly speaking, a return value of POLLIN does not
- * guarantee that the log is readable without blocking, as there is a small
- * chance that the writer can lap the reader in the interim between poll()
- * returning and the read() request.
- */
-static unsigned int logger_poll(struct file *file, poll_table *wait)
-{
-	struct logger_reader *reader;
-	struct logger_log *log;
-	unsigned int ret = POLLOUT | POLLWRNORM;
-
-	if (!(file->f_mode & FMODE_READ))
-		return ret;
-
-	reader = file->private_data;
-	log = reader->log;
-
-	poll_wait(file, &log->wq, wait);
-
-	mutex_lock(&log->mutex);
-	if (!reader->r_all)
-		reader->r_off = get_next_entry_by_uid(log,
-			reader->r_off, current_euid());
-
-	if (log->w_off != reader->r_off)
-		ret |= POLLIN | POLLRDNORM;
-	mutex_unlock(&log->mutex);
-
-	return ret;
-}
-
-static long logger_set_version(struct logger_reader *reader, void __user *arg)
-{
-	int version;
-
-	if (copy_from_user(&version, arg, sizeof(int)))
-		return -EFAULT;
-
-	if ((version < 1) || (version > 2))
-		return -EINVAL;
-
-	reader->r_ver = version;
-	return 0;
-}
-
-static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct logger_log *log = file_get_log(file);
-	struct logger_reader *reader;
-	long ret = -EINVAL;
-	void __user *argp = (void __user *) arg;
-
-	mutex_lock(&log->mutex);
-
-	switch (cmd) {
-	case LOGGER_GET_LOG_BUF_SIZE:
-		ret = log->size;
-		break;
-	case LOGGER_GET_LOG_LEN:
-		if (!(file->f_mode & FMODE_READ)) {
-			ret = -EBADF;
-			break;
-		}
-		reader = file->private_data;
-		if (log->w_off >= reader->r_off)
-			ret = log->w_off - reader->r_off;
-		else
-			ret = (log->size - reader->r_off) + log->w_off;
-		break;
-	case LOGGER_GET_NEXT_ENTRY_LEN:
-		if (!(file->f_mode & FMODE_READ)) {
-			ret = -EBADF;
-			break;
-		}
-		reader = file->private_data;
-
-		if (!reader->r_all)
-			reader->r_off = get_next_entry_by_uid(log,
-				reader->r_off, current_euid());
-
-		if (log->w_off != reader->r_off)
-			ret = get_user_hdr_len(reader->r_ver) +
-				get_entry_msg_len(log, reader->r_off);
-		else
-			ret = 0;
-		break;
-	case LOGGER_FLUSH_LOG:
-		if (!(file->f_mode & FMODE_WRITE)) {
-			ret = -EBADF;
-			break;
-		}
-		if (!(in_egroup_p(file_inode(file)->i_gid) ||
-				capable(CAP_SYSLOG))) {
-			ret = -EPERM;
-			break;
-		}
-		list_for_each_entry(reader, &log->readers, list)
-			reader->r_off = log->w_off;
-		log->head = log->w_off;
-		ret = 0;
-		break;
-	case LOGGER_GET_VERSION:
-		if (!(file->f_mode & FMODE_READ)) {
-			ret = -EBADF;
-			break;
-		}
-		reader = file->private_data;
-		ret = reader->r_ver;
-		break;
-	case LOGGER_SET_VERSION:
-		if (!(file->f_mode & FMODE_READ)) {
-			ret = -EBADF;
-			break;
-		}
-		reader = file->private_data;
-		ret = logger_set_version(reader, argp);
-		break;
-	}
-
-	mutex_unlock(&log->mutex);
-
-	return ret;
-}
-
-static const struct file_operations logger_fops = {
-	.owner = THIS_MODULE,
-	.read = logger_read,
-	.write_iter = logger_write_iter,
-	.poll = logger_poll,
-	.unlocked_ioctl = logger_ioctl,
-	.compat_ioctl = logger_ioctl,
-	.open = logger_open,
-	.release = logger_release,
-};
-
-/*
- * Log size must must be a power of two, and greater than
- * (LOGGER_ENTRY_MAX_PAYLOAD + sizeof(struct logger_entry)).
- */
-static int __init create_log(char *log_name, int size)
-{
-	int ret = 0;
-	struct logger_log *log;
-	unsigned char *buffer;
-
-	buffer = vmalloc(size);
-	if (buffer == NULL)
-		return -ENOMEM;
-
-	log = kzalloc(sizeof(struct logger_log), GFP_KERNEL);
-	if (log == NULL) {
-		ret = -ENOMEM;
-		goto out_free_buffer;
-	}
-	log->buffer = buffer;
-
-	log->misc.minor = MISC_DYNAMIC_MINOR;
-	log->misc.name = kstrdup(log_name, GFP_KERNEL);
-	if (log->misc.name == NULL) {
-		ret = -ENOMEM;
-		goto out_free_log;
-	}
-
-	log->misc.fops = &logger_fops;
-	log->misc.parent = NULL;
-
-	init_waitqueue_head(&log->wq);
-	INIT_LIST_HEAD(&log->readers);
-	mutex_init(&log->mutex);
-	log->w_off = 0;
-	log->head = 0;
-	log->size = size;
-
-	INIT_LIST_HEAD(&log->logs);
-	list_add_tail(&log->logs, &log_list);
-
-	/* finally, initialize the misc device for this log */
-	ret = misc_register(&log->misc);
-	if (unlikely(ret)) {
-		pr_err("failed to register misc device for log '%s'!\n",
-				log->misc.name);
-		goto out_free_misc_name;
-	}
-
-	pr_info("created %luK log '%s'\n",
-		(unsigned long) log->size >> 10, log->misc.name);
-
-	return 0;
-
-out_free_misc_name:
-	kfree(log->misc.name);
-
-out_free_log:
-	kfree(log);
-
-out_free_buffer:
-	vfree(buffer);
-	return ret;
-}
-
-static int __init logger_init(void)
-{
-	int ret;
-
-	ret = create_log(LOGGER_LOG_MAIN, 256*1024);
-	if (unlikely(ret))
-		goto out;
-
-	ret = create_log(LOGGER_LOG_EVENTS, 256*1024);
-	if (unlikely(ret))
-		goto out;
-
-	ret = create_log(LOGGER_LOG_RADIO, 256*1024);
-	if (unlikely(ret))
-		goto out;
-
-	ret = create_log(LOGGER_LOG_SYSTEM, 256*1024);
-	if (unlikely(ret))
-		goto out;
-
-out:
-	return ret;
-}
-
-static void __exit logger_exit(void)
-{
-	struct logger_log *current_log, *next_log;
-
-	list_for_each_entry_safe(current_log, next_log, &log_list, logs) {
-		/* we have to delete all the entry inside log_list */
-		misc_deregister(&current_log->misc);
-		vfree(current_log->buffer);
-		kfree(current_log->misc.name);
-		list_del(&current_log->logs);
-		kfree(current_log);
-	}
-}
-
-
-device_initcall(logger_init);
-module_exit(logger_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Robert Love, <rlove@google.com>");
-MODULE_DESCRIPTION("Android Logger");
diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h
deleted file mode 100644
index 70af7d805dff..000000000000
--- a/drivers/staging/android/logger.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* include/linux/logger.h
- *
- * Copyright (C) 2007-2008 Google, Inc.
- * Author: Robert Love <rlove@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _LINUX_LOGGER_H
-#define _LINUX_LOGGER_H
-
-#include <linux/types.h>
-#include <linux/ioctl.h>
-
-/**
- * struct user_logger_entry_compat - defines a single entry that is given to a logger
- * @len:	The length of the payload
- * @__pad:	Two bytes of padding that appear to be required
- * @pid:	The generating process' process ID
- * @tid:	The generating process' thread ID
- * @sec:	The number of seconds that have elapsed since the Epoch
- * @nsec:	The number of nanoseconds that have elapsed since @sec
- * @msg:	The message that is to be logged
- *
- * The userspace structure for version 1 of the logger_entry ABI.
- * This structure is returned to userspace unless the caller requests
- * an upgrade to a newer ABI version.
- */
-struct user_logger_entry_compat {
-	__u16		len;
-	__u16		__pad;
-	__s32		pid;
-	__s32		tid;
-	__s32		sec;
-	__s32		nsec;
-	char		msg[0];
-};
-
-/**
- * struct logger_entry - defines a single entry that is given to a logger
- * @len:	The length of the payload
- * @hdr_size:	sizeof(struct logger_entry_v2)
- * @pid:	The generating process' process ID
- * @tid:	The generating process' thread ID
- * @sec:	The number of seconds that have elapsed since the Epoch
- * @nsec:	The number of nanoseconds that have elapsed since @sec
- * @euid:	Effective UID of logger
- * @msg:	The message that is to be logged
- *
- * The structure for version 2 of the logger_entry ABI.
- * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)
- * is called with version >= 2
- */
-struct logger_entry {
-	__u16		len;
-	__u16		hdr_size;
-	__s32		pid;
-	__s32		tid;
-	__s32		sec;
-	__s32		nsec;
-	kuid_t		euid;
-	char		msg[0];
-};
-
-#define LOGGER_LOG_RADIO	"log_radio"	/* radio-related messages */
-#define LOGGER_LOG_EVENTS	"log_events"	/* system/hardware events */
-#define LOGGER_LOG_SYSTEM	"log_system"	/* system/framework messages */
-#define LOGGER_LOG_MAIN		"log_main"	/* everything else */
-
-#define LOGGER_ENTRY_MAX_PAYLOAD	4076
-
-#define __LOGGERIO	0xAE
-
-#define LOGGER_GET_LOG_BUF_SIZE		_IO(__LOGGERIO, 1) /* size of log */
-#define LOGGER_GET_LOG_LEN		_IO(__LOGGERIO, 2) /* used log len */
-#define LOGGER_GET_NEXT_ENTRY_LEN	_IO(__LOGGERIO, 3) /* next entry len */
-#define LOGGER_FLUSH_LOG		_IO(__LOGGERIO, 4) /* flush log */
-#define LOGGER_GET_VERSION		_IO(__LOGGERIO, 5) /* abi version */
-#define LOGGER_SET_VERSION		_IO(__LOGGERIO, 6) /* abi version */
-
-#endif /* _LINUX_LOGGER_H */
diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c
index 1532a86404be..91ed2c4cff45 100644
--- a/drivers/staging/android/sync_debug.c
+++ b/drivers/staging/android/sync_debug.c
@@ -96,7 +96,8 @@ static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
 		   sync_status_str(status));
 
 	if (status <= 0) {
-		struct timespec64 ts64 = ktime_to_timespec64(pt->base.timestamp);
+		struct timespec64 ts64 =
+			ktime_to_timespec64(pt->base.timestamp);
 
 		seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec);
 	}
diff --git a/drivers/staging/android/uapi/android_alarm.h b/drivers/staging/android/uapi/android_alarm.h
deleted file mode 100644
index aa013f6f5f3a..000000000000
--- a/drivers/staging/android/uapi/android_alarm.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* drivers/staging/android/uapi/android_alarm.h
- *
- * Copyright (C) 2006-2007 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.
- *
- */
-
-#ifndef _UAPI_LINUX_ANDROID_ALARM_H
-#define _UAPI_LINUX_ANDROID_ALARM_H
-
-#include <linux/ioctl.h>
-#include <linux/time.h>
-
-enum android_alarm_type {
-	/* return code bit numbers or set alarm arg */
-	ANDROID_ALARM_RTC_WAKEUP,
-	ANDROID_ALARM_RTC,
-	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
-	ANDROID_ALARM_ELAPSED_REALTIME,
-	ANDROID_ALARM_SYSTEMTIME,
-
-	ANDROID_ALARM_TYPE_COUNT,
-
-	/* return code bit numbers */
-	/* ANDROID_ALARM_TIME_CHANGE = 16 */
-};
-
-enum android_alarm_return_flags {
-	ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
-	ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
-	ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK =
-				1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
-	ANDROID_ALARM_ELAPSED_REALTIME_MASK =
-				1U << ANDROID_ALARM_ELAPSED_REALTIME,
-	ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
-	ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
-};
-
-/* Disable alarm */
-#define ANDROID_ALARM_CLEAR(type)           _IO('a', 0 | ((type) << 4))
-
-/* Ack last alarm and wait for next */
-#define ANDROID_ALARM_WAIT                  _IO('a', 1)
-
-#define ALARM_IOW(c, type, size)            _IOW('a', (c) | ((type) << 4), size)
-/* Set alarm */
-#define ANDROID_ALARM_SET(type)             ALARM_IOW(2, type, struct timespec)
-#define ANDROID_ALARM_SET_AND_WAIT(type)    ALARM_IOW(3, type, struct timespec)
-#define ANDROID_ALARM_GET_TIME(type)        ALARM_IOW(4, type, struct timespec)
-#define ANDROID_ALARM_SET_RTC               _IOW('a', 5, struct timespec)
-#define ANDROID_ALARM_BASE_CMD(cmd)         (cmd & ~(_IOC(0, 0, 0xf0, 0)))
-#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd)    (_IOC_NR(cmd) >> 4)
-
-#endif
diff --git a/drivers/staging/board/board.c b/drivers/staging/board/board.c
index 6050fbdfd31f..d5a6abc84519 100644
--- a/drivers/staging/board/board.c
+++ b/drivers/staging/board/board.c
@@ -11,8 +11,7 @@ static bool find_by_address(u64 base_address)
 	struct resource res;
 
 	while (dn) {
-		if (of_can_translate_address(dn)
-		    && !of_address_to_resource(dn, 0, &res)) {
+		if (!of_address_to_resource(dn, 0, &res)) {
 			if (res.start == base_address) {
 				of_node_put(dn);
 				return true;
diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
index 471d0877f382..5455bf3d5a91 100644
--- a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
+++ b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
@@ -91,8 +91,10 @@ static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long event,
 
 	if (ndata->clk == clk_wzrd->clk_in1)
 		max = clk_wzrd_max_freq[clk_wzrd->speed_grade - 1];
-	if (ndata->clk == clk_wzrd->axi_clk)
+	else if (ndata->clk == clk_wzrd->axi_clk)
 		max = WZRD_ACLK_MAX_FREQ;
+	else
+		return NOTIFY_DONE;	/* should never happen */
 
 	switch (event) {
 	case PRE_RATE_CHANGE:
@@ -239,6 +241,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
 	/* register div per output */
 	for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) {
 		const char *clkout_name;
+
 		if (of_property_read_string_index(np, "clock-output-names", i,
 						  &clkout_name)) {
 			dev_err(&pdev->dev,
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index a8201fe87512..593fcb1783b4 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -168,7 +168,7 @@ config COMEDI_PCL730
 
 config COMEDI_PCL812
 	tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216"
-	depends on VIRT_TO_BUS && ISA_DMA_API
+	select COMEDI_ISADMA if ISA_DMA_API
 	---help---
 	  Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink
 	  ACL-8112DG/HG/PG, ACL-8113, ACL-8216, ICP DAS A-821PGH/PGL/PGL-NDA,
@@ -179,7 +179,7 @@ config COMEDI_PCL812
 
 config COMEDI_PCL816
 	tristate "Advantech PCL-814 and PCL-816 ISA card support"
-	depends on VIRT_TO_BUS && ISA_DMA_API
+	select COMEDI_ISADMA if ISA_DMA_API
 	---help---
 	  Enable support for Advantech PCL-814 and PCL-816 ISA cards
 
@@ -188,7 +188,7 @@ config COMEDI_PCL816
 
 config COMEDI_PCL818
 	tristate "Advantech PCL-718 and PCL-818 ISA card support"
-	depends on VIRT_TO_BUS && ISA_DMA_API
+	select COMEDI_ISADMA if ISA_DMA_API
 	---help---
 	  Enable support for Advantech PCL-818 ISA cards
 	  PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818 and PCL-718
@@ -281,7 +281,7 @@ config COMEDI_DAS08_ISA
 
 config COMEDI_DAS16
 	tristate "DAS-16 compatible ISA and PC/104 card support"
-	depends on ISA_DMA_API
+	select COMEDI_ISADMA if ISA_DMA_API
 	select COMEDI_8255
 	---help---
 	  Enable support for Keithley Metrabyte/ComputerBoards DAS16
@@ -309,7 +309,7 @@ config COMEDI_DAS800
 
 config COMEDI_DAS1800
 	tristate "DAS1800 and compatible ISA card support"
-	depends on VIRT_TO_BUS && ISA_DMA_API
+	select COMEDI_ISADMA if ISA_DMA_API
 	---help---
 	  Enable support for DAS1800 and compatible ISA cards
 	  Keithley Metrabyte DAS-1701ST, DAS-1701ST-DA, DAS-1701/AO,
@@ -372,7 +372,7 @@ config COMEDI_DT2817
 
 config COMEDI_DT282X
 	tristate "Data Translation DT2821 series and DT-EZ ISA card support"
-	depends on VIRT_TO_BUS && ISA_DMA_API
+	select COMEDI_ISADMA if ISA_DMA_API
 	---help---
 	  Enable support for Data Translation DT2821 series including DT-EZ
 	  DT2821, DT2821-F-16SE, DT2821-F-8DI, DT2821-G-16SE, DT2821-G-8DI,
@@ -462,7 +462,7 @@ config COMEDI_ADQ12B
 
 config COMEDI_NI_AT_A2150
 	tristate "NI AT-A2150 ISA card support"
-	depends on VIRT_TO_BUS && ISA_DMA_API
+	select COMEDI_ISADMA if ISA_DMA_API
 	---help---
 	  Enable support for National Instruments AT-A2150 cards
 
@@ -502,7 +502,7 @@ config COMEDI_NI_ATMIO16D
 config COMEDI_NI_LABPC_ISA
 	tristate "NI Lab-PC and compatibles ISA support"
 	select COMEDI_NI_LABPC
-	select COMEDI_NI_LABPC_ISADMA if ISA_DMA_API && VIRT_TO_BUS
+	select COMEDI_NI_LABPC_ISADMA if ISA_DMA_API
 	---help---
 	  Enable support for National Instruments Lab-PC and compatibles
 	  Lab-PC-1200, Lab-PC-1200AI, Lab-PC+.
@@ -724,7 +724,6 @@ config COMEDI_ADL_PCI9111
 config COMEDI_ADL_PCI9118
 	tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support"
 	depends on HAS_DMA
-	depends on VIRT_TO_BUS
 	---help---
 	  Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards
 
@@ -1263,12 +1262,16 @@ config COMEDI_DAS08
 	tristate
 	select COMEDI_8255
 
+config COMEDI_ISADMA
+	tristate
+
 config COMEDI_NI_LABPC
 	tristate
 	select COMEDI_8255
 
 config COMEDI_NI_LABPC_ISADMA
 	tristate
+	select COMEDI_ISADMA
 
 config COMEDI_NI_TIO
 	tristate
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index 5a4c74f703b3..25848244c4b1 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -1,23 +1,23 @@
 /*
-    comedi/comedi_compat32.c
-    32-bit ioctl compatibility for 64-bit comedi kernel module.
-
-    Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk>
-    Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/>
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-*/
+ * comedi/comedi_compat32.c
+ * 32-bit ioctl compatibility for 64-bit comedi kernel module.
+ *
+ * Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk>
+ * Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
 #include <linux/uaccess.h>
 #include <linux/compat.h>
@@ -27,11 +27,15 @@
 
 #define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
 #define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
-/* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
- * It's too late to change it now, but it only affects the command number. */
+/*
+ * N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
+ * It's too late to change it now, but it only affects the command number.
+ */
 #define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct)
-/* N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
- * It's too late to change it now, but it only affects the command number. */
+/*
+ * N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
+ * It's too late to change it now, but it only affects the command number.
+ */
 #define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct)
 #define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct)
 #define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct)
@@ -39,7 +43,7 @@
 struct comedi32_chaninfo_struct {
 	unsigned int subdev;
 	compat_uptr_t maxdata_list;	/* 32-bit 'unsigned int *' */
-	compat_uptr_t flaglist;	/* 32-bit 'unsigned int *' */
+	compat_uptr_t flaglist;		/* 32-bit 'unsigned int *' */
 	compat_uptr_t rangelist;	/* 32-bit 'unsigned int *' */
 	unsigned int unused[4];
 };
@@ -62,16 +66,16 @@ struct comedi32_cmd_struct {
 	unsigned int scan_end_arg;
 	unsigned int stop_src;
 	unsigned int stop_arg;
-	compat_uptr_t chanlist;	/* 32-bit 'unsigned int *' */
+	compat_uptr_t chanlist;		/* 32-bit 'unsigned int *' */
 	unsigned int chanlist_len;
-	compat_uptr_t data;	/* 32-bit 'short *' */
+	compat_uptr_t data;		/* 32-bit 'short *' */
 	unsigned int data_len;
 };
 
 struct comedi32_insn_struct {
 	unsigned int insn;
 	unsigned int n;
-	compat_uptr_t data;	/* 32-bit 'unsigned int *' */
+	compat_uptr_t data;		/* 32-bit 'unsigned int *' */
 	unsigned int subdev;
 	unsigned int chanspec;
 	unsigned int unused[3];
@@ -79,7 +83,7 @@ struct comedi32_insn_struct {
 
 struct comedi32_insnlist_struct {
 	unsigned int n_insns;
-	compat_uptr_t insns;	/* 32-bit 'struct comedi_insn *' */
+	compat_uptr_t insns;		/* 32-bit 'struct comedi_insn *' */
 };
 
 /* Handle translated ioctl. */
@@ -215,10 +219,12 @@ static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32,
 	int err;
 	unsigned int temp;
 
-	/* Copy back most of cmd structure. */
-	/* Assume the pointer values are already valid. */
-	/* (Could use ptr_to_compat() to set them, but that wasn't implemented
-	 * until kernel version 2.6.11.) */
+	/*
+	 * Copy back most of cmd structure.
+	 *
+	 * Assume the pointer values are already valid.
+	 * (Could use ptr_to_compat() to set them.)
+	 */
 	if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd)) ||
 	    !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32)))
 		return -EFAULT;
@@ -262,7 +268,7 @@ static int compat_cmd(struct file *file, unsigned long arg)
 {
 	struct comedi_cmd __user *cmd;
 	struct comedi32_cmd_struct __user *cmd32;
-	int rc;
+	int rc, err;
 
 	cmd32 = compat_ptr(arg);
 	cmd = compat_alloc_user_space(sizeof(*cmd));
@@ -271,7 +277,15 @@ static int compat_cmd(struct file *file, unsigned long arg)
 	if (rc)
 		return rc;
 
-	return translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
+	rc = translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
+	if (rc == -EAGAIN) {
+		/* Special case: copy cmd back to user. */
+		err = put_compat_cmd(cmd32, cmd);
+		if (err)
+			rc = err;
+	}
+
+	return rc;
 }
 
 /* Handle 32-bit COMEDI_CMDTEST ioctl. */
@@ -395,10 +409,12 @@ static int compat_insn(struct file *file, unsigned long arg)
 	return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn);
 }
 
-/* Process untranslated ioctl. */
-/* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
-static inline int raw_ioctl(struct file *file, unsigned int cmd,
-			    unsigned long arg)
+/*
+ * compat_ioctl file operation.
+ *
+ * Returns -ENOIOCTLCMD for unrecognised ioctl codes.
+ */
+long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	int rc;
 
@@ -445,10 +461,3 @@ static inline int raw_ioctl(struct file *file, unsigned int cmd,
 	}
 	return rc;
 }
-
-/* compat_ioctl file operation. */
-/* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
-long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	return raw_ioctl(file, cmd, arg);
-}
diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h
index 2d0a6fcf60f3..5ce77f3e8c22 100644
--- a/drivers/staging/comedi/comedi_compat32.h
+++ b/drivers/staging/comedi/comedi_compat32.h
@@ -1,23 +1,23 @@
 /*
-    comedi/comedi_compat32.h
-    32-bit ioctl compatibility for 64-bit comedi kernel module.
-
-    Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk>
-    Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/>
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-*/
+ * comedi/comedi_compat32.h
+ * 32-bit ioctl compatibility for 64-bit comedi kernel module.
+ *
+ * Author: Ian Abbott, MEV Ltd. <abbotti@mev.co.uk>
+ * Copyright (C) 2007 MEV Ltd. <http://www.mev.co.uk/>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
 #ifndef _COMEDI_COMPAT32_H
 #define _COMEDI_COMPAT32_H
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index f143cb64d69e..727640e89c73 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1,20 +1,20 @@
 /*
-    comedi/comedi_fops.c
-    comedi kernel module
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-*/
+ * comedi/comedi_fops.c
+ * comedi kernel module
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
@@ -113,6 +113,18 @@ static void comedi_dev_kref_release(struct kref *kref)
 	kfree(dev);
 }
 
+/**
+ * comedi_dev_put - release a use of a comedi device structure
+ * @dev: comedi_device struct
+ *
+ * Must be called when a user of a comedi device is finished with it.
+ * When the last user of the comedi device calls this function, the
+ * comedi device is destroyed.
+ *
+ * Return 1 if the comedi device is destroyed by this call or dev is
+ * NULL, otherwise return 0.  Callers must not assume the comedi
+ * device is still valid if this function returns 0.
+ */
 int comedi_dev_put(struct comedi_device *dev)
 {
 	if (dev)
@@ -220,6 +232,18 @@ static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor)
 	return dev;
 }
 
+/**
+ * comedi_dev_get_from_minor - get comedi device by minor device number
+ * @minor: minor device number
+ *
+ * Finds the comedi device associated by the minor device number, if any,
+ * and increments its reference count.  The comedi device is prevented from
+ * being freed until a matching call is made to comedi_dev_put().
+ *
+ * Return a pointer to the comedi device if it exists, with its usage
+ * reference incremented.  Return NULL if no comedi device exists with the
+ * specified minor device number.
+ */
 struct comedi_device *comedi_dev_get_from_minor(unsigned minor)
 {
 	if (minor < COMEDI_NUM_BOARD_MINORS)
@@ -323,8 +347,7 @@ static int resize_async_buffer(struct comedi_device *dev,
 		return -EBUSY;
 	}
 
-	/* make sure buffer is an integral number of pages
-	 * (we round up) */
+	/* make sure buffer is an integral number of pages (we round up) */
 	new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
 
 	retval = comedi_buf_alloc(dev, s, new_size);
@@ -600,11 +623,18 @@ static unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s)
 	return runflags;
 }
 
+/**
+ * comedi_is_subdevice_running - check if async command running on subdevice
+ * @s: comedi_subdevice struct
+ *
+ * Return true if an asynchronous comedi command is active on the comedi
+ * subdevice, else return false.
+ */
 bool comedi_is_subdevice_running(struct comedi_subdevice *s)
 {
 	unsigned runflags = comedi_get_subdevice_runflags(s);
 
-	return (runflags & SRF_RUNNING) ? true : false;
+	return (runflags & COMEDI_SRF_RUNNING) ? true : false;
 }
 EXPORT_SYMBOL_GPL(comedi_is_subdevice_running);
 
@@ -612,14 +642,14 @@ static bool comedi_is_subdevice_in_error(struct comedi_subdevice *s)
 {
 	unsigned runflags = comedi_get_subdevice_runflags(s);
 
-	return (runflags & SRF_ERROR) ? true : false;
+	return (runflags & COMEDI_SRF_ERROR) ? true : false;
 }
 
 static bool comedi_is_subdevice_idle(struct comedi_subdevice *s)
 {
 	unsigned runflags = comedi_get_subdevice_runflags(s);
 
-	return (runflags & (SRF_ERROR | SRF_RUNNING)) ? false : true;
+	return (runflags & COMEDI_SRF_BUSY_MASK) ? false : true;
 }
 
 /**
@@ -634,20 +664,20 @@ void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size)
 {
 	s->private = kzalloc(size, GFP_KERNEL);
 	if (s->private)
-		s->runflags |= SRF_FREE_SPRIV;
+		s->runflags |= COMEDI_SRF_FREE_SPRIV;
 	return s->private;
 }
 EXPORT_SYMBOL_GPL(comedi_alloc_spriv);
 
 /*
-   This function restores a subdevice to an idle state.
+ * This function restores a subdevice to an idle state.
  */
 static void do_become_nonbusy(struct comedi_device *dev,
 			      struct comedi_subdevice *s)
 {
 	struct comedi_async *async = s->async;
 
-	comedi_set_subdevice_runflags(s, SRF_RUNNING, 0);
+	comedi_set_subdevice_runflags(s, COMEDI_SRF_RUNNING, 0);
 	if (async) {
 		comedi_buf_reset(s);
 		async->inttrig = NULL;
@@ -709,18 +739,18 @@ static int is_device_busy(struct comedi_device *dev)
 }
 
 /*
-	COMEDI_DEVCONFIG
-	device config ioctl
-
-	arg:
-		pointer to devconfig structure
-
-	reads:
-		devconfig structure at arg
-
-	writes:
-		none
-*/
+ * COMEDI_DEVCONFIG ioctl
+ * attaches (and configures) or detaches a legacy device
+ *
+ * arg:
+ *	pointer to comedi_devconfig structure (NULL if detaching)
+ *
+ * reads:
+ *	comedi_devconfig structure (if attaching)
+ *
+ * writes:
+ *	nothing
+ */
 static int do_devconfig_ioctl(struct comedi_device *dev,
 			      struct comedi_devconfig __user *arg)
 {
@@ -761,19 +791,18 @@ static int do_devconfig_ioctl(struct comedi_device *dev,
 }
 
 /*
-	COMEDI_BUFCONFIG
-	buffer configuration ioctl
-
-	arg:
-		pointer to bufconfig structure
-
-	reads:
-		bufconfig at arg
-
-	writes:
-		modified bufconfig at arg
-
-*/
+ * COMEDI_BUFCONFIG ioctl
+ * buffer configuration
+ *
+ * arg:
+ *	pointer to comedi_bufconfig structure
+ *
+ * reads:
+ *	comedi_bufconfig structure
+ *
+ * writes:
+ *	modified comedi_bufconfig structure
+ */
 static int do_bufconfig_ioctl(struct comedi_device *dev,
 			      struct comedi_bufconfig __user *arg)
 {
@@ -823,19 +852,18 @@ copyback:
 }
 
 /*
-	COMEDI_DEVINFO
-	device info ioctl
-
-	arg:
-		pointer to devinfo structure
-
-	reads:
-		none
-
-	writes:
-		devinfo structure
-
-*/
+ * COMEDI_DEVINFO ioctl
+ * device info
+ *
+ * arg:
+ *	pointer to comedi_devinfo structure
+ *
+ * reads:
+ *	nothing
+ *
+ * writes:
+ *	comedi_devinfo structure
+ */
 static int do_devinfo_ioctl(struct comedi_device *dev,
 			    struct comedi_devinfo __user *arg,
 			    struct file *file)
@@ -870,19 +898,18 @@ static int do_devinfo_ioctl(struct comedi_device *dev,
 }
 
 /*
-	COMEDI_SUBDINFO
-	subdevice info ioctl
-
-	arg:
-		pointer to array of subdevice info structures
-
-	reads:
-		none
-
-	writes:
-		array of subdevice info structures at arg
-
-*/
+ * COMEDI_SUBDINFO ioctl
+ * subdevices info
+ *
+ * arg:
+ *	pointer to array of comedi_subdinfo structures
+ *
+ * reads:
+ *	nothing
+ *
+ * writes:
+ *	array of comedi_subdinfo structures
+ */
 static int do_subdinfo_ioctl(struct comedi_device *dev,
 			     struct comedi_subdinfo __user *arg, void *file)
 {
@@ -944,19 +971,19 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
 }
 
 /*
-	COMEDI_CHANINFO
-	subdevice info ioctl
-
-	arg:
-		pointer to chaninfo structure
-
-	reads:
-		chaninfo structure at arg
-
-	writes:
-		arrays at elements of chaninfo structure
-
-*/
+ * COMEDI_CHANINFO ioctl
+ * subdevice channel info
+ *
+ * arg:
+ *	pointer to comedi_chaninfo structure
+ *
+ * reads:
+ *	comedi_chaninfo structure
+ *
+ * writes:
+ *	array of maxdata values to chaninfo->maxdata_list if requested
+ *	array of range table lengths to chaninfo->range_table_list if requested
+ */
 static int do_chaninfo_ioctl(struct comedi_device *dev,
 			     struct comedi_chaninfo __user *arg)
 {
@@ -1004,20 +1031,19 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
 	return 0;
 }
 
- /*
-    COMEDI_BUFINFO
-    buffer information ioctl
-
-    arg:
-    pointer to bufinfo structure
-
-    reads:
-    bufinfo at arg
-
-    writes:
-    modified bufinfo at arg
-
-  */
+/*
+ * COMEDI_BUFINFO ioctl
+ * buffer information
+ *
+ * arg:
+ *	pointer to comedi_bufinfo structure
+ *
+ * reads:
+ *	comedi_bufinfo structure
+ *
+ * writes:
+ *	modified comedi_bufinfo structure
+ */
 static int do_bufinfo_ioctl(struct comedi_device *dev,
 			    struct comedi_bufinfo __user *arg, void *file)
 {
@@ -1135,8 +1161,10 @@ static int check_insn_config_length(struct comedi_insn *insn,
 		if (insn->n == 6)
 			return 0;
 		break;
-		/* by default we allow the insn since we don't have checks for
-		 * all possible cases yet */
+		/*
+		 * by default we allow the insn since we don't have checks for
+		 * all possible cases yet
+		 */
 	default:
 		pr_warn("No check for data length of config insn id %i is implemented\n",
 			data[0]);
@@ -1287,9 +1315,11 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
 			if (insn->n != 2) {
 				ret = -EINVAL;
 			} else {
-				/* Most drivers ignore the base channel in
+				/*
+				 * Most drivers ignore the base channel in
 				 * insn->chanspec.  Fix this here if
-				 * the subdevice has <= 32 channels.  */
+				 * the subdevice has <= 32 channels.
+				 */
 				unsigned int orig_mask = data[0];
 				unsigned int shift = 0;
 
@@ -1326,19 +1356,19 @@ out:
 }
 
 /*
- *	COMEDI_INSNLIST
- *	synchronous instructions
+ * COMEDI_INSNLIST ioctl
+ * synchronous instruction list
  *
- *	arg:
- *		pointer to sync cmd structure
+ * arg:
+ *	pointer to comedi_insnlist structure
  *
- *	reads:
- *		sync cmd struct at arg
- *		instruction list
- *		data (for writes)
+ * reads:
+ *	comedi_insnlist structure
+ *	array of comedi_insn structures from insnlist->insns pointer
+ *	data (for writes) from insns[].data pointers
  *
- *	writes:
- *		data (for reads)
+ * writes:
+ *	data (for reads) to insns[].data pointers
  */
 /* arbitrary limits */
 #define MAX_SAMPLES 256
@@ -1415,18 +1445,18 @@ error:
 }
 
 /*
- *	COMEDI_INSN
- *	synchronous instructions
+ * COMEDI_INSN ioctl
+ * synchronous instruction
  *
- *	arg:
- *		pointer to insn
+ * arg:
+ *	pointer to comedi_insn structure
  *
- *	reads:
- *		struct comedi_insn struct at arg
- *		data (for writes)
+ * reads:
+ *	comedi_insn structure
+ *	data (for writes) from insn->data pointer
  *
- *	writes:
- *		data (for reads)
+ * writes:
+ *	data (for reads) to insn->data pointer
  */
 static int do_insn_ioctl(struct comedi_device *dev,
 			 struct comedi_insn __user *arg, void *file)
@@ -1558,6 +1588,20 @@ static int __comedi_get_user_chanlist(struct comedi_device *dev,
 	return 0;
 }
 
+/*
+ * COMEDI_CMD ioctl
+ * asynchronous acquisition command set-up
+ *
+ * arg:
+ *	pointer to comedi_cmd structure
+ *
+ * reads:
+ *	comedi_cmd structure
+ *	channel/range list from cmd->chanlist pointer
+ *
+ * writes:
+ *	possibly modified comedi_cmd structure (when -EAGAIN returned)
+ */
 static int do_cmd_ioctl(struct comedi_device *dev,
 			struct comedi_cmd __user *arg, void *file)
 {
@@ -1634,10 +1678,13 @@ static int do_cmd_ioctl(struct comedi_device *dev,
 	if (async->cmd.flags & CMDF_WAKE_EOS)
 		async->cb_mask |= COMEDI_CB_EOS;
 
-	comedi_set_subdevice_runflags(s, SRF_ERROR | SRF_RUNNING, SRF_RUNNING);
+	comedi_set_subdevice_runflags(s, COMEDI_SRF_BUSY_MASK,
+				      COMEDI_SRF_RUNNING);
 
-	/* set s->busy _after_ setting SRF_RUNNING flag to avoid race with
-	 * comedi_read() or comedi_write() */
+	/*
+	 * Set s->busy _after_ setting COMEDI_SRF_RUNNING flag to avoid
+	 * race with comedi_read() or comedi_write().
+	 */
 	s->busy = file;
 	ret = s->do_cmd(dev, s);
 	if (ret == 0)
@@ -1650,20 +1697,19 @@ cleanup:
 }
 
 /*
-	COMEDI_CMDTEST
-	command testing ioctl
-
-	arg:
-		pointer to cmd structure
-
-	reads:
-		cmd structure at arg
-		channel/range list
-
-	writes:
-		modified cmd structure at arg
-
-*/
+ * COMEDI_CMDTEST ioctl
+ * asynchronous aquisition command testing
+ *
+ * arg:
+ *	pointer to comedi_cmd structure
+ *
+ * reads:
+ *	comedi_cmd structure
+ *	channel/range list from cmd->chanlist pointer
+ *
+ * writes:
+ *	possibly modified comedi_cmd structure
+ */
 static int do_cmdtest_ioctl(struct comedi_device *dev,
 			    struct comedi_cmd __user *arg, void *file)
 {
@@ -1706,20 +1752,18 @@ static int do_cmdtest_ioctl(struct comedi_device *dev,
 }
 
 /*
-	COMEDI_LOCK
-	lock subdevice
-
-	arg:
-		subdevice number
-
-	reads:
-		none
-
-	writes:
-		none
-
-*/
-
+ * COMEDI_LOCK ioctl
+ * lock subdevice
+ *
+ * arg:
+ *	subdevice number
+ *
+ * reads:
+ *	nothing
+ *
+ * writes:
+ *	nothing
+ */
 static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg,
 			 void *file)
 {
@@ -1742,21 +1786,18 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned long arg,
 }
 
 /*
-	COMEDI_UNLOCK
-	unlock subdevice
-
-	arg:
-		subdevice number
-
-	reads:
-		none
-
-	writes:
-		none
-
-	This function isn't protected by the semaphore, since
-	we already own the lock.
-*/
+ * COMEDI_UNLOCK ioctl
+ * unlock subdevice
+ *
+ * arg:
+ *	subdevice number
+ *
+ * reads:
+ *	nothing
+ *
+ * writes:
+ *	nothing
+ */
 static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg,
 			   void *file)
 {
@@ -1779,19 +1820,18 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned long arg,
 }
 
 /*
-	COMEDI_CANCEL
-	cancel acquisition ioctl
-
-	arg:
-		subdevice number
-
-	reads:
-		nothing
-
-	writes:
-		nothing
-
-*/
+ * COMEDI_CANCEL ioctl
+ * cancel asynchronous acquisition
+ *
+ * arg:
+ *	subdevice number
+ *
+ * reads:
+ *	nothing
+ *
+ * writes:
+ *	nothing
+ */
 static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg,
 			   void *file)
 {
@@ -1813,19 +1853,18 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned long arg,
 }
 
 /*
-	COMEDI_POLL ioctl
-	instructs driver to synchronize buffers
-
-	arg:
-		subdevice number
-
-	reads:
-		nothing
-
-	writes:
-		nothing
-
-*/
+ * COMEDI_POLL ioctl
+ * instructs driver to synchronize buffers
+ *
+ * arg:
+ *	subdevice number
+ *
+ * reads:
+ *	nothing
+ *
+ * writes:
+ *	nothing
+ */
 static int do_poll_ioctl(struct comedi_device *dev, unsigned long arg,
 			 void *file)
 {
@@ -1941,8 +1980,10 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
 
 	mutex_lock(&dev->mutex);
 
-	/* Device config is special, because it must work on
-	 * an unconfigured device. */
+	/*
+	 * Device config is special, because it must work on
+	 * an unconfigured device.
+	 */
 	if (cmd == COMEDI_DEVCONFIG) {
 		if (minor >= COMEDI_NUM_BOARD_MINORS) {
 			/* Device config not appropriate on non-board minors. */
@@ -1954,8 +1995,10 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
 		if (rc == 0) {
 			if (arg == 0 &&
 			    dev->minor >= comedi_num_legacy_minors) {
-				/* Successfully unconfigured a dynamically
-				 * allocated device.  Try and remove it. */
+				/*
+				 * Successfully unconfigured a dynamically
+				 * allocated device.  Try and remove it.
+				 */
 				if (comedi_clear_board_dev(dev)) {
 					mutex_unlock(&dev->mutex);
 					comedi_free_board_dev(dev);
@@ -2581,6 +2624,17 @@ static const struct file_operations comedi_fops = {
 	.llseek = noop_llseek,
 };
 
+/**
+ * comedi_event - handle events for asynchronous comedi command
+ * @dev: comedi_device struct
+ * @s: comedi_subdevice struct associated with dev
+ * Context: interrupt (usually), s->spin_lock spin-lock not held
+ *
+ * If an asynchronous comedi command is active on the subdevice, process
+ * any COMEDI_CB_... event flags that have been set, usually by an
+ * interrupt handler.  These may change the run state of the asynchronous
+ * command, wake a task, and/or send a SIGIO signal.
+ */
 void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_async *async = s->async;
@@ -2591,18 +2645,21 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
 		return;
 
 	if (s->async->events & COMEDI_CB_CANCEL_MASK)
-		runflags_mask |= SRF_RUNNING;
+		runflags_mask |= COMEDI_SRF_RUNNING;
 
 	/*
 	 * Remember if an error event has occurred, so an error
 	 * can be returned the next time the user does a read().
 	 */
 	if (s->async->events & COMEDI_CB_ERROR_MASK) {
-		runflags_mask |= SRF_ERROR;
-		runflags |= SRF_ERROR;
+		runflags_mask |= COMEDI_SRF_ERROR;
+		runflags |= COMEDI_SRF_ERROR;
 	}
 	if (runflags_mask) {
-		/*sets SRF_ERROR and SRF_RUNNING together atomically */
+		/*
+		 * Sets COMEDI_SRF_ERROR and COMEDI_SRF_RUNNING together
+		 * atomically.
+		 */
 		comedi_set_subdevice_runflags(s, runflags_mask, runflags);
 	}
 
diff --git a/drivers/staging/comedi/comedi_pcmcia.c b/drivers/staging/comedi/comedi_pcmcia.c
index 0529bae8e5ac..7e784399a16f 100644
--- a/drivers/staging/comedi/comedi_pcmcia.c
+++ b/drivers/staging/comedi/comedi_pcmcia.c
@@ -19,10 +19,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
-#include "comedidev.h"
+#include "comedi_pcmcia.h"
 
 /**
  * comedi_to_pcmcia_dev() - comedi_device pointer to pcmcia_device pointer.
diff --git a/drivers/staging/comedi/comedi_pcmcia.h b/drivers/staging/comedi/comedi_pcmcia.h
new file mode 100644
index 000000000000..5d3db2b9b4a1
--- /dev/null
+++ b/drivers/staging/comedi/comedi_pcmcia.h
@@ -0,0 +1,55 @@
+/*
+ * comedi_pcmcia.h
+ * header file for Comedi PCMCIA drivers
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _COMEDI_PCMCIA_H
+#define _COMEDI_PCMCIA_H
+
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "comedidev.h"
+
+struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *);
+
+int comedi_pcmcia_enable(struct comedi_device *,
+			 int (*conf_check)(struct pcmcia_device *, void *));
+void comedi_pcmcia_disable(struct comedi_device *);
+
+int comedi_pcmcia_auto_config(struct pcmcia_device *, struct comedi_driver *);
+void comedi_pcmcia_auto_unconfig(struct pcmcia_device *);
+
+int comedi_pcmcia_driver_register(struct comedi_driver *,
+				  struct pcmcia_driver *);
+void comedi_pcmcia_driver_unregister(struct comedi_driver *,
+				     struct pcmcia_driver *);
+
+/**
+ * module_comedi_pcmcia_driver() - Helper macro for registering a comedi PCMCIA driver
+ * @__comedi_driver: comedi_driver struct
+ * @__pcmcia_driver: pcmcia_driver struct
+ *
+ * Helper macro for comedi PCMCIA drivers which do not do anything special
+ * in module init/exit. This eliminates a lot of boilerplate. Each
+ * module may only use this macro once, and calling it replaces
+ * module_init() and module_exit()
+ */
+#define module_comedi_pcmcia_driver(__comedi_driver, __pcmcia_driver) \
+	module_driver(__comedi_driver, comedi_pcmcia_driver_register, \
+			comedi_pcmcia_driver_unregister, &(__pcmcia_driver))
+
+#endif /* _COMEDI_PCMCIA_H */
diff --git a/drivers/staging/comedi/comedi_usb.c b/drivers/staging/comedi/comedi_usb.c
index 0b862a64c049..68b75e8feec0 100644
--- a/drivers/staging/comedi/comedi_usb.c
+++ b/drivers/staging/comedi/comedi_usb.c
@@ -17,9 +17,8 @@
  */
 
 #include <linux/module.h>
-#include <linux/usb.h>
 
-#include "comedidev.h"
+#include "comedi_usb.h"
 
 /**
  * comedi_to_usb_interface() - comedi_device pointer to usb_interface pointer.
diff --git a/drivers/staging/comedi/comedi_usb.h b/drivers/staging/comedi/comedi_usb.h
new file mode 100644
index 000000000000..721128bece3c
--- /dev/null
+++ b/drivers/staging/comedi/comedi_usb.h
@@ -0,0 +1,50 @@
+/*
+ * comedi_usb.h
+ * header file for USB Comedi drivers
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _COMEDI_USB_H
+#define _COMEDI_USB_H
+
+#include <linux/usb.h>
+
+#include "comedidev.h"
+
+struct usb_interface *comedi_to_usb_interface(struct comedi_device *);
+struct usb_device *comedi_to_usb_dev(struct comedi_device *);
+
+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_driver_register(struct comedi_driver *, struct usb_driver *);
+void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *);
+
+/**
+ * module_comedi_usb_driver() - Helper macro for registering a comedi USB driver
+ * @__comedi_driver: comedi_driver struct
+ * @__usb_driver: usb_driver struct
+ *
+ * Helper macro for comedi USB drivers which do not do anything special
+ * in module init/exit. This eliminates a lot of boilerplate. Each
+ * module may only use this macro once, and calling it replaces
+ * module_init() and module_exit()
+ */
+#define module_comedi_usb_driver(__comedi_driver, __usb_driver) \
+	module_driver(__comedi_driver, comedi_usb_driver_register, \
+			comedi_usb_driver_unregister, &(__usb_driver))
+
+#endif /* _COMEDI_USB_H */
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index 77be191988ca..e138eb0dc374 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -299,34 +299,25 @@ struct comedi_device {
 
 void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s);
 
-/* we can expand the number of bits used to encode devices/subdevices into
- the minor number soon, after more distros support > 8 bit minor numbers
- (like after Debian Etch gets released) */
-enum comedi_minor_bits {
-	COMEDI_DEVICE_MINOR_MASK = 0xf,
-	COMEDI_SUBDEVICE_MINOR_MASK = 0xf0
-};
-
-static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4;
-static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
-
 struct comedi_device *comedi_dev_get_from_minor(unsigned minor);
 int comedi_dev_put(struct comedi_device *dev);
 
-void init_polling(void);
-void cleanup_polling(void);
-void start_polling(struct comedi_device *);
-void stop_polling(struct comedi_device *);
-
-/* subdevice runflags */
-enum subdevice_runflags {
-	SRF_RT = 0x00000002,
-	/* indicates an COMEDI_CB_ERROR event has occurred since the last
-	 * command was started */
-	SRF_ERROR = 0x00000004,
-	SRF_RUNNING = 0x08000000,
-	SRF_FREE_SPRIV = 0x80000000,	/* free s->private on detach */
-};
+/**
+ * comedi_subdevice "runflags"
+ * @COMEDI_SRF_RT:		DEPRECATED: command is running real-time
+ * @COMEDI_SRF_ERROR:		indicates an COMEDI_CB_ERROR event has occurred
+ *				since the last command was started
+ * @COMEDI_SRF_RUNNING:		command is running
+ * @COMEDI_SRF_FREE_SPRIV:	free s->private on detach
+ *
+ * @COMEDI_SRF_BUSY_MASK:	runflags that indicate the subdevice is "busy"
+ */
+#define COMEDI_SRF_RT		BIT(1)
+#define COMEDI_SRF_ERROR	BIT(2)
+#define COMEDI_SRF_RUNNING	BIT(27)
+#define COMEDI_SRF_FREE_SPRIV	BIT(31)
+
+#define COMEDI_SRF_BUSY_MASK	(COMEDI_SRF_ERROR | COMEDI_SRF_RUNNING)
 
 bool comedi_is_subdevice_running(struct comedi_subdevice *s);
 
@@ -605,66 +596,4 @@ void comedi_pci_driver_unregister(struct comedi_driver *, struct pci_driver *);
 	module_driver(__comedi_driver, comedi_pci_driver_register, \
 			comedi_pci_driver_unregister, &(__pci_driver))
 
-/* comedi_pcmcia.c - comedi PCMCIA driver specific functions */
-
-struct pcmcia_driver;
-struct pcmcia_device;
-
-struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *);
-
-int comedi_pcmcia_enable(struct comedi_device *,
-			 int (*conf_check)(struct pcmcia_device *, void *));
-void comedi_pcmcia_disable(struct comedi_device *);
-
-int comedi_pcmcia_auto_config(struct pcmcia_device *, struct comedi_driver *);
-void comedi_pcmcia_auto_unconfig(struct pcmcia_device *);
-
-int comedi_pcmcia_driver_register(struct comedi_driver *,
-				  struct pcmcia_driver *);
-void comedi_pcmcia_driver_unregister(struct comedi_driver *,
-				     struct pcmcia_driver *);
-
-/**
- * module_comedi_pcmcia_driver() - Helper macro for registering a comedi PCMCIA driver
- * @__comedi_driver: comedi_driver struct
- * @__pcmcia_driver: pcmcia_driver struct
- *
- * Helper macro for comedi PCMCIA drivers which do not do anything special
- * in module init/exit. This eliminates a lot of boilerplate. Each
- * module may only use this macro once, and calling it replaces
- * module_init() and module_exit()
- */
-#define module_comedi_pcmcia_driver(__comedi_driver, __pcmcia_driver) \
-	module_driver(__comedi_driver, comedi_pcmcia_driver_register, \
-			comedi_pcmcia_driver_unregister, &(__pcmcia_driver))
-
-/* comedi_usb.c - comedi USB driver specific functions */
-
-struct usb_driver;
-struct usb_interface;
-
-struct usb_interface *comedi_to_usb_interface(struct comedi_device *);
-struct usb_device *comedi_to_usb_dev(struct comedi_device *);
-
-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_driver_register(struct comedi_driver *, struct usb_driver *);
-void comedi_usb_driver_unregister(struct comedi_driver *, struct usb_driver *);
-
-/**
- * module_comedi_usb_driver() - Helper macro for registering a comedi USB driver
- * @__comedi_driver: comedi_driver struct
- * @__usb_driver: usb_driver struct
- *
- * Helper macro for comedi USB drivers which do not do anything special
- * in module init/exit. This eliminates a lot of boilerplate. Each
- * module may only use this macro once, and calling it replaces
- * module_init() and module_exit()
- */
-#define module_comedi_usb_driver(__comedi_driver, __usb_driver) \
-	module_driver(__comedi_driver, comedi_usb_driver_register, \
-			comedi_usb_driver_unregister, &(__usb_driver))
-
 #endif /* _COMEDIDEV_H */
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 61802d7947ae..f32e71438948 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -125,7 +125,7 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev)
 	if (dev->subdevices) {
 		for (i = 0; i < dev->n_subdevices; i++) {
 			s = &dev->subdevices[i];
-			if (s->runflags & SRF_FREE_SPRIV)
+			if (s->runflags & COMEDI_SRF_FREE_SPRIV)
 				kfree(s->private);
 			comedi_free_subdevice_minor(s);
 			if (s->async) {
diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h
index 9f4c1411719d..51b9c8d279c0 100644
--- a/drivers/staging/comedi/drivers/8253.h
+++ b/drivers/staging/comedi/drivers/8253.h
@@ -1,20 +1,20 @@
 /*
-    comedi/drivers/8253.h
-    Header file for 8253
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-*/
+ * comedi/drivers/8253.h
+ * Header file for 8253
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
 #ifndef _8253_H
 #define _8253_H
@@ -44,9 +44,11 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
 	unsigned int start;
 	unsigned int ns_low, ns_high;
 	static const unsigned int max_count = 0x10000;
-	/* exit early if everything is already correct (this can save time
+	/*
+	 * exit early if everything is already correct (this can save time
 	 * since this function may be called repeatedly during command tests
-	 * and execution) */
+	 * and execution)
+	 */
 	div1 = *d1 ? *d1 : max_count;
 	div2 = *d2 ? *d2 : max_count;
 	divider = div1 * div2;
@@ -114,13 +116,14 @@ static inline void i8253_cascade_ns_to_timer(int i8253_osc_base,
 	}
 
 	*nanosec = div1 * div2 * i8253_osc_base;
-	/*  masking is done since counter maps zero to 0x10000 */
+	/* masking is done since counter maps zero to 0x10000 */
 	*d1 = div1 & 0xffff;
 	*d2 = div2 & 0xffff;
 }
 
 #ifndef CMDTEST
-/* i8254_load programs 8254 counter chip.  It should also work for the 8253.
+/*
+ * i8254_load programs 8254 counter chip.  It should also work for the 8253.
  * base_address is the lowest io address
  * for the chip (the address of counter 0).
  * counter_number is the counter you want to load (0,1 or 2)
@@ -158,12 +161,12 @@ static inline int i8254_load(unsigned long base_address, unsigned int regshift,
 		return -1;
 
 	byte = counter_number << 6;
-	byte |= 0x30;		/*  load low then high byte */
-	byte |= (mode << 1);	/*  set counter mode */
+	byte |= 0x30;		/* load low then high byte */
+	byte |= (mode << 1);	/* set counter mode */
 	outb(byte, base_address + (i8254_control_reg << regshift));
-	byte = count & 0xff;	/*  lsb of counter value */
+	byte = count & 0xff;	/* lsb of counter value */
 	outb(byte, base_address + (counter_number << regshift));
-	byte = (count >> 8) & 0xff;	/*  msb of counter value */
+	byte = (count >> 8) & 0xff;	/* msb of counter value */
 	outb(byte, base_address + (counter_number << regshift));
 
 	return 0;
@@ -187,18 +190,18 @@ static inline int i8254_mm_load(void __iomem *base_address,
 		return -1;
 
 	byte = counter_number << 6;
-	byte |= 0x30;		/*  load low then high byte */
-	byte |= (mode << 1);	/*  set counter mode */
+	byte |= 0x30;		/* load low then high byte */
+	byte |= (mode << 1);	/* set counter mode */
 	writeb(byte, base_address + (i8254_control_reg << regshift));
-	byte = count & 0xff;	/*  lsb of counter value */
+	byte = count & 0xff;	/* lsb of counter value */
 	writeb(byte, base_address + (counter_number << regshift));
-	byte = (count >> 8) & 0xff;	/*  msb of counter value */
+	byte = (count >> 8) & 0xff;	/* msb of counter value */
 	writeb(byte, base_address + (counter_number << regshift));
 
 	return 0;
 }
 
-/* Returns 16 bit counter value, should work for 8253 also.*/
+/* Returns 16 bit counter value, should work for 8253 also. */
 static inline int i8254_read(unsigned long base_address, unsigned int regshift,
 			     unsigned int counter_number)
 {
@@ -208,13 +211,13 @@ static inline int i8254_read(unsigned long base_address, unsigned int regshift,
 	if (counter_number > 2)
 		return -1;
 
-	/*  latch counter */
+	/* latch counter */
 	byte = counter_number << 6;
 	outb(byte, base_address + (i8254_control_reg << regshift));
 
-	/*  read lsb */
+	/* read lsb */
 	ret = inb(base_address + (counter_number << regshift));
-	/*  read msb */
+	/* read msb */
 	ret += inb(base_address + (counter_number << regshift)) << 8;
 
 	return ret;
@@ -230,13 +233,13 @@ static inline int i8254_mm_read(void __iomem *base_address,
 	if (counter_number > 2)
 		return -1;
 
-	/*  latch counter */
+	/* latch counter */
 	byte = counter_number << 6;
 	writeb(byte, base_address + (i8254_control_reg << regshift));
 
-	/*  read lsb */
+	/* read lsb */
 	ret = readb(base_address + (counter_number << regshift));
-	/*  read msb */
+	/* read msb */
 	ret += readb(base_address + (counter_number << regshift)) << 8;
 
 	return ret;
@@ -252,9 +255,9 @@ static inline void i8254_write(unsigned long base_address,
 	if (counter_number > 2)
 		return;
 
-	byte = count & 0xff;	/*  lsb of counter value */
+	byte = count & 0xff;	/* lsb of counter value */
 	outb(byte, base_address + (counter_number << regshift));
-	byte = (count >> 8) & 0xff;	/*  msb of counter value */
+	byte = (count >> 8) & 0xff;	/* msb of counter value */
 	outb(byte, base_address + (counter_number << regshift));
 }
 
@@ -268,13 +271,14 @@ static inline void i8254_mm_write(void __iomem *base_address,
 	if (counter_number > 2)
 		return;
 
-	byte = count & 0xff;	/*  lsb of counter value */
+	byte = count & 0xff;	/* lsb of counter value */
 	writeb(byte, base_address + (counter_number << regshift));
-	byte = (count >> 8) & 0xff;	/*  msb of counter value */
+	byte = (count >> 8) & 0xff;	/* msb of counter value */
 	writeb(byte, base_address + (counter_number << regshift));
 }
 
-/* Set counter mode, should work for 8253 also.
+/*
+ * Set counter mode, should work for 8253 also.
  * Note: the 'mode' value is different to that for i8254_load() and comes
  * from the INSN_CONFIG_8254_SET_MODE command:
  *   I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
@@ -293,8 +297,8 @@ static inline int i8254_set_mode(unsigned long base_address,
 		return -1;
 
 	byte = counter_number << 6;
-	byte |= 0x30;		/*  load low then high byte */
-	byte |= mode;		/*  set counter mode and BCD|binary */
+	byte |= 0x30;		/* load low then high byte */
+	byte |= mode;		/* set counter mode and BCD|binary */
 	outb(byte, base_address + (i8254_control_reg << regshift));
 
 	return 0;
@@ -313,8 +317,8 @@ static inline int i8254_mm_set_mode(void __iomem *base_address,
 		return -1;
 
 	byte = counter_number << 6;
-	byte |= 0x30;		/*  load low then high byte */
-	byte |= mode;		/*  set counter mode and BCD|binary */
+	byte |= 0x30;		/* load low then high byte */
+	byte |= mode;		/* set counter mode and BCD|binary */
 	writeb(byte, base_address + (i8254_control_reg << regshift));
 
 	return 0;
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
index 34d4d8b5f31e..c2f15de6a547 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -1,76 +1,51 @@
 /*
-    comedi/drivers/8255.c
-    Driver for 8255
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1998 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-*/
-/*
-Driver: 8255
-Description: generic 8255 support
-Devices: [standard] 8255 (8255)
-Author: ds
-Status: works
-Updated: Fri,  7 Jun 2002 12:56:45 -0700
-
-The classic in digital I/O.  The 8255 appears in Comedi as a single
-digital I/O subdevice with 24 channels.  The channel 0 corresponds
-to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
-7.  Direction configuration is done in blocks, with channels 0-7,
-8-15, 16-19, and 20-23 making up the 4 blocks.  The only 8255 mode
-supported is mode 0.
-
-You should enable compilation this driver if you plan to use a board
-that has an 8255 chip.  For multifunction boards, the main driver will
-configure the 8255 subdevice automatically.
-
-This driver also works independently with ISA and PCI cards that
-directly map the 8255 registers to I/O ports, including cards with
-multiple 8255 chips.  To configure the driver for such a card, the
-option list should be a list of the I/O port bases for each of the
-8255 chips.  For example,
-
-  comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
-
-Note that most PCI 8255 boards do NOT work with this driver, and
-need a separate driver as a wrapper.  For those that do work, the
-I/O port base address can be found in the output of 'lspci -v'.
-
-*/
+ * comedi/drivers/8255.c
+ * Driver for 8255
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
 /*
-   This file contains an exported subdevice for driving an 8255.
-
-   To use this subdevice as part of another driver, you need to
-   set up the subdevice in the attach function of the driver by
-   calling:
-
-     subdev_8255_init(device, subdevice, io_function, iobase)
-
-   device and subdevice are pointers to the device and subdevice
-   structures.  io_function will be called to provide the
-   low-level input/output to the device, i.e., actual register
-   access.  io_function will be called with the value of iobase
-   as the last parameter.  If the 8255 device is mapped as 4
-   consecutive I/O ports, you can use NULL for io_function
-   and the I/O port base for iobase, and an internal function will
-   handle the register access.
-
-   In addition, if the main driver handles interrupts, you can
-   enable commands on the subdevice by calling subdev_8255_init_irq()
-   instead.  Then, when you get an interrupt that is likely to be
-   from the 8255, you should call subdev_8255_interrupt(), which
-   will copy the latched value to a Comedi buffer.
+ * Driver: 8255
+ * Description: generic 8255 support
+ * Devices: [standard] 8255 (8255)
+ * Author: ds
+ * Status: works
+ * Updated: Fri,  7 Jun 2002 12:56:45 -0700
+ *
+ * The classic in digital I/O.  The 8255 appears in Comedi as a single
+ * digital I/O subdevice with 24 channels.  The channel 0 corresponds
+ * to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
+ * 7.  Direction configuration is done in blocks, with channels 0-7,
+ * 8-15, 16-19, and 20-23 making up the 4 blocks.  The only 8255 mode
+ * supported is mode 0.
+ *
+ * You should enable compilation this driver if you plan to use a board
+ * that has an 8255 chip.  For multifunction boards, the main driver will
+ * configure the 8255 subdevice automatically.
+ *
+ * This driver also works independently with ISA and PCI cards that
+ * directly map the 8255 registers to I/O ports, including cards with
+ * multiple 8255 chips.  To configure the driver for such a card, the
+ * option list should be a list of the I/O port bases for each of the
+ * 8255 chips.  For example,
+ *
+ *   comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
+ *
+ * Note that most PCI 8255 boards do NOT work with this driver, and
+ * need a separate driver as a wrapper.  For those that do work, the
+ * I/O port base address can be found in the output of 'lspci -v'.
  */
 
 #include <linux/module.h>
@@ -218,6 +193,33 @@ static int __subdev_8255_init(struct comedi_device *dev,
 	return 0;
 }
 
+/**
+ * subdev_8255_init - initialize DIO subdevice for driving I/O mapped 8255
+ * @dev: comedi device owning subdevice
+ * @s: comedi subdevice to initialize
+ * @io: (optional) register I/O call-back function
+ * @regbase: offset of 8255 registers from dev->iobase, or call-back context
+ *
+ * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip.
+ *
+ * If the optional I/O call-back function is provided, its prototype is of
+ * the following form:
+ *
+ *   int my_8255_callback(struct comedi_device *dev,
+ *                        struct comedi_subdevice *s, int dir, int port,
+ *                        int data, unsigned long regbase);
+ *
+ * where 'dev', 's', and 'regbase' match the values passed to this function,
+ * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir'
+ * is the direction (0 for read, 1 for write) and 'data' is the value to be
+ * written.  It should return 0 if writing or the value read if reading.
+ *
+ * If the optional I/O call-back function is not provided, an internal
+ * call-back function is used which uses consecutive I/O port addresses
+ * starting at dev->iobase + regbase.
+ *
+ * Return: -ENOMEM if failed to allocate memory, zero on success.
+ */
 int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
 		     int (*io)(struct comedi_device *,
 			       int, int, int, unsigned long),
@@ -227,6 +229,33 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 EXPORT_SYMBOL_GPL(subdev_8255_init);
 
+/**
+ * subdev_8255_mm_init - initialize DIO subdevice for driving mmio-mapped 8255
+ * @dev: comedi device owning subdevice
+ * @s: comedi subdevice to initialize
+ * @io: (optional) register I/O call-back function
+ * @regbase: offset of 8255 registers from dev->mmio, or call-back context
+ *
+ * Initializes a comedi subdevice as a DIO subdevice driving an 8255 chip.
+ *
+ * If the optional I/O call-back function is provided, its prototype is of
+ * the following form:
+ *
+ *   int my_8255_callback(struct comedi_device *dev,
+ *                        struct comedi_subdevice *s, int dir, int port,
+ *                        int data, unsigned long regbase);
+ *
+ * where 'dev', 's', and 'regbase' match the values passed to this function,
+ * 'port' is the 8255 port number 0 to 3 (including the control port), 'dir'
+ * is the direction (0 for read, 1 for write) and 'data' is the value to be
+ * written.  It should return 0 if writing or the value read if reading.
+ *
+ * If the optional I/O call-back function is not provided, an internal
+ * call-back function is used which uses consecutive MMIO virtual addresses
+ * starting at dev->mmio + regbase.
+ *
+ * Return: -ENOMEM if failed to allocate memory, zero on success.
+ */
 int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s,
 			int (*io)(struct comedi_device *,
 				  int, int, int, unsigned long),
@@ -235,10 +264,9 @@ int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s,
 	return __subdev_8255_init(dev, s, io, regbase, true);
 }
 EXPORT_SYMBOL_GPL(subdev_8255_mm_init);
-/*
-
-   Start of the 8255 standalone device
 
+/*
+ * Start of the 8255 standalone device
  */
 
 static int dev_8255_attach(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h
index 5985c8e0330f..934b940ebd3c 100644
--- a/drivers/staging/comedi/drivers/8255.h
+++ b/drivers/staging/comedi/drivers/8255.h
@@ -1,20 +1,20 @@
 /*
-    module/8255.h
-    Header file for 8255
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1998 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-*/
+ * module/8255.h
+ * Header file for 8255
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
 #ifndef _8255_H
 #define _8255_H
diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c
index 8b9589828855..984764211a2d 100644
--- a/drivers/staging/comedi/drivers/8255_pci.c
+++ b/drivers/staging/comedi/drivers/8255_pci.c
@@ -22,33 +22,44 @@
  */
 
 /*
-Driver: 8255_pci
-Description: Generic PCI based 8255 Digital I/O boards
-Devices: (ADLink) PCI-7224 [adl_pci-7224] - 24 channels
-	 (ADLink) PCI-7248 [adl_pci-7248] - 48 channels
-	 (ADLink) PCI-7296 [adl_pci-7296] - 96 channels
-	 (Measurement Computing) PCI-DIO24 [cb_pci-dio24] - 24 channels
-	 (Measurement Computing) PCI-DIO24H [cb_pci-dio24h] - 24 channels
-	 (Measurement Computing) PCI-DIO48H [cb_pci-dio48h] - 48 channels
-	 (Measurement Computing) PCI-DIO96H [cb_pci-dio96h] - 96 channels
-	 (National Instruments) PCI-DIO-96 [ni_pci-dio-96] - 96 channels
-	 (National Instruments) PCI-DIO-96B [ni_pci-dio-96b] - 96 channels
-	 (National Instruments) PXI-6508 [ni_pxi-6508] - 96 channels
-	 (National Instruments) PCI-6503 [ni_pci-6503] - 24 channels
-	 (National Instruments) PCI-6503B [ni_pci-6503b] - 24 channels
-	 (National Instruments) PCI-6503X [ni_pci-6503x] - 24 channels
-	 (National Instruments) PXI-6503 [ni_pxi-6503] - 24 channels
-Author: H Hartley Sweeten <hsweeten@visionengravers.com>
-Updated: Wed, 12 Sep 2012 11:52:01 -0700
-Status: untested
-
-Some of these boards also have an 8254 programmable timer/counter
-chip. This chip is not currently supported by this driver.
-
-Interrupt support for these boards is also not currently supported.
-
-Configuration Options: not applicable, uses PCI auto config
-*/
+ * Driver: 8255_pci
+ * Description: Generic PCI based 8255 Digital I/O boards
+ * Devices: [ADLink] PCI-7224 (adl_pci-7224), PCI-7248 (adl_pci-7248),
+ *   PCI-7296 (adl_pci-7296),
+ *   [Measurement Computing] PCI-DIO24 (cb_pci-dio24),
+ *   PCI-DIO24H (cb_pci-dio24h), PCI-DIO48H (cb_pci-dio48h),
+ *   PCI-DIO96H (cb_pci-dio96h),
+ *   [National Instruments] PCI-DIO-96 (ni_pci-dio-96),
+ *   PCI-DIO-96B (ni_pci-dio-96b), PXI-6508 (ni_pxi-6508),
+ *   PCI-6503 (ni_pci-6503), PCI-6503B (ni_pci-6503b),
+ *   PCI-6503X (ni_pci-6503x), PXI-6503 (ni_pxi-6503)
+ * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
+ * Updated: Wed, 12 Sep 2012 11:52:01 -0700
+ * Status: untested
+ *
+ * These boards have one or more 8255 digital I/O chips, each of which
+ * is supported as a separate 24-channel DIO subdevice.
+ *
+ * Boards with 24 DIO channels (1 DIO subdevice):
+ *
+ *   PCI-7224, PCI-DIO24, PCI-DIO24H, PCI-6503, PCI-6503B, PCI-6503X,
+ *   PXI-6503
+ *
+ * Boards with 48 DIO channels (2 DIO subdevices):
+ *
+ *   PCI-7248, PCI-DIO48H
+ *
+ * Boards with 96 DIO channels (4 DIO subdevices):
+ *
+ *   PCI-7296, PCI-DIO96H, PCI-DIO-96, PCI-DIO-96B, PXI-6508
+ *
+ * Some of these boards also have an 8254 programmable timer/counter
+ * chip.  This chip is not currently supported by this driver.
+ *
+ * Interrupt support for these boards is also not currently supported.
+ *
+ * Configuration Options: not applicable, uses PCI auto config.
+ */
 
 #include <linux/module.h>
 #include <linux/pci.h>
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index 84fdf20ca986..7d1fbd53a8ab 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -3,6 +3,7 @@
 ccflags-$(CONFIG_COMEDI_DEBUG)		:= -DDEBUG
 
 # Comedi "helper" modules
+obj-$(CONFIG_COMEDI_ISADMA)		+= comedi_isadma.o
 
 # Comedi misc drivers
 obj-$(CONFIG_COMEDI_BOND)		+= comedi_bond.o
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
deleted file mode 100644
index bfa9228c833f..000000000000
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
+++ /dev/null
@@ -1,2365 +0,0 @@
-/*
- * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
- *
- *	ADDI-DATA GmbH
- *	Dieselstrasse 3
- *	D-77833 Ottersweier
- *	Tel: +19(0)7223/9493-0
- *	Fax: +49(0)7223/9493-92
- *	http://www.addi-data.com
- *	info@addi-data.com
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * 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.
- *
- */
-
-/* Card Specific information */
-#define APCI1500_ADDRESS_RANGE		4
-
-/* DIGITAL INPUT-OUTPUT DEFINE */
-
-#define APCI1500_DIGITAL_OP		2
-#define APCI1500_DIGITAL_IP		0
-#define APCI1500_AND			2
-#define APCI1500_OR			4
-#define APCI1500_OR_PRIORITY		6
-#define APCI1500_CLK_SELECT		0
-#define COUNTER1			0
-#define COUNTER2			1
-#define COUNTER3			2
-#define APCI1500_COUNTER		0x20
-#define APCI1500_TIMER			0
-#define APCI1500_WATCHDOG		0
-#define APCI1500_SINGLE			0
-#define APCI1500_CONTINUOUS		0x80
-#define APCI1500_DISABLE		0
-#define APCI1500_ENABLE			1
-#define APCI1500_SOFTWARE_TRIGGER	0x4
-#define APCI1500_HARDWARE_TRIGGER	0x10
-#define APCI1500_SOFTWARE_GATE		0
-#define APCI1500_HARDWARE_GATE		0x8
-#define START				0
-#define STOP				1
-#define TRIGGER				2
-
-/*
- * Zillog I/O enumeration
- */
-enum {
-	APCI1500_Z8536_PORT_C,
-	APCI1500_Z8536_PORT_B,
-	APCI1500_Z8536_PORT_A,
-	APCI1500_Z8536_CONTROL_REGISTER
-};
-
-/*
- * Z8536 CIO Internal Address
- */
-enum {
-	APCI1500_RW_MASTER_INTERRUPT_CONTROL,
-	APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-	APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
-	APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
-	APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
-	APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
-	APCI1500_RW_PORT_C_DATA_DIRECTION,
-	APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
-
-	APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-	APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-	APCI1500_RW_CPT_TMR1_CMD_STATUS,
-	APCI1500_RW_CPT_TMR2_CMD_STATUS,
-	APCI1500_RW_CPT_TMR3_CMD_STATUS,
-	APCI1500_RW_PORT_A_DATA,
-	APCI1500_RW_PORT_B_DATA,
-	APCI1500_RW_PORT_C_DATA,
-
-	APCI1500_R_CPT_TMR1_VALUE_HIGH,
-	APCI1500_R_CPT_TMR1_VALUE_LOW,
-	APCI1500_R_CPT_TMR2_VALUE_HIGH,
-	APCI1500_R_CPT_TMR2_VALUE_LOW,
-	APCI1500_R_CPT_TMR3_VALUE_HIGH,
-	APCI1500_R_CPT_TMR3_VALUE_LOW,
-	APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
-	APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
-	APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
-	APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
-	APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
-	APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
-	APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
-	APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
-	APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
-	APCI1500_R_CURRENT_VECTOR,
-
-	APCI1500_RW_PORT_A_SPECIFICATION,
-	APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
-	APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
-	APCI1500_RW_PORT_A_DATA_DIRECTION,
-	APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
-	APCI1500_RW_PORT_A_PATTERN_POLARITY,
-	APCI1500_RW_PORT_A_PATTERN_TRANSITION,
-	APCI1500_RW_PORT_A_PATTERN_MASK,
-
-	APCI1500_RW_PORT_B_SPECIFICATION,
-	APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
-	APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
-	APCI1500_RW_PORT_B_DATA_DIRECTION,
-	APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
-	APCI1500_RW_PORT_B_PATTERN_POLARITY,
-	APCI1500_RW_PORT_B_PATTERN_TRANSITION,
-	APCI1500_RW_PORT_B_PATTERN_MASK
-};
-
-static int i_TimerCounter1Init;
-static int i_TimerCounter2Init;
-static int i_WatchdogCounter3Init;
-static int i_Event1Status, i_Event2Status;
-static int i_TimerCounterWatchdogInterrupt;
-static int i_Logic, i_CounterLogic;
-static int i_InterruptMask;
-static int i_InputChannel;
-static int i_TimerCounter1Enabled, i_TimerCounter2Enabled,
-	   i_WatchdogCounter3Enabled;
-
-/*
- * An event can be generated for each port. The first event is related to the
- * first 8 channels (port 1) and the second to the following 6 channels (port 2)
- * An interrupt is generated when one or both events have occurred.
- *
- * data[0] Number of the input port on which the event will take place (1 or 2)
- * data[1] The event logic for port 1 has three possibilities:
- *	APCI1500_AND		This logic links the inputs with an AND logic.
- *	APCI1500_OR		This logic links the inputs with a OR logic.
- *	APCI1500_OR_PRIORITY	This logic links the inputs with a priority OR
- *				logic. Input 1 has the highest priority level
- *				and input 8 the	smallest.
- *	For the second port the user has 1 possibility:
- *	APCI1500_OR	This logic links the inputs with a polarity OR logic
- * data[2] These 8-character word for port1 and 6-character word for port 2
- *	   give the mask of the event. Each place gives the state of the input
- *	   channels and can have one of these six characters
- *	0 This input must be on 0
- *	1 This input must be on 1
- *	2 This input reacts to a falling edge
- *	3 This input reacts to a rising edge
- *	4 This input reacts to both edges
- *	5 This input is not used for event
- */
-static int apci1500_di_config(struct comedi_device *dev,
-			      struct comedi_subdevice *s,
-			      struct comedi_insn *insn,
-			      unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-	int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0;
-	int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0;
-	int i_PatternTransitionCount = 0, i_RegValue;
-	int i;
-
-	/* Selects the master interrupt control register */
-	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Disables  the main interrupt on the board */
-	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	if (data[0] == 1) {
-		i_MaxChannel = 8;
-	} else {
-		if (data[0] == 2) {
-			i_MaxChannel = 6;
-		} else {
-			dev_warn(dev->class_dev,
-				"The specified port event does not exist\n");
-			return -EINVAL;
-		}
-	}
-	switch (data[1]) {
-	case 0:
-		data[1] = APCI1500_AND;
-		break;
-	case 1:
-		data[1] = APCI1500_OR;
-		break;
-	case 2:
-		data[1] = APCI1500_OR_PRIORITY;
-		break;
-	default:
-		dev_warn(dev->class_dev,
-			"The specified interrupt logic does not exist\n");
-		return -EINVAL;
-	}
-
-	i_Logic = data[1];
-	for (i_Count = i_MaxChannel, i = 0; i_Count > 0; i_Count--, i++) {
-		i_EventMask = data[2 + i];
-		switch (i_EventMask) {
-		case 0:
-			i_PatternMask =
-				i_PatternMask | (1 << (i_MaxChannel - i_Count));
-			break;
-		case 1:
-			i_PatternMask =
-				i_PatternMask | (1 << (i_MaxChannel - i_Count));
-			i_PatternPolarity =
-				i_PatternPolarity | (1 << (i_MaxChannel -
-					i_Count));
-			break;
-		case 2:
-			i_PatternMask =
-				i_PatternMask | (1 << (i_MaxChannel - i_Count));
-			i_PatternTransition =
-				i_PatternTransition | (1 << (i_MaxChannel -
-					i_Count));
-			break;
-		case 3:
-			i_PatternMask =
-				i_PatternMask | (1 << (i_MaxChannel - i_Count));
-			i_PatternPolarity =
-				i_PatternPolarity | (1 << (i_MaxChannel -
-					i_Count));
-			i_PatternTransition =
-				i_PatternTransition | (1 << (i_MaxChannel -
-					i_Count));
-			break;
-		case 4:
-			i_PatternTransition =
-				i_PatternTransition | (1 << (i_MaxChannel -
-					i_Count));
-			break;
-		case 5:
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"The option indicated in the event mask does not exist\n");
-			return -EINVAL;
-		}
-	}
-
-	if (data[0] == 1) {
-		/* Test the interrupt logic */
-
-		if (data[1] == APCI1500_AND ||
-			data[1] == APCI1500_OR ||
-			data[1] == APCI1500_OR_PRIORITY) {
-			/* Tests if a transition was declared */
-			/* for a OR PRIORITY logic            */
-
-			if (data[1] == APCI1500_OR_PRIORITY
-				&& i_PatternTransition != 0) {
-				dev_warn(dev->class_dev,
-					"Transition error on an OR PRIORITY logic\n");
-				return -EINVAL;
-			}
-
-			/* Tests if more than one transition */
-			/* was declared for an AND logic     */
-
-			if (data[1] == APCI1500_AND) {
-				for (i_Count = 0; i_Count < 8; i_Count++) {
-					i_PatternTransitionCount =
-						i_PatternTransitionCount +
-						((i_PatternTransition >>
-							i_Count) & 0x1);
-
-				}
-
-				if (i_PatternTransitionCount > 1) {
-					dev_warn(dev->class_dev,
-						"Transition error on an AND logic\n");
-					return -EINVAL;
-				}
-			}
-
-			/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-			outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Disable Port A */
-			outb(0xF0,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Selects the polarity register of port 1    */
-			outb(APCI1500_RW_PORT_A_PATTERN_POLARITY,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(i_PatternPolarity,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Selects the pattern mask register of      */
-			/* port 1                                    */
-			outb(APCI1500_RW_PORT_A_PATTERN_MASK,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(i_PatternMask,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Selects the pattern transition register  */
-			/* of port 1                                */
-			outb(APCI1500_RW_PORT_A_PATTERN_TRANSITION,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(i_PatternTransition,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Selects the mode specification mask    */
-			/* register of port 1                     */
-			outb(APCI1500_RW_PORT_A_SPECIFICATION,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_RegValue =
-				inb(devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Selects the mode specification mask    */
-			/* register of port 1                     */
-			outb(APCI1500_RW_PORT_A_SPECIFICATION,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Port A new mode    */
-
-			i_RegValue = (i_RegValue & 0xF9) | data[1] | 0x9;
-			outb(i_RegValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			i_Event1Status = 1;
-
-			/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-
-			outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Enable Port A */
-			outb(0xF4,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-		} else {
-			dev_warn(dev->class_dev,
-				"The choice for interrupt logic does not exist\n");
-			return -EINVAL;
-		}
-	}
-
-	/* Test if event setting for port 2 */
-
-	if (data[0] == 2) {
-		/* Test the event logic */
-
-		if (data[1] == APCI1500_OR) {
-			/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-			outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Disable Port B */
-			outb(0x74,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Selects the mode specification mask  */
-			/* register of port B                   */
-			outb(APCI1500_RW_PORT_B_SPECIFICATION,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_RegValue =
-				inb(devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Selects the mode specification mask    */
-			/* register of port B                     */
-			outb(APCI1500_RW_PORT_B_SPECIFICATION,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_RegValue = i_RegValue & 0xF9;
-			outb(i_RegValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Selects error channels 1 and 2 */
-
-			i_PatternMask = (i_PatternMask | 0xC0);
-			i_PatternPolarity = (i_PatternPolarity | 0xC0);
-			i_PatternTransition = (i_PatternTransition | 0xC0);
-
-			/* Selects the polarity register of port 2    */
-			outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(i_PatternPolarity,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Selects the pattern transition register    */
-			/* of port 2                                  */
-			outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(i_PatternTransition,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Selects the pattern Mask register    */
-			/* of port 2                                  */
-
-			outb(APCI1500_RW_PORT_B_PATTERN_MASK,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(i_PatternMask,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Selects the mode specification mask    */
-			/* register of port 2                     */
-			outb(APCI1500_RW_PORT_B_SPECIFICATION,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_RegValue =
-				inb(devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Selects the mode specification mask    */
-			/* register of port 2                     */
-			outb(APCI1500_RW_PORT_B_SPECIFICATION,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_RegValue = (i_RegValue & 0xF9) | 4;
-			outb(i_RegValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			i_Event2Status = 1;
-			/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-
-			outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Enable Port B */
-
-			outb(0xF4,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-		} else {
-			dev_warn(dev->class_dev,
-				"The choice for interrupt logic does not exist\n");
-			return -EINVAL;
-		}
-	}
-
-	return insn->n;
-}
-
-/*
- * Allows or disallows a port event
- *
- * data[0] 0 = Start input event, 1 = Stop input event
- * data[1] Number of port (1 or 2)
- */
-static int apci1500_di_write(struct comedi_device *dev,
-			     struct comedi_subdevice *s,
-			     struct comedi_insn *insn,
-			     unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-	int i_Event1InterruptStatus = 0, i_Event2InterruptStatus =
-		0, i_RegValue;
-
-	switch (data[0]) {
-	case START:
-		/* Tests the port number */
-
-		if (data[1] == 1 || data[1] == 2) {
-			/* Test if port 1 selected */
-
-			if (data[1] == 1) {
-				/* Test if event initialised */
-				if (i_Event1Status == 1) {
-					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Disable Port A */
-					outb(0xF0,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Selects the command and status register of      */
-					/* port 1                                          */
-					outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Allows the pattern interrupt      */
-					outb(0xC0,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Enable Port A */
-					outb(0xF4,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					i_Event1InterruptStatus = 1;
-					outb(APCI1500_RW_PORT_A_SPECIFICATION,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					i_RegValue =
-						inb(devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-
-					/* Selects the master interrupt control register */
-					outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Authorizes the main interrupt on the board */
-					outb(0xD0,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-
-				} else {
-					dev_warn(dev->class_dev,
-						"Event 1 not initialised\n");
-					return -EINVAL;
-				}
-			}
-			if (data[1] == 2) {
-
-				if (i_Event2Status == 1) {
-					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Disable Port B */
-					outb(0x74,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Selects the command and status register of      */
-					/* port 2                                          */
-					outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Allows the pattern interrupt      */
-					outb(0xC0,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Enable Port B */
-					outb(0xF4,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-
-					/* Selects the master interrupt control register */
-					outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Authorizes the main interrupt on the board */
-					outb(0xD0,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					i_Event2InterruptStatus = 1;
-				} else {
-					dev_warn(dev->class_dev,
-						"Event 2 not initialised\n");
-					return -EINVAL;
-				}
-			}
-		} else {
-			dev_warn(dev->class_dev,
-				"The port parameter is in error\n");
-			return -EINVAL;
-		}
-
-		break;
-
-	case STOP:
-		/* Tests the port number */
-
-		if (data[1] == 1 || data[1] == 2) {
-			/* Test if port 1 selected */
-
-			if (data[1] == 1) {
-				/* Test if event initialised */
-				if (i_Event1Status == 1) {
-					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Disable Port A */
-					outb(0xF0,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Selects the command and status register of      */
-					/* port 1                                          */
-					outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Inhibits the pattern interrupt      */
-					outb(0xE0,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Enable Port A */
-					outb(0xF4,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					i_Event1InterruptStatus = 0;
-				} else {
-					dev_warn(dev->class_dev,
-						"Event 1 not initialised\n");
-					return -EINVAL;
-				}
-			}
-			if (data[1] == 2) {
-				/* Test if event initialised */
-				if (i_Event2Status == 1) {
-					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Disable Port B */
-					outb(0x74,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Selects the command and status register of      */
-					/* port 2                                         */
-					outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Inhibits the pattern interrupt      */
-					outb(0xE0,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
-					outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-					/* Enable Port B */
-					outb(0xF4,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					i_Event2InterruptStatus = 0;
-				} else {
-
-					dev_warn(dev->class_dev,
-						"Event 2 not initialised\n");
-					return -EINVAL;
-				}
-			}
-
-		} else {
-			dev_warn(dev->class_dev,
-				"The port parameter is in error\n");
-			return -EINVAL;
-		}
-		break;
-	default:
-		dev_warn(dev->class_dev,
-			"The option of START/STOP logic does not exist\n");
-		return -EINVAL;
-	}
-
-	return insn->n;
-}
-
-/*
- * Return the status of the digital input
- */
-static int apci1500_di_read(struct comedi_device *dev,
-			    struct comedi_subdevice *s,
-			    struct comedi_insn *insn,
-			    unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-	int i_DummyRead = 0;
-
-	/* Software reset */
-	i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the master configuration control register */
-	outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the mode specification register of port A */
-	outb(APCI1500_RW_PORT_A_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the data path polarity register of port A */
-	outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* High level of port A means 1 */
-	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the data direction register of port A */
-	outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* All bits used as inputs */
-	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port A */
-	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/*  Selects the command and status register of port A */
-	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates the interrupt management of port A:  */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the handshake specification register of port A */
-	outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes the register */
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the mode specification register of port B */
-	outb(APCI1500_RW_PORT_B_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the data path polarity register of port B */
-	outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* A high level of port B means 1 */
-	outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the data direction register of port B */
-	outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* All bits used as inputs */
-	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port B */
-	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port B */
-	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates the interrupt management of port B:         */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the handshake specification register of port B */
-	outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes the register */
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the data path polarity register of port C */
-	outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* High level of port C means 1 */
-	outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the data direction register of port C */
-	outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* All bits used as inputs except channel 1 */
-	outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the special IO register of port C */
-	outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes it */
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 1 */
-	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 1 */
-	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates the interrupt management of timer 1         */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 2 */
-	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 2 */
-	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates Timer 2 interrupt management:               */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 3 */
-	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of Timer 3 */
-	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates interrupt management of timer 3:            */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the master interrupt control register */
-	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes all interrupts */
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	return insn->n;
-}
-
-static int apci1500_di_insn_bits(struct comedi_device *dev,
-				 struct comedi_subdevice *s,
-				 struct comedi_insn *insn,
-				 unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-
-	data[1] = inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP);
-
-	return insn->n;
-}
-
-/*
- * Configures the digital output memory and the digital output error interrupt
- *
- * data[1] 1 = Enable the voltage error interrupt
- *	   2 = Disable the voltage error interrupt
- */
-static int apci1500_do_config(struct comedi_device *dev,
-			      struct comedi_subdevice *s,
-			      struct comedi_insn *insn,
-			      unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-
-	devpriv->b_OutputMemoryStatus = data[0];
-	return insn->n;
-}
-
-/*
- * Writes port value to the selected port
- */
-static int apci1500_do_write(struct comedi_device *dev,
-			     struct comedi_subdevice *s,
-			     struct comedi_insn *insn,
-			     unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-	static unsigned int ui_Temp;
-	unsigned int ui_Temp1;
-	unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec);	/*  get the channel */
-
-	if (!devpriv->b_OutputMemoryStatus)
-		ui_Temp = 0;
-
-	if (data[3] == 0) {
-		if (data[1] == 0) {
-			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
-			outw(data[0],
-				devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
-		} else {
-			if (data[1] == 1) {
-				switch (ui_NoOfChannel) {
-
-				case 2:
-					data[0] =
-						(data[0] << (2 *
-							data[2])) | ui_Temp;
-					break;
-
-				case 4:
-					data[0] =
-						(data[0] << (4 *
-							data[2])) | ui_Temp;
-					break;
-
-				case 8:
-					data[0] =
-						(data[0] << (8 *
-							data[2])) | ui_Temp;
-					break;
-
-				case 15:
-					data[0] = data[0] | ui_Temp;
-					break;
-
-				default:
-					dev_err(dev->class_dev,
-						"chan spec wrong\n");
-					return -EINVAL;	/*  "sorry channel spec wrong " */
-
-				}
-
-				outw(data[0],
-					devpriv->i_IobaseAddon +
-					APCI1500_DIGITAL_OP);
-			} else {
-				dev_warn(dev->class_dev,
-					"Specified channel not supported\n");
-				return -EINVAL;
-			}
-		}
-	} else {
-		if (data[3] == 1) {
-			if (data[1] == 0) {
-				data[0] = ~data[0] & 0x1;
-				ui_Temp1 = 1;
-				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
-				ui_Temp = ui_Temp | ui_Temp1;
-				data[0] =
-					(data[0] << ui_NoOfChannel) ^
-					0xffffffff;
-				data[0] = data[0] & ui_Temp;
-				outw(data[0],
-					devpriv->i_IobaseAddon +
-					APCI1500_DIGITAL_OP);
-			} else {
-				if (data[1] == 1) {
-					switch (ui_NoOfChannel) {
-
-					case 2:
-						data[0] = ~data[0] & 0x3;
-						ui_Temp1 = 3;
-						ui_Temp1 =
-							ui_Temp1 << 2 * data[2];
-						ui_Temp = ui_Temp | ui_Temp1;
-						data[0] =
-							((data[0] << (2 *
-									data
-									[2])) ^
-							0xffffffff) & ui_Temp;
-						break;
-
-					case 4:
-						data[0] = ~data[0] & 0xf;
-						ui_Temp1 = 15;
-						ui_Temp1 =
-							ui_Temp1 << 4 * data[2];
-						ui_Temp = ui_Temp | ui_Temp1;
-						data[0] =
-							((data[0] << (4 *
-									data
-									[2])) ^
-							0xffffffff) & ui_Temp;
-						break;
-
-					case 8:
-						data[0] = ~data[0] & 0xff;
-						ui_Temp1 = 255;
-						ui_Temp1 =
-							ui_Temp1 << 8 * data[2];
-						ui_Temp = ui_Temp | ui_Temp1;
-						data[0] =
-							((data[0] << (8 *
-									data
-									[2])) ^
-							0xffffffff) & ui_Temp;
-						break;
-
-					case 15:
-						break;
-
-					default:
-						dev_err(dev->class_dev,
-							"chan spec wrong\n");
-						return -EINVAL;	/*  "sorry channel spec wrong " */
-
-					}
-
-					outw(data[0],
-						devpriv->i_IobaseAddon +
-						APCI1500_DIGITAL_OP);
-				} else {
-					dev_warn(dev->class_dev,
-						"Specified channel not supported\n");
-					return -EINVAL;
-				}
-			}
-		} else {
-			dev_warn(dev->class_dev,
-				"Specified functionality does not exist\n");
-			return -EINVAL;
-		}
-	}
-	ui_Temp = data[0];
-	return insn->n;
-}
-
-/*
- * Configures The Watchdog
- *
- * data[0] 0 = APCI1500_115_KHZ, 1 = APCI1500_3_6_KHZ, 2 = APCI1500_1_8_KHZ
- * data[1] 0 = Counter1/Timer1, 1 =  Counter2/Timer2, 2 = Counter3/Watchdog
- * data[2] 0 = Counter, 1 = Timer/Watchdog
- * data[3] This parameter has two meanings. If the counter/timer is used as
- *	a counter the limit value of the counter is given. If the counter/timer
- *	is used as a timer, the divider factor for the output is given.
- * data[4] 0 = APCI1500_CONTINUOUS, 1 = APCI1500_SINGLE
- * data[5] 0 = Software Trigger, 1 = Hardware Trigger
- * data[6] 0 = Software gate, 1 = Hardware gate
- * data[7] 0 = Interrupt Disable, 1 = Interrupt Enable
- */
-static int apci1500_timer_config(struct comedi_device *dev,
-				 struct comedi_subdevice *s,
-				 struct comedi_insn *insn,
-				 unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-	int i_TimerCounterMode, i_MasterConfiguration;
-
-	devpriv->tsk_Current = current;
-
-	/* Selection of the input clock */
-	if (data[0] == 0 || data[0] == 1 || data[0] == 2) {
-		outw(data[0], devpriv->i_IobaseAddon + APCI1500_CLK_SELECT);
-	} else {
-		if (data[0] != 3) {
-			dev_warn(dev->class_dev,
-				"The option for input clock selection does not exist\n");
-			return -EINVAL;
-		}
-	}
-	/* Select the counter/timer */
-	switch (data[1]) {
-	case COUNTER1:
-		/* selecting counter or timer */
-		switch (data[2]) {
-		case 0:
-			data[2] = APCI1500_COUNTER;
-			break;
-		case 1:
-			data[2] = APCI1500_TIMER;
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"This choice is not a timer nor a counter\n");
-			return -EINVAL;
-		}
-
-		/* Selecting  single or continuous mode */
-		switch (data[4]) {
-		case 0:
-			data[4] = APCI1500_CONTINUOUS;
-			break;
-		case 1:
-			data[4] = APCI1500_SINGLE;
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"This option for single/continuous mode does not exist\n");
-			return -EINVAL;
-		}
-
-		i_TimerCounterMode = data[2] | data[4] | 7;
-		/* Test the reload value */
-
-		if ((data[3] >= 0) && (data[3] <= 65535)) {
-			if (data[7] == APCI1500_ENABLE
-				|| data[7] == APCI1500_DISABLE) {
-
-				/* Selects the mode register of timer/counter 1 */
-				outb(APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				/* Writes the new mode */
-				outb(i_TimerCounterMode,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the constant register of timer/counter 1 */
-
-				outb(APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Writes the low value  */
-
-				outb(data[3],
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the constant register of timer/counter 1 */
-
-				outb(APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Writes the high value  */
-
-				data[3] = data[3] >> 8;
-				outb(data[3],
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the master configuration register */
-
-				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Reads the register */
-
-				i_MasterConfiguration =
-					inb(devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Enables timer/counter 1 and triggers timer/counter 1 */
-
-				i_MasterConfiguration =
-					i_MasterConfiguration | 0x40;
-
-				/* Selects the master configuration register */
-				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Writes the new configuration */
-				outb(i_MasterConfiguration,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				/* Selects the commands register of     */
-				/* timer/counter 1                      */
-
-				outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Disable timer/counter 1 */
-
-				outb(0x0,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				/* Selects the commands register of     */
-				/* timer/counter 1                      */
-				outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Trigger timer/counter 1 */
-				outb(0x2,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-			} else {
-				dev_warn(dev->class_dev,
-					"Error in selection of interrupt enable or disable\n");
-				return -EINVAL;
-			}
-		} else {
-			dev_warn(dev->class_dev,
-				"Error in selection of reload value\n");
-			return -EINVAL;
-		}
-		i_TimerCounterWatchdogInterrupt = data[7];
-		i_TimerCounter1Init = 1;
-		break;
-
-	case COUNTER2:		/* selecting counter or timer */
-		switch (data[2]) {
-		case 0:
-			data[2] = APCI1500_COUNTER;
-			break;
-		case 1:
-			data[2] = APCI1500_TIMER;
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"This choice is not a timer nor a counter\n");
-			return -EINVAL;
-		}
-
-		/* Selecting  single or continuous mode */
-		switch (data[4]) {
-		case 0:
-			data[4] = APCI1500_CONTINUOUS;
-			break;
-		case 1:
-			data[4] = APCI1500_SINGLE;
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"This option for single/continuous mode does not exist\n");
-			return -EINVAL;
-		}
-
-		/* Selecting  software or hardware trigger */
-		switch (data[5]) {
-		case 0:
-			data[5] = APCI1500_SOFTWARE_TRIGGER;
-			break;
-		case 1:
-			data[5] = APCI1500_HARDWARE_TRIGGER;
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"This choice for software or hardware trigger does not exist\n");
-			return -EINVAL;
-		}
-
-		/* Selecting  software or hardware gate */
-		switch (data[6]) {
-		case 0:
-			data[6] = APCI1500_SOFTWARE_GATE;
-			break;
-		case 1:
-			data[6] = APCI1500_HARDWARE_GATE;
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"This choice for software or hardware gate does not exist\n");
-			return -EINVAL;
-		}
-
-		i_TimerCounterMode = data[2] | data[4] | data[5] | data[6] | 7;
-
-		/* Test the reload value */
-
-		if ((data[3] >= 0) && (data[3] <= 65535)) {
-			if (data[7] == APCI1500_ENABLE
-				|| data[7] == APCI1500_DISABLE) {
-
-				/* Selects the mode register of timer/counter 2 */
-				outb(APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				/* Writes the new mode */
-				outb(i_TimerCounterMode,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the constant register of timer/counter 2 */
-
-				outb(APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Writes the low value  */
-
-				outb(data[3],
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the constant register of timer/counter 2 */
-
-				outb(APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Writes the high value  */
-
-				data[3] = data[3] >> 8;
-				outb(data[3],
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the master configuration register */
-
-				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Reads the register */
-
-				i_MasterConfiguration =
-					inb(devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Enables timer/counter 2 and triggers timer/counter 2 */
-
-				i_MasterConfiguration =
-					i_MasterConfiguration | 0x20;
-
-				/* Selects the master configuration register */
-				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Writes the new configuration */
-				outb(i_MasterConfiguration,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				/* Selects the commands register of     */
-				/* timer/counter 2                      */
-
-				outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Disable timer/counter 2 */
-
-				outb(0x0,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				/* Selects the commands register of     */
-				/* timer/counter 2                      */
-				outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Trigger timer/counter 1 */
-				outb(0x2,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-			} else {
-				dev_warn(dev->class_dev,
-					"Error in selection of interrupt enable or disable\n");
-				return -EINVAL;
-			}
-		} else {
-			dev_warn(dev->class_dev,
-				"Error in selection of reload value\n");
-			return -EINVAL;
-		}
-		i_TimerCounterWatchdogInterrupt = data[7];
-		i_TimerCounter2Init = 1;
-		break;
-
-	case COUNTER3:		/* selecting counter or watchdog */
-		switch (data[2]) {
-		case 0:
-			data[2] = APCI1500_COUNTER;
-			break;
-		case 1:
-			data[2] = APCI1500_WATCHDOG;
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"This choice is not a watchdog nor a counter\n");
-			return -EINVAL;
-		}
-
-		/* Selecting  single or continuous mode */
-		switch (data[4]) {
-		case 0:
-			data[4] = APCI1500_CONTINUOUS;
-			break;
-		case 1:
-			data[4] = APCI1500_SINGLE;
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"This option for single/continuous mode does not exist\n");
-			return -EINVAL;
-		}
-
-		/* Selecting  software or hardware gate */
-		switch (data[6]) {
-		case 0:
-			data[6] = APCI1500_SOFTWARE_GATE;
-			break;
-		case 1:
-			data[6] = APCI1500_HARDWARE_GATE;
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"This choice for software or hardware gate does not exist\n");
-			return -EINVAL;
-		}
-
-		/* Test if used for watchdog */
-
-		if (data[2] == APCI1500_WATCHDOG) {
-			/* - Enables the output line */
-			/* - Enables retrigger       */
-			/* - Pulses output           */
-			i_TimerCounterMode = data[2] | data[4] | 0x54;
-		} else {
-			i_TimerCounterMode = data[2] | data[4] | data[6] | 7;
-		}
-		/* Test the reload value */
-
-		if ((data[3] >= 0) && (data[3] <= 65535)) {
-			if (data[7] == APCI1500_ENABLE
-				|| data[7] == APCI1500_DISABLE) {
-
-				/* Selects the mode register of watchdog/counter 3 */
-				outb(APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				/* Writes the new mode */
-				outb(i_TimerCounterMode,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the constant register of watchdog/counter 3 */
-
-				outb(APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Writes the low value  */
-
-				outb(data[3],
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the constant register of watchdog/counter 3 */
-
-				outb(APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Writes the high value  */
-
-				data[3] = data[3] >> 8;
-				outb(data[3],
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the master configuration register */
-
-				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Reads the register */
-
-				i_MasterConfiguration =
-					inb(devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Enables watchdog/counter 3 and triggers watchdog/counter 3 */
-
-				i_MasterConfiguration =
-					i_MasterConfiguration | 0x10;
-
-				/* Selects the master configuration register */
-				outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Writes the new configuration */
-				outb(i_MasterConfiguration,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Test if COUNTER */
-				if (data[2] == APCI1500_COUNTER) {
-
-					/* Selects the command register of   */
-					/* watchdog/counter 3                */
-					outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Disable the  watchdog/counter 3 and starts it */
-					outb(0x0,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-
-					/* Selects the command register of   */
-					/* watchdog/counter 3                */
-
-					outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					/* Trigger the  watchdog/counter 3 and starts it */
-					outb(0x2,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-
-				}
-
-			} else {
-
-				dev_warn(dev->class_dev,
-					"Error in selection of interrupt enable or disable\n");
-				return -EINVAL;
-			}
-		} else {
-			dev_warn(dev->class_dev,
-				"Error in selection of reload value\n");
-			return -EINVAL;
-		}
-		i_TimerCounterWatchdogInterrupt = data[7];
-		i_WatchdogCounter3Init = 1;
-		break;
-
-	default:
-		dev_warn(dev->class_dev,
-			"The specified counter/timer option does not exist\n");
-		return -EINVAL;
-	}
-	i_CounterLogic = data[2];
-	return insn->n;
-}
-
-/*
- * Start / Stop or trigger the timer counter or Watchdog
- *
- * data[0] 0 = Counter1/Timer1, 1 =  Counter2/Timer2, 2 = Counter3/Watchdog
- * data[1] 0 = Start, 1 = Stop, 2 = Trigger
- * data[2] 0 = Counter, 1 = Timer/Watchdog
- */
-static int apci1500_timer_write(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				struct comedi_insn *insn,
-				unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-	int i_CommandAndStatusValue;
-
-	switch (data[0]) {
-	case COUNTER1:
-		switch (data[1]) {
-		case START:
-			if (i_TimerCounter1Init == 1) {
-				if (i_TimerCounterWatchdogInterrupt == 1)
-					i_CommandAndStatusValue = 0xC4;	/* Enable the interrupt */
-				else
-					i_CommandAndStatusValue = 0xE4;	/* disable the interrupt */
-
-				/* Starts timer/counter 1 */
-				i_TimerCounter1Enabled = 1;
-				/* Selects the commands and status register */
-				outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				outb(i_CommandAndStatusValue,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-			} else {
-				dev_warn(dev->class_dev,
-					"Counter/Timer1 not configured\n");
-				return -EINVAL;
-			}
-			break;
-
-		case STOP:
-
-			/* Stop timer/counter 1 */
-
-			/* Selects the commands and status register */
-			outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(0x00,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_TimerCounter1Enabled = 0;
-			break;
-
-		case TRIGGER:
-			if (i_TimerCounter1Init == 1) {
-				if (i_TimerCounter1Enabled == 1) {
-					/* Set Trigger and gate */
-
-					i_CommandAndStatusValue = 0x6;
-				} else {
-					/* Set Trigger */
-
-					i_CommandAndStatusValue = 0x2;
-				}
-
-				/* Selects the commands and status register */
-				outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				outb(i_CommandAndStatusValue,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-			} else {
-				dev_warn(dev->class_dev,
-					"Counter/Timer1 not configured\n");
-				return -EINVAL;
-			}
-			break;
-
-		default:
-			dev_warn(dev->class_dev,
-				"The specified option for start/stop/trigger does not exist\n");
-			return -EINVAL;
-		}
-		break;
-
-	case COUNTER2:
-		switch (data[1]) {
-		case START:
-			if (i_TimerCounter2Init == 1) {
-				if (i_TimerCounterWatchdogInterrupt == 1)
-					i_CommandAndStatusValue = 0xC4;	/* Enable the interrupt */
-				else
-					i_CommandAndStatusValue = 0xE4;	/* disable the interrupt */
-
-				/* Starts timer/counter 2 */
-				i_TimerCounter2Enabled = 1;
-				/* Selects the commands and status register */
-				outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				outb(i_CommandAndStatusValue,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-			} else {
-				dev_warn(dev->class_dev,
-					"Counter/Timer2 not configured\n");
-				return -EINVAL;
-			}
-			break;
-
-		case STOP:
-
-			/* Stop timer/counter 2 */
-
-			/* Selects the commands and status register */
-			outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(0x00,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_TimerCounter2Enabled = 0;
-			break;
-		case TRIGGER:
-			if (i_TimerCounter2Init == 1) {
-				if (i_TimerCounter2Enabled == 1) {
-					/* Set Trigger and gate */
-
-					i_CommandAndStatusValue = 0x6;
-				} else {
-					/* Set Trigger */
-
-					i_CommandAndStatusValue = 0x2;
-				}
-
-				/* Selects the commands and status register */
-				outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				outb(i_CommandAndStatusValue,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-			} else {
-				dev_warn(dev->class_dev,
-					"Counter/Timer2 not configured\n");
-				return -EINVAL;
-			}
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"The specified option for start/stop/trigger does not exist\n");
-			return -EINVAL;
-		}
-		break;
-	case COUNTER3:
-		switch (data[1]) {
-		case START:
-			if (i_WatchdogCounter3Init == 1) {
-
-				if (i_TimerCounterWatchdogInterrupt == 1)
-					i_CommandAndStatusValue = 0xC4;	/* Enable the interrupt */
-				else
-					i_CommandAndStatusValue = 0xE4;	/* disable the interrupt */
-
-				/* Starts Watchdog/counter 3 */
-				i_WatchdogCounter3Enabled = 1;
-				/* Selects the commands and status register */
-				outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				outb(i_CommandAndStatusValue,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-			} else {
-				dev_warn(dev->class_dev,
-					"Watchdog/Counter3 not configured\n");
-				return -EINVAL;
-			}
-			break;
-
-		case STOP:
-
-			/* Stop Watchdog/counter 3 */
-
-			/* Selects the commands and status register */
-			outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(0x00,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_WatchdogCounter3Enabled = 0;
-			break;
-
-		case TRIGGER:
-			switch (data[2]) {
-			case 0:	/* triggering counter 3 */
-				if (i_WatchdogCounter3Init == 1) {
-					if (i_WatchdogCounter3Enabled == 1) {
-						/* Set Trigger and gate */
-
-						i_CommandAndStatusValue = 0x6;
-					} else {
-						/* Set Trigger */
-
-						i_CommandAndStatusValue = 0x2;
-					}
-
-					/* Selects the commands and status register */
-					outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					outb(i_CommandAndStatusValue,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-				} else {
-					dev_warn(dev->class_dev,
-						"Counter3 not configured\n");
-					return -EINVAL;
-				}
-				break;
-			case 1:
-				/* triggering Watchdog 3 */
-				if (i_WatchdogCounter3Init == 1) {
-
-					/* Selects the commands and status register */
-					outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-					outb(0x6,
-						devpriv->iobase +
-						APCI1500_Z8536_CONTROL_REGISTER);
-				} else {
-					dev_warn(dev->class_dev,
-						"Watchdog 3 not configured\n");
-					return -EINVAL;
-				}
-				break;
-			default:
-				dev_warn(dev->class_dev,
-					"Wrong choice of watchdog/counter3\n");
-				return -EINVAL;
-			}
-			break;
-		default:
-			dev_warn(dev->class_dev,
-				"The specified option for start/stop/trigger does not exist\n");
-			return -EINVAL;
-		}
-		break;
-	default:
-		dev_warn(dev->class_dev,
-			"The specified choice for counter/watchdog/timer does not exist\n");
-		return -EINVAL;
-	}
-	return insn->n;
-}
-
-/*
- * Read The Watchdog
- *
- * data[0] 0 = Counter1/Timer1, 1 =  Counter2/Timer2, 2 = Counter3/Watchdog
- */
-static int apci1500_timer_bits(struct comedi_device *dev,
-			       struct comedi_subdevice *s,
-			       struct comedi_insn *insn,
-			       unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-	int i_CommandAndStatusValue;
-
-	switch (data[0]) {
-	case COUNTER1:
-		/* Read counter/timer1 */
-		if (i_TimerCounter1Init == 1) {
-			if (i_TimerCounter1Enabled == 1) {
-				/* Set RCC and gate */
-
-				i_CommandAndStatusValue = 0xC;
-			} else {
-				/* Set RCC */
-
-				i_CommandAndStatusValue = 0x8;
-			}
-
-			/* Selects the commands and status register */
-			outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(i_CommandAndStatusValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Selects the counter register (high) */
-			outb(APCI1500_R_CPT_TMR1_VALUE_HIGH,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			data[0] =
-				inb(devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			data[0] = data[0] << 8;
-			data[0] = data[0] & 0xff00;
-			outb(APCI1500_R_CPT_TMR1_VALUE_LOW,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			data[0] =
-				data[0] | inb(devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-		} else {
-			dev_warn(dev->class_dev,
-				"Timer/Counter1 not configured\n");
-			return -EINVAL;
-		}
-		break;
-	case COUNTER2:
-		/* Read counter/timer2 */
-		if (i_TimerCounter2Init == 1) {
-			if (i_TimerCounter2Enabled == 1) {
-				/* Set RCC and gate */
-
-				i_CommandAndStatusValue = 0xC;
-			} else {
-				/* Set RCC */
-
-				i_CommandAndStatusValue = 0x8;
-			}
-
-			/* Selects the commands and status register */
-			outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(i_CommandAndStatusValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Selects the counter register (high) */
-			outb(APCI1500_R_CPT_TMR2_VALUE_HIGH,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			data[0] =
-				inb(devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			data[0] = data[0] << 8;
-			data[0] = data[0] & 0xff00;
-			outb(APCI1500_R_CPT_TMR2_VALUE_LOW,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			data[0] =
-				data[0] | inb(devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-		} else {
-			dev_warn(dev->class_dev,
-				"Timer/Counter2 not configured\n");
-			return -EINVAL;
-		}
-		break;
-	case COUNTER3:
-		/* Read counter/watchdog2 */
-		if (i_WatchdogCounter3Init == 1) {
-			if (i_WatchdogCounter3Enabled == 1) {
-				/* Set RCC and gate */
-
-				i_CommandAndStatusValue = 0xC;
-			} else {
-				/* Set RCC */
-
-				i_CommandAndStatusValue = 0x8;
-			}
-
-			/* Selects the commands and status register */
-			outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			outb(i_CommandAndStatusValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-
-			/* Selects the counter register (high) */
-			outb(APCI1500_R_CPT_TMR3_VALUE_HIGH,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			data[0] =
-				inb(devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			data[0] = data[0] << 8;
-			data[0] = data[0] & 0xff00;
-			outb(APCI1500_R_CPT_TMR3_VALUE_LOW,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			data[0] =
-				data[0] | inb(devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-		} else {
-			dev_warn(dev->class_dev,
-				"WatchdogCounter3 not configured\n");
-			return -EINVAL;
-		}
-		break;
-	default:
-		dev_warn(dev->class_dev,
-			"The choice of timer/counter/watchdog does not exist\n");
-		return -EINVAL;
-	}
-
-	return insn->n;
-}
-
-/*
- * Read the interrupt mask
- *
- * data[0] The interrupt mask value
- * data[1] Channel Number
- */
-static int apci1500_timer_read(struct comedi_device *dev,
-			       struct comedi_subdevice *s,
-			       struct comedi_insn *insn,
-			       unsigned int *data)
-{
-	data[0] = i_InterruptMask;
-	data[1] = i_InputChannel;
-	i_InterruptMask = 0;
-	return insn->n;
-}
-
-/*
- * Configures the interrupt registers
- */
-static int apci1500_do_bits(struct comedi_device *dev,
-			    struct comedi_subdevice *s,
-			    struct comedi_insn *insn,
-			    unsigned int *data)
-{
-	struct apci1500_private *devpriv = dev->private;
-	unsigned int ui_Status;
-	int i_RegValue;
-	int i_Constant;
-
-	devpriv->tsk_Current = current;
-	outl(0x0, devpriv->i_IobaseAmcc + 0x38);
-	if (data[0] == 1) {
-		i_Constant = 0xC0;
-	} else {
-		if (data[0] == 0) {
-			i_Constant = 0x00;
-		} else {
-			dev_warn(dev->class_dev,
-				"The parameter passed to driver is in error for enabling the voltage interrupt\n");
-			return -EINVAL;
-		}
-	}
-
-	/* Selects the mode specification register of port B */
-	outb(APCI1500_RW_PORT_B_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(APCI1500_RW_PORT_B_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Writes the new configuration (APCI1500_OR) */
-	i_RegValue = (i_RegValue & 0xF9) | APCI1500_OR;
-
-	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port B */
-	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Authorises the interrupt on the board */
-	outb(0xC0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the pattern polarity register of port B */
-	outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the pattern transition register of port B */
-	outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the pattern mask register of port B */
-	outb(APCI1500_RW_PORT_B_PATTERN_MASK,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the command and status register of port A */
-	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes the interrupt of port A */
-
-	i_RegValue = (i_RegValue & 0x0F) | 0x20;
-	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port  B */
-	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes the interrupt of port B */
-
-	i_RegValue = (i_RegValue & 0x0F) | 0x20;
-	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the command and status register of timer 1 */
-	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes the interrupt of timer 1 */
-
-	i_RegValue = (i_RegValue & 0x0F) | 0x20;
-	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the command and status register of timer 2 */
-	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes the interrupt of timer 2 */
-
-	i_RegValue = (i_RegValue & 0x0F) | 0x20;
-	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the command and status register of timer 3 */
-	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes the interrupt of timer 3 */
-
-	i_RegValue = (i_RegValue & 0x0F) | 0x20;
-	outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the master interrupt control register */
-	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Authorizes the main interrupt on the board */
-	outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Enables the PCI interrupt */
-	outl(0x3000, devpriv->i_IobaseAmcc + 0x38);
-	ui_Status = inl(devpriv->i_IobaseAmcc + 0x10);
-	ui_Status = inl(devpriv->i_IobaseAmcc + 0x38);
-	outl(0x23000, devpriv->i_IobaseAmcc + 0x38);
-
-	return insn->n;
-}
-
-static irqreturn_t apci1500_interrupt(int irq, void *d)
-{
-
-	struct comedi_device *dev = d;
-	struct apci1500_private *devpriv = dev->private;
-	unsigned int ui_InterruptStatus = 0;
-	int i_RegValue = 0;
-
-	/* Clear the interrupt mask */
-	i_InterruptMask = 0;
-
-	/* Read the board interrupt status */
-	ui_InterruptStatus = inl(devpriv->i_IobaseAmcc + 0x38);
-
-	/* Test if board generated a interrupt */
-	if ((ui_InterruptStatus & 0x800000) == 0x800000) {
-		/* Disable all Interrupt */
-		/* Selects the master interrupt control register */
-		/* Disables  the main interrupt on the board */
-		/* Selects the command and status register of port A */
-		outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		i_RegValue =
-			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		if ((i_RegValue & 0x60) == 0x60) {
-			/* Selects the command and status register of port A */
-			outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Deletes the interrupt of port A */
-			i_RegValue = (i_RegValue & 0x0F) | 0x20;
-			outb(i_RegValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_InterruptMask = i_InterruptMask | 1;
-			if (i_Logic == APCI1500_OR_PRIORITY) {
-				outb(APCI1500_RW_PORT_A_SPECIFICATION,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				i_RegValue =
-					inb(devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				/* Selects the interrupt vector register of port A */
-				outb(APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
-					devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-				i_RegValue =
-					inb(devpriv->iobase +
-					APCI1500_Z8536_CONTROL_REGISTER);
-
-				i_InputChannel = 1 + (i_RegValue >> 1);
-
-			} else {
-				i_InputChannel = 0;
-			}
-		}
-
-		/* Selects the command and status register of port B */
-		outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		i_RegValue =
-			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		if ((i_RegValue & 0x60) == 0x60) {
-			/* Selects the command and status register of port B */
-			outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Deletes the interrupt of port B */
-			i_RegValue = (i_RegValue & 0x0F) | 0x20;
-			outb(i_RegValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Reads port B */
-			i_RegValue =
-				inb((unsigned int) devpriv->iobase +
-				APCI1500_Z8536_PORT_B);
-
-			i_RegValue = i_RegValue & 0xC0;
-			/* Tests if this is an external error */
-
-			if (i_RegValue) {
-				/* Disable the interrupt */
-				/* Selects the command and status register of port B */
-				outl(0x0, devpriv->i_IobaseAmcc + 0x38);
-
-				if (i_RegValue & 0x80) {
-					i_InterruptMask =
-						i_InterruptMask | 0x40;
-				}
-
-				if (i_RegValue & 0x40) {
-					i_InterruptMask =
-						i_InterruptMask | 0x80;
-				}
-			} else {
-				i_InterruptMask = i_InterruptMask | 2;
-			}
-		}
-
-		/* Selects the command and status register of timer 1 */
-		outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		i_RegValue =
-			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		if ((i_RegValue & 0x60) == 0x60) {
-			/* Selects the command and status register of timer 1 */
-			outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Deletes the interrupt of timer 1 */
-			i_RegValue = (i_RegValue & 0x0F) | 0x20;
-			outb(i_RegValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_InterruptMask = i_InterruptMask | 4;
-		}
-		/* Selects the command and status register of timer 2 */
-		outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		i_RegValue =
-			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		if ((i_RegValue & 0x60) == 0x60) {
-			/* Selects the command and status register of timer 2 */
-			outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Deletes the interrupt of timer 2 */
-			i_RegValue = (i_RegValue & 0x0F) | 0x20;
-			outb(i_RegValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			i_InterruptMask = i_InterruptMask | 8;
-		}
-
-		/* Selects the command and status register of timer 3 */
-		outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		i_RegValue =
-			inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		if ((i_RegValue & 0x60) == 0x60) {
-			/* Selects the command and status register of timer 3 */
-			outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			/* Deletes the interrupt of timer 3 */
-			i_RegValue = (i_RegValue & 0x0F) | 0x20;
-			outb(i_RegValue,
-				devpriv->iobase +
-				APCI1500_Z8536_CONTROL_REGISTER);
-			if (i_CounterLogic == APCI1500_COUNTER)
-				i_InterruptMask = i_InterruptMask | 0x10;
-			else
-				i_InterruptMask = i_InterruptMask | 0x20;
-		}
-
-		send_sig(SIGIO, devpriv->tsk_Current, 0);	/*  send signal to the sample */
-		/* Enable all Interrupts */
-
-		/* Selects the master interrupt control register */
-		outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
-			devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-		/* Authorizes the main interrupt on the board */
-		outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	} else {
-		dev_warn(dev->class_dev,
-			"Interrupt from unknown source\n");
-
-	}
-
-	return IRQ_HANDLED;
-}
-
-static int apci1500_reset(struct comedi_device *dev)
-{
-	struct apci1500_private *devpriv = dev->private;
-	int i_DummyRead = 0;
-
-	i_TimerCounter1Init = 0;
-	i_TimerCounter2Init = 0;
-	i_WatchdogCounter3Init = 0;
-	i_Event1Status = 0;
-	i_Event2Status = 0;
-	i_TimerCounterWatchdogInterrupt = 0;
-	i_Logic = 0;
-	i_CounterLogic = 0;
-	i_InterruptMask = 0;
-	i_InputChannel = 0;
-	i_TimerCounter1Enabled = 0;
-	i_TimerCounter2Enabled = 0;
-	i_WatchdogCounter3Enabled = 0;
-
-	/* Software reset */
-	i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the master configuration control register */
-	outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the mode specification register of port A */
-	outb(APCI1500_RW_PORT_A_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the data path polarity register of port A */
-	outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* High level of port A means 1 */
-	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the data direction register of port A */
-	outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* All bits used as inputs */
-	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port A */
-	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/*  Selects the command and status register of port A */
-	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates the interrupt management of port A:  */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the handshake specification register of port A */
-	outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes the register */
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the mode specification register of port B */
-	outb(APCI1500_RW_PORT_B_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the data path polarity register of port B */
-	outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* A high level of port B means 1 */
-	outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the data direction register of port B */
-	outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* All bits used as inputs */
-	outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port B */
-	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port B */
-	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates the interrupt management of port B:         */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the handshake specification register of port B */
-	outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes the register */
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-
-	/* Selects the data path polarity register of port C */
-	outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* High level of port C means 1 */
-	outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the data direction register of port C */
-	outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* All bits used as inputs except channel 1 */
-	outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the special IO register of port C */
-	outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes it */
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 1 */
-	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 1 */
-	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates the interrupt management of timer 1         */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 2 */
-	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 2 */
-	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates Timer 2 interrupt management:               */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 3 */
-	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes IP and IUS */
-	outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of Timer 3 */
-	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates interrupt management of timer 3:            */
-	outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the master interrupt control register */
-	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deletes all interrupts */
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* reset all the digital outputs */
-	outw(0x0, devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
-	/* Disable the board interrupt */
-	/* Selects the master interrupt control register */
-	outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates all interrupts */
-	outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port A */
-	outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates all interrupts */
-	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of port B */
-	outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates all interrupts */
-	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 1 */
-	outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates all interrupts */
-	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 2 */
-	outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates all interrupts */
-	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Selects the command and status register of timer 3*/
-	outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
-		devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	/* Deactivates all interrupts */
-	outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
-	return 0;
-}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
index 339519a3d6b5..1f2f78186d58 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -93,7 +93,6 @@ static int apci3501_write_insn_timer(struct comedi_device *dev,
 {
 	struct apci3501_private *devpriv = dev->private;
 	unsigned int ul_Command1 = 0;
-	int i_Temp;
 
 	if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
 
@@ -135,7 +134,7 @@ static int apci3501_write_insn_timer(struct comedi_device *dev,
 		}
 	}
 
-	i_Temp = inl(dev->iobase + APCI3501_TIMER_STATUS_REG) & 0x1;
+	inl(dev->iobase + APCI3501_TIMER_STATUS_REG);
 	return insn->n;
 }
 
diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c
index bf14165297b7..4911b627203b 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1032.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1032.c
@@ -22,6 +22,54 @@
  * more details.
  */
 
+/*
+ * Driver: addi_apci_1032
+ * Description: ADDI-DATA APCI-1032 Digital Input Board
+ * Author: ADDI-DATA GmbH <info@addi-data.com>,
+ *   H Hartley Sweeten <hsweeten@visionengravers.com>
+ * Status: untested
+ * Devices: [ADDI-DATA] APCI-1032 (addi_apci_1032)
+ *
+ * Configuration options:
+ *   None; devices are configured automatically.
+ *
+ * This driver models the APCI-1032 as a 32-channel, digital input subdevice
+ * plus an additional digital input subdevice to handle change-of-state (COS)
+ * interrupts (if an interrupt handler can be set up successfully).
+ *
+ * The COS subdevice supports comedi asynchronous read commands.
+ *
+ * Change-Of-State (COS) interrupt configuration:
+ *
+ * Channels 0 to 15 are interruptible. These channels can be configured
+ * to generate interrupts based on AND/OR logic for the desired channels.
+ *
+ *   OR logic:
+ *   - reacts to rising or falling edges
+ *   - interrupt is generated when any enabled channel meets the desired
+ *     interrupt condition
+ *
+ *   AND logic:
+ *   - reacts to changes in level of the selected inputs
+ *   - interrupt is generated when all enabled channels meet the desired
+ *     interrupt condition
+ *   - after an interrupt, a change in level must occur on the selected
+ *     inputs to release the IRQ logic
+ *
+ * The COS subdevice must be configured before setting up a comedi
+ * asynchronous command:
+ *
+ *   data[0] : INSN_CONFIG_DIGITAL_TRIG
+ *   data[1] : trigger number (= 0)
+ *   data[2] : configuration operation:
+ *             - COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
+ *             - COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts
+ *             - COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts
+ *   data[3] : left-shift for data[4] and data[5]
+ *   data[4] : rising-edge/high level channels
+ *   data[5] : falling-edge/low level channels
+ */
+
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -62,36 +110,6 @@ static int apci1032_reset(struct comedi_device *dev)
 	return 0;
 }
 
-/*
- * Change-Of-State (COS) interrupt configuration
- *
- * Channels 0 to 15 are interruptible. These channels can be configured
- * to generate interrupts based on AND/OR logic for the desired channels.
- *
- *	OR logic
- *		- reacts to rising or falling edges
- *		- interrupt is generated when any enabled channel
- *		  meet the desired interrupt condition
- *
- *	AND logic
- *		- reacts to changes in level of the selected inputs
- *		- interrupt is generated when all enabled channels
- *		  meet the desired interrupt condition
- *		- after an interrupt, a change in level must occur on
- *		  the selected inputs to release the IRQ logic
- *
- * The COS interrupt must be configured before it can be enabled.
- *
- *	data[0] : INSN_CONFIG_DIGITAL_TRIG
- *	data[1] : trigger number (= 0)
- *	data[2] : configuration operation:
- *	          COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
- *	          COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts
- *	          COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts
- *	data[3] : left-shift for data[4] and data[5]
- *	data[4] : rising-edge/high level channels
- *	data[5] : falling-edge/low level channels
- */
 static int apci1032_cos_insn_config(struct comedi_device *dev,
 				    struct comedi_subdevice *s,
 				    struct comedi_insn *insn,
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
index 30b132c3d092..f15aa1f6b476 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1500.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -1,22 +1,755 @@
+/*
+ * addi_apci_1500.c
+ * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
+ *
+ *	ADDI-DATA GmbH
+ *	Dieselstrasse 3
+ *	D-77833 Ottersweier
+ *	Tel: +19(0)7223/9493-0
+ *	Fax: +49(0)7223/9493-92
+ *	http://www.addi-data.com
+ *	info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/sched.h>
 #include <linux/interrupt.h>
 
 #include "../comedidev.h"
 #include "comedi_fc.h"
 #include "amcc_s5933.h"
+#include "z8536.h"
+
+/*
+ * PCI Bar 0 Register map (devpriv->amcc)
+ * see amcc_s5933.h for register and bit defines
+ */
+
+/*
+ * PCI Bar 1 Register map (dev->iobase)
+ * see z8536.h for Z8536 internal registers and bit defines
+ */
+#define APCI1500_Z8536_PORTC_REG	0x00
+#define APCI1500_Z8536_PORTB_REG	0x01
+#define APCI1500_Z8536_PORTA_REG	0x02
+#define APCI1500_Z8536_CTRL_REG		0x03
+
+/*
+ * PCI Bar 2 Register map (devpriv->addon)
+ */
+#define APCI1500_CLK_SEL_REG		0x00
+#define APCI1500_DI_REG			0x00
+#define APCI1500_DO_REG			0x02
 
 struct apci1500_private {
-	int iobase;
-	int i_IobaseAmcc;
-	int i_IobaseAddon;
-	int i_IobaseReserved;
-	unsigned char b_OutputMemoryStatus;
-	struct task_struct *tsk_Current;
+	unsigned long amcc;
+	unsigned long addon;
+
+	unsigned int clk_src;
+
+	/* Digital trigger configuration [0]=AND [1]=OR */
+	unsigned int pm[2];	/* Pattern Mask */
+	unsigned int pt[2];	/* Pattern Transition */
+	unsigned int pp[2];	/* Pattern Polarity */
 };
 
-#include "addi-data/hwdrv_apci1500.c"
+static unsigned int z8536_read(struct comedi_device *dev, unsigned int reg)
+{
+	unsigned long flags;
+	unsigned int val;
+
+	spin_lock_irqsave(&dev->spinlock, flags);
+	outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
+	val = inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
+	spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	return val;
+}
+
+static void z8536_write(struct comedi_device *dev,
+			unsigned int val, unsigned int reg)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->spinlock, flags);
+	outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG);
+	outb(val, dev->iobase + APCI1500_Z8536_CTRL_REG);
+	spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static void z8536_reset(struct comedi_device *dev)
+{
+	unsigned long flags;
+
+	/*
+	 * Even if the state of the Z8536 is not known, the following
+	 * sequence will reset it and put it in State 0.
+	 */
+	spin_lock_irqsave(&dev->spinlock, flags);
+	inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
+	outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
+	inb(dev->iobase + APCI1500_Z8536_CTRL_REG);
+	outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
+	outb(1, dev->iobase + APCI1500_Z8536_CTRL_REG);
+	outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG);
+	spin_unlock_irqrestore(&dev->spinlock, flags);
+
+	/* Disable all Ports and Counter/Timers */
+	z8536_write(dev, 0x00, Z8536_CFG_CTRL_REG);
+
+	/*
+	 * Port A is connected to Ditial Input channels 0-7.
+	 * Configure the port to allow interrupt detection.
+	 */
+	z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
+			 Z8536_PAB_MODE_SB |
+			 Z8536_PAB_MODE_PMS_DISABLE,
+		    Z8536_PA_MODE_REG);
+	z8536_write(dev, 0xff, Z8536_PB_DPP_REG);
+	z8536_write(dev, 0xff, Z8536_PA_DD_REG);
+
+	/*
+	 * Port B is connected to Ditial Input channels 8-13.
+	 * Configure the port to allow interrupt detection.
+	 *
+	 * NOTE: Bits 7 and 6 of Port B are connected to internal
+	 * diagnostic signals and bit 7 is inverted.
+	 */
+	z8536_write(dev, Z8536_PAB_MODE_PTS_BIT |
+			 Z8536_PAB_MODE_SB |
+			 Z8536_PAB_MODE_PMS_DISABLE,
+		    Z8536_PB_MODE_REG);
+	z8536_write(dev, 0x7f, Z8536_PB_DPP_REG);
+	z8536_write(dev, 0xff, Z8536_PB_DD_REG);
+
+	/*
+	 * Not sure what Port C is connected to...
+	 */
+	z8536_write(dev, 0x09, Z8536_PC_DPP_REG);
+	z8536_write(dev, 0x0e, Z8536_PC_DD_REG);
+
+	/*
+	 * Clear and disable all interrupt sources.
+	 *
+	 * Just in case, the reset of the Z8536 should have already
+	 * done this.
+	 */
+	z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PA_CMDSTAT_REG);
+	z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
+
+	z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PB_CMDSTAT_REG);
+	z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
+
+	z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(0));
+	z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(0));
+
+	z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(1));
+	z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(1));
+
+	z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(2));
+	z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(2));
+
+	/* Disable all interrupts */
+	z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
+}
+
+static void apci1500_port_enable(struct comedi_device *dev, bool enable)
+{
+	unsigned int cfg;
+
+	cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
+	if (enable)
+		cfg |= (Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
+	else
+		cfg &= ~(Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE);
+	z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
+}
+
+static void apci1500_timer_enable(struct comedi_device *dev,
+				  unsigned int chan, bool enable)
+{
+	unsigned int bit;
+	unsigned int cfg;
+
+	if (chan == 0)
+		bit = Z8536_CFG_CTRL_CT1E;
+	else if (chan == 1)
+		bit = Z8536_CFG_CTRL_CT2E;
+	else
+		bit = Z8536_CFG_CTRL_PCE_CT3E;
+
+	cfg = z8536_read(dev, Z8536_CFG_CTRL_REG);
+	if (enable) {
+		cfg |= bit;
+	} else {
+		cfg &= ~bit;
+		z8536_write(dev, 0x00, Z8536_CT_CMDSTAT_REG(chan));
+	}
+	z8536_write(dev, cfg, Z8536_CFG_CTRL_REG);
+}
+
+static bool apci1500_ack_irq(struct comedi_device *dev,
+			     unsigned int reg)
+{
+	unsigned int val;
+
+	val = z8536_read(dev, reg);
+	if ((val & Z8536_STAT_IE_IP) == Z8536_STAT_IE_IP) {
+		val &= 0x0f;			/* preserve any write bits */
+		val |= Z8536_CMD_CLR_IP_IUS;
+		z8536_write(dev, val, reg);
+
+		return true;
+	}
+	return false;
+}
+
+static irqreturn_t apci1500_interrupt(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct apci1500_private *devpriv = dev->private;
+	struct comedi_subdevice *s = dev->read_subdev;
+	unsigned int status = 0;
+	unsigned int val;
+
+	val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
+	if (!(val & INTCSR_INTR_ASSERTED))
+		return IRQ_NONE;
+
+	if (apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG))
+		status |= 0x01;	/* port a event (inputs 0-7) */
+
+	if (apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG)) {
+		/* Tests if this is an external error */
+		val = inb(dev->iobase + APCI1500_Z8536_PORTB_REG);
+		val &= 0xc0;
+		if (val) {
+			if (val & 0x80)	/* voltage error */
+				status |= 0x40;
+			if (val & 0x40)	/* short circuit error */
+				status |= 0x80;
+		} else {
+			status |= 0x02;	/* port b event (inputs 8-13) */
+		}
+	}
+
+	/*
+	 * NOTE: The 'status' returned by the sample matches the
+	 * interrupt mask information from the APCI-1500 Users Manual.
+	 *
+	 *    Mask     Meaning
+	 * ----------  ------------------------------------------
+	 * 0x00000001  Event 1 has occured
+	 * 0x00000010  Event 2 has occured
+	 * 0x00000100  Counter/timer 1 has run down (not implemented)
+	 * 0x00001000  Counter/timer 2 has run down (not implemented)
+	 * 0x00010000  Counter 3 has run down (not implemented)
+	 * 0x00100000  Watchdog has run down (not implemented)
+	 * 0x01000000  Voltage error
+	 * 0x10000000  Short-circuit error
+	 */
+	comedi_buf_write_samples(s, &status, 1);
+	comedi_handle_events(dev, s);
+
+	return IRQ_HANDLED;
+}
+
+static int apci1500_di_cancel(struct comedi_device *dev,
+			      struct comedi_subdevice *s)
+{
+	/* Disables the main interrupt on the board */
+	z8536_write(dev, 0x00, Z8536_INT_CTRL_REG);
+
+	/* Disable Ports A & B */
+	apci1500_port_enable(dev, false);
+
+	/* Ack any pending interrupts */
+	apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG);
+	apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG);
+
+	/* Disable pattern interrupts */
+	z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG);
+	z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG);
+
+	/* Enable Ports A & B */
+	apci1500_port_enable(dev, true);
+
+	return 0;
+}
+
+static int apci1500_di_inttrig_start(struct comedi_device *dev,
+				     struct comedi_subdevice *s,
+				     unsigned int trig_num)
+{
+	struct apci1500_private *devpriv = dev->private;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int pa_mode = Z8536_PAB_MODE_PMS_DISABLE;
+	unsigned int pb_mode = Z8536_PAB_MODE_PMS_DISABLE;
+	unsigned int pa_trig = trig_num & 0x01;
+	unsigned int pb_trig = (trig_num >> 1) & 0x01;
+	bool valid_trig = false;
+	unsigned int val;
+
+	if (trig_num != cmd->start_arg)
+		return -EINVAL;
+
+	/* Disable Ports A & B */
+	apci1500_port_enable(dev, false);
+
+	/* Set Port A for selected trigger pattern */
+	z8536_write(dev, devpriv->pm[pa_trig] & 0xff, Z8536_PA_PM_REG);
+	z8536_write(dev, devpriv->pt[pa_trig] & 0xff, Z8536_PA_PT_REG);
+	z8536_write(dev, devpriv->pp[pa_trig] & 0xff, Z8536_PA_PP_REG);
+
+	/* Set Port B for selected trigger pattern */
+	z8536_write(dev, (devpriv->pm[pb_trig] >> 8) & 0xff, Z8536_PB_PM_REG);
+	z8536_write(dev, (devpriv->pt[pb_trig] >> 8) & 0xff, Z8536_PB_PT_REG);
+	z8536_write(dev, (devpriv->pp[pb_trig] >> 8) & 0xff, Z8536_PB_PP_REG);
+
+	/* Set Port A trigger mode (if enabled) and enable interrupt */
+	if (devpriv->pm[pa_trig] & 0xff) {
+		pa_mode = pa_trig ? Z8536_PAB_MODE_PMS_AND
+				  : Z8536_PAB_MODE_PMS_OR;
+
+		val = z8536_read(dev, Z8536_PA_MODE_REG);
+		val &= ~Z8536_PAB_MODE_PMS_MASK;
+		val |= (pa_mode | Z8536_PAB_MODE_IMO);
+		z8536_write(dev, val, Z8536_PA_MODE_REG);
+
+		z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PA_CMDSTAT_REG);
+
+		valid_trig = true;
+
+		dev_dbg(dev->class_dev,
+			"Port A configured for %s mode pattern detection\n",
+			pa_trig ? "AND" : "OR");
+	}
+
+	/* Set Port B trigger mode (if enabled) and enable interrupt */
+	if (devpriv->pm[pb_trig] & 0xff00) {
+		pb_mode = pb_trig ? Z8536_PAB_MODE_PMS_AND
+				  : Z8536_PAB_MODE_PMS_OR;
+
+		val = z8536_read(dev, Z8536_PB_MODE_REG);
+		val &= ~Z8536_PAB_MODE_PMS_MASK;
+		val |= (pb_mode | Z8536_PAB_MODE_IMO);
+		z8536_write(dev, val, Z8536_PB_MODE_REG);
+
+		z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PB_CMDSTAT_REG);
+
+		valid_trig = true;
+
+		dev_dbg(dev->class_dev,
+			"Port B configured for %s mode pattern detection\n",
+			pb_trig ? "AND" : "OR");
+	}
+
+	/* Enable Ports A & B */
+	apci1500_port_enable(dev, true);
+
+	if (!valid_trig) {
+		dev_dbg(dev->class_dev,
+			"digital trigger %d is not configured\n", trig_num);
+		return -EINVAL;
+	}
+
+	/* Authorizes the main interrupt on the board */
+	z8536_write(dev, Z8536_INT_CTRL_MIE | Z8536_INT_CTRL_DLC,
+		    Z8536_INT_CTRL_REG);
+
+	return 0;
+}
+
+static int apci1500_di_cmd(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
+{
+	s->async->inttrig = apci1500_di_inttrig_start;
+
+	return 0;
+}
+
+static int apci1500_di_cmdtest(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_cmd *cmd)
+{
+	int err = 0;
+
+	/* Step 1 : check if triggers are trivially valid */
+
+	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
+	err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+	err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
+
+	if (err)
+		return 1;
+
+	/* Step 2a : make sure trigger sources are unique */
+	/* Step 2b : and mutually compatible */
+
+	/* Step 3: check if arguments are trivially valid */
+
+	/*
+	 * Internal start source triggers:
+	 *
+	 *   0	AND mode for Port A (digital inputs 0-7)
+	 *	AND mode for Port B (digital inputs 8-13 and internal signals)
+	 *
+	 *   1	OR mode for Port A (digital inputs 0-7)
+	 *	AND mode for Port B (digital inputs 8-13 and internal signals)
+	 *
+	 *   2	AND mode for Port A (digital inputs 0-7)
+	 *	OR mode for Port B (digital inputs 8-13 and internal signals)
+	 *
+	 *   3	OR mode for Port A (digital inputs 0-7)
+	 *	OR mode for Port B (digital inputs 8-13 and internal signals)
+	 */
+	err |= cfc_check_trigger_arg_max(&cmd->start_arg, 3);
+
+	err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+	err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+	err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
+	if (err)
+		return 3;
+
+	/* Step 4: fix up any arguments */
+
+	/* Step 5: check channel list if it exists */
+
+	return 0;
+}
+
+/*
+ * The pattern-recognition logic must be configured before the digital
+ * input async command is started.
+ *
+ * Digital input channels 0 to 13 can generate interrupts. Channels 14
+ * and 15 are connected to internal board status/diagnostic signals.
+ *
+ * Channel 14 - Voltage error (the external supply is < 5V)
+ * Channel 15 - Short-circuit/overtemperature error
+ *
+ *	data[0] : INSN_CONFIG_DIGITAL_TRIG
+ *	data[1] : trigger number
+ *		  0 = AND mode
+ *		  1 = OR mode
+ *	data[2] : configuration operation:
+ *	          COMEDI_DIGITAL_TRIG_DISABLE = no interrupts
+ *	          COMEDI_DIGITAL_TRIG_ENABLE_EDGES = edge interrupts
+ *	          COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = level interrupts
+ *	data[3] : left-shift for data[4] and data[5]
+ *	data[4] : rising-edge/high level channels
+ *	data[5] : falling-edge/low level channels
+ */
+static int apci1500_di_cfg_trig(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn,
+				unsigned int *data)
+{
+	struct apci1500_private *devpriv = dev->private;
+	unsigned int trig = data[1];
+	unsigned int shift = data[3];
+	unsigned int hi_mask = data[4] << shift;
+	unsigned int lo_mask = data[5] << shift;
+	unsigned int chan_mask = hi_mask | lo_mask;
+	unsigned int old_mask = (1 << shift) - 1;
+	unsigned int pm = devpriv->pm[trig] & old_mask;
+	unsigned int pt = devpriv->pt[trig] & old_mask;
+	unsigned int pp = devpriv->pp[trig] & old_mask;
+
+	if (trig > 1) {
+		dev_dbg(dev->class_dev,
+			"invalid digital trigger number (0=AND, 1=OR)\n");
+		return -EINVAL;
+	}
+
+	if (chan_mask > 0xffff) {
+		dev_dbg(dev->class_dev, "invalid digital trigger channel\n");
+		return -EINVAL;
+	}
+
+	switch (data[2]) {
+	case COMEDI_DIGITAL_TRIG_DISABLE:
+		/* clear trigger configuration */
+		pm = 0;
+		pt = 0;
+		pp = 0;
+		break;
+	case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
+		pm |= chan_mask;	/* enable channels */
+		pt |= chan_mask;	/* enable edge detection */
+		pp |= hi_mask;		/* rising-edge channels */
+		pp &= ~lo_mask;		/* falling-edge channels */
+		break;
+	case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS:
+		pm |= chan_mask;	/* enable channels */
+		pt &= ~chan_mask;	/* enable level detection */
+		pp |= hi_mask;		/* high level channels */
+		pp &= ~lo_mask;		/* low level channels */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/*
+	 * The AND mode trigger can only have one channel (max) enabled
+	 * for edge detection.
+	 */
+	if (trig == 0) {
+		int ret = 0;
+		unsigned int src;
+
+		src = pt & 0xff;
+		if (src)
+			ret |= cfc_check_trigger_is_unique(src);
+
+		src = (pt >> 8) & 0xff;
+		if (src)
+			ret |= cfc_check_trigger_is_unique(src);
+
+		if (ret) {
+			dev_dbg(dev->class_dev,
+				"invalid AND trigger configuration\n");
+			return ret;
+		}
+	}
+
+	/* save the trigger configuration */
+	devpriv->pm[trig] = pm;
+	devpriv->pt[trig] = pt;
+	devpriv->pp[trig] = pp;
+
+	return insn->n;
+}
+
+static int apci1500_di_insn_config(struct comedi_device *dev,
+				   struct comedi_subdevice *s,
+				   struct comedi_insn *insn,
+				   unsigned int *data)
+{
+	switch (data[0]) {
+	case INSN_CONFIG_DIGITAL_TRIG:
+		return apci1500_di_cfg_trig(dev, s, insn, data);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int apci1500_di_insn_bits(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn,
+				 unsigned int *data)
+{
+	struct apci1500_private *devpriv = dev->private;
+
+	data[1] = inw(devpriv->addon + APCI1500_DI_REG);
+
+	return insn->n;
+}
+
+static int apci1500_do_insn_bits(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn,
+				 unsigned int *data)
+{
+	struct apci1500_private *devpriv = dev->private;
+
+	if (comedi_dio_update_state(s, data))
+		outw(s->state, devpriv->addon + APCI1500_DO_REG);
+
+	data[1] = s->state;
+
+	return insn->n;
+}
+
+static int apci1500_timer_insn_config(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      struct comedi_insn *insn,
+				      unsigned int *data)
+{
+	struct apci1500_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int val;
+
+	switch (data[0]) {
+	case INSN_CONFIG_ARM:
+		val = data[1] & s->maxdata;
+		z8536_write(dev, val & 0xff, Z8536_CT_RELOAD_LSB_REG(chan));
+		z8536_write(dev, (val >> 8) & 0xff,
+			    Z8536_CT_RELOAD_MSB_REG(chan));
+
+		apci1500_timer_enable(dev, chan, true);
+		z8536_write(dev, Z8536_CT_CMDSTAT_GCB,
+			    Z8536_CT_CMDSTAT_REG(chan));
+		break;
+	case INSN_CONFIG_DISARM:
+		apci1500_timer_enable(dev, chan, false);
+		break;
+
+	case INSN_CONFIG_GET_COUNTER_STATUS:
+		data[1] = 0;
+		val = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
+		if (val & Z8536_CT_STAT_CIP)
+			data[1] |= COMEDI_COUNTER_COUNTING;
+		if (val & Z8536_CT_CMDSTAT_GCB)
+			data[1] |= COMEDI_COUNTER_ARMED;
+		if (val & Z8536_STAT_IP) {
+			data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
+			apci1500_ack_irq(dev, Z8536_CT_CMDSTAT_REG(chan));
+		}
+		data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
+			  COMEDI_COUNTER_TERMINAL_COUNT;
+		break;
+
+	case INSN_CONFIG_SET_COUNTER_MODE:
+		/* Simulate the 8254 timer modes */
+		switch (data[1]) {
+		case I8254_MODE0:
+			/* Interrupt on Terminal Count */
+			val = Z8536_CT_MODE_ECE |
+			      Z8536_CT_MODE_DCS_ONESHOT;
+			break;
+		case I8254_MODE1:
+			/* Hardware Retriggerable One-Shot */
+			val = Z8536_CT_MODE_ETE |
+			      Z8536_CT_MODE_DCS_ONESHOT;
+			break;
+		case I8254_MODE2:
+			/* Rate Generator */
+			val = Z8536_CT_MODE_CSC |
+			      Z8536_CT_MODE_DCS_PULSE;
+			break;
+		case I8254_MODE3:
+			/* Square Wave Mode */
+			val = Z8536_CT_MODE_CSC |
+			      Z8536_CT_MODE_DCS_SQRWAVE;
+			break;
+		case I8254_MODE4:
+			/* Software Triggered Strobe */
+			val = Z8536_CT_MODE_REB |
+			      Z8536_CT_MODE_DCS_PULSE;
+			break;
+		case I8254_MODE5:
+			/* Hardware Triggered Strobe (watchdog) */
+			val = Z8536_CT_MODE_EOE |
+			      Z8536_CT_MODE_ETE |
+			      Z8536_CT_MODE_REB |
+			      Z8536_CT_MODE_DCS_PULSE;
+			break;
+		default:
+			return -EINVAL;
+		}
+		apci1500_timer_enable(dev, chan, false);
+		z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
+		break;
+
+	case INSN_CONFIG_SET_CLOCK_SRC:
+		if (data[1] > 2)
+			return -EINVAL;
+		devpriv->clk_src = data[1];
+		if (devpriv->clk_src == 2)
+			devpriv->clk_src = 3;
+		outw(devpriv->clk_src, devpriv->addon + APCI1500_CLK_SEL_REG);
+		break;
+	case INSN_CONFIG_GET_CLOCK_SRC:
+		switch (devpriv->clk_src) {
+		case 0:
+			data[1] = 0;		/* 111.86 kHz / 2 */
+			data[2] = 17879;	/* 17879 ns (approx) */
+			break;
+		case 1:
+			data[1] = 1;		/* 3.49 kHz / 2 */
+			data[2] = 573066;	/* 573066 ns (approx) */
+			break;
+		case 3:
+			data[1] = 2;		/* 1.747 kHz / 2 */
+			data[2] = 1164822;	/* 1164822 ns (approx) */
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+
+	case INSN_CONFIG_SET_GATE_SRC:
+		if (chan == 0)
+			return -EINVAL;
+
+		val = z8536_read(dev, Z8536_CT_MODE_REG(chan));
+		val &= Z8536_CT_MODE_EGE;
+		if (data[1] == 1)
+			val |= Z8536_CT_MODE_EGE;
+		else if (data[1] > 1)
+			return -EINVAL;
+		z8536_write(dev, val, Z8536_CT_MODE_REG(chan));
+		break;
+	case INSN_CONFIG_GET_GATE_SRC:
+		if (chan == 0)
+			return -EINVAL;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return insn->n;
+}
+
+static int apci1500_timer_insn_write(struct comedi_device *dev,
+				     struct comedi_subdevice *s,
+				     struct comedi_insn *insn,
+				     unsigned int *data)
+{
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int cmd;
+
+	cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
+	cmd &= Z8536_CT_CMDSTAT_GCB;	/* preserve gate */
+	cmd |= Z8536_CT_CMD_TCB;	/* set trigger */
+
+	/* software trigger a timer, it only makes sense to do one write */
+	if (insn->n)
+		z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
+
+	return insn->n;
+}
+
+static int apci1500_timer_insn_read(struct comedi_device *dev,
+				    struct comedi_subdevice *s,
+				    struct comedi_insn *insn,
+				    unsigned int *data)
+{
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int cmd;
+	unsigned int val;
+	int i;
+
+	cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan));
+	cmd &= Z8536_CT_CMDSTAT_GCB;	/* preserve gate */
+	cmd |= Z8536_CT_CMD_RCC;	/* set RCC */
+
+	for (i = 0; i < insn->n; i++) {
+		z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan));
+
+		val = z8536_read(dev, Z8536_CT_VAL_MSB_REG(chan)) << 8;
+		val |= z8536_read(dev, Z8536_CT_VAL_LSB_REG(chan));
+
+		data[i] = val;
+	}
+
+	return insn->n;
+}
 
 static int apci1500_auto_attach(struct comedi_device *dev,
 				unsigned long context)
@@ -35,10 +768,10 @@ static int apci1500_auto_attach(struct comedi_device *dev,
 		return ret;
 
 	dev->iobase = pci_resource_start(pcidev, 1);
-	devpriv->iobase = dev->iobase;
-	devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
-	devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
-	devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
+	devpriv->amcc = pci_resource_start(pcidev, 0);
+	devpriv->addon = pci_resource_start(pcidev, 2);
+
+	z8536_reset(dev);
 
 	if (pcidev->irq > 0) {
 		ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED,
@@ -51,51 +784,66 @@ static int apci1500_auto_attach(struct comedi_device *dev,
 	if (ret)
 		return ret;
 
-	/*  Allocate and Initialise DI Subdevice Structures */
+	/* Digital Input subdevice */
 	s = &dev->subdevices[0];
-	s->type = COMEDI_SUBD_DI;
-	s->subdev_flags = SDF_READABLE;
-	s->n_chan = 16;
-	s->maxdata = 1;
-	s->range_table = &range_digital;
-	s->insn_config = apci1500_di_config;
-	s->insn_read = apci1500_di_read;
-	s->insn_write = apci1500_di_write;
-	s->insn_bits = apci1500_di_insn_bits;
-
-	/*  Allocate and Initialise DO Subdevice Structures */
+	s->type		= COMEDI_SUBD_DI;
+	s->subdev_flags	= SDF_READABLE;
+	s->n_chan	= 16;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= apci1500_di_insn_bits;
+	if (dev->irq) {
+		dev->read_subdev = s;
+		s->subdev_flags |= SDF_CMD_READ;
+		s->len_chanlist	= 1;
+		s->insn_config	= apci1500_di_insn_config;
+		s->do_cmdtest	= apci1500_di_cmdtest;
+		s->do_cmd	= apci1500_di_cmd;
+		s->cancel	= apci1500_di_cancel;
+	}
+
+	/* Digital Output subdevice */
 	s = &dev->subdevices[1];
-	s->type = COMEDI_SUBD_DO;
-	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-	s->n_chan = 16;
-	s->maxdata = 1;
-	s->range_table = &range_digital;
-	s->insn_config = apci1500_do_config;
-	s->insn_write = apci1500_do_write;
-	s->insn_bits = apci1500_do_bits;
-
-	/*  Allocate and Initialise Timer Subdevice Structures */
+	s->type		= COMEDI_SUBD_DO;
+	s->subdev_flags	= SDF_WRITABLE;
+	s->n_chan	= 16;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= apci1500_do_insn_bits;
+
+	/* reset all the digital outputs */
+	outw(0x0, devpriv->addon + APCI1500_DO_REG);
+
+	/* Counter/Timer(Watchdog) subdevice */
 	s = &dev->subdevices[2];
-	s->type = COMEDI_SUBD_TIMER;
-	s->subdev_flags = SDF_WRITABLE;
-	s->n_chan = 1;
-	s->maxdata = 0;
-	s->len_chanlist = 1;
-	s->range_table = &range_digital;
-	s->insn_write = apci1500_timer_write;
-	s->insn_read = apci1500_timer_read;
-	s->insn_config = apci1500_timer_config;
-	s->insn_bits = apci1500_timer_bits;
-
-	apci1500_reset(dev);
+	s->type		= COMEDI_SUBD_TIMER;
+	s->subdev_flags	= SDF_WRITABLE | SDF_READABLE;
+	s->n_chan	= 3;
+	s->maxdata	= 0xffff;
+	s->range_table	= &range_unknown;
+	s->insn_config	= apci1500_timer_insn_config;
+	s->insn_write	= apci1500_timer_insn_write;
+	s->insn_read	= apci1500_timer_insn_read;
+
+	/* Enable the PCI interrupt */
+	if (dev->irq) {
+		outl(0x2000 | INTCSR_INBOX_FULL_INT,
+		     devpriv->amcc + AMCC_OP_REG_INTCSR);
+		inl(devpriv->amcc + AMCC_OP_REG_IMB1);
+		inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
+		outl(INTCSR_INBOX_INTR_STATUS | 0x2000 | INTCSR_INBOX_FULL_INT,
+		     devpriv->amcc + AMCC_OP_REG_INTCSR);
+	}
 
 	return 0;
 }
 
 static void apci1500_detach(struct comedi_device *dev)
 {
-	if (dev->iobase)
-		apci1500_reset(dev);
+	struct apci1500_private *devpriv = dev->private;
+
+	if (devpriv->amcc)
+		outl(0x0, devpriv->amcc + AMCC_OP_REG_INTCSR);
 	comedi_pci_detach(dev);
 }
 
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
index a726efcea6a5..5961f195ba0b 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -267,7 +267,6 @@ static irqreturn_t apci3501_interrupt(int irq, void *d)
 	struct apci3501_private *devpriv = dev->private;
 	unsigned int ui_Timer_AOWatchdog;
 	unsigned long ul_Command1;
-	int i_temp;
 
 	/*  Disable Interrupt */
 	ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG);
@@ -285,7 +284,7 @@ static irqreturn_t apci3501_interrupt(int irq, void *d)
 	ul_Command1 = inl(dev->iobase + APCI3501_TIMER_CTRL_REG);
 	ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
 	outl(ul_Command1, dev->iobase + APCI3501_TIMER_CTRL_REG);
-	i_temp = inl(dev->iobase + APCI3501_TIMER_STATUS_REG) & 0x1;
+	inl(dev->iobase + APCI3501_TIMER_STATUS_REG);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
index 528f15c25dae..a3ea4b7c18dd 100644
--- a/drivers/staging/comedi/drivers/adl_pci6208.c
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -19,8 +19,7 @@
 /*
  * Driver: adl_pci6208
  * Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards
- * Devices: (ADLink) PCI-6208 [adl_pci6208]
- *	    (ADLink) PCI-6216 [adl_pci6216]
+ * Devices: [ADLink] PCI-6208 (adl_pci6208), PCI-6216 (adl_pci6216)
  * Author: nsyeow <nsyeow@pd.jaring.my>
  * Updated: Fri, 30 Jan 2004 14:44:27 +0800
  * Status: untested
diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c
index fb8e5f582496..618e641ffaac 100644
--- a/drivers/staging/comedi/drivers/adl_pci7x3x.c
+++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c
@@ -22,27 +22,35 @@
  */
 
 /*
-Driver: adl_pci7x3x
-Description: 32/64-Channel Isolated Digital I/O Boards
-Devices: (ADLink) PCI-7230 [adl_pci7230] - 16 input / 16 output
-	 (ADLink) PCI-7233 [adl_pci7233] - 32 input
-	 (ADLink) PCI-7234 [adl_pci7234] - 32 output
-	 (ADLink) PCI-7432 [adl_pci7432] - 32 input / 32 output
-	 (ADLink) PCI-7433 [adl_pci7433] - 64 input
-	 (ADLink) PCI-7434 [adl_pci7434] - 64 output
-Author: H Hartley Sweeten <hsweeten@visionengravers.com>
-Updated: Thu, 02 Aug 2012 14:27:46 -0700
-Status: untested
-
-The PCI-7230, PCI-7432 and PCI-7433 boards also support external
-interrupt signals on digital input channels 0 and 1. The PCI-7233
-has dual-interrupt sources for change-of-state (COS) on any 16
-digital input channels of LSB and for COS on any 16 digital input
-lines of MSB. Interrupts are not currently supported by this
-driver.
-
-Configuration Options: not applicable, uses comedi PCI auto config
-*/
+ * Driver: adl_pci7x3x
+ * Description: 32/64-Channel Isolated Digital I/O Boards
+ * Devices: [ADLink] PCI-7230 (adl_pci7230), PCI-7233 (adl_pci7233),
+ *   PCI-7234 (adl_pci7234), PCI-7432 (adl_pci7432), PCI-7433 (adl_pci7433),
+ *   PCI-7434 (adl_pci7434)
+ * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
+ * Updated: Thu, 02 Aug 2012 14:27:46 -0700
+ * Status: untested
+ *
+ * One or two subdevices are setup by this driver depending on
+ * the number of digital inputs and/or outputs provided by the
+ * board. Each subdevice has a maximum of 32 channels.
+ *
+ *	PCI-7230 - 2 subdevices: 0 - 16 input, 1 - 16 output
+ *	PCI-7233 - 1 subdevice: 0 - 32 input
+ *	PCI-7234 - 1 subdevice: 0 - 32 output
+ *	PCI-7432 - 2 subdevices: 0 - 32 input, 1 - 32 output
+ *	PCI-7433 - 2 subdevices: 0 - 32 input, 1 - 32 input
+ *	PCI-7434 - 2 subdevices: 0 - 32 output, 1 - 32 output
+ *
+ * The PCI-7230, PCI-7432 and PCI-7433 boards also support external
+ * interrupt signals on digital input channels 0 and 1. The PCI-7233
+ * has dual-interrupt sources for change-of-state (COS) on any 16
+ * digital input channels of LSB and for COS on any 16 digital input
+ * lines of MSB. Interrupts are not currently supported by this
+ * driver.
+ *
+ * Configuration Options: not applicable, uses comedi PCI auto config
+ */
 
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -155,18 +163,6 @@ static int adl_pci7x3x_auto_attach(struct comedi_device *dev,
 		return ret;
 	dev->iobase = pci_resource_start(pcidev, 2);
 
-	/*
-	 * One or two subdevices are setup by this driver depending on
-	 * the number of digital inputs and/or outputs provided by the
-	 * board. Each subdevice has a maximum of 32 channels.
-	 *
-	 *	PCI-7230 - 2 subdevices: 0 - 16 input, 1 - 16 output
-	 *	PCI-7233 - 1 subdevice: 0 - 32 input
-	 *	PCI-7234 - 1 subdevice: 0 - 32 output
-	 *	PCI-7432 - 2 subdevices: 0 - 32 input, 1 - 32 output
-	 *	PCI-7433 - 2 subdevices: 0 - 32 input, 1 - 32 input
-	 *	PCI-7434 - 2 subdevices: 0 - 32 output, 1 - 32 output
-	 */
 	ret = comedi_alloc_subdevices(dev, board->nsubdevs);
 	if (ret)
 		return ret;
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
index 72bccb447a74..cc6c53b800a7 100644
--- a/drivers/staging/comedi/drivers/adl_pci8164.c
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -18,7 +18,7 @@
 /*
  * Driver: adl_pci8164
  * Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
- * Devices: (ADLink) PCI-8164 [adl_pci8164]
+ * Devices: [ADLink] PCI-8164 (adl_pci8164)
  * Author: Michel Lachaine <mike@mikelachaine.ca>
  * Status: experimental
  * Updated: Mon, 14 Apr 2008 15:10:32 +0100
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index 47f6c0e9f014..f68dc99f8e27 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -539,7 +539,7 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
 			spin_unlock_irqrestore(&dev->spinlock, irq_flags);
 			dev_dbg(dev->class_dev, "fifo overflow\n");
 			outb(0, dev->iobase + PCI9111_INT_CLR_REG);
-			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+			async->events |= COMEDI_CB_ERROR;
 			comedi_handle_events(dev, s);
 
 			return IRQ_HANDLED;
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 26603582e71a..f61e392c2d3e 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -749,13 +749,13 @@ static irqreturn_t pci9118_interrupt(int irq, void *d)
 
 	if (intcsr & MASTER_ABORT_INT) {
 		dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
-		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		s->async->events |= COMEDI_CB_ERROR;
 		goto interrupt_exit;
 	}
 
 	if (intcsr & TARGET_ABORT_INT) {
 		dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
-		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		s->async->events |= COMEDI_CB_ERROR;
 		goto interrupt_exit;
 	}
 
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index d02df7d0c629..9800c01e6fb9 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -51,11 +51,6 @@ Configuration options:
 #include "8253.h"
 #include "amcc_s5933.h"
 
-/* hardware types of the cards */
-#define TYPE_PCI171X	0
-#define TYPE_PCI1713	2
-#define TYPE_PCI1720	3
-
 #define PCI171x_AD_DATA	 0	/* R:   A/D data */
 #define PCI171x_SOFTTRG	 0	/* W:   soft trigger for A/D */
 #define PCI171x_RANGE	 2	/* W:   A/D gain/range register */
@@ -164,7 +159,7 @@ static const struct comedi_lrange range_pci17x1 = {
 
 static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
 
-static const struct comedi_lrange range_pci1720 = {
+static const struct comedi_lrange pci1720_ao_range = {
 	4, {
 		UNI_RANGE(5),
 		UNI_RANGE(10),
@@ -173,7 +168,7 @@ static const struct comedi_lrange range_pci1720 = {
 	}
 };
 
-static const struct comedi_lrange range_pci171x_da = {
+static const struct comedi_lrange pci171x_ao_range = {
 	2, {
 		UNI_RANGE(5),
 		UNI_RANGE(10)
@@ -191,112 +186,81 @@ enum pci1710_boardid {
 
 struct boardtype {
 	const char *name;	/*  board name */
-	char have_irq;		/*  1=card support IRQ */
-	char cardtype;		/*  0=1710& co. 2=1713, ... */
 	int n_aichan;		/*  num of A/D chans */
-	int n_aichand;		/*  num of A/D chans in diff mode */
-	int n_aochan;		/*  num of D/A chans */
-	int n_dichan;		/*  num of DI chans */
-	int n_dochan;		/*  num of DO chans */
-	int n_counter;		/*  num of counters */
-	int ai_maxdata;		/*  resolution of A/D */
-	int ao_maxdata;		/*  resolution of D/A */
 	const struct comedi_lrange *rangelist_ai;	/*  rangelist for A/D */
 	const char *rangecode_ai;	/*  range codes for programming */
-	const struct comedi_lrange *rangelist_ao;	/*  rangelist for D/A */
-	unsigned int ai_ns_min;	/*  max sample speed of card v ns */
-	unsigned int fifo_half_size;	/*  size of FIFO/2 */
+	unsigned int is_pci1713:1;
+	unsigned int is_pci1720:1;
+	unsigned int has_irq:1;
+	unsigned int has_large_fifo:1;	/* 4K or 1K FIFO */
+	unsigned int has_diff_ai:1;
+	unsigned int has_ao:1;
+	unsigned int has_di_do:1;
+	unsigned int has_counter:1;
 };
 
 static const struct boardtype boardtypes[] = {
 	[BOARD_PCI1710] = {
 		.name		= "pci1710",
-		.have_irq	= 1,
-		.cardtype	= TYPE_PCI171X,
 		.n_aichan	= 16,
-		.n_aichand	= 8,
-		.n_aochan	= 2,
-		.n_dichan	= 16,
-		.n_dochan	= 16,
-		.n_counter	= 1,
-		.ai_maxdata	= 0x0fff,
-		.ao_maxdata	= 0x0fff,
 		.rangelist_ai	= &range_pci1710_3,
 		.rangecode_ai	= range_codes_pci1710_3,
-		.rangelist_ao	= &range_pci171x_da,
-		.ai_ns_min	= 10000,
-		.fifo_half_size	= 2048,
+		.has_irq	= 1,
+		.has_large_fifo	= 1,
+		.has_diff_ai	= 1,
+		.has_ao		= 1,
+		.has_di_do	= 1,
+		.has_counter	= 1,
 	},
 	[BOARD_PCI1710HG] = {
 		.name		= "pci1710hg",
-		.have_irq	= 1,
-		.cardtype	= TYPE_PCI171X,
 		.n_aichan	= 16,
-		.n_aichand	= 8,
-		.n_aochan	= 2,
-		.n_dichan	= 16,
-		.n_dochan	= 16,
-		.n_counter	= 1,
-		.ai_maxdata	= 0x0fff,
-		.ao_maxdata	= 0x0fff,
 		.rangelist_ai	= &range_pci1710hg,
 		.rangecode_ai	= range_codes_pci1710hg,
-		.rangelist_ao	= &range_pci171x_da,
-		.ai_ns_min	= 10000,
-		.fifo_half_size	= 2048,
+		.has_irq	= 1,
+		.has_large_fifo	= 1,
+		.has_diff_ai	= 1,
+		.has_ao		= 1,
+		.has_di_do	= 1,
+		.has_counter	= 1,
 	},
 	[BOARD_PCI1711] = {
 		.name		= "pci1711",
-		.have_irq	= 1,
-		.cardtype	= TYPE_PCI171X,
 		.n_aichan	= 16,
-		.n_aochan	= 2,
-		.n_dichan	= 16,
-		.n_dochan	= 16,
-		.n_counter	= 1,
-		.ai_maxdata	= 0x0fff,
-		.ao_maxdata	= 0x0fff,
 		.rangelist_ai	= &range_pci17x1,
 		.rangecode_ai	= range_codes_pci17x1,
-		.rangelist_ao	= &range_pci171x_da,
-		.ai_ns_min	= 10000,
-		.fifo_half_size	= 512,
+		.has_irq	= 1,
+		.has_ao		= 1,
+		.has_di_do	= 1,
+		.has_counter	= 1,
 	},
 	[BOARD_PCI1713] = {
 		.name		= "pci1713",
-		.have_irq	= 1,
-		.cardtype	= TYPE_PCI1713,
 		.n_aichan	= 32,
-		.n_aichand	= 16,
-		.ai_maxdata	= 0x0fff,
 		.rangelist_ai	= &range_pci1710_3,
 		.rangecode_ai	= range_codes_pci1710_3,
-		.ai_ns_min	= 10000,
-		.fifo_half_size	= 2048,
+		.is_pci1713	= 1,
+		.has_irq	= 1,
+		.has_large_fifo	= 1,
+		.has_diff_ai	= 1,
 	},
 	[BOARD_PCI1720] = {
 		.name		= "pci1720",
-		.cardtype	= TYPE_PCI1720,
-		.n_aochan	= 4,
-		.ao_maxdata	= 0x0fff,
-		.rangelist_ao	= &range_pci1720,
+		.is_pci1720	= 1,
+		.has_ao		= 1,
 	},
 	[BOARD_PCI1731] = {
 		.name		= "pci1731",
-		.have_irq	= 1,
-		.cardtype	= TYPE_PCI171X,
 		.n_aichan	= 16,
-		.n_dichan	= 16,
-		.n_dochan	= 16,
-		.ai_maxdata	= 0x0fff,
 		.rangelist_ai	= &range_pci17x1,
 		.rangecode_ai	= range_codes_pci17x1,
-		.ai_ns_min	= 10000,
-		.fifo_half_size	= 512,
+		.has_irq	= 1,
+		.has_di_do	= 1,
 	},
 };
 
 struct pci1710_private {
+	unsigned int max_samples;
 	unsigned int CntrlReg;	/*  Control register */
 	unsigned char ai_et;
 	unsigned int ai_et_CntrlReg;
@@ -308,39 +272,10 @@ struct pci1710_private {
 	unsigned int act_chanlist[32];	/*  list of scanned channel */
 	unsigned char saved_seglen;	/* len of the non-repeating chanlist */
 	unsigned char da_ranges;	/*  copy of D/A outpit range register */
-	unsigned short ao_data[4];	/*  data output buffer */
 	unsigned int cnt0_write_wait;	/* after a write, wait for update of the
 					 * internal state */
 };
 
-/*  used for gain list programming */
-static const unsigned int muxonechan[] = {
-	0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707,
-	0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
-	0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
-	0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
-};
-
-static int pci171x_ai_dropout(struct comedi_device *dev,
-			      struct comedi_subdevice *s,
-			      unsigned int chan,
-			      unsigned int val)
-{
-	const struct boardtype *board = dev->board_ptr;
-	struct pci1710_private *devpriv = dev->private;
-
-	if (board->cardtype != TYPE_PCI1713) {
-		if ((val & 0xf000) != devpriv->act_chanlist[chan]) {
-			dev_err(dev->class_dev,
-				"A/D data droput: received from channel %d, expected %d\n",
-				(val >> 12) & 0xf,
-				(devpriv->act_chanlist[chan] >> 12) & 0xf);
-			return -ENODATA;
-		}
-	}
-	return 0;
-}
-
 static int pci171x_ai_check_chanlist(struct comedi_device *dev,
 				     struct comedi_subdevice *s,
 				     struct comedi_cmd *cmd)
@@ -407,33 +342,39 @@ static int pci171x_ai_check_chanlist(struct comedi_device *dev,
 	return 0;
 }
 
-static void setup_channel_list(struct comedi_device *dev,
-			       struct comedi_subdevice *s,
-			       unsigned int *chanlist, unsigned int n_chan,
-			       unsigned int seglen)
+static void pci171x_ai_setup_chanlist(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      unsigned int *chanlist,
+				      unsigned int n_chan,
+				      unsigned int seglen)
 {
-	const struct boardtype *this_board = dev->board_ptr;
+	const struct boardtype *board = dev->board_ptr;
 	struct pci1710_private *devpriv = dev->private;
-	unsigned int i, range, chanprog;
+	unsigned int first_chan = CR_CHAN(chanlist[0]);
+	unsigned int last_chan = CR_CHAN(chanlist[seglen - 1]);
+	unsigned int i;
 
 	for (i = 0; i < seglen; i++) {	/*  store range list to card */
-		chanprog = muxonechan[CR_CHAN(chanlist[i])];
-		outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */
-		range = this_board->rangecode_ai[CR_RANGE(chanlist[i])];
-		if (CR_AREF(chanlist[i]) == AREF_DIFF)
-			range |= 0x0020;
-		outw(range, dev->iobase + PCI171x_RANGE); /* select gain */
-		devpriv->act_chanlist[i] =
-			(CR_CHAN(chanlist[i]) << 12) & 0xf000;
-	}
-	for ( ; i < n_chan; i++) { /* store remainder of channel list */
-		devpriv->act_chanlist[i] =
-			(CR_CHAN(chanlist[i]) << 12) & 0xf000;
+		unsigned int chan = CR_CHAN(chanlist[i]);
+		unsigned int range = CR_RANGE(chanlist[i]);
+		unsigned int aref = CR_AREF(chanlist[i]);
+		unsigned int rangeval;
+
+		rangeval = board->rangecode_ai[range];
+		if (aref == AREF_DIFF)
+			rangeval |= 0x0020;
+
+		/* select channel and set range */
+		outw(chan | (chan << 8), dev->iobase + PCI171x_MUX);
+		outw(rangeval, dev->iobase + PCI171x_RANGE);
+
+		devpriv->act_chanlist[i] = chan;
 	}
+	for ( ; i < n_chan; i++)	/* store remainder of channel list */
+		devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]);
 
-	devpriv->ai_et_MuxVal =
-		CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
 	/* select channel interval to scan */
+	devpriv->ai_et_MuxVal = first_chan | (last_chan << 8);
 	outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);
 }
 
@@ -450,9 +391,39 @@ static int pci171x_ai_eoc(struct comedi_device *dev,
 	return -EBUSY;
 }
 
-static int pci171x_insn_read_ai(struct comedi_device *dev,
+static int pci171x_ai_read_sample(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  unsigned int cur_chan,
+				  unsigned int *val)
+{
+	const struct boardtype *board = dev->board_ptr;
+	struct pci1710_private *devpriv = dev->private;
+	unsigned int sample;
+	unsigned int chan;
+
+	sample = inw(dev->iobase + PCI171x_AD_DATA);
+	if (!board->is_pci1713) {
+		/*
+		 * The upper 4 bits of the 16-bit sample are the channel number
+		 * that the sample was acquired from. Verify that this channel
+		 * number matches the expected channel number.
+		 */
+		chan = sample >> 12;
+		if (chan != devpriv->act_chanlist[cur_chan]) {
+			dev_err(dev->class_dev,
+				"A/D data droput: received from channel %d, expected %d\n",
+				chan, devpriv->act_chanlist[cur_chan]);
+			return -ENODATA;
+		}
+	}
+	*val = sample & s->maxdata;
+	return 0;
+}
+
+static int pci171x_ai_insn_read(struct comedi_device *dev,
 				struct comedi_subdevice *s,
-				struct comedi_insn *insn, unsigned int *data)
+				struct comedi_insn *insn,
+				unsigned int *data)
 {
 	struct pci1710_private *devpriv = dev->private;
 	unsigned int chan = CR_CHAN(insn->chanspec);
@@ -465,7 +436,7 @@ static int pci171x_insn_read_ai(struct comedi_device *dev,
 	outb(0, dev->iobase + PCI171x_CLRFIFO);
 	outb(0, dev->iobase + PCI171x_CLRINT);
 
-	setup_channel_list(dev, s, &insn->chanspec, 1, 1);
+	pci171x_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1);
 
 	for (i = 0; i < insn->n; i++) {
 		unsigned int val;
@@ -476,12 +447,11 @@ static int pci171x_insn_read_ai(struct comedi_device *dev,
 		if (ret)
 			break;
 
-		val = inw(dev->iobase + PCI171x_AD_DATA);
-		ret = pci171x_ai_dropout(dev, s, chan, val);
+		ret = pci171x_ai_read_sample(dev, s, chan, &val);
 		if (ret)
 			break;
 
-		data[i] = val & s->maxdata;
+		data[i] = val;
 	}
 
 	outb(0, dev->iobase + PCI171x_CLRFIFO);
@@ -490,73 +460,43 @@ static int pci171x_insn_read_ai(struct comedi_device *dev,
 	return ret ? ret : insn->n;
 }
 
-/*
-==============================================================================
-*/
-static int pci171x_insn_write_ao(struct comedi_device *dev,
+static int pci171x_ao_insn_write(struct comedi_device *dev,
 				 struct comedi_subdevice *s,
-				 struct comedi_insn *insn, unsigned int *data)
+				 struct comedi_insn *insn,
+				 unsigned int *data)
 {
 	struct pci1710_private *devpriv = dev->private;
-	unsigned int val;
-	int n, chan, range, ofs;
-
-	chan = CR_CHAN(insn->chanspec);
-	range = CR_RANGE(insn->chanspec);
-	if (chan) {
-		devpriv->da_ranges &= 0xfb;
-		devpriv->da_ranges |= (range << 2);
-		outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
-		ofs = PCI171x_DA2;
-	} else {
-		devpriv->da_ranges &= 0xfe;
-		devpriv->da_ranges |= range;
-		outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
-		ofs = PCI171x_DA1;
-	}
-	val = devpriv->ao_data[chan];
-
-	for (n = 0; n < insn->n; n++) {
-		val = data[n];
-		outw(val, dev->iobase + ofs);
-	}
-
-	devpriv->ao_data[chan] = val;
-
-	return n;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int range = CR_RANGE(insn->chanspec);
+	unsigned int reg = chan ? PCI171x_DA2 : PCI171x_DA1;
+	unsigned int val = s->readback[chan];
+	int i;
 
-}
+	devpriv->da_ranges &= ~(1 << (chan << 1));
+	devpriv->da_ranges |= (range << (chan << 1));
+	outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
 
-/*
-==============================================================================
-*/
-static int pci171x_insn_read_ao(struct comedi_device *dev,
-				struct comedi_subdevice *s,
-				struct comedi_insn *insn, unsigned int *data)
-{
-	struct pci1710_private *devpriv = dev->private;
-	int n, chan;
+	for (i = 0; i < insn->n; i++) {
+		val = data[i];
+		outw(val, dev->iobase + reg);
+	}
 
-	chan = CR_CHAN(insn->chanspec);
-	for (n = 0; n < insn->n; n++)
-		data[n] = devpriv->ao_data[chan];
+	s->readback[chan] = val;
 
-	return n;
+	return insn->n;
 }
 
-/*
-==============================================================================
-*/
-static int pci171x_insn_bits_di(struct comedi_device *dev,
+static int pci171x_di_insn_bits(struct comedi_device *dev,
 				struct comedi_subdevice *s,
-				struct comedi_insn *insn, unsigned int *data)
+				struct comedi_insn *insn,
+				unsigned int *data)
 {
 	data[1] = inw(dev->iobase + PCI171x_DI);
 
 	return insn->n;
 }
 
-static int pci171x_insn_bits_do(struct comedi_device *dev,
+static int pci171x_do_insn_bits(struct comedi_device *dev,
 				struct comedi_subdevice *s,
 				struct comedi_insn *insn,
 				unsigned int *data)
@@ -584,10 +524,7 @@ static void pci171x_start_pacer(struct comedi_device *dev,
 	}
 }
 
-/*
-==============================================================================
-*/
-static int pci171x_insn_counter_read(struct comedi_device *dev,
+static int pci171x_counter_insn_read(struct comedi_device *dev,
 				     struct comedi_subdevice *s,
 				     struct comedi_insn *insn,
 				     unsigned int *data)
@@ -608,10 +545,7 @@ static int pci171x_insn_counter_read(struct comedi_device *dev,
 	return insn->n;
 }
 
-/*
-==============================================================================
-*/
-static int pci171x_insn_counter_write(struct comedi_device *dev,
+static int pci171x_counter_insn_write(struct comedi_device *dev,
 				      struct comedi_subdevice *s,
 				      struct comedi_insn *insn,
 				      unsigned int *data)
@@ -638,10 +572,7 @@ static int pci171x_insn_counter_write(struct comedi_device *dev,
 	return insn->n;
 }
 
-/*
-==============================================================================
-*/
-static int pci171x_insn_counter_config(struct comedi_device *dev,
+static int pci171x_counter_insn_config(struct comedi_device *dev,
 				       struct comedi_subdevice *s,
 				       struct comedi_insn *insn,
 				       unsigned int *data)
@@ -677,57 +608,48 @@ static int pci171x_insn_counter_config(struct comedi_device *dev,
 	return 1;
 }
 
-/*
-==============================================================================
-*/
-static int pci1720_insn_write_ao(struct comedi_device *dev,
+static int pci1720_ao_insn_write(struct comedi_device *dev,
 				 struct comedi_subdevice *s,
-				 struct comedi_insn *insn, unsigned int *data)
+				 struct comedi_insn *insn,
+				 unsigned int *data)
 {
 	struct pci1710_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int range = CR_RANGE(insn->chanspec);
 	unsigned int val;
-	int n, rangereg, chan;
-
-	chan = CR_CHAN(insn->chanspec);
-	rangereg = devpriv->da_ranges & (~(0x03 << (chan << 1)));
-	rangereg |= (CR_RANGE(insn->chanspec) << (chan << 1));
-	if (rangereg != devpriv->da_ranges) {
-		outb(rangereg, dev->iobase + PCI1720_RANGE);
-		devpriv->da_ranges = rangereg;
+	int i;
+
+	val = devpriv->da_ranges & (~(0x03 << (chan << 1)));
+	val |= (range << (chan << 1));
+	if (val != devpriv->da_ranges) {
+		outb(val, dev->iobase + PCI1720_RANGE);
+		devpriv->da_ranges = val;
 	}
-	val = devpriv->ao_data[chan];
 
-	for (n = 0; n < insn->n; n++) {
-		val = data[n];
+	val = s->readback[chan];
+	for (i = 0; i < insn->n; i++) {
+		val = data[i];
 		outw(val, dev->iobase + PCI1720_DA0 + (chan << 1));
-		outb(0, dev->iobase + PCI1720_SYNCOUT);	/*  update outputs */
+		outb(0, dev->iobase + PCI1720_SYNCOUT);	/* update outputs */
 	}
 
-	devpriv->ao_data[chan] = val;
+	s->readback[chan] = val;
 
-	return n;
+	return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci171x_ai_cancel(struct comedi_device *dev,
 			     struct comedi_subdevice *s)
 {
-	const struct boardtype *this_board = dev->board_ptr;
 	struct pci1710_private *devpriv = dev->private;
 
-	switch (this_board->cardtype) {
-	default:
-		devpriv->CntrlReg &= Control_CNT0;
-		devpriv->CntrlReg |= Control_SW;
-		/* reset any operations */
-		outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
-		pci171x_start_pacer(dev, false);
-		outb(0, dev->iobase + PCI171x_CLRFIFO);
-		outb(0, dev->iobase + PCI171x_CLRINT);
-		break;
-	}
+	devpriv->CntrlReg &= Control_CNT0;
+	devpriv->CntrlReg |= Control_SW;
+	/* reset any operations */
+	outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+	pci171x_start_pacer(dev, false);
+	outb(0, dev->iobase + PCI171x_CLRFIFO);
+	outb(0, dev->iobase + PCI171x_CLRINT);
 
 	return 0;
 }
@@ -743,29 +665,25 @@ static void pci1710_handle_every_sample(struct comedi_device *dev,
 	status = inw(dev->iobase + PCI171x_STATUS);
 	if (status & Status_FE) {
 		dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", status);
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
-		comedi_handle_events(dev, s);
+		s->async->events |= COMEDI_CB_ERROR;
 		return;
 	}
 	if (status & Status_FF) {
 		dev_dbg(dev->class_dev,
 			"A/D FIFO Full status (Fatal Error!) (%4x)\n", status);
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
-		comedi_handle_events(dev, s);
+		s->async->events |= COMEDI_CB_ERROR;
 		return;
 	}
 
 	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear our INT request */
 
 	for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) {
-		val = inw(dev->iobase + PCI171x_AD_DATA);
-		ret = pci171x_ai_dropout(dev, s, s->async->cur_chan, val);
+		ret = pci171x_ai_read_sample(dev, s, s->async->cur_chan, &val);
 		if (ret) {
-			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+			s->async->events |= COMEDI_CB_ERROR;
 			break;
 		}
 
-		val &= s->maxdata;
 		comedi_buf_write_samples(s, &val, 1);
 
 		if (cmd->stop_src == TRIG_COUNT &&
@@ -776,85 +694,53 @@ static void pci1710_handle_every_sample(struct comedi_device *dev,
 	}
 
 	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear our INT request */
-
-	comedi_handle_events(dev, s);
-}
-
-/*
-==============================================================================
-*/
-static int move_block_from_fifo(struct comedi_device *dev,
-				struct comedi_subdevice *s, int n, int turn)
-{
-	unsigned int val;
-	int ret;
-	int i;
-
-	for (i = 0; i < n; i++) {
-		val = inw(dev->iobase + PCI171x_AD_DATA);
-
-		ret = pci171x_ai_dropout(dev, s, s->async->cur_chan, val);
-		if (ret) {
-			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
-			return ret;
-		}
-
-		val &= s->maxdata;
-		comedi_buf_write_samples(s, &val, 1);
-	}
-	return 0;
 }
 
 static void pci1710_handle_fifo(struct comedi_device *dev,
 				struct comedi_subdevice *s)
 {
-	const struct boardtype *this_board = dev->board_ptr;
-	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned int nsamples;
-	unsigned int m;
-
-	m = inw(dev->iobase + PCI171x_STATUS);
-	if (!(m & Status_FH)) {
-		dev_dbg(dev->class_dev, "A/D FIFO not half full! (%4x)\n", m);
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
-		comedi_handle_events(dev, s);
+	struct pci1710_private *devpriv = dev->private;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int status;
+	int i;
+
+	status = inw(dev->iobase + PCI171x_STATUS);
+	if (!(status & Status_FH)) {
+		dev_dbg(dev->class_dev, "A/D FIFO not half full!\n");
+		async->events |= COMEDI_CB_ERROR;
 		return;
 	}
-	if (m & Status_FF) {
+	if (status & Status_FF) {
 		dev_dbg(dev->class_dev,
-			"A/D FIFO Full status (Fatal Error!) (%4x)\n", m);
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
-		comedi_handle_events(dev, s);
+			"A/D FIFO Full status (Fatal Error!)\n");
+		async->events |= COMEDI_CB_ERROR;
 		return;
 	}
 
-	nsamples = this_board->fifo_half_size;
-	if (comedi_samples_to_bytes(s, nsamples) >= s->async->prealloc_bufsz) {
-		m = comedi_bytes_to_samples(s, s->async->prealloc_bufsz);
-		if (move_block_from_fifo(dev, s, m, 0))
-			return;
-		nsamples -= m;
-	}
+	for (i = 0; i < devpriv->max_samples; i++) {
+		unsigned int val;
+		int ret;
 
-	if (nsamples) {
-		if (move_block_from_fifo(dev, s, nsamples, 1))
-			return;
-	}
+		ret = pci171x_ai_read_sample(dev, s, s->async->cur_chan, &val);
+		if (ret) {
+			s->async->events |= COMEDI_CB_ERROR;
+			break;
+		}
 
-	if (cmd->stop_src == TRIG_COUNT &&
-	    s->async->scans_done >= cmd->stop_arg) {
-		s->async->events |= COMEDI_CB_EOA;
-		comedi_handle_events(dev, s);
-		return;
+		if (!comedi_buf_write_samples(s, &val, 1))
+			break;
+
+		if (cmd->stop_src == TRIG_COUNT &&
+		    async->scans_done >= cmd->stop_arg) {
+			async->events |= COMEDI_CB_EOA;
+			break;
+		}
 	}
-	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear our INT request */
 
-	comedi_handle_events(dev, s);
+	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear our INT request */
 }
 
-/*
-==============================================================================
-*/
 static irqreturn_t interrupt_service_pci1710(int irq, void *d)
 {
 	struct comedi_device *dev = d;
@@ -891,6 +777,8 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d)
 	else
 		pci1710_handle_fifo(dev, s);
 
+	comedi_handle_events(dev, s);
+
 	return IRQ_HANDLED;
 }
 
@@ -901,8 +789,8 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	pci171x_start_pacer(dev, false);
 
-	setup_channel_list(dev, s, cmd->chanlist, cmd->chanlist_len,
-			   devpriv->saved_seglen);
+	pci171x_ai_setup_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len,
+				  devpriv->saved_seglen);
 
 	outb(0, dev->iobase + PCI171x_CLRFIFO);
 	outb(0, dev->iobase + PCI171x_CLRINT);
@@ -937,14 +825,10 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	return 0;
 }
 
-/*
-==============================================================================
-*/
 static int pci171x_ai_cmdtest(struct comedi_device *dev,
 			      struct comedi_subdevice *s,
 			      struct comedi_cmd *cmd)
 {
-	const struct boardtype *this_board = dev->board_ptr;
 	struct pci1710_private *devpriv = dev->private;
 	int err = 0;
 	unsigned int arg;
@@ -977,8 +861,7 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
 	err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
 
 	if (cmd->convert_src == TRIG_TIMER)
-		err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
-						 this_board->ai_ns_min);
+		err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000);
 	else	/* TRIG_FOLLOW */
 		err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
 
@@ -1016,12 +899,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
 	return 0;
 }
 
-/*
-==============================================================================
-*/
 static int pci171x_reset(struct comedi_device *dev)
 {
-	const struct boardtype *this_board = dev->board_ptr;
+	const struct boardtype *board = dev->board_ptr;
 	struct pci1710_private *devpriv = dev->private;
 
 	outw(0x30, dev->iobase + PCI171x_CNTCTRL);
@@ -1033,15 +913,11 @@ static int pci171x_reset(struct comedi_device *dev)
 	outb(0, dev->iobase + PCI171x_CLRINT);	/*  clear INT request */
 	pci171x_start_pacer(dev, false);
 	devpriv->da_ranges = 0;
-	if (this_board->n_aochan) {
+	if (board->has_ao) {
 		/* set DACs to 0..5V */
 		outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
 		outw(0, dev->iobase + PCI171x_DA1); /* set DA outputs to 0V */
-		devpriv->ao_data[0] = 0x0000;
-		if (this_board->n_aochan > 1) {
-			outw(0, dev->iobase + PCI171x_DA2);
-			devpriv->ao_data[1] = 0x0000;
-		}
+		outw(0, dev->iobase + PCI171x_DA2);
 	}
 	outw(0, dev->iobase + PCI171x_DO);	/*  digital outputs to 0 */
 	outb(0, dev->iobase + PCI171x_CLRFIFO);	/*  clear FIFO */
@@ -1050,9 +926,6 @@ static int pci171x_reset(struct comedi_device *dev)
 	return 0;
 }
 
-/*
-==============================================================================
-*/
 static int pci1720_reset(struct comedi_device *dev)
 {
 	struct pci1710_private *devpriv = dev->private;
@@ -1066,43 +939,35 @@ static int pci1720_reset(struct comedi_device *dev)
 	outw(0x0800, dev->iobase + PCI1720_DA2);
 	outw(0x0800, dev->iobase + PCI1720_DA3);
 	outb(0, dev->iobase + PCI1720_SYNCOUT);	/*  update outputs */
-	devpriv->ao_data[0] = 0x0800;
-	devpriv->ao_data[1] = 0x0800;
-	devpriv->ao_data[2] = 0x0800;
-	devpriv->ao_data[3] = 0x0800;
+
 	return 0;
 }
 
-/*
-==============================================================================
-*/
 static int pci1710_reset(struct comedi_device *dev)
 {
-	const struct boardtype *this_board = dev->board_ptr;
+	const struct boardtype *board = dev->board_ptr;
 
-	switch (this_board->cardtype) {
-	case TYPE_PCI1720:
+	if (board->is_pci1720)
 		return pci1720_reset(dev);
-	default:
-		return pci171x_reset(dev);
-	}
+
+	return pci171x_reset(dev);
 }
 
 static int pci1710_auto_attach(struct comedi_device *dev,
 			       unsigned long context)
 {
 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-	const struct boardtype *this_board = NULL;
+	const struct boardtype *board = NULL;
 	struct pci1710_private *devpriv;
 	struct comedi_subdevice *s;
 	int ret, subdev, n_subdevices;
 
 	if (context < ARRAY_SIZE(boardtypes))
-		this_board = &boardtypes[context];
-	if (!this_board)
+		board = &boardtypes[context];
+	if (!board)
 		return -ENODEV;
-	dev->board_ptr = this_board;
-	dev->board_name = this_board->name;
+	dev->board_ptr = board;
+	dev->board_name = board->name;
 
 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 	if (!devpriv)
@@ -1114,15 +979,13 @@ static int pci1710_auto_attach(struct comedi_device *dev,
 	dev->iobase = pci_resource_start(pcidev, 2);
 
 	n_subdevices = 0;
-	if (this_board->n_aichan)
-		n_subdevices++;
-	if (this_board->n_aochan)
-		n_subdevices++;
-	if (this_board->n_dichan)
+	if (board->n_aichan)
 		n_subdevices++;
-	if (this_board->n_dochan)
+	if (board->has_ao)
 		n_subdevices++;
-	if (this_board->n_counter)
+	if (board->has_di_do)
+		n_subdevices += 2;
+	if (board->has_counter)
 		n_subdevices++;
 
 	ret = comedi_alloc_subdevices(dev, n_subdevices);
@@ -1131,7 +994,7 @@ static int pci1710_auto_attach(struct comedi_device *dev,
 
 	pci1710_reset(dev);
 
-	if (this_board->have_irq && pcidev->irq) {
+	if (board->has_irq && pcidev->irq) {
 		ret = request_irq(pcidev->irq, interrupt_service_pci1710,
 				  IRQF_SHARED, dev->board_name, dev);
 		if (ret == 0)
@@ -1140,85 +1003,93 @@ static int pci1710_auto_attach(struct comedi_device *dev,
 
 	subdev = 0;
 
-	if (this_board->n_aichan) {
+	if (board->n_aichan) {
 		s = &dev->subdevices[subdev];
-		s->type = COMEDI_SUBD_AI;
-		s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
-		if (this_board->n_aichand)
-			s->subdev_flags |= SDF_DIFF;
-		s->n_chan = this_board->n_aichan;
-		s->maxdata = this_board->ai_maxdata;
-		s->range_table = this_board->rangelist_ai;
-		s->insn_read = pci171x_insn_read_ai;
+		s->type		= COMEDI_SUBD_AI;
+		s->subdev_flags	= SDF_READABLE | SDF_COMMON | SDF_GROUND;
+		if (board->has_diff_ai)
+			s->subdev_flags	|= SDF_DIFF;
+		s->n_chan	= board->n_aichan;
+		s->maxdata	= 0x0fff;
+		s->range_table	= board->rangelist_ai;
+		s->insn_read	= pci171x_ai_insn_read;
 		if (dev->irq) {
 			dev->read_subdev = s;
-			s->subdev_flags |= SDF_CMD_READ;
-			s->len_chanlist = s->n_chan;
-			s->do_cmdtest = pci171x_ai_cmdtest;
-			s->do_cmd = pci171x_ai_cmd;
-			s->cancel = pci171x_ai_cancel;
+			s->subdev_flags	|= SDF_CMD_READ;
+			s->len_chanlist	= s->n_chan;
+			s->do_cmdtest	= pci171x_ai_cmdtest;
+			s->do_cmd	= pci171x_ai_cmd;
+			s->cancel	= pci171x_ai_cancel;
 		}
 		subdev++;
 	}
 
-	if (this_board->n_aochan) {
+	if (board->has_ao) {
 		s = &dev->subdevices[subdev];
-		s->type = COMEDI_SUBD_AO;
-		s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
-		s->n_chan = this_board->n_aochan;
-		s->maxdata = this_board->ao_maxdata;
-		s->len_chanlist = this_board->n_aochan;
-		s->range_table = this_board->rangelist_ao;
-		switch (this_board->cardtype) {
-		case TYPE_PCI1720:
-			s->insn_write = pci1720_insn_write_ao;
-			break;
-		default:
-			s->insn_write = pci171x_insn_write_ao;
-			break;
+		s->type		= COMEDI_SUBD_AO;
+		s->subdev_flags	= SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+		s->maxdata	= 0x0fff;
+		if (board->is_pci1720) {
+			s->n_chan	= 4;
+			s->range_table	= &pci1720_ao_range;
+			s->insn_write	= pci1720_ao_insn_write;
+		} else {
+			s->n_chan	= 2;
+			s->range_table	= &pci171x_ao_range;
+			s->insn_write	= pci171x_ao_insn_write;
 		}
-		s->insn_read = pci171x_insn_read_ao;
+
+		ret = comedi_alloc_subdev_readback(s);
+		if (ret)
+			return ret;
+
+		/* initialize the readback values to match the board reset */
+		if (board->is_pci1720) {
+			int i;
+
+			for (i = 0; i < s->n_chan; i++)
+				s->readback[i] = 0x0800;
+		}
+
 		subdev++;
 	}
 
-	if (this_board->n_dichan) {
+	if (board->has_di_do) {
 		s = &dev->subdevices[subdev];
-		s->type = COMEDI_SUBD_DI;
-		s->subdev_flags = SDF_READABLE;
-		s->n_chan = this_board->n_dichan;
-		s->maxdata = 1;
-		s->len_chanlist = this_board->n_dichan;
-		s->range_table = &range_digital;
-		s->insn_bits = pci171x_insn_bits_di;
+		s->type		= COMEDI_SUBD_DI;
+		s->subdev_flags	= SDF_READABLE;
+		s->n_chan	= 16;
+		s->maxdata	= 1;
+		s->range_table	= &range_digital;
+		s->insn_bits	= pci171x_di_insn_bits;
 		subdev++;
-	}
 
-	if (this_board->n_dochan) {
 		s = &dev->subdevices[subdev];
-		s->type = COMEDI_SUBD_DO;
-		s->subdev_flags = SDF_WRITABLE;
-		s->n_chan = this_board->n_dochan;
-		s->maxdata = 1;
-		s->len_chanlist = this_board->n_dochan;
-		s->range_table = &range_digital;
-		s->insn_bits = pci171x_insn_bits_do;
+		s->type		= COMEDI_SUBD_DO;
+		s->subdev_flags	= SDF_WRITABLE;
+		s->n_chan	= 16;
+		s->maxdata	= 1;
+		s->range_table	= &range_digital;
+		s->insn_bits	= pci171x_do_insn_bits;
 		subdev++;
 	}
 
-	if (this_board->n_counter) {
+	if (board->has_counter) {
 		s = &dev->subdevices[subdev];
-		s->type = COMEDI_SUBD_COUNTER;
-		s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-		s->n_chan = this_board->n_counter;
-		s->len_chanlist = this_board->n_counter;
-		s->maxdata = 0xffff;
-		s->range_table = &range_unknown;
-		s->insn_read = pci171x_insn_counter_read;
-		s->insn_write = pci171x_insn_counter_write;
-		s->insn_config = pci171x_insn_counter_config;
+		s->type		= COMEDI_SUBD_COUNTER;
+		s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
+		s->n_chan	= 1;
+		s->maxdata	= 0xffff;
+		s->range_table	= &range_unknown;
+		s->insn_read	= pci171x_counter_insn_read;
+		s->insn_write	= pci171x_counter_insn_write;
+		s->insn_config	= pci171x_counter_insn_config;
 		subdev++;
 	}
 
+	/* max_samples is half the FIFO size (2 bytes/sample) */
+	devpriv->max_samples = (board->has_large_fifo) ? 2048 : 512;
+
 	return 0;
 }
 
@@ -1312,5 +1183,5 @@ static struct pci_driver adv_pci1710_pci_driver = {
 module_comedi_pci_driver(adv_pci1710_driver, adv_pci1710_pci_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi: Advantech PCI-1710 Series Multifunction DAS Cards");
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
index 65f854e1eb66..f1945be89eff 100644
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -20,7 +20,7 @@
  * Driver: adv_pci1723
  * Description: Advantech PCI-1723
  * Author: yonggang <rsmgnu@gmail.com>, Ian Abbott <abbotti@mev.co.uk>
- * Devices: (Advantech) PCI-1723 [adv_pci1723]
+ * Devices: [Advantech] PCI-1723 (adv_pci1723)
  * Updated: Mon, 14 Apr 2008 15:12:56 +0100
  * Status: works
  *
diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c
index a8d28403262e..a3573ea6f9c0 100644
--- a/drivers/staging/comedi/drivers/adv_pci1724.c
+++ b/drivers/staging/comedi/drivers/adv_pci1724.c
@@ -22,7 +22,7 @@
 /*
  * Driver: adv_pci1724
  * Description: Advantech PCI-1724U
- * Devices: (Advantech) PCI-1724U [adv_pci1724]
+ * Devices: [Advantech] PCI-1724U (adv_pci1724)
  * Author: Frank Mori Hess <fmh6jj@gmail.com>
  * Updated: 2013-02-09
  * Status: works
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index 7b5ed439c164..1c7b325a373c 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -1,48 +1,155 @@
 /*
+ * aio_iiro_16.c
+ * Comedi driver for Access I/O Products 104-IIRO-16 board
+ * Copyright (C) 2006 C&C Technologies, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
-    comedi/drivers/aio_iiro_16.c
+/*
+ * Driver: aio_iiro_16
+ * Description: Access I/O Products PC/104 Isolated Input/Relay Output Board
+ * Author: Zachary Ware <zach.ware@cctechnol.com>
+ * Devices: [Access I/O] 104-IIRO-16 (aio_iiro_16)
+ * Status: experimental
+ *
+ * Configuration Options:
+ *   [0] - I/O port base address
+ *   [1] - IRQ (optional)
+ *
+ * The board supports interrupts on change of state of the digital inputs.
+ * The sample data returned by the async command indicates which inputs
+ * changed state and the current state of the inputs:
+ *
+ *	Bit 23 - IRQ Enable (1) / Disable (0)
+ *	Bit 17 - Input 8-15 Changed State (1 = Changed, 0 = No Change)
+ *	Bit 16 - Input 0-7 Changed State (1 = Changed, 0 = No Change)
+ *	Bit 15 - Digital input 15
+ *	...
+ *	Bit 0  - Digital input 0
+ */
 
-    Driver for Access I/O Products PC-104 AIO-IIRO-16 Digital I/O board
-    Copyright (C) 2006 C&C Technologies, Inc.
+#include <linux/module.h>
+#include <linux/interrupt.h>
 
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
+#include "../comedidev.h"
 
-    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 "comedi_fc.h"
 
-/*
+#define AIO_IIRO_16_RELAY_0_7		0x00
+#define AIO_IIRO_16_INPUT_0_7		0x01
+#define AIO_IIRO_16_IRQ			0x02
+#define AIO_IIRO_16_RELAY_8_15		0x04
+#define AIO_IIRO_16_INPUT_8_15		0x05
+#define AIO_IIRO_16_STATUS		0x07
+#define AIO_IIRO_16_STATUS_IRQE		BIT(7)
+#define AIO_IIRO_16_STATUS_INPUT_8_15	BIT(1)
+#define AIO_IIRO_16_STATUS_INPUT_0_7	BIT(0)
 
-Driver: aio_iiro_16
-Description: Access I/O Products PC-104 IIRO16 Relay And Isolated Input Board
-Author: Zachary Ware <zach.ware@cctechnol.com>
-Devices:
- [Access I/O] PC-104 AIO12-8
-Status: experimental
+static unsigned int aio_iiro_16_read_inputs(struct comedi_device *dev)
+{
+	unsigned int val;
 
-Configuration Options:
-  [0] - I/O port base address
+	val = inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
+	val |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;
 
-*/
+	return val;
+}
 
-#include <linux/module.h>
-#include "../comedidev.h"
+static irqreturn_t aio_iiro_16_cos(int irq, void *d)
+{
+	struct comedi_device *dev = d;
+	struct comedi_subdevice *s = dev->read_subdev;
+	unsigned int status;
+	unsigned int val;
+
+	status = inb(dev->iobase + AIO_IIRO_16_STATUS);
+	if (!(status & AIO_IIRO_16_STATUS_IRQE))
+		return IRQ_NONE;
+
+	val = aio_iiro_16_read_inputs(dev);
+	val |= (status << 16);
+
+	comedi_buf_write_samples(s, &val, 1);
+	comedi_handle_events(dev, s);
+
+	return IRQ_HANDLED;
+}
+
+static void aio_iiro_enable_irq(struct comedi_device *dev, bool enable)
+{
+	if (enable)
+		inb(dev->iobase + AIO_IIRO_16_IRQ);
+	else
+		outb(0, dev->iobase + AIO_IIRO_16_IRQ);
+}
+
+static int aio_iiro_16_cos_cancel(struct comedi_device *dev,
+				  struct comedi_subdevice *s)
+{
+	aio_iiro_enable_irq(dev, false);
+
+	return 0;
+}
 
-#define AIO_IIRO_16_RELAY_0_7	0x00
-#define AIO_IIRO_16_INPUT_0_7	0x01
-#define AIO_IIRO_16_IRQ		0x02
-#define AIO_IIRO_16_RELAY_8_15	0x04
-#define AIO_IIRO_16_INPUT_8_15	0x05
+static int aio_iiro_16_cos_cmd(struct comedi_device *dev,
+			       struct comedi_subdevice *s)
+{
+	aio_iiro_enable_irq(dev, true);
+
+	return 0;
+}
+
+static int aio_iiro_16_cos_cmdtest(struct comedi_device *dev,
+				   struct comedi_subdevice *s,
+				   struct comedi_cmd *cmd)
+{
+	int err = 0;
+
+	/* Step 1 : check if triggers are trivially valid */
+
+	err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+	err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+	err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+	err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+	err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
+
+	if (err)
+		return 1;
+
+	/* Step 2a : make sure trigger sources are unique */
+	/* Step 2b : and mutually compatible */
+
+	/* Step 3: check if arguments are trivially valid */
 
-static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
-					   struct comedi_subdevice *s,
-					   struct comedi_insn *insn,
-					   unsigned int *data)
+	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+	err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+	err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+	err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+	err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
+	if (err)
+		return 3;
+
+	/* Step 4: fix up any arguments */
+
+	/* Step 5: check channel list if it exists */
+
+	return 0;
+}
+
+static int aio_iiro_16_do_insn_bits(struct comedi_device *dev,
+				    struct comedi_subdevice *s,
+				    struct comedi_insn *insn,
+				    unsigned int *data)
 {
 	if (comedi_dio_update_state(s, data)) {
 		outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
@@ -55,14 +162,12 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
 	return insn->n;
 }
 
-static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
-					  struct comedi_subdevice *s,
-					  struct comedi_insn *insn,
-					  unsigned int *data)
+static int aio_iiro_16_di_insn_bits(struct comedi_device *dev,
+				    struct comedi_subdevice *s,
+				    struct comedi_insn *insn,
+				    unsigned int *data)
 {
-	data[1] = 0;
-	data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
-	data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;
+	data[1] = aio_iiro_16_read_inputs(dev);
 
 	return insn->n;
 }
@@ -77,25 +182,52 @@ static int aio_iiro_16_attach(struct comedi_device *dev,
 	if (ret)
 		return ret;
 
+	aio_iiro_enable_irq(dev, false);
+
+	/*
+	 * Digital input change of state interrupts are optionally supported
+	 * using IRQ 2-7, 10-12, 14, or 15.
+	 */
+	if ((1 << it->options[1]) & 0xdcfc) {
+		ret = request_irq(it->options[1], aio_iiro_16_cos, 0,
+				  dev->board_name, dev);
+		if (ret == 0)
+			dev->irq = it->options[1];
+	}
+
 	ret = comedi_alloc_subdevices(dev, 2);
 	if (ret)
 		return ret;
 
+	/* Digital Output subdevice */
 	s = &dev->subdevices[0];
-	s->type = COMEDI_SUBD_DIO;
-	s->subdev_flags = SDF_WRITABLE;
-	s->n_chan = 16;
-	s->maxdata = 1;
-	s->range_table = &range_digital;
-	s->insn_bits = aio_iiro_16_dio_insn_bits_write;
-
+	s->type		= COMEDI_SUBD_DO;
+	s->subdev_flags	= SDF_WRITABLE;
+	s->n_chan	= 16;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= aio_iiro_16_do_insn_bits;
+
+	/* get the initial state of the relays */
+	s->state = inb(dev->iobase + AIO_IIRO_16_RELAY_0_7) |
+		   (inb(dev->iobase + AIO_IIRO_16_RELAY_8_15) << 8);
+
+	/* Digital Input subdevice */
 	s = &dev->subdevices[1];
-	s->type = COMEDI_SUBD_DIO;
-	s->subdev_flags = SDF_READABLE;
-	s->n_chan = 16;
-	s->maxdata = 1;
-	s->range_table = &range_digital;
-	s->insn_bits = aio_iiro_16_dio_insn_bits_read;
+	s->type		= COMEDI_SUBD_DI;
+	s->subdev_flags	= SDF_READABLE;
+	s->n_chan	= 16;
+	s->maxdata	= 1;
+	s->range_table	= &range_digital;
+	s->insn_bits	= aio_iiro_16_di_insn_bits;
+	if (dev->irq) {
+		dev->read_subdev = s;
+		s->subdev_flags	|= SDF_CMD_READ | SDF_LSAMPL;
+		s->len_chanlist	= 1;
+		s->do_cmdtest	= aio_iiro_16_cos_cmdtest;
+		s->do_cmd	= aio_iiro_16_cos_cmd;
+		s->cancel	= aio_iiro_16_cos_cancel;
+	}
 
 	return 0;
 }
@@ -109,5 +241,5 @@ static struct comedi_driver aio_iiro_16_driver = {
 module_comedi_driver(aio_iiro_16_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Access I/O Products 104-IIRO-16 board");
 MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
index e7cb7032a910..1a109e30d8ff 100644
--- a/drivers/staging/comedi/drivers/c6xdigio.c
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -22,7 +22,7 @@
  * Description: Mechatronic Systems Inc. C6x_DIGIO DSP daughter card
  * Author: Dan Block
  * Status: unknown
- * Devices: (Mechatronic Systems Inc.) C6x_DIGIO DSP daughter card [c6xdigio]
+ * Devices: [Mechatronic Systems Inc.] C6x_DIGIO DSP daughter card (c6xdigio)
  * Updated: Sun Nov 20 20:18:34 EST 2005
  *
  * Configuration Options:
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index 0a48d2a961d5..1079b6c72b15 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -38,10 +38,7 @@ Status: experimental
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 
-#include "../comedidev.h"
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
+#include "../comedi_pcmcia.h"
 
 #include "comedi_fc.h"
 #include "8253.h"
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index 669b1703eb99..dd0c65a5b5a0 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -1355,7 +1355,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
 		outw(devpriv->adc_fifo_bits | LADFUL,
 		     devpriv->control_status + INT_ADCFIFO);
 		spin_unlock_irqrestore(&dev->spinlock, flags);
-		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		async->events |= COMEDI_CB_ERROR;
 	}
 
 	comedi_handle_events(dev, s);
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index eddb7ace43df..5b43e4e6d037 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -439,6 +439,29 @@ static const struct comedi_lrange ai_ranges_64xx = {
 	}
 };
 
+static const uint8_t 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 */
+};
+
+/* analog input ranges for 64-Mx boards */
+static const struct comedi_lrange ai_ranges_64_mx = {
+	7, {
+		BIP_RANGE(5),
+		BIP_RANGE(2.5),
+		BIP_RANGE(1.25),
+		BIP_RANGE(0.625),
+		UNI_RANGE(5),
+		UNI_RANGE(2.5),
+		UNI_RANGE(1.25)
+	}
+};
+
+static const uint8_t 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 */
+};
+
 /* analog input ranges for 60xx boards */
 static const struct comedi_lrange ai_ranges_60xx = {
 	4, {
@@ -449,6 +472,10 @@ static const struct comedi_lrange ai_ranges_60xx = {
 	}
 };
 
+static const uint8_t ai_range_code_60xx[4] = {
+	0x0, 0x1, 0x4, 0x7	/* bipolar 10, 5, 0.5, 0.05 */
+};
+
 /* analog input ranges for 6030, etc boards */
 static const struct comedi_lrange ai_ranges_6030 = {
 	14, {
@@ -469,6 +496,11 @@ static const struct comedi_lrange ai_ranges_6030 = {
 	}
 };
 
+static const uint8_t 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 */
+};
+
 /* analog input ranges for 6052, etc boards */
 static const struct comedi_lrange ai_ranges_6052 = {
 	15, {
@@ -490,6 +522,11 @@ static const struct comedi_lrange ai_ranges_6052 = {
 	}
 };
 
+static const uint8_t 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 */
+};
+
 /* analog input ranges for 4020 board */
 static const struct comedi_lrange ai_ranges_4020 = {
 	2, {
@@ -593,6 +630,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;
 	int ao_nchan;		/*  number of analog out channels */
 	int ao_bits;		/*  analog output resolution */
 	int ao_scan_speed;	/*  analog output scan speed */
@@ -651,6 +689,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
 		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_code	= ai_range_code_64xx,
 		.ao_range_table	= &ao_ranges_64xx,
 		.ao_range_code	= ao_range_code_64xx,
 		.ai_fifo	= &ai_fifo_64xx,
@@ -666,6 +705,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
 		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_code	= ai_range_code_64xx,
 		.ao_range_table	= &ao_ranges_64xx,
 		.ao_range_code	= ao_range_code_64xx,
 		.ai_fifo	= &ai_fifo_64xx,
@@ -680,7 +720,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_bits	= 16,
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
-		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_table	= &ai_ranges_64_mx,
+		.ai_range_code	= ai_range_code_64_mx,
 		.ao_range_table	= &ao_ranges_64xx,
 		.ao_range_code	= ao_range_code_64xx,
 		.ai_fifo	= &ai_fifo_64xx,
@@ -695,7 +736,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_bits	= 16,
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
-		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_table	= &ai_ranges_64_mx,
+		.ai_range_code	= ai_range_code_64_mx,
 		.ao_range_table	= &ao_ranges_64xx,
 		.ao_range_code	= ao_range_code_64xx,
 		.ai_fifo	= &ai_fifo_64xx,
@@ -710,7 +752,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_bits	= 16,
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
-		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_table	= &ai_ranges_64_mx,
+		.ai_range_code	= ai_range_code_64_mx,
 		.ao_range_table	= &ao_ranges_64xx,
 		.ao_range_code	= ao_range_code_64xx,
 		.ai_fifo	= &ai_fifo_64xx,
@@ -725,6 +768,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_bits	= 16,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_60xx,
+		.ai_range_code	= ai_range_code_60xx,
 		.ao_range_table	= &range_bipolar10,
 		.ao_range_code	= ao_range_code_60xx,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -740,6 +784,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 100000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_60xx,
+		.ai_range_code	= ai_range_code_60xx,
 		.ao_range_table	= &range_bipolar10,
 		.ao_range_code	= ao_range_code_60xx,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -754,6 +799,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 100000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_60xx,
+		.ai_range_code	= ai_range_code_60xx,
 		.ao_range_table	= &range_bipolar10,
 		.ao_range_code	= ao_range_code_60xx,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -769,6 +815,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 100000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_60xx,
+		.ai_range_code	= ai_range_code_60xx,
 		.ao_range_table	= &range_bipolar10,
 		.ao_range_code	= ao_range_code_60xx,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -784,6 +831,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_6030,
+		.ai_range_code	= ai_range_code_6030,
 		.ao_range_table	= &ao_ranges_6030,
 		.ao_range_code	= ao_range_code_6030,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -799,6 +847,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_6030,
+		.ai_range_code	= ai_range_code_6030,
 		.ao_range_table	= &ao_ranges_6030,
 		.ao_range_code	= ao_range_code_6030,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -812,6 +861,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_nchan	= 0,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_6030,
+		.ai_range_code	= ai_range_code_6030,
 		.ai_fifo	= &ai_fifo_60xx,
 		.has_8255	= 0,
 	},
@@ -823,6 +873,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_nchan	= 0,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_6030,
+		.ai_range_code	= ai_range_code_6030,
 		.ai_fifo	= &ai_fifo_60xx,
 		.has_8255	= 0,
 	},
@@ -835,6 +886,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 0,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_60xx,
+		.ai_range_code	= ai_range_code_60xx,
 		.ai_fifo	= &ai_fifo_60xx,
 		.has_8255	= 0,
 	},
@@ -848,6 +900,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 100000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_60xx,
+		.ai_range_code	= ai_range_code_60xx,
 		.ao_range_table	= &range_bipolar10,
 		.ao_range_code	= ao_range_code_60xx,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -863,6 +916,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 100000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_60xx,
+		.ai_range_code	= ai_range_code_60xx,
 		.ao_range_table	= &range_bipolar10,
 		.ao_range_code	= ao_range_code_60xx,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -878,6 +932,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 1000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_6052,
+		.ai_range_code	= ai_range_code_6052,
 		.ao_range_table	= &ao_ranges_6030,
 		.ao_range_code	= ao_range_code_6030,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -893,6 +948,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 3333,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_6052,
+		.ai_range_code	= ai_range_code_6052,
 		.ao_range_table	= &ao_ranges_6030,
 		.ao_range_code	= ao_range_code_6030,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -908,6 +964,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 1000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_6052,
+		.ai_range_code	= ai_range_code_6052,
 		.ao_range_table	= &ao_ranges_6030,
 		.ao_range_code	= ao_range_code_6030,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -923,6 +980,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 1000,
 		.layout		= LAYOUT_60XX,
 		.ai_range_table	= &ai_ranges_6052,
+		.ai_range_code	= ai_range_code_6052,
 		.ao_range_table	= &ao_ranges_6030,
 		.ao_range_code	= ao_range_code_6030,
 		.ai_fifo	= &ai_fifo_60xx,
@@ -957,6 +1015,7 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
 		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_code	= ai_range_code_64xx,
 		.ai_fifo	= ai_fifo_64xx,
 		.has_8255	= 1,
 	},
@@ -968,7 +1027,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_nchan	= 0,
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
-		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_table	= &ai_ranges_64_mx,
+		.ai_range_code	= ai_range_code_64_mx,
 		.ai_fifo	= ai_fifo_64xx,
 		.has_8255	= 1,
 	},
@@ -980,7 +1040,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_nchan	= 0,
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
-		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_table	= &ai_ranges_64_mx,
+		.ai_range_code	= ai_range_code_64_mx,
 		.ai_fifo	= ai_fifo_64xx,
 		.has_8255	= 1,
 	},
@@ -992,7 +1053,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_nchan	= 0,
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
-		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_table	= &ai_ranges_64_mx,
+		.ai_range_code	= ai_range_code_64_mx,
 		.ai_fifo	= ai_fifo_64xx,
 		.has_8255	= 1,
 	},
@@ -1004,7 +1066,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_nchan	= 2,
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
-		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_table	= &ai_ranges_64_mx,
+		.ai_range_code	= ai_range_code_64_mx,
 		.ai_fifo	= ai_fifo_64xx,
 		.has_8255	= 1,
 	},
@@ -1016,7 +1079,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_nchan	= 2,
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
-		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_table	= &ai_ranges_64_mx,
+		.ai_range_code	= ai_range_code_64_mx,
 		.ai_fifo	= ai_fifo_64xx,
 		.has_8255	= 1,
 	},
@@ -1028,7 +1092,8 @@ static const struct pcidas64_board pcidas64_boards[] = {
 		.ao_nchan	= 2,
 		.ao_scan_speed	= 10000,
 		.layout		= LAYOUT_64XX,
-		.ai_range_table	= &ai_ranges_64xx,
+		.ai_range_table	= &ai_ranges_64_mx,
+		.ai_range_code	= ai_range_code_64_mx,
 		.ai_fifo	= ai_fifo_64xx,
 		.has_8255	= 1,
 	},
@@ -1115,45 +1180,8 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
 				       unsigned int range_index)
 {
 	const struct pcidas64_board *thisboard = dev->board_ptr;
-	const struct comedi_krange *range =
-		&thisboard->ai_range_table->range[range_index];
-	unsigned int bits = 0;
 
-	switch (range->max) {
-	case 10000000:
-		bits = 0x000;
-		break;
-	case 5000000:
-		bits = 0x100;
-		break;
-	case 2000000:
-	case 2500000:
-		bits = 0x200;
-		break;
-	case 1000000:
-	case 1250000:
-		bits = 0x300;
-		break;
-	case 500000:
-		bits = 0x400;
-		break;
-	case 200000:
-	case 250000:
-		bits = 0x500;
-		break;
-	case 100000:
-		bits = 0x600;
-		break;
-	case 50000:
-		bits = 0x700;
-		break;
-	default:
-		dev_err(dev->class_dev, "bug! in %s\n", __func__);
-		break;
-	}
-	if (range->min == 0)
-		bits += 0x900;
-	return bits;
+	return thisboard->ai_range_code[range_index] << 8;
 }
 
 static unsigned int hw_revision(const struct comedi_device *dev,
@@ -2776,7 +2804,7 @@ static void handle_ai_interrupt(struct comedi_device *dev,
 	/*  check for fifo overrun */
 	if (status & ADC_OVERRUN_BIT) {
 		dev_err(dev->class_dev, "fifo overrun\n");
-		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		async->events |= COMEDI_CB_ERROR;
 	}
 	/*  spin lock makes sure no one else changes plx dma control reg */
 	spin_lock_irqsave(&dev->spinlock, flags);
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index 01875d7c376f..2b2cfcdda5bd 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -22,12 +22,10 @@
 /*
  * Driver: cb_pcidda
  * Description: MeasurementComputing PCI-DDA series
- * Devices: (Measurement Computing) PCI-DDA08/12 [pci-dda08/12]
- *	    (Measurement Computing) PCI-DDA04/12 [pci-dda04/12]
- *	    (Measurement Computing) PCI-DDA02/12 [pci-dda02/12]
- *	    (Measurement Computing) PCI-DDA08/16 [pci-dda08/16]
- *	    (Measurement Computing) PCI-DDA04/16 [pci-dda04/16]
- *	    (Measurement Computing) PCI-DDA02/16 [pci-dda02/16]
+ * Devices: [Measurement Computing] PCI-DDA08/12 (pci-dda08/12),
+ *   PCI-DDA04/12 (pci-dda04/12), PCI-DDA02/12 (pci-dda02/12),
+ *   PCI-DDA08/16 (pci-dda08/16), PCI-DDA04/16 (pci-dda04/16),
+ *   PCI-DDA02/16 (pci-dda02/16)
  * Author: Ivan Martinez <ivanmr@altavista.com>
  *	   Frank Mori Hess <fmhess@users.sourceforge.net>
  * Status: works
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
index 85b2f4ab1ba4..221d3819c967 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -261,6 +261,7 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it)
 			{
 				/* Append dev:subdev to devpriv->name */
 				char buf[20];
+
 				snprintf(buf, sizeof(buf), "%u:%u ",
 					 bdev->minor, bdev->subdev);
 				strlcat(devpriv->name, buf,
diff --git a/drivers/staging/comedi/drivers/comedi_isadma.c b/drivers/staging/comedi/drivers/comedi_isadma.c
new file mode 100644
index 000000000000..dbdea71d6b95
--- /dev/null
+++ b/drivers/staging/comedi/drivers/comedi_isadma.c
@@ -0,0 +1,262 @@
+/*
+ * COMEDI ISA DMA support functions
+ * Copyright (c) 2014 H Hartley Sweeten <hsweeten@visionengravers.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/slab.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <asm/dma.h>
+
+#include "../comedidev.h"
+
+#include "comedi_isadma.h"
+
+/**
+ * comedi_isadma_program - program and enable an ISA DMA transfer
+ * @desc:	the ISA DMA cookie to program and enable
+ */
+void comedi_isadma_program(struct comedi_isadma_desc *desc)
+{
+	unsigned long flags;
+
+	flags = claim_dma_lock();
+	clear_dma_ff(desc->chan);
+	set_dma_mode(desc->chan, desc->mode);
+	set_dma_addr(desc->chan, desc->hw_addr);
+	set_dma_count(desc->chan, desc->size);
+	enable_dma(desc->chan);
+	release_dma_lock(flags);
+}
+EXPORT_SYMBOL_GPL(comedi_isadma_program);
+
+/**
+ * comedi_isadma_disable - disable the ISA DMA channel
+ * @dma_chan:	the DMA channel to disable
+ *
+ * Returns the residue (remaining bytes) left in the DMA transfer.
+ */
+unsigned int comedi_isadma_disable(unsigned int dma_chan)
+{
+	unsigned long flags;
+	unsigned int residue;
+
+	flags = claim_dma_lock();
+	disable_dma(dma_chan);
+	residue = get_dma_residue(dma_chan);
+	release_dma_lock(flags);
+
+	return residue;
+}
+EXPORT_SYMBOL_GPL(comedi_isadma_disable);
+
+/**
+ * comedi_isadma_disable_on_sample - disable the ISA DMA channel
+ * @dma_chan:	the DMA channel to disable
+ * @size:	the sample size (in bytes)
+ *
+ * Returns the residue (remaining bytes) left in the DMA transfer.
+ */
+unsigned int comedi_isadma_disable_on_sample(unsigned int dma_chan,
+					     unsigned int size)
+{
+	int stalled = 0;
+	unsigned long flags;
+	unsigned int residue;
+	unsigned int new_residue;
+
+	residue = comedi_isadma_disable(dma_chan);
+	while (residue % size) {
+		/* residue is a partial sample, enable DMA to allow more data */
+		flags = claim_dma_lock();
+		enable_dma(dma_chan);
+		release_dma_lock(flags);
+
+		udelay(2);
+		new_residue = comedi_isadma_disable(dma_chan);
+
+		/* is DMA stalled? */
+		if (new_residue == residue) {
+			stalled++;
+			if (stalled > 10)
+				break;
+		}
+		residue = new_residue;
+		stalled = 0;
+	}
+	return residue;
+}
+EXPORT_SYMBOL_GPL(comedi_isadma_disable_on_sample);
+
+/**
+ * comedi_isadma_poll - poll the current DMA transfer
+ * @dma:	the ISA DMA to poll
+ *
+ * Returns the position (in bytes) of the current DMA transfer.
+ */
+unsigned int comedi_isadma_poll(struct comedi_isadma *dma)
+{
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
+	unsigned long flags;
+	unsigned int result;
+	unsigned int result1;
+
+	flags = claim_dma_lock();
+	clear_dma_ff(desc->chan);
+	if (!isa_dma_bridge_buggy)
+		disable_dma(desc->chan);
+	result = get_dma_residue(desc->chan);
+	/*
+	 * Read the counter again and choose higher value in order to
+	 * avoid reading during counter lower byte roll over if the
+	 * isa_dma_bridge_buggy is set.
+	 */
+	result1 = get_dma_residue(desc->chan);
+	if (!isa_dma_bridge_buggy)
+		enable_dma(desc->chan);
+	release_dma_lock(flags);
+
+	if (result < result1)
+		result = result1;
+	if (result >= desc->size || result == 0)
+		return 0;
+	else
+		return desc->size - result;
+}
+EXPORT_SYMBOL_GPL(comedi_isadma_poll);
+
+/**
+ * comedi_isadma_set_mode - set the ISA DMA transfer direction
+ * @desc:	the ISA DMA cookie to set
+ * @dma_dir:	the DMA direction
+ */
+void comedi_isadma_set_mode(struct comedi_isadma_desc *desc, char dma_dir)
+{
+	desc->mode = (dma_dir == COMEDI_ISADMA_READ) ? DMA_MODE_READ
+						     : DMA_MODE_WRITE;
+}
+EXPORT_SYMBOL_GPL(comedi_isadma_set_mode);
+
+/**
+ * comedi_isadma_alloc - allocate and initialize the ISA DMA
+ * @dev:	comedi_device struct
+ * @n_desc:	the number of cookies to allocate
+ * @dma_chan:	DMA channel for the first cookie
+ * @dma_chan2:	DMA channel for the second cookie
+ * @maxsize:	the size of the buffer to allocate for each cookie
+ * @dma_dir:	the DMA direction
+ *
+ * Returns the allocated and initialized ISA DMA or NULL if anything fails.
+ */
+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)
+{
+	struct comedi_isadma *dma = NULL;
+	struct comedi_isadma_desc *desc;
+	unsigned int dma_chans[2];
+	int i;
+
+	if (n_desc < 1 || n_desc > 2)
+		goto no_dma;
+
+	dma = kzalloc(sizeof(*dma), GFP_KERNEL);
+	if (!dma)
+		goto no_dma;
+
+	desc = kcalloc(n_desc, sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		goto no_dma;
+	dma->desc = desc;
+	dma->n_desc = n_desc;
+
+	dma_chans[0] = dma_chan1;
+	if (dma_chan2 == 0 || dma_chan2 == dma_chan1)
+		dma_chans[1] = dma_chan1;
+	else
+		dma_chans[1] = dma_chan2;
+
+	if (request_dma(dma_chans[0], dev->board_name))
+		goto no_dma;
+	dma->chan = dma_chans[0];
+	if (dma_chans[1] != dma_chans[0]) {
+		if (request_dma(dma_chans[1], dev->board_name))
+			goto no_dma;
+	}
+	dma->chan2 = dma_chans[1];
+
+	for (i = 0; i < n_desc; i++) {
+		desc = &dma->desc[i];
+		desc->chan = dma_chans[i];
+		desc->maxsize = maxsize;
+		desc->virt_addr = dma_alloc_coherent(NULL, desc->maxsize,
+						     &desc->hw_addr,
+						     GFP_KERNEL);
+		if (!desc->virt_addr)
+			goto no_dma;
+		comedi_isadma_set_mode(desc, dma_dir);
+	}
+
+	return dma;
+
+no_dma:
+	comedi_isadma_free(dma);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(comedi_isadma_alloc);
+
+/**
+ * comedi_isadma_free - free the ISA DMA
+ * @dma:	the ISA DMA to free
+ */
+void comedi_isadma_free(struct comedi_isadma *dma)
+{
+	struct comedi_isadma_desc *desc;
+	int i;
+
+	if (!dma)
+		return;
+
+	if (dma->desc) {
+		for (i = 0; i < dma->n_desc; i++) {
+			desc = &dma->desc[i];
+			if (desc->virt_addr)
+				dma_free_coherent(NULL, desc->maxsize,
+						desc->virt_addr, desc->hw_addr);
+		}
+		kfree(dma->desc);
+	}
+	if (dma->chan2 && dma->chan2 != dma->chan)
+		free_dma(dma->chan2);
+	if (dma->chan)
+		free_dma(dma->chan);
+	kfree(dma);
+}
+EXPORT_SYMBOL_GPL(comedi_isadma_free);
+
+static int __init comedi_isadma_init(void)
+{
+	return 0;
+}
+module_init(comedi_isadma_init);
+
+static void __exit comedi_isadma_exit(void)
+{
+}
+module_exit(comedi_isadma_exit);
+
+MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
+MODULE_DESCRIPTION("Comedi ISA DMA support");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/comedi/drivers/comedi_isadma.h b/drivers/staging/comedi/drivers/comedi_isadma.h
new file mode 100644
index 000000000000..c7c524faf595
--- /dev/null
+++ b/drivers/staging/comedi/drivers/comedi_isadma.h
@@ -0,0 +1,116 @@
+/*
+ * COMEDI ISA DMA support functions
+ * Copyright (c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _COMEDI_ISADMA_H
+#define _COMEDI_ISADMA_H
+
+/*
+ * These are used to avoid issues when <asm/dma.h> and the DMA_MODE_
+ * defines are not available.
+ */
+#define COMEDI_ISADMA_READ	0
+#define COMEDI_ISADMA_WRITE	1
+
+/**
+ * struct comedi_isadma_desc - cookie for ISA DMA
+ * @virt_addr:	virtual address of buffer
+ * @hw_addr:	hardware (bus) address of buffer
+ * @chan:	DMA channel
+ * @maxsize:	allocated size of buffer (in bytes)
+ * @size:	transfer size (in bytes)
+ * @mode:	DMA_MODE_READ or DMA_MODE_WRITE
+ */
+struct comedi_isadma_desc {
+	void *virt_addr;
+	dma_addr_t hw_addr;
+	unsigned int chan;
+	unsigned int maxsize;
+	unsigned int size;
+	char mode;
+};
+
+/**
+ * struct comedi_isadma - ISA DMA data
+ * @desc:	cookie for each DMA buffer
+ * @n_desc:	the number of cookies
+ * @cur_dma:	the current cookie in use
+ * @chan:	the first DMA channel requested
+ * @chan2:	the second DMA channel requested
+ */
+struct comedi_isadma {
+	struct comedi_isadma_desc *desc;
+	int n_desc;
+	int cur_dma;
+	unsigned int chan;
+	unsigned int chan2;
+};
+
+#if IS_ENABLED(CONFIG_ISA_DMA_API)
+
+void comedi_isadma_program(struct comedi_isadma_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);
+
+struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *,
+					  int n_desc, unsigned int dma_chan1,
+					  unsigned int dma_chan2,
+					  unsigned int maxsize, char dma_dir);
+void comedi_isadma_free(struct comedi_isadma *);
+
+#else	/* !IS_ENABLED(CONFIG_ISA_DMA_API) */
+
+static inline void comedi_isadma_program(struct comedi_isadma_desc *desc)
+{
+}
+
+static inline unsigned int comedi_isadma_disable(unsigned int dma_chan)
+{
+	return 0;
+}
+
+static inline unsigned int
+comedi_isadma_disable_on_sample(unsigned int dma_chan, unsigned int size)
+{
+	return 0;
+}
+
+static inline unsigned int comedi_isadma_poll(struct comedi_isadma *dma)
+{
+	return 0;
+}
+
+static inline void comedi_isadma_set_mode(struct comedi_isadma_desc *desc,
+					  char dma_dir)
+{
+}
+
+static inline 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)
+{
+	return NULL;
+}
+
+static inline void comedi_isadma_free(struct comedi_isadma *dma)
+{
+}
+
+#endif	/* !IS_ENABLED(CONFIG_ISA_DMA_API) */
+
+#endif	/* #ifndef _COMEDI_ISADMA_H */
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
index 3bac903c8627..ceef6931edbe 100644
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ b/drivers/staging/comedi/drivers/comedi_parport.c
@@ -24,7 +24,7 @@
  * Description: Standard PC parallel port
  * Author: ds
  * Status: works in immediate mode
- * Devices: (standard) parallel port [comedi_parport]
+ * Devices: [standard] parallel port (comedi_parport)
  * Updated: Tue, 30 Apr 2002 21:11:45 -0700
  *
  * A cheap and easy way to get a few more digital I/O lines. Steal
diff --git a/drivers/staging/comedi/drivers/dac02.c b/drivers/staging/comedi/drivers/dac02.c
index beb36c8dd00a..a6798ad8fa7f 100644
--- a/drivers/staging/comedi/drivers/dac02.c
+++ b/drivers/staging/comedi/drivers/dac02.c
@@ -24,7 +24,7 @@
 /*
  * Driver: dac02
  * Description: Comedi driver for DAC02 compatible boards
- * Devices: (Keithley Metrabyte) DAC-02 [dac02]
+ * Devices: [Keithley Metrabyte] DAC-02 (dac02)
  * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
  * Updated: Tue, 11 Mar 2014 11:27:19 -0700
  * Status: unknown
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index 20a9f0eb72b5..c78c0df9bbe3 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -1,6 +1,6 @@
 /*
  *  comedi/drivers/das08.c
- *  comedi driver for common DAS08 support (used by ISA/PCI/PCMCIA drivers)
+ *  comedi module for common DAS08 support (used by ISA/PCI/PCMCIA drivers)
  *
  *  COMEDI - Linux Control and Measurement Device Interface
  *  Copyright (C) 2000 David A. Schleef <ds@schleef.org>
@@ -18,21 +18,6 @@
  *  GNU General Public License for more details.
  */
 
-/*
- * Driver: das08
- * Description: DAS-08 compatible boards
- * Devices: various, see das08_isa, das08_cs, and das08_pci drivers
- * Author: Warren Jasper, ds, Frank Hess
- * Updated: Fri, 31 Aug 2012 19:19:06 +0100
- * Status: works
- *
- * This driver is used by the das08_isa, das08_cs, and das08_pci
- * drivers to provide the common support for the DAS-08 hardware.
- *
- * The driver doesn't support asynchronous commands, since the
- * cheap das08 hardware doesn't really support them.
- */
-
 #include <linux/module.h>
 
 #include "../comedidev.h"
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index f3ccc2ce6d49..93fab6890161 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -41,10 +41,7 @@ Command support does not exist, but could be added for this board.
 
 #include <linux/module.h>
 
-#include "../comedidev.h"
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
+#include "../comedi_pcmcia.h"
 
 #include "das08.h"
 
diff --git a/drivers/staging/comedi/drivers/das08_isa.c b/drivers/staging/comedi/drivers/das08_isa.c
index e4ba268e78ab..2d9a31dab552 100644
--- a/drivers/staging/comedi/drivers/das08_isa.c
+++ b/drivers/staging/comedi/drivers/das08_isa.c
@@ -21,18 +21,12 @@
 /*
  * Driver: das08_isa
  * Description: DAS-08 ISA/PC-104 compatible boards
- * Devices: (Keithley Metrabyte) DAS08 [isa-das08],
- *	    (ComputerBoards) DAS08 [isa-das08]
- *	    (ComputerBoards) DAS08-PGM [das08-pgm]
- *	    (ComputerBoards) DAS08-PGH [das08-pgh]
- *	    (ComputerBoards) DAS08-PGL [das08-pgl]
- *	    (ComputerBoards) DAS08-AOH [das08-aoh]
- *	    (ComputerBoards) DAS08-AOL [das08-aol]
- *	    (ComputerBoards) DAS08-AOM [das08-aom]
- *	    (ComputerBoards) DAS08/JR-AO [das08/jr-ao]
- *	    (ComputerBoards) DAS08/JR-16-AO [das08jr-16-ao]
- *	    (ComputerBoards) PC104-DAS08 [pc104-das08]
- *	    (ComputerBoards) DAS08/JR/16 [das08jr/16]
+ * Devices: [Keithley Metrabyte] DAS08 (isa-das08),
+ *   [ComputerBoards] DAS08 (isa-das08), DAS08-PGM (das08-pgm),
+ *   DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
+ *   DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
+ *   DAS08/JR-16-AO (das08jr-16-ao), PC104-DAS08 (pc104-das08),
+ *   DAS08/JR/16 (das08jr/16)
  * Author: Warren Jasper, ds, Frank Hess
  * Updated: Fri, 31 Aug 2012 19:19:06 +0100
  * Status: works
diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c
index 0987ce554945..b2ea10b848c3 100644
--- a/drivers/staging/comedi/drivers/das08_pci.c
+++ b/drivers/staging/comedi/drivers/das08_pci.c
@@ -21,7 +21,7 @@
 /*
  * Driver: das08_pci
  * Description: DAS-08 PCI compatible boards
- * Devices: (ComputerBoards) PCI-DAS08 [pci-das08]
+ * Devices: [ComputerBoards] PCI-DAS08 (pci-das08)
  * Author: Warren Jasper, ds, Frank Hess
  * Updated: Fri, 31 Aug 2012 19:19:06 +0100
  * Status: works
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
index 2436057304a3..2c20311120f1 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -22,28 +22,17 @@
  * Driver: das16
  * Description: DAS16 compatible boards
  * Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
- * Devices: (Keithley Metrabyte) DAS-16 [das-16]
- *	    (Keithley Metrabyte) DAS-16G [das-16g]
- *	    (Keithley Metrabyte) DAS-16F [das-16f]
- *	    (Keithley Metrabyte) DAS-1201 [das-1201]
- *	    (Keithley Metrabyte) DAS-1202 [das-1202]
- *	    (Keithley Metrabyte) DAS-1401 [das-1401]
- *	    (Keithley Metrabyte) DAS-1402 [das-1402]
- *	    (Keithley Metrabyte) DAS-1601 [das-1601]
- *	    (Keithley Metrabyte) DAS-1602 [das-1602]
- *	    (ComputerBoards) PC104-DAS16/JR [pc104-das16jr]
- *	    (ComputerBoards) PC104-DAS16JR/16 [pc104-das16jr/16]
- *	    (ComputerBoards) CIO-DAS16 [cio-das16]
- *	    (ComputerBoards) CIO-DAS16F [cio-das16/f]
- *	    (ComputerBoards) CIO-DAS16/JR [cio-das16/jr]
- *	    (ComputerBoards) CIO-DAS16JR/16 [cio-das16jr/16]
- *	    (ComputerBoards) CIO-DAS1401/12 [cio-das1401/12]
- *	    (ComputerBoards) CIO-DAS1402/12 [cio-das1402/12]
- *	    (ComputerBoards) CIO-DAS1402/16 [cio-das1402/16]
- *	    (ComputerBoards) CIO-DAS1601/12 [cio-das1601/12]
- *	    (ComputerBoards) CIO-DAS1602/12 [cio-das1602/12]
- *	    (ComputerBoards) CIO-DAS1602/16 [cio-das1602/16]
- *	    (ComputerBoards) CIO-DAS16/330 [cio-das16/330]
+ * Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
+ *   DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
+ *   DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
+ *   DAS-1602 (das-1602),
+ *   [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
+ *   PC104-DAS16JR/16 (pc104-das16jr/16), CIO-DAS16 (cio-das16),
+ *   CIO-DAS16F (cio-das16/f), CIO-DAS16/JR (cio-das16/jr),
+ *   CIO-DAS16JR/16 (cio-das16jr/16), CIO-DAS1401/12 (cio-das1401/12),
+ *   CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
+ *   CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
+ *   CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
  * Status: works
  * Updated: 2003-10-12
  *
@@ -82,17 +71,14 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
 #include <linux/interrupt.h>
 
-#include <asm/dma.h>
-
 #include "../comedidev.h"
 
+#include "comedi_isadma.h"
+#include "comedi_fc.h"
 #include "8253.h"
 #include "8255.h"
-#include "comedi_fc.h"
 
 #define DAS16_DMA_SIZE 0xff00	/*  size in bytes of allocated dma buffer */
 
@@ -451,86 +437,37 @@ static inline int timer_period(void)
 }
 
 struct das16_private_struct {
+	struct comedi_isadma	*dma;
 	unsigned int		clockbase;
 	unsigned int		ctrl_reg;
-	unsigned long		adc_byte_count;
 	unsigned int		divisor1;
 	unsigned int		divisor2;
-	unsigned int		dma_chan;
-	uint16_t		*dma_buffer[2];
-	dma_addr_t		dma_buffer_addr[2];
-	unsigned int		current_buffer;
-	unsigned int		dma_transfer_size;
-	struct comedi_lrange	*user_ai_range_table;
-	struct comedi_lrange	*user_ao_range_table;
 	struct timer_list	timer;
-	short			timer_running;
 	unsigned long		extra_iobase;
 	unsigned int		can_burst:1;
+	unsigned int		timer_running:1;
 };
 
-static void das16_ai_enable(struct comedi_device *dev,
-			    unsigned int mode, unsigned int src)
-{
-	struct das16_private_struct *devpriv = dev->private;
-
-	devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE |
-			       DAS16_CTRL_DMAE |
-			       DAS16_CTRL_PACING_MASK);
-	devpriv->ctrl_reg |= mode;
-
-	if (src == TRIG_EXT)
-		devpriv->ctrl_reg |= DAS16_CTRL_EXT_PACER;
-	else
-		devpriv->ctrl_reg |= DAS16_CTRL_INT_PACER;
-	outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
-}
-
-static void das16_ai_disable(struct comedi_device *dev)
+static void das16_ai_setup_dma(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       unsigned int unread_samples)
 {
 	struct das16_private_struct *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
+	unsigned int max_samples = comedi_bytes_to_samples(s, desc->maxsize);
+	unsigned int nsamples;
 
-	/* disable interrupts, dma and pacer clocked conversions */
-	devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE |
-			       DAS16_CTRL_DMAE |
-			       DAS16_CTRL_PACING_MASK);
-	outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
-}
-
-/* the pc104-das16jr (at least) has problems if the dma
-	transfer is interrupted in the middle of transferring
-	a 16 bit sample, so this function takes care to get
-	an even transfer count after disabling dma
-	channel.
-*/
-static int disable_dma_on_even(struct comedi_device *dev)
-{
-	struct das16_private_struct *devpriv = dev->private;
-	static const int disable_limit = 100;
-	static const int enable_timeout = 100;
-	int residue;
-	int new_residue;
-	int i;
-	int j;
-
-	disable_dma(devpriv->dma_chan);
-	residue = get_dma_residue(devpriv->dma_chan);
-	for (i = 0; i < disable_limit && (residue % 2); ++i) {
-		enable_dma(devpriv->dma_chan);
-		for (j = 0; j < enable_timeout; ++j) {
-			udelay(2);
-			new_residue = get_dma_residue(devpriv->dma_chan);
-			if (new_residue != residue)
-				break;
-		}
-		disable_dma(devpriv->dma_chan);
-		residue = get_dma_residue(devpriv->dma_chan);
-	}
-	if (i == disable_limit) {
-		dev_err(dev->class_dev,
-			"failed to get an even dma transfer, could be trouble\n");
+	/*
+	 * Determine dma size based on the buffer size plus the number of
+	 * unread samples and the number of samples remaining in the command.
+	 */
+	nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
+	if (nsamples > unread_samples) {
+		nsamples -= unread_samples;
+		desc->size = comedi_samples_to_bytes(s, nsamples);
+		comedi_isadma_program(desc);
 	}
-	return residue;
 }
 
 static void das16_interrupt(struct comedi_device *dev)
@@ -539,11 +476,12 @@ static void das16_interrupt(struct comedi_device *dev)
 	struct comedi_subdevice *s = dev->read_subdev;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
 	unsigned long spin_flags;
-	unsigned long dma_flags;
+	unsigned int residue;
+	unsigned int nbytes;
 	unsigned int nsamples;
-	int num_bytes, residue;
-	int buffer_index;
 
 	spin_lock_irqsave(&dev->spinlock, spin_flags);
 	if (!(devpriv->ctrl_reg & DAS16_CTRL_DMAE)) {
@@ -551,42 +489,36 @@ static void das16_interrupt(struct comedi_device *dev)
 		return;
 	}
 
-	dma_flags = claim_dma_lock();
-	clear_dma_ff(devpriv->dma_chan);
-	residue = disable_dma_on_even(dev);
+	/*
+	 * The pc104-das16jr (at least) has problems if the dma
+	 * transfer is interrupted in the middle of transferring
+	 * a 16 bit sample.
+	 */
+	residue = comedi_isadma_disable_on_sample(desc->chan,
+						  comedi_bytes_per_sample(s));
 
-	/*  figure out how many points to read */
-	if (residue > devpriv->dma_transfer_size) {
+	/* figure out how many samples to read */
+	if (residue > desc->size) {
 		dev_err(dev->class_dev, "residue > transfer size!\n");
-		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
-		num_bytes = 0;
-	} else
-		num_bytes = devpriv->dma_transfer_size - residue;
-
-	if (cmd->stop_src == TRIG_COUNT &&
-					num_bytes >= devpriv->adc_byte_count) {
-		num_bytes = devpriv->adc_byte_count;
-		async->events |= COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
+		nbytes = 0;
+	} else {
+		nbytes = desc->size - residue;
 	}
+	nsamples = comedi_bytes_to_samples(s, nbytes);
 
-	buffer_index = devpriv->current_buffer;
-	devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
-	devpriv->adc_byte_count -= num_bytes;
-
-	/*  re-enable  dma */
-	if ((async->events & COMEDI_CB_EOA) == 0) {
-		set_dma_addr(devpriv->dma_chan,
-			     devpriv->dma_buffer_addr[devpriv->current_buffer]);
-		set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
-		enable_dma(devpriv->dma_chan);
+	/* restart DMA if more samples are needed */
+	if (nsamples) {
+		dma->cur_dma = 1 - dma->cur_dma;
+		das16_ai_setup_dma(dev, s, nsamples);
 	}
-	release_dma_lock(dma_flags);
 
 	spin_unlock_irqrestore(&dev->spinlock, spin_flags);
 
-	nsamples = comedi_bytes_to_samples(s, num_bytes);
-	comedi_buf_write_samples(s, devpriv->dma_buffer[buffer_index],
-				 nsamples);
+	comedi_buf_write_samples(s, desc->virt_addr, nsamples);
+
+	if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
+		async->events |= COMEDI_CB_EOA;
 
 	comedi_handle_events(dev, s);
 }
@@ -605,6 +537,29 @@ static void das16_timer_interrupt(unsigned long arg)
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 }
 
+static void das16_ai_set_mux_range(struct comedi_device *dev,
+				   unsigned int first_chan,
+				   unsigned int last_chan,
+				   unsigned int range)
+{
+	const struct das16_board *board = dev->board_ptr;
+
+	/* set multiplexer */
+	outb(first_chan | (last_chan << 4), dev->iobase + DAS16_MUX_REG);
+
+	/* some boards do not have programmable gain */
+	if (board->ai_pg == das16_pg_none)
+		return;
+
+	/*
+	 * Set gain (this is also burst rate register but according to
+	 * computer boards manual, burst rate does nothing, even on
+	 * keithley cards).
+	 */
+	outb((das16_gainlists[board->ai_pg])[range],
+	     dev->iobase + DAS16_GAIN_REG);
+}
+
 static int das16_ai_check_chanlist(struct comedi_device *dev,
 				   struct comedi_subdevice *s,
 				   struct comedi_cmd *cmd)
@@ -755,13 +710,15 @@ static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
 
 static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	const struct das16_board *board = dev->board_ptr;
 	struct das16_private_struct *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
+	unsigned int first_chan = CR_CHAN(cmd->chanlist[0]);
+	unsigned int last_chan = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+	unsigned int range = CR_RANGE(cmd->chanlist[0]);
 	unsigned int byte;
 	unsigned long flags;
-	int range;
 
 	if (cmd->flags & CMDF_PRIORITY) {
 		dev_err(dev->class_dev,
@@ -769,24 +726,11 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 		return -1;
 	}
 
-	devpriv->adc_byte_count = cmd->stop_arg * comedi_bytes_per_scan(s);
-
 	if (devpriv->can_burst)
 		outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV_REG);
 
-	/*  set scan limits */
-	byte = CR_CHAN(cmd->chanlist[0]);
-	byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
-	outb(byte, dev->iobase + DAS16_MUX_REG);
-
-	/* set gain (this is also burst rate register but according to
-	 * computer boards manual, burst rate does nothing, even on
-	 * keithley cards) */
-	if (board->ai_pg != das16_pg_none) {
-		range = CR_RANGE(cmd->chanlist[0]);
-		outb((das16_gainlists[board->ai_pg])[range],
-		     dev->iobase + DAS16_GAIN_REG);
-	}
+	/* set mux and range for chanlist scan */
+	das16_ai_set_mux_range(dev, first_chan, last_chan, range);
 
 	/* set counter mode and counts */
 	cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags);
@@ -805,19 +749,9 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 	}
 	outb(byte, dev->iobase + DAS16_PACER_REG);
 
-	/*  set up dma transfer */
-	flags = claim_dma_lock();
-	disable_dma(devpriv->dma_chan);
-	/* clear flip-flop to make sure 2-byte registers for
-	 * count and address get set correctly */
-	clear_dma_ff(devpriv->dma_chan);
-	devpriv->current_buffer = 0;
-	set_dma_addr(devpriv->dma_chan,
-		     devpriv->dma_buffer_addr[devpriv->current_buffer]);
-	devpriv->dma_transfer_size = DAS16_DMA_SIZE;
-	set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
-	enable_dma(devpriv->dma_chan);
-	release_dma_lock(flags);
+	/* set up dma transfer */
+	dma->cur_dma = 0;
+	das16_ai_setup_dma(dev, s, 0);
 
 	/*  set up timer */
 	spin_lock_irqsave(&dev->spinlock, flags);
@@ -825,7 +759,14 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->timer.expires = jiffies + timer_period();
 	add_timer(&devpriv->timer);
 
-	das16_ai_enable(dev, DAS16_CTRL_DMAE, cmd->convert_src);
+	/* enable DMA interrupt with external or internal pacing */
+	devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE | DAS16_CTRL_PACING_MASK);
+	devpriv->ctrl_reg |= DAS16_CTRL_DMAE;
+	if (cmd->convert_src == TRIG_EXT)
+		devpriv->ctrl_reg |= DAS16_CTRL_EXT_PACER;
+	else
+		devpriv->ctrl_reg |= DAS16_CTRL_INT_PACER;
+	outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
 
 	if (devpriv->can_burst)
 		outb(0, dev->iobase + DAS1600_CONV_REG);
@@ -837,12 +778,17 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct das16_private_struct *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev->spinlock, flags);
 
-	das16_ai_disable(dev);
-	disable_dma(devpriv->dma_chan);
+	/* disable interrupts, dma and pacer clocked conversions */
+	devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE | DAS16_CTRL_DMAE |
+			       DAS16_CTRL_PACING_MASK);
+	outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG);
+
+	comedi_isadma_disable(dma->chan);
 
 	/*  disable SW timer */
 	if (devpriv->timer_running) {
@@ -893,23 +839,14 @@ static int das16_ai_insn_read(struct comedi_device *dev,
 			      struct comedi_insn *insn,
 			      unsigned int *data)
 {
-	const struct das16_board *board = dev->board_ptr;
 	unsigned int chan = CR_CHAN(insn->chanspec);
 	unsigned int range = CR_RANGE(insn->chanspec);
 	unsigned int val;
 	int ret;
 	int i;
 
-	das16_ai_disable(dev);
-
-	/* set multiplexer */
-	outb(chan | (chan << 4), dev->iobase + DAS16_MUX_REG);
-
-	/* set gain */
-	if (board->ai_pg != das16_pg_none) {
-		outb((das16_gainlists[board->ai_pg])[range],
-		     dev->iobase + DAS16_GAIN_REG);
-	}
+	/* set mux and range for single channel */
+	das16_ai_set_mux_range(dev, chan, chan, range);
 
 	for (i = 0; i < insn->n; i++) {
 		/* trigger conversion */
@@ -1001,14 +938,107 @@ static void das16_reset(struct comedi_device *dev)
 	outb(0, dev->iobase + DAS16_TIMER_BASE_REG + i8254_control_reg);
 }
 
+static void das16_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
+{
+	struct das16_private_struct *devpriv = dev->private;
+
+	/* only DMA channels 3 and 1 are valid */
+	if (!(dma_chan == 1 || dma_chan == 3))
+		return;
+
+	/* DMA uses two buffers */
+	devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
+					   DAS16_DMA_SIZE, COMEDI_ISADMA_READ);
+	if (devpriv->dma) {
+		init_timer(&devpriv->timer);
+		devpriv->timer.function = das16_timer_interrupt;
+		devpriv->timer.data = (unsigned long)dev;
+	}
+}
+
+static void das16_free_dma(struct comedi_device *dev)
+{
+	struct das16_private_struct *devpriv = dev->private;
+
+	if (devpriv) {
+		if (devpriv->timer.data)
+			del_timer_sync(&devpriv->timer);
+		comedi_isadma_free(devpriv->dma);
+	}
+}
+
+static const struct comedi_lrange *das16_ai_range(struct comedi_device *dev,
+						  struct comedi_subdevice *s,
+						  struct comedi_devconfig *it,
+						  unsigned int pg_type,
+						  unsigned int status)
+{
+	unsigned int min = it->options[4];
+	unsigned int max = it->options[5];
+
+	/* get any user-defined input range */
+	if (pg_type == das16_pg_none && (min || max)) {
+		struct comedi_lrange *lrange;
+		struct comedi_krange *krange;
+
+		/* allocate single-range range table */
+		lrange = comedi_alloc_spriv(s,
+					    sizeof(*lrange) + sizeof(*krange));
+		if (!lrange)
+			return &range_unknown;
+
+		/* initialize ai range */
+		lrange->length = 1;
+		krange = lrange->range;
+		krange->min = min;
+		krange->max = max;
+		krange->flags = UNIT_volt;
+
+		return lrange;
+	}
+
+	/* use software programmable range */
+	if (status & DAS16_STATUS_UNIPOLAR)
+		return das16_ai_uni_lranges[pg_type];
+	return das16_ai_bip_lranges[pg_type];
+}
+
+static const struct comedi_lrange *das16_ao_range(struct comedi_device *dev,
+						  struct comedi_subdevice *s,
+						  struct comedi_devconfig *it)
+{
+	unsigned int min = it->options[6];
+	unsigned int max = it->options[7];
+
+	/* get any user-defined output range */
+	if (min || max) {
+		struct comedi_lrange *lrange;
+		struct comedi_krange *krange;
+
+		/* allocate single-range range table */
+		lrange = comedi_alloc_spriv(s,
+					    sizeof(*lrange) + sizeof(*krange));
+		if (!lrange)
+			return &range_unknown;
+
+		/* initialize ao range */
+		lrange->length = 1;
+		krange = lrange->range;
+		krange->min = min;
+		krange->max = max;
+		krange->flags = UNIT_volt;
+
+		return lrange;
+	}
+
+	return &range_unknown;
+}
+
 static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	const struct das16_board *board = dev->board_ptr;
 	struct das16_private_struct *devpriv;
 	struct comedi_subdevice *s;
-	struct comedi_lrange *lrange;
-	struct comedi_krange *krange;
-	unsigned int dma_chan = it->options[2];
 	unsigned int status;
 	int ret;
 
@@ -1063,72 +1093,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			devpriv->clockbase = I8254_OSC_BASE_1MHZ;
 	}
 
-	/* initialize dma */
-	if (dma_chan == 1 || dma_chan == 3) {
-		unsigned long flags;
-		int i;
-
-		if (request_dma(dma_chan, dev->board_name)) {
-			dev_err(dev->class_dev,
-				"failed to request dma channel %i\n",
-				dma_chan);
-			return -EINVAL;
-		}
-		devpriv->dma_chan = dma_chan;
-
-		/* allocate dma buffers */
-		for (i = 0; i < 2; i++) {
-			void *p;
-
-			p = pci_alloc_consistent(NULL, DAS16_DMA_SIZE,
-						 &devpriv->dma_buffer_addr[i]);
-			if (!p)
-				return -ENOMEM;
-			devpriv->dma_buffer[i] = p;
-		}
-
-		flags = claim_dma_lock();
-		disable_dma(devpriv->dma_chan);
-		set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
-		release_dma_lock(flags);
-
-		init_timer(&devpriv->timer);
-		devpriv->timer.function = das16_timer_interrupt;
-		devpriv->timer.data = (unsigned long)dev;
-	}
-
-	/* get any user-defined input range */
-	if (board->ai_pg == das16_pg_none &&
-	    (it->options[4] || it->options[5])) {
-		/* allocate single-range range table */
-		lrange = kzalloc(sizeof(*lrange) + sizeof(*krange), GFP_KERNEL);
-		if (!lrange)
-			return -ENOMEM;
-
-		/* initialize ai range */
-		devpriv->user_ai_range_table = lrange;
-		lrange->length = 1;
-		krange = devpriv->user_ai_range_table->range;
-		krange->min = it->options[4];
-		krange->max = it->options[5];
-		krange->flags = UNIT_volt;
-	}
-
-	/* get any user-defined output range */
-	if (it->options[6] || it->options[7]) {
-		/* allocate single-range range table */
-		lrange = kzalloc(sizeof(*lrange) + sizeof(*krange), GFP_KERNEL);
-		if (!lrange)
-			return -ENOMEM;
-
-		/* initialize ao range */
-		devpriv->user_ao_range_table = lrange;
-		lrange->length = 1;
-		krange = devpriv->user_ao_range_table->range;
-		krange->min = it->options[6];
-		krange->max = it->options[7];
-		krange->flags = UNIT_volt;
-	}
+	das16_alloc_dma(dev, it->options[2]);
 
 	ret = comedi_alloc_subdevices(dev, 4 + board->has_8255);
 	if (ret)
@@ -1149,15 +1114,9 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 	s->len_chanlist	= s->n_chan;
 	s->maxdata	= board->ai_maxdata;
-	if (devpriv->user_ai_range_table) { /*  user defined ai range */
-		s->range_table	= devpriv->user_ai_range_table;
-	} else if (status & DAS16_STATUS_UNIPOLAR) {
-		s->range_table	= das16_ai_uni_lranges[board->ai_pg];
-	} else {
-		s->range_table	= das16_ai_bip_lranges[board->ai_pg];
-	}
+	s->range_table	= das16_ai_range(dev, s, it, board->ai_pg, status);
 	s->insn_read	= das16_ai_insn_read;
-	if (devpriv->dma_chan) {
+	if (devpriv->dma) {
 		dev->read_subdev = s;
 		s->subdev_flags	|= SDF_CMD_READ;
 		s->do_cmdtest	= das16_cmd_test;
@@ -1173,7 +1132,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		s->subdev_flags	= SDF_WRITABLE;
 		s->n_chan	= 2;
 		s->maxdata	= 0x0fff;
-		s->range_table	= devpriv->user_ao_range_table;
+		s->range_table	= das16_ao_range(dev, s, it);
 		s->insn_write	= das16_ao_insn_write;
 
 		ret = comedi_alloc_subdev_readback(s);
@@ -1230,25 +1189,11 @@ static void das16_detach(struct comedi_device *dev)
 {
 	const struct das16_board *board = dev->board_ptr;
 	struct das16_private_struct *devpriv = dev->private;
-	int i;
 
 	if (devpriv) {
-		if (devpriv->timer.data)
-			del_timer_sync(&devpriv->timer);
 		if (dev->iobase)
 			das16_reset(dev);
-
-		for (i = 0; i < 2; i++) {
-			if (devpriv->dma_buffer[i])
-				pci_free_consistent(NULL, DAS16_DMA_SIZE,
-						    devpriv->dma_buffer[i],
-						    devpriv->
-						    dma_buffer_addr[i]);
-		}
-		if (devpriv->dma_chan)
-			free_dma(devpriv->dma_chan);
-		kfree(devpriv->user_ai_range_table);
-		kfree(devpriv->user_ao_range_table);
+		das16_free_dma(dev);
 
 		if (devpriv->extra_iobase)
 			release_region(devpriv->extra_iobase,
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index 80f41b7e8273..3666a68979fb 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -455,7 +455,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status)
 	/* this probably won't catch overruns since the card doesn't generate
 	 * overrun interrupts, but we might as well try */
 	if (status & OVRUN) {
-		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		async->events |= COMEDI_CB_ERROR;
 		dev_err(dev->class_dev, "fifo overflow\n");
 	}
 
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index be825d21a185..0790a28828de 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -98,12 +98,12 @@ TODO:
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/io.h>
-#include "../comedidev.h"
 
-#include <asm/dma.h>
+#include "../comedidev.h"
 
-#include "8253.h"
+#include "comedi_isadma.h"
 #include "comedi_fc.h"
+#include "8253.h"
 
 /* misc. defines */
 #define DAS1800_SIZE           16	/* uses 16 io addresses */
@@ -421,19 +421,14 @@ static const struct das1800_board das1800_boards[] = {
 };
 
 struct das1800_private {
+	struct comedi_isadma *dma;
 	unsigned int divisor1;	/* value to load into board's counter 1 for timed conversions */
 	unsigned int divisor2;	/* value to load into board's counter 2 for timed conversions */
 	int irq_dma_bits;	/* bits for control register b */
 	/* dma bits for control register b, stored so that dma can be
 	 * turned on and off */
 	int dma_bits;
-	unsigned int dma0;	/* dma channels used */
-	unsigned int dma1;
-	unsigned int dma_current;	/* dma channel currently in use */
-	uint16_t *ai_buf0;	/* pointers to dma buffers */
-	uint16_t *ai_buf1;
-	uint16_t *dma_current_buf;	/* pointer to dma buffer currently being used */
-	unsigned int dma_transfer_size;	/* size of transfer currently used, in bytes */
+	uint16_t *fifo_buf;	/* bounce buffer for analog input FIFO */
 	unsigned long iobase2;	/* secondary io address used for analog out on 'ao' boards */
 	unsigned short ao_update_bits;	/* remembers the last write to the
 					 * 'update' dac */
@@ -480,9 +475,9 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev,
 	struct das1800_private *devpriv = dev->private;
 	unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2);
 
-	insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, nsamples);
-	munge_data(dev, devpriv->ai_buf0, nsamples);
-	comedi_buf_write_samples(s, devpriv->ai_buf0, nsamples);
+	insw(dev->iobase + DAS1800_FIFO, devpriv->fifo_buf, nsamples);
+	munge_data(dev, devpriv->fifo_buf, nsamples);
+	comedi_buf_write_samples(s, devpriv->fifo_buf, nsamples);
 }
 
 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
@@ -508,29 +503,21 @@ static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
 	}
 }
 
-/* Utility function used by das1800_flush_dma() and das1800_handle_dma().
- * Assumes dma lock is held */
+/* Utility function used by das1800_flush_dma() and das1800_handle_dma() */
 static void das1800_flush_dma_channel(struct comedi_device *dev,
 				      struct comedi_subdevice *s,
-				      unsigned int channel, uint16_t *buffer)
+				      struct comedi_isadma_desc *desc)
 {
-	struct das1800_private *devpriv = dev->private;
-	unsigned int nbytes;
+	unsigned int residue = comedi_isadma_disable(desc->chan);
+	unsigned int nbytes = desc->size - residue;
 	unsigned int nsamples;
 
-	disable_dma(channel);
-
-	/* clear flip-flop to make sure 2-byte registers
-	 * get set correctly */
-	clear_dma_ff(channel);
-
 	/*  figure out how many points to read */
-	nbytes = devpriv->dma_transfer_size - get_dma_residue(channel);
 	nsamples = comedi_bytes_to_samples(s, nbytes);
 	nsamples = comedi_nsamples_left(s, nsamples);
 
-	munge_data(dev, buffer, nsamples);
-	comedi_buf_write_samples(s, buffer, nsamples);
+	munge_data(dev, desc->virt_addr, nsamples);
+	comedi_buf_write_samples(s, desc->virt_addr, nsamples);
 }
 
 /* flushes remaining data from board when external trigger has stopped acquisition
@@ -539,28 +526,19 @@ static void das1800_flush_dma(struct comedi_device *dev,
 			      struct comedi_subdevice *s)
 {
 	struct das1800_private *devpriv = dev->private;
-	unsigned long flags;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
 	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
 
-	flags = claim_dma_lock();
-	das1800_flush_dma_channel(dev, s, devpriv->dma_current,
-				  devpriv->dma_current_buf);
+	das1800_flush_dma_channel(dev, s, desc);
 
 	if (dual_dma) {
 		/*  switch to other channel and flush it */
-		if (devpriv->dma_current == devpriv->dma0) {
-			devpriv->dma_current = devpriv->dma1;
-			devpriv->dma_current_buf = devpriv->ai_buf1;
-		} else {
-			devpriv->dma_current = devpriv->dma0;
-			devpriv->dma_current_buf = devpriv->ai_buf0;
-		}
-		das1800_flush_dma_channel(dev, s, devpriv->dma_current,
-					  devpriv->dma_current_buf);
+		dma->cur_dma = 1 - dma->cur_dma;
+		desc = &dma->desc[dma->cur_dma];
+		das1800_flush_dma_channel(dev, s, desc);
 	}
 
-	release_dma_lock(flags);
-
 	/*  get any remaining samples in fifo */
 	das1800_handle_fifo_not_empty(dev, s);
 }
@@ -569,47 +547,41 @@ static void das1800_handle_dma(struct comedi_device *dev,
 			       struct comedi_subdevice *s, unsigned int status)
 {
 	struct das1800_private *devpriv = dev->private;
-	unsigned long flags;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
 	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
 
-	flags = claim_dma_lock();
-	das1800_flush_dma_channel(dev, s, devpriv->dma_current,
-				  devpriv->dma_current_buf);
-	/*  re-enable  dma channel */
-	set_dma_addr(devpriv->dma_current,
-		     virt_to_bus(devpriv->dma_current_buf));
-	set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
-	enable_dma(devpriv->dma_current);
-	release_dma_lock(flags);
+	das1800_flush_dma_channel(dev, s, desc);
+
+	/* re-enable dma channel */
+	comedi_isadma_program(desc);
 
 	if (status & DMATC) {
 		/*  clear DMATC interrupt bit */
 		outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
 		/*  switch dma channels for next time, if appropriate */
-		if (dual_dma) {
-			/*  read data from the other channel next time */
-			if (devpriv->dma_current == devpriv->dma0) {
-				devpriv->dma_current = devpriv->dma1;
-				devpriv->dma_current_buf = devpriv->ai_buf1;
-			} else {
-				devpriv->dma_current = devpriv->dma0;
-				devpriv->dma_current_buf = devpriv->ai_buf0;
-			}
-		}
+		if (dual_dma)
+			dma->cur_dma = 1 - dma->cur_dma;
 	}
 }
 
 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct das1800_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc;
+	int i;
 
 	outb(0x0, dev->iobase + DAS1800_STATUS);	/* disable conversions */
 	outb(0x0, dev->iobase + DAS1800_CONTROL_B);	/* disable interrupts and dma */
 	outb(0x0, dev->iobase + DAS1800_CONTROL_A);	/* disable and clear fifo and stop triggering */
-	if (devpriv->dma0)
-		disable_dma(devpriv->dma0);
-	if (devpriv->dma1)
-		disable_dma(devpriv->dma1);
+
+	for (i = 0; i < 2; i++) {
+		desc = &dma->desc[i];
+		if (desc->chan)
+			comedi_isadma_disable(desc->chan);
+	}
+
 	return 0;
 }
 
@@ -639,7 +611,7 @@ static void das1800_ai_handler(struct comedi_device *dev)
 		/*  clear OVF interrupt bit */
 		outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
 		dev_err(dev->class_dev, "FIFO overflow\n");
-		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
 		comedi_handle_events(dev, s);
 		return;
 	}
@@ -963,79 +935,64 @@ static void das1800_setup_counters(struct comedi_device *dev,
 	}
 }
 
-/* utility function that suggests a dma transfer size based on the conversion period 'ns' */
-static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd)
+static unsigned int das1800_ai_transfer_size(struct comedi_device *dev,
+					     struct comedi_subdevice *s,
+					     unsigned int maxbytes,
+					     unsigned int ns)
 {
-	unsigned int size = DMA_BUF_SIZE;
-	static const int sample_size = 2;	/*  size in bytes of one sample from board */
-	unsigned int fill_time = 300000000;	/*  target time in nanoseconds for filling dma buffer */
-	unsigned int max_size;	/*  maximum size we will allow for a transfer */
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int max_samples = comedi_bytes_to_samples(s, maxbytes);
+	unsigned int samples;
+
+	samples = max_samples;
 
-	/*  make dma buffer fill in 0.3 seconds for timed modes */
+	/* for timed modes, make dma buffer fill in 'ns' time */
 	switch (cmd->scan_begin_src) {
-	case TRIG_FOLLOW:	/*  not in burst mode */
+	case TRIG_FOLLOW:	/* not in burst mode */
 		if (cmd->convert_src == TRIG_TIMER)
-			size = (fill_time / cmd->convert_arg) * sample_size;
+			samples = ns / cmd->convert_arg;
 		break;
 	case TRIG_TIMER:
-		size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
-		    sample_size;
-		break;
-	default:
-		size = DMA_BUF_SIZE;
+		samples = ns / (cmd->scan_begin_arg * cmd->chanlist_len);
 		break;
 	}
 
-	/*  set a minimum and maximum size allowed */
-	max_size = DMA_BUF_SIZE;
-	/*  if we are taking limited number of conversions, limit transfer size to that */
-	if (cmd->stop_src == TRIG_COUNT &&
-	    cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
-		max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
+	/* limit samples to what is remaining in the command */
+	samples = comedi_nsamples_left(s, samples);
 
-	if (size > max_size)
-		size = max_size;
-	if (size < sample_size)
-		size = sample_size;
+	if (samples > max_samples)
+		samples = max_samples;
+	if (samples < 1)
+		samples = 1;
 
-	return size;
+	return comedi_samples_to_bytes(s, samples);
 }
 
-/* sets up dma */
-static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
+static void das1800_ai_setup_dma(struct comedi_device *dev,
+				 struct comedi_subdevice *s)
 {
 	struct das1800_private *devpriv = dev->private;
-	unsigned long lock_flags;
-	const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[0];
+	unsigned int bytes;
 
 	if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
 		return;
 
-	/* determine a reasonable dma transfer size */
-	devpriv->dma_transfer_size = suggest_transfer_size(cmd);
-	lock_flags = claim_dma_lock();
-	disable_dma(devpriv->dma0);
-	/* clear flip-flop to make sure 2-byte registers for
-	 * count and address get set correctly */
-	clear_dma_ff(devpriv->dma0);
-	set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
-	/*  set appropriate size of transfer */
-	set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
-	devpriv->dma_current = devpriv->dma0;
-	devpriv->dma_current_buf = devpriv->ai_buf0;
-	enable_dma(devpriv->dma0);
-	/*  set up dual dma if appropriate */
-	if (dual_dma) {
-		disable_dma(devpriv->dma1);
-		/* clear flip-flop to make sure 2-byte registers for
-		 * count and address get set correctly */
-		clear_dma_ff(devpriv->dma1);
-		set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
-		/*  set appropriate size of transfer */
-		set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
-		enable_dma(devpriv->dma1);
+	dma->cur_dma = 0;
+
+	/* determine a dma transfer size to fill buffer in 0.3 sec */
+	bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000);
+
+	desc->size = bytes;
+	comedi_isadma_program(desc);
+
+	/* set up dual dma if appropriate */
+	if (devpriv->irq_dma_bits & DMA_DUAL) {
+		desc = &dma->desc[1];
+		desc->size = bytes;
+		comedi_isadma_program(desc);
 	}
-	release_dma_lock(lock_flags);
 }
 
 /* programs channel/gain list into card */
@@ -1097,7 +1054,7 @@ static int das1800_ai_do_cmd(struct comedi_device *dev,
 	/* setup card and start */
 	program_chanlist(dev, cmd);
 	das1800_setup_counters(dev, cmd);
-	setup_dma(dev, cmd);
+	das1800_ai_setup_dma(dev, s);
 	outb(control_c, dev->iobase + DAS1800_CONTROL_C);
 	/*  set conversion rate and length for burst mode */
 	if (control_c & BMDE) {
@@ -1234,79 +1191,57 @@ static int das1800_do_wbits(struct comedi_device *dev,
 	return insn->n;
 }
 
-static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
-			    unsigned int dma1)
+static void das1800_init_dma(struct comedi_device *dev,
+			     struct comedi_devconfig *it)
 {
 	struct das1800_private *devpriv = dev->private;
-	unsigned long flags;
+	unsigned int *dma_chan;
 
-	/*  need an irq to do dma */
-	if (dev->irq && dma0) {
-		/* encode dma0 and dma1 into 2 digit hexadecimal for switch */
-		switch ((dma0 & 0x7) | (dma1 << 4)) {
-		case 0x5:	/*  dma0 == 5 */
-			devpriv->dma_bits |= DMA_CH5;
-			break;
-		case 0x6:	/*  dma0 == 6 */
-			devpriv->dma_bits |= DMA_CH6;
-			break;
-		case 0x7:	/*  dma0 == 7 */
-			devpriv->dma_bits |= DMA_CH7;
-			break;
-		case 0x65:	/*  dma0 == 5, dma1 == 6 */
-			devpriv->dma_bits |= DMA_CH5_CH6;
-			break;
-		case 0x76:	/*  dma0 == 6, dma1 == 7 */
-			devpriv->dma_bits |= DMA_CH6_CH7;
-			break;
-		case 0x57:	/*  dma0 == 7, dma1 == 5 */
-			devpriv->dma_bits |= DMA_CH7_CH5;
-			break;
-		default:
-			dev_err(dev->class_dev,
-				"only supports dma channels 5 through 7\n");
-			dev_err(dev->class_dev,
-				"Dual dma only allows the following combinations:\n");
-			dev_err(dev->class_dev,
-				"dma 5,6 / 6,7 / or 7,5\n");
-			return -EINVAL;
-		}
-		if (request_dma(dma0, dev->driver->driver_name)) {
-			dev_err(dev->class_dev,
-				"failed to allocate dma channel %i\n", dma0);
-			return -EINVAL;
-		}
-		devpriv->dma0 = dma0;
-		devpriv->dma_current = dma0;
-		if (dma1) {
-			if (request_dma(dma1, dev->driver->driver_name)) {
-				dev_err(dev->class_dev,
-					"failed to allocate dma channel %i\n",
-					dma1);
-				return -EINVAL;
-			}
-			devpriv->dma1 = dma1;
-		}
-		devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
-		if (devpriv->ai_buf0 == NULL)
-			return -ENOMEM;
-		devpriv->dma_current_buf = devpriv->ai_buf0;
-		if (dma1) {
-			devpriv->ai_buf1 =
-			    kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
-			if (devpriv->ai_buf1 == NULL)
-				return -ENOMEM;
-		}
-		flags = claim_dma_lock();
-		disable_dma(devpriv->dma0);
-		set_dma_mode(devpriv->dma0, DMA_MODE_READ);
-		if (dma1) {
-			disable_dma(devpriv->dma1);
-			set_dma_mode(devpriv->dma1, DMA_MODE_READ);
-		}
-		release_dma_lock(flags);
+	/*
+	 * it->options[2] is DMA channel 0
+	 * it->options[3] is DMA channel 1
+	 *
+	 * Encode the DMA channels into 2 digit hexadecimal for switch.
+	 */
+	dma_chan = &it->options[2];
+
+	switch ((dma_chan[0] & 0x7) | (dma_chan[1] << 4)) {
+	case 0x5:	/*  dma0 == 5 */
+		devpriv->dma_bits = DMA_CH5;
+		break;
+	case 0x6:	/*  dma0 == 6 */
+		devpriv->dma_bits = DMA_CH6;
+		break;
+	case 0x7:	/*  dma0 == 7 */
+		devpriv->dma_bits = DMA_CH7;
+		break;
+	case 0x65:	/*  dma0 == 5, dma1 == 6 */
+		devpriv->dma_bits = DMA_CH5_CH6;
+		break;
+	case 0x76:	/*  dma0 == 6, dma1 == 7 */
+		devpriv->dma_bits = DMA_CH6_CH7;
+		break;
+	case 0x57:	/*  dma0 == 7, dma1 == 5 */
+		devpriv->dma_bits = DMA_CH7_CH5;
+		break;
+	default:
+		return;
 	}
-	return 0;
+
+	/* DMA can use 1 or 2 buffers, each with a separate channel */
+	devpriv->dma = comedi_isadma_alloc(dev, dma_chan[1] ? 2 : 1,
+					   dma_chan[0], dma_chan[1],
+					   DMA_BUF_SIZE, COMEDI_ISADMA_READ);
+	if (!devpriv->dma)
+		devpriv->dma_bits = 0;
+}
+
+static void das1800_free_dma(struct comedi_device *dev)
+{
+	struct das1800_private *devpriv = dev->private;
+
+	if (devpriv)
+		comedi_isadma_free(devpriv->dma);
 }
 
 static int das1800_probe(struct comedi_device *dev)
@@ -1374,8 +1309,6 @@ static int das1800_attach(struct comedi_device *dev,
 	struct das1800_private *devpriv;
 	struct comedi_subdevice *s;
 	unsigned int irq = it->options[1];
-	unsigned int dma0 = it->options[2];
-	unsigned int dma1 = it->options[3];
 	int board;
 	int ret;
 
@@ -1437,16 +1370,13 @@ static int das1800_attach(struct comedi_device *dev,
 		}
 	}
 
-	ret = das1800_init_dma(dev, dma0, dma1);
-	if (ret < 0)
-		return ret;
+	/* an irq and one dma channel is required to use dma */
+	if (dev->irq & it->options[2])
+		das1800_init_dma(dev, it);
 
-	if (devpriv->ai_buf0 == NULL) {
-		devpriv->ai_buf0 =
-		    kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
-		if (devpriv->ai_buf0 == NULL)
-			return -ENOMEM;
-	}
+	devpriv->fifo_buf = kmalloc_array(FIFO_SIZE, sizeof(uint16_t), GFP_KERNEL);
+	if (!devpriv->fifo_buf)
+		return -ENOMEM;
 
 	ret = comedi_alloc_subdevices(dev, 4);
 	if (ret)
@@ -1523,13 +1453,9 @@ static void das1800_detach(struct comedi_device *dev)
 {
 	struct das1800_private *devpriv = dev->private;
 
+	das1800_free_dma(dev);
 	if (devpriv) {
-		if (devpriv->dma0)
-			free_dma(devpriv->dma0);
-		if (devpriv->dma1)
-			free_dma(devpriv->dma1);
-		kfree(devpriv->ai_buf0);
-		kfree(devpriv->ai_buf1);
+		kfree(devpriv->fifo_buf);
 		if (devpriv->iobase2)
 			release_region(devpriv->iobase2, DAS1800_SIZE);
 	}
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
index 780f4f646ea0..b8755b50a11e 100644
--- a/drivers/staging/comedi/drivers/das6402.c
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -20,8 +20,8 @@
 /*
  * Driver: das6402
  * Description: Keithley Metrabyte DAS6402 (& compatibles)
- * Devices: (Keithley Metrabyte) DAS6402-12 (das6402-12)
- *	    (Keithley Metrabyte) DAS6402-16 (das6402-16)
+ * Devices: [Keithley Metrabyte] DAS6402-12 (das6402-12),
+ *   DAS6402-16 (das6402-16)
  * Author: H Hartley Sweeten <hsweeten@visionengravers.com>
  * Updated: Fri, 14 Mar 2014 10:18:43 -0700
  * Status: unknown
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index e5bdc2423445..ff7f4be3f314 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -511,7 +511,7 @@ static irqreturn_t das800_interrupt(int irq, void *d)
 
 	if (fifo_overflow) {
 		spin_unlock_irqrestore(&dev->spinlock, irq_flags);
-		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
 		comedi_handle_events(dev, s);
 		return IRQ_HANDLED;
 	}
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 6df298a99cc6..1af006609fc1 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -19,7 +19,7 @@
 /*
  * Driver: dmm32at
  * Description: Diamond Systems Diamond-MM-32-AT
- * Devices: (Diamond Systems) Diamond-MM-32-AT [dmm32at]
+ * Devices: [Diamond Systems] Diamond-MM-32-AT (dmm32at)
  * Author: Perry J. Piplani <perry.j.piplani@nasa.gov>
  * Updated: Fri Jun  4 09:13:24 CDT 2004
  * Status: experimental
@@ -365,7 +365,7 @@ static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
 	/* enable the ai conversion interrupt and the clock to start scans */
 	outb(DMM32AT_INTCLK_ADINT |
 	     DMM32AT_INTCLK_CLKEN | DMM32AT_INTCLK_CLKSEL,
-             dev->iobase + DMM32AT_INTCLK_REG);
+	     dev->iobase + DMM32AT_INTCLK_REG);
 }
 
 static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index 2be98bb9a809..db21d2135856 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -20,22 +20,12 @@
  * Driver: dt282x
  * Description: Data Translation DT2821 series (including DT-EZ)
  * Author: ds
- * Devices: (Data Translation) DT2821 [dt2821]
- *	    (Data Translation) DT2821-F-16SE [dt2821-f]
- *	    (Data Translation) DT2821-F-8DI [dt2821-f]
- *	    (Data Translation) DT2821-G-16SE [dt2821-g]
- *	    (Data Translation) DT2821-G-8DI [dt2821-g]
- *	    (Data Translation) DT2823 [dt2823]
- *	    (Data Translation) DT2824-PGH [dt2824-pgh]
- *	    (Data Translation) DT2824-PGL [dt2824-pgl]
- *	    (Data Translation) DT2825 [dt2825]
- *	    (Data Translation) DT2827 [dt2827]
- *	    (Data Translation) DT2828 [dt2828]
- *	    (Data Translation) DT2928 [dt2829]
- *	    (Data Translation) DT21-EZ [dt21-ez]
- *	    (Data Translation) DT23-EZ [dt23-ez]
- *	    (Data Translation) DT24-EZ [dt24-ez]
- *	    (Data Translation) DT24-EZ-PGL [dt24-ez-pgl]
+ * Devices: [Data Translation] DT2821 (dt2821), DT2821-F-16SE (dt2821-f),
+ *   DT2821-F-8DI (dt2821-f), DT2821-G-16SE (dt2821-g),
+ *   DT2821-G-8DI (dt2821-g), DT2823 (dt2823), DT2824-PGH (dt2824-pgh),
+ *   DT2824-PGL (dt2824-pgl), DT2825 (dt2825), DT2827 (dt2827),
+ *   DT2828 (dt2828), DT2928 (dt2829), DT21-EZ (dt21-ez), DT23-EZ (dt23-ez),
+ *   DT24-EZ (dt24-ez), DT24-EZ-PGL (dt24-ez-pgl)
  * Status: complete
  * Updated: Wed, 22 Aug 2001 17:11:34 -0700
  *
@@ -66,15 +56,14 @@
  */
 
 #include <linux/module.h>
-#include "../comedidev.h"
-
 #include <linux/delay.h>
 #include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 
-#include <asm/dma.h>
+#include "../comedidev.h"
 
+#include "comedi_isadma.h"
 #include "comedi_fc.h"
 
 /*
@@ -311,55 +300,36 @@ static const struct dt282x_board boardtypes[] = {
 };
 
 struct dt282x_private {
+	struct comedi_isadma *dma;
 	unsigned int ad_2scomp:1;
-
 	unsigned int divisor;
-
 	int dacsr;	/* software copies of registers */
 	int adcsr;
 	int supcsr;
-
 	int ntrig;
 	int nread;
-
-	struct {
-		int chan;
-		unsigned short *buf;	/* DMA buffer */
-		int size;	/* size of current transfer */
-	} dma[2];
-	int dma_maxsize;	/* max size of DMA transfer (in bytes) */
-	int current_dma_index;
 	int dma_dir;
 };
 
 static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
 {
 	struct dt282x_private *devpriv = dev->private;
-	int dma_chan;
-	unsigned long dma_ptr;
-	unsigned long flags;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma_index];
 
 	if (!devpriv->ntrig)
 		return 0;
 
 	if (n == 0)
-		n = devpriv->dma_maxsize;
+		n = desc->maxsize;
 	if (n > devpriv->ntrig * 2)
 		n = devpriv->ntrig * 2;
 	devpriv->ntrig -= n / 2;
 
-	devpriv->dma[dma_index].size = n;
-	dma_chan = devpriv->dma[dma_index].chan;
-	dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
-
-	set_dma_mode(dma_chan, DMA_MODE_READ);
-	flags = claim_dma_lock();
-	clear_dma_ff(dma_chan);
-	set_dma_addr(dma_chan, dma_ptr);
-	set_dma_count(dma_chan, n);
-	release_dma_lock(flags);
+	desc->size = n;
+	comedi_isadma_set_mode(desc, devpriv->dma_dir);
 
-	enable_dma(dma_chan);
+	comedi_isadma_program(desc);
 
 	return n;
 }
@@ -367,22 +337,13 @@ static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
 static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
 {
 	struct dt282x_private *devpriv = dev->private;
-	int dma_chan;
-	unsigned long dma_ptr;
-	unsigned long flags;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma_index];
 
-	devpriv->dma[dma_index].size = n;
-	dma_chan = devpriv->dma[dma_index].chan;
-	dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
+	desc->size = n;
+	comedi_isadma_set_mode(desc, devpriv->dma_dir);
 
-	set_dma_mode(dma_chan, DMA_MODE_WRITE);
-	flags = claim_dma_lock();
-	clear_dma_ff(dma_chan);
-	set_dma_addr(dma_chan, dma_ptr);
-	set_dma_count(dma_chan, n);
-	release_dma_lock(flags);
-
-	enable_dma(dma_chan);
+	comedi_isadma_program(desc);
 
 	return n;
 }
@@ -390,9 +351,14 @@ static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
 static void dt282x_disable_dma(struct comedi_device *dev)
 {
 	struct dt282x_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc;
+	int i;
 
-	disable_dma(devpriv->dma[0].chan);
-	disable_dma(devpriv->dma[1].chan);
+	for (i = 0; i < 2; i++) {
+		desc = &dma->desc[i];
+		comedi_isadma_disable(desc->chan);
+	}
 }
 
 static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags)
@@ -454,11 +420,12 @@ static unsigned int dt282x_ao_setup_dma(struct comedi_device *dev,
 					int cur_dma)
 {
 	struct dt282x_private *devpriv = dev->private;
-	void *ptr = devpriv->dma[cur_dma].buf;
-	unsigned int nsamples = comedi_bytes_to_samples(s, devpriv->dma_maxsize);
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[cur_dma];
+	unsigned int nsamples = comedi_bytes_to_samples(s, desc->maxsize);
 	unsigned int nbytes;
 
-	nbytes = comedi_buf_read_samples(s, ptr, nsamples);
+	nbytes = comedi_buf_read_samples(s, desc->virt_addr, nsamples);
 	if (nbytes)
 		dt282x_prep_ao_dma(dev, cur_dma, nbytes);
 	else
@@ -471,39 +438,37 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev,
 				    struct comedi_subdevice *s)
 {
 	struct dt282x_private *devpriv = dev->private;
-	int cur_dma = devpriv->current_dma_index;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
 
 	outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
 	     dev->iobase + DT2821_SUPCSR_REG);
 
-	disable_dma(devpriv->dma[cur_dma].chan);
-
-	devpriv->current_dma_index = 1 - cur_dma;
+	comedi_isadma_disable(desc->chan);
 
-	if (!dt282x_ao_setup_dma(dev, s, cur_dma))
+	if (!dt282x_ao_setup_dma(dev, s, dma->cur_dma))
 		s->async->events |= COMEDI_CB_OVERFLOW;
+
+	dma->cur_dma = 1 - dma->cur_dma;
 }
 
 static void dt282x_ai_dma_interrupt(struct comedi_device *dev,
 				    struct comedi_subdevice *s)
 {
 	struct dt282x_private *devpriv = dev->private;
-	int cur_dma = devpriv->current_dma_index;
-	void *ptr = devpriv->dma[cur_dma].buf;
-	int size = devpriv->dma[cur_dma].size;
-	unsigned int nsamples = comedi_bytes_to_samples(s, size);
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
+	unsigned int nsamples = comedi_bytes_to_samples(s, desc->size);
 	int ret;
 
 	outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
 	     dev->iobase + DT2821_SUPCSR_REG);
 
-	disable_dma(devpriv->dma[cur_dma].chan);
-
-	devpriv->current_dma_index = 1 - cur_dma;
+	comedi_isadma_disable(desc->chan);
 
-	dt282x_munge(dev, s, ptr, size);
-	ret = comedi_buf_write_samples(s, ptr, nsamples);
-	if (ret != size)
+	dt282x_munge(dev, s, desc->virt_addr, desc->size);
+	ret = comedi_buf_write_samples(s, desc->virt_addr, nsamples);
+	if (ret != desc->size)
 		return;
 
 	devpriv->nread -= nsamples;
@@ -524,7 +489,9 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev,
 	}
 #endif
 	/* restart the channel */
-	dt282x_prep_ai_dma(dev, cur_dma, 0);
+	dt282x_prep_ai_dma(dev, dma->cur_dma, 0);
+
+	dma->cur_dma = 1 - dma->cur_dma;
 }
 
 static irqreturn_t dt282x_interrupt(int irq, void *d)
@@ -545,7 +512,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
 	dacsr = inw(dev->iobase + DT2821_DACSR_REG);
 	supcsr = inw(dev->iobase + DT2821_SUPCSR_REG);
 	if (supcsr & DT2821_SUPCSR_DMAD) {
-		if (devpriv->dma_dir == DMA_MODE_READ)
+		if (devpriv->dma_dir == COMEDI_ISADMA_READ)
 			dt282x_ai_dma_interrupt(dev, s);
 		else
 			dt282x_ao_dma_interrupt(dev, s_ao);
@@ -718,14 +685,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
 
 	err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
 
-	if (cmd->scan_begin_src == TRIG_FOLLOW) {
-		/* internal trigger */
-		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-	} else {
-		/* external trigger */
-		/* should be level/edge, hi/lo specification here */
-		err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
-	}
+	err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
 
 	err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 4000);
 
@@ -757,6 +717,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev,
 static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct dt282x_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
 	struct comedi_cmd *cmd = &s->async->cmd;
 	int ret;
 
@@ -778,8 +739,8 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg;
 	devpriv->nread = devpriv->ntrig;
 
-	devpriv->dma_dir = DMA_MODE_READ;
-	devpriv->current_dma_index = 0;
+	devpriv->dma_dir = COMEDI_ISADMA_READ;
+	dma->cur_dma = 0;
 	dt282x_prep_ai_dma(dev, 0, 0);
 	if (devpriv->ntrig) {
 		dt282x_prep_ai_dma(dev, 1, 0);
@@ -942,6 +903,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev,
 static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct dt282x_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
 	struct comedi_cmd *cmd = &s->async->cmd;
 
 	dt282x_disable_dma(dev);
@@ -958,8 +920,8 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len;
 	devpriv->nread = devpriv->ntrig;
 
-	devpriv->dma_dir = DMA_MODE_WRITE;
-	devpriv->current_dma_index = 0;
+	devpriv->dma_dir = COMEDI_ISADMA_WRITE;
+	dma->cur_dma = 0;
 
 	outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
 
@@ -1063,46 +1025,42 @@ static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
 	return ai_range_table[x];
 }
 
-static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2)
+static void dt282x_alloc_dma(struct comedi_device *dev,
+			     struct comedi_devconfig *it)
 {
 	struct dt282x_private *devpriv = dev->private;
-	int ret;
+	unsigned int irq_num = it->options[1];
+	unsigned int dma_chan[2];
 
-	ret = request_dma(dma1, "dt282x A");
-	if (ret)
-		return -EBUSY;
-	devpriv->dma[0].chan = dma1;
+	if (it->options[2] < it->options[3]) {
+		dma_chan[0] = it->options[2];
+		dma_chan[1] = it->options[3];
+	} else {
+		dma_chan[0] = it->options[3];
+		dma_chan[1] = it->options[2];
+	}
 
-	ret = request_dma(dma2, "dt282x B");
-	if (ret)
-		return -EBUSY;
-	devpriv->dma[1].chan = dma2;
+	if (!irq_num || dma_chan[0] == dma_chan[1] ||
+	    dma_chan[0] < 5 || dma_chan[0] > 7 ||
+	    dma_chan[1] < 5 || dma_chan[1] > 7)
+		return;
 
-	devpriv->dma_maxsize = PAGE_SIZE;
-	devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
-	devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
-	if (!devpriv->dma[0].buf || !devpriv->dma[1].buf)
-		return -ENOMEM;
+	if (request_irq(irq_num, dt282x_interrupt, 0, dev->board_name, dev))
+		return;
 
-	return 0;
+	/* DMA uses two 4K buffers with separate DMA channels */
+	devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan[0], dma_chan[1],
+					   PAGE_SIZE, 0);
+	if (!devpriv->dma)
+		free_irq(irq_num, dev);
 }
 
 static void dt282x_free_dma(struct comedi_device *dev)
 {
 	struct dt282x_private *devpriv = dev->private;
-	int i;
-
-	if (!devpriv)
-		return;
 
-	for (i = 0; i < 2; i++) {
-		if (devpriv->dma[i].chan)
-			free_dma(devpriv->dma[i].chan);
-		if (devpriv->dma[i].buf)
-			free_page((unsigned long)devpriv->dma[i].buf);
-		devpriv->dma[i].chan = 0;
-		devpriv->dma[i].buf = NULL;
-	}
+	if (devpriv)
+		comedi_isadma_free(devpriv->dma);
 }
 
 static int dt282x_initialize(struct comedi_device *dev)
@@ -1160,36 +1118,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		return -ENOMEM;
 
 	/* an IRQ and 2 DMA channels are required for async command support */
-	if (it->options[1] && it->options[2] && it->options[3]) {
-		unsigned int irq = it->options[1];
-		unsigned int dma1 = it->options[2];
-		unsigned int dma2 = it->options[3];
-
-		if (dma2 < dma1) {
-			unsigned int swap;
-
-			swap = dma1;
-			dma1 = dma2;
-			dma2 = swap;
-		}
-
-		if (dma1 != dma2 &&
-		    dma1 >= 5 && dma1 <= 7 &&
-		    dma2 >= 5 && dma2 <= 7) {
-			ret = request_irq(irq, dt282x_interrupt, 0,
-					  dev->board_name, dev);
-			if (ret == 0) {
-				dev->irq = irq;
-
-				ret = dt282x_grab_dma(dev, dma1, dma2);
-				if (ret < 0) {
-					dt282x_free_dma(dev);
-					free_irq(dev->irq, dev);
-					dev->irq = 0;
-				}
-			}
-		}
-	}
+	dt282x_alloc_dma(dev, it);
 
 	ret = comedi_alloc_subdevices(dev, 3);
 	if (ret)
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 1d9a7a63e06f..0aa51980e327 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -355,7 +355,7 @@ static irqreturn_t dt3k_interrupt(int irq, void *d)
 		dt3k_ai_empty_fifo(dev, s);
 
 	if (status & (DT3000_ADSWERR | DT3000_ADHWERR))
-		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		s->async->events |= COMEDI_CB_ERROR;
 
 	debug_n_ints++;
 	if (debug_n_ints >= 10)
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index 06c601d8fdff..e11c216a4c85 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -42,9 +42,8 @@ for my needs.
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/uaccess.h>
-#include <linux/usb.h>
 
-#include "../comedidev.h"
+#include "../comedi_usb.h"
 
 #define DT9812_DIAGS_BOARD_INFO_ADDR	0xFBFF
 #define DT9812_MAX_WRITE_CMD_PIPE_SIZE	32
diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c
index 1b6324c6eb29..6c1e442f6c81 100644
--- a/drivers/staging/comedi/drivers/dyna_pci10xx.c
+++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c
@@ -14,24 +14,23 @@
  */
 
 /*
- Driver: dyna_pci10xx
- Devices: Dynalog India PCI DAQ Cards, http://www.dynalogindia.com/
- Author: Prashant Shah <pshah.mumbai@gmail.com>
- Developed at Automation Labs, Chemical Dept., IIT Bombay, India.
- Prof. Kannan Moudgalya <kannan@iitb.ac.in>
- http://www.iitb.ac.in
- Status: Stable
- Version: 1.0
- Device Supported :
- - Dynalog PCI 1050
-
- Notes :
- - Dynalog India Pvt. Ltd. does not have a registered PCI Vendor ID and
- they are using the PLX Technlogies Vendor ID since that is the PCI Chip used
- in the card.
- - Dynalog India Pvt. Ltd. has provided the internal register specification for
- their cards in their manuals.
-*/
+ * Driver: dyna_pci10xx
+ * Description: Dynalog India PCI DAQ Cards, http://www.dynalogindia.com/
+ * Devices: [Dynalog] PCI-1050 (dyna_pci1050)
+ * Author: Prashant Shah <pshah.mumbai@gmail.com>
+ * Status: Stable
+ *
+ * Developed at Automation Labs, Chemical Dept., IIT Bombay, India.
+ * Prof. Kannan Moudgalya <kannan@iitb.ac.in>
+ * http://www.iitb.ac.in
+ *
+ * Notes :
+ * - Dynalog India Pvt. Ltd. does not have a registered PCI Vendor ID and
+ *   they are using the PLX Technlogies Vendor ID since that is the PCI Chip
+ *   used in the card.
+ * - Dynalog India Pvt. Ltd. has provided the internal register specification
+ *   for their cards in their manuals.
+ */
 
 #include <linux/module.h>
 #include <linux/delay.h>
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index 0979f536ed39..deada9784b69 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -261,12 +261,12 @@ static irqreturn_t gsc_hpdi_interrupt(int irq, void *d)
 
 	if (hpdi_board_status & RX_OVERRUN_BIT) {
 		dev_err(dev->class_dev, "rx fifo overrun\n");
-		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		async->events |= COMEDI_CB_ERROR;
 	}
 
 	if (hpdi_board_status & RX_UNDERRUN_BIT) {
 		dev_err(dev->class_dev, "rx fifo underrun\n");
-		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		async->events |= COMEDI_CB_ERROR;
 	}
 
 	if (devpriv->dio_count == 0)
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 1085d66935fe..0768bc42a5db 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -9,7 +9,7 @@
 /*
  * Driver: ii_pci20kc
  * Description: Intelligent Instruments PCI-20001C carrier board
- * Devices: (Intelligent Instrumentation) PCI-20001C [ii_pci20kc]
+ * Devices: [Intelligent Instrumentation] PCI-20001C (ii_pci20kc)
  * Author: Markus Kempf <kempf@matsci.uni-sb.de>
  * Status: works
  *
diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h
index 20478ae8fad6..356811defaf4 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.h
+++ b/drivers/staging/comedi/drivers/jr3_pci.h
@@ -261,8 +261,9 @@ struct intern_transform {
 	} link[8];
 };
 
-/*  JR3 force/torque sensor data definition. For more information see sensor and */
-/*  hardware manuals. */
+/*  JR3 force/torque sensor data definition. For more information see sensor
+ *  and hardware manuals.
+ */
 
 struct jr3_channel {
 	/*  Raw_channels is the area used to store the raw data coming from */
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
index 77e94a34b51e..3c19e0f178ca 100644
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -19,7 +19,7 @@
 /*
  * Driver: ke_counter
  * Description: Driver for Kolter Electronic Counter Card
- * Devices: (Kolter Electronic) PCI Counter Card [ke_counter]
+ * Devices: [Kolter Electronic] PCI Counter Card (ke_counter)
  * Author: Michael Hillmann
  * Updated: Mon, 14 Apr 2008 15:42:42 +0100
  * Status: tested
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index 915685c1c85c..d120aa244cf9 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -1068,7 +1068,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 				 ME4000_AI_CTRL_BIT_SC_IRQ);
 			outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
 
-			s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+			s->async->events |= COMEDI_CB_ERROR;
 
 			dev_err(dev->class_dev, "FIFO overflow\n");
 		} else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
@@ -1089,7 +1089,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 				 ME4000_AI_CTRL_BIT_SC_IRQ);
 			outl(tmp, dev->iobase + ME4000_AI_CTRL_REG);
 
-			s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+			s->async->events |= COMEDI_CB_ERROR;
 
 			dev_err(dev->class_dev, "Undefined FIFO state\n");
 		}
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index b5278c11e622..92e23527f2cb 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -19,8 +19,7 @@
 /*
  * Driver: me_daq
  * Description: Meilhaus PCI data acquisition cards
- * Devices: (Meilhaus) ME-2600i [me-2600i]
- *          (Meilhaus) ME-2000i [me-2000i]
+ * Devices: [Meilhaus] ME-2600i (me-2600i), ME-2000i (me-2000i)
  * Author: Michael Hillmann <hillmann@syscongroup.de>
  * Status: experimental
  *
@@ -175,7 +174,7 @@ struct me_private_data {
 
 static inline void sleep(unsigned sec)
 {
-	current->state = TASK_INTERRUPTIBLE;
+	__set_current_state(TASK_INTERRUPTIBLE);
 	schedule_timeout(sec * HZ);
 }
 
diff --git a/drivers/staging/comedi/drivers/mf6x4.c b/drivers/staging/comedi/drivers/mf6x4.c
index af21bc180c46..db972bce2b5b 100644
--- a/drivers/staging/comedi/drivers/mf6x4.c
+++ b/drivers/staging/comedi/drivers/mf6x4.c
@@ -18,7 +18,7 @@
 /*
  * Driver: mf6x4
  * Description: Humusoft MF634 and MF624 Data acquisition card driver
- * Devices: Humusoft MF634, Humusoft MF624
+ * Devices: [Humusoft] MF634 (mf634), MF624 (mf624)
  * Author: Rostislav Lisovy <lisovy@gmail.com>
  * Status: works
  * Updated:
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index ffc9e61d6cdd..1e537a5cf862 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -494,9 +494,7 @@ EXPORT_SYMBOL_GPL(mite_bytes_read_from_memory_ub);
 unsigned mite_dma_tcr(struct mite_channel *mite_chan)
 {
 	struct mite_struct *mite = mite_chan->mite;
-	int lkar;
 
-	lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
 	return readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel));
 }
 EXPORT_SYMBOL_GPL(mite_dma_tcr);
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
index f99847f3999f..530f716f6586 100644
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -19,8 +19,7 @@
 /*
  * Driver: ni_6527
  * Description: National Instruments 6527
- * Devices: (National Instruments) PCI-6527 [pci-6527]
- *          (National Instruments) PXI-6527 [pxi-6527]
+ * Devices: [National Instruments] PCI-6527 (pci-6527), PXI-6527 (pxi-6527)
  * Author: David A. Schleef <ds@schleef.org>
  * Updated: Sat, 25 Jan 2003 13:24:40 -0800
  * Status: works
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index bcb326e31562..67cb758eb0cd 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -25,28 +25,14 @@
  * Author: Jon Grierson <jd@renko.co.uk>,
  *	   Frank Mori Hess <fmhess@users.sourceforge.net>
  * Status: testing
- * Devices: (National Instruments) PCI-6509 [ni_65xx]
- *	    (National Instruments) PXI-6509 [ni_65xx]
- *	    (National Instruments) PCI-6510 [ni_65xx]
- *	    (National Instruments) PCI-6511 [ni_65xx]
- *	    (National Instruments) PXI-6511 [ni_65xx]
- *	    (National Instruments) PCI-6512 [ni_65xx]
- *	    (National Instruments) PXI-6512 [ni_65xx]
- *	    (National Instruments) PCI-6513 [ni_65xx]
- *	    (National Instruments) PXI-6513 [ni_65xx]
- *	    (National Instruments) PCI-6514 [ni_65xx]
- *	    (National Instruments) PXI-6514 [ni_65xx]
- *	    (National Instruments) PCI-6515 [ni_65xx]
- *	    (National Instruments) PXI-6515 [ni_65xx]
- *	    (National Instruments) PCI-6516 [ni_65xx]
- *	    (National Instruments) PCI-6517 [ni_65xx]
- *	    (National Instruments) PCI-6518 [ni_65xx]
- *	    (National Instruments) PCI-6519 [ni_65xx]
- *	    (National Instruments) PCI-6520 [ni_65xx]
- *	    (National Instruments) PCI-6521 [ni_65xx]
- *	    (National Instruments) PXI-6521 [ni_65xx]
- *	    (National Instruments) PCI-6528 [ni_65xx]
- *	    (National Instruments) PXI-6528 [ni_65xx]
+ * Devices: [National Instruments] PCI-6509 (pci-6509), PXI-6509 (pxi-6509),
+ *   PCI-6510 (pci-6510), PCI-6511 (pci-6511), PXI-6511 (pxi-6511),
+ *   PCI-6512 (pci-6512), PXI-6512 (pxi-6512), PCI-6513 (pci-6513),
+ *   PXI-6513 (pxi-6513), PCI-6514 (pci-6514), PXI-6514 (pxi-6514),
+ *   PCI-6515 (pxi-6515), PXI-6515 (pxi-6515), PCI-6516 (pci-6516),
+ *   PCI-6517 (pci-6517), PCI-6518 (pci-6518), PCI-6519 (pci-6519),
+ *   PCI-6520 (pci-6520), PCI-6521 (pci-6521), PXI-6521 (pxi-6521),
+ *   PCI-6528 (pci-6528), PXI-6528 (pxi-6528)
  * Updated: Mon, 21 Jul 2014 12:49:58 +0000
  *
  * Configuration Options: not applicable, uses PCI auto config
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 69e543a0bf22..a1ce0b0b8c41 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -62,14 +62,13 @@ TRIG_WAKE_EOS
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
-#include "../comedidev.h"
-
 #include <linux/io.h>
 
-#include <asm/dma.h>
+#include "../comedidev.h"
 
-#include "8253.h"
+#include "comedi_isadma.h"
 #include "comedi_fc.h"
+#include "8253.h"
 
 #define A2150_DMA_BUFFER_SIZE	0xff00	/*  size in bytes of dma buffer */
 
@@ -146,11 +145,8 @@ static const struct a2150_board a2150_boards[] = {
 };
 
 struct a2150_private {
-
-	volatile unsigned int count;	/* number of data points left to be taken */
-	unsigned int dma;	/*  dma channel */
-	uint16_t *dma_buffer;	/*  dma buffer */
-	unsigned int dma_transfer_size;	/*  size in bytes of dma transfers */
+	struct comedi_isadma *dma;
+	unsigned int count;	/* number of data points left to be taken */
 	int irq_dma_bits;	/*  irq/dma register bits */
 	int config_bits;	/*  config register bits */
 };
@@ -158,68 +154,54 @@ struct a2150_private {
 /* interrupt service routine */
 static irqreturn_t a2150_interrupt(int irq, void *d)
 {
-	int i;
-	int status;
-	unsigned long flags;
 	struct comedi_device *dev = d;
 	struct a2150_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[0];
 	struct comedi_subdevice *s = dev->read_subdev;
-	struct comedi_async *async;
-	struct comedi_cmd *cmd;
+	struct comedi_async *async = s->async;
+	struct comedi_cmd *cmd = &async->cmd;
+	unsigned short *buf = desc->virt_addr;
 	unsigned int max_points, num_points, residue, leftover;
 	unsigned short dpnt;
+	int status;
+	int i;
 
-	if (!dev->attached) {
-		dev_err(dev->class_dev, "premature interrupt\n");
+	if (!dev->attached)
 		return IRQ_HANDLED;
-	}
-	/*  initialize async here to make sure s is not NULL */
-	async = s->async;
-	cmd = &async->cmd;
 
 	status = inw(dev->iobase + STATUS_REG);
-
-	if ((status & INTR_BIT) == 0) {
-		dev_err(dev->class_dev, "spurious interrupt\n");
+	if ((status & INTR_BIT) == 0)
 		return IRQ_NONE;
-	}
 
 	if (status & OVFL_BIT) {
-		dev_err(dev->class_dev, "fifo overflow\n");
-		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
 		comedi_handle_events(dev, s);
 	}
 
 	if ((status & DMA_TC_BIT) == 0) {
-		dev_err(dev->class_dev,
-			"caught non-dma interrupt?  Aborting.\n");
-		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
 		comedi_handle_events(dev, s);
 		return IRQ_HANDLED;
 	}
 
-	flags = claim_dma_lock();
-	disable_dma(devpriv->dma);
-	/* clear flip-flop to make sure 2-byte registers for
-	 * count and address get set correctly */
-	clear_dma_ff(devpriv->dma);
-
-	/*  figure out how many points to read */
-	max_points = comedi_bytes_to_samples(s, devpriv->dma_transfer_size);
-	/* residue is the number of points left to be done on the dma
+	/*
+	 * residue is the number of bytes left to be done on the dma
 	 * transfer.  It should always be zero at this point unless
 	 * the stop_src is set to external triggering.
 	 */
-	residue = comedi_bytes_to_samples(s, get_dma_residue(devpriv->dma));
-	num_points = max_points - residue;
+	residue = comedi_isadma_disable(desc->chan);
+
+	/*  figure out how many points to read */
+	max_points = comedi_bytes_to_samples(s, desc->size);
+	num_points = max_points - comedi_bytes_to_samples(s, residue);
 	if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
 		num_points = devpriv->count;
 
 	/*  figure out how many points will be stored next time */
 	leftover = 0;
 	if (cmd->stop_src == TRIG_NONE) {
-		leftover = comedi_bytes_to_samples(s,
-						   devpriv->dma_transfer_size);
+		leftover = comedi_bytes_to_samples(s, desc->size);
 	} else if (devpriv->count > max_points) {
 		leftover = devpriv->count - max_points;
 		if (leftover > max_points)
@@ -234,7 +216,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
 
 	for (i = 0; i < num_points; i++) {
 		/* write data point to comedi buffer */
-		dpnt = devpriv->dma_buffer[i];
+		dpnt = buf[i];
 		/*  convert from 2's complement to unsigned coding */
 		dpnt ^= 0x8000;
 		comedi_buf_write_samples(s, &dpnt, 1);
@@ -245,14 +227,11 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
 			}
 		}
 	}
-	/*  re-enable  dma */
+	/* re-enable dma */
 	if (leftover) {
-		set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
-		set_dma_count(devpriv->dma,
-			      comedi_samples_to_bytes(s, leftover));
-		enable_dma(devpriv->dma);
+		desc->size = comedi_samples_to_bytes(s, leftover);
+		comedi_isadma_program(desc);
 	}
-	release_dma_lock(flags);
 
 	comedi_handle_events(dev, s);
 
@@ -265,13 +244,15 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct a2150_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[0];
 
 	/*  disable dma on card */
 	devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
 	outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
 
 	/*  disable computer's dma */
-	disable_dma(devpriv->dma);
+	comedi_isadma_disable(desc->chan);
 
 	/*  clear fifo and reset triggering circuitry */
 	outw(0, dev->iobase + FIFO_RESET_REG);
@@ -503,10 +484,11 @@ static int a2150_ai_cmdtest(struct comedi_device *dev,
 static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct a2150_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[0];
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
 	unsigned long timer_base = dev->iobase + I8253_BASE_REG;
-	unsigned long lock_flags;
 	unsigned int old_config_bits = devpriv->config_bits;
 	unsigned int trigger_bits;
 
@@ -542,27 +524,19 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	/*  initialize number of samples remaining */
 	devpriv->count = cmd->stop_arg * cmd->chanlist_len;
 
-	/*  enable computer's dma */
-	lock_flags = claim_dma_lock();
-	disable_dma(devpriv->dma);
-	/* clear flip-flop to make sure 2-byte registers for
-	 * count and address get set correctly */
-	clear_dma_ff(devpriv->dma);
-	set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
+	comedi_isadma_disable(desc->chan);
+
 	/*  set size of transfer to fill in 1/3 second */
 #define ONE_THIRD_SECOND 333333333
-	devpriv->dma_transfer_size =
-	    sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
-	    ONE_THIRD_SECOND / cmd->scan_begin_arg;
-	if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
-		devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
-	if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
-		devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
-	devpriv->dma_transfer_size -=
-	    devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
-	set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
-	enable_dma(devpriv->dma);
-	release_dma_lock(lock_flags);
+	desc->size = comedi_bytes_per_sample(s) * cmd->chanlist_len *
+		    ONE_THIRD_SECOND / cmd->scan_begin_arg;
+	if (desc->size > desc->maxsize)
+		desc->size = desc->maxsize;
+	if (desc->size < comedi_bytes_per_sample(s))
+		desc->size = comedi_bytes_per_sample(s);
+	desc->size -= desc->size % comedi_bytes_per_sample(s);
+
+	comedi_isadma_program(desc);
 
 	/* clear dma interrupt before enabling it, to try and get rid of that
 	 * one spurious interrupt that has been happening */
@@ -677,6 +651,45 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	return n;
 }
 
+static void a2150_alloc_irq_and_dma(struct comedi_device *dev,
+				    struct comedi_devconfig *it)
+{
+	struct a2150_private *devpriv = dev->private;
+	unsigned int irq_num = it->options[1];
+	unsigned int dma_chan = it->options[2];
+
+	/*
+	 * Only IRQs 15, 14, 12-9, and 7-3 are valid.
+	 * Only DMA channels 7-5 and 3-0 are valid.
+	 */
+	if (irq_num > 15 || dma_chan > 7 ||
+	    !((1 << irq_num) & 0xdef8) || !((1 << dma_chan) & 0xef))
+		return;
+
+	if (request_irq(irq_num, a2150_interrupt, 0, dev->board_name, dev))
+		return;
+
+	/* DMA uses 1 buffer */
+	devpriv->dma = comedi_isadma_alloc(dev, 1, dma_chan, dma_chan,
+					   A2150_DMA_BUFFER_SIZE,
+					   COMEDI_ISADMA_READ);
+	if (!devpriv->dma) {
+		free_irq(irq_num, dev);
+	} else {
+		dev->irq = irq_num;
+		devpriv->irq_dma_bits = IRQ_LVL_BITS(irq_num) |
+					DMA_CHAN_BITS(dma_chan);
+	}
+}
+
+static void a2150_free_dma(struct comedi_device *dev)
+{
+	struct a2150_private *devpriv = dev->private;
+
+	if (devpriv)
+		comedi_isadma_free(devpriv->dma);
+}
+
 /* probes board type, returns offset */
 static int a2150_probe(struct comedi_device *dev)
 {
@@ -690,8 +703,6 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	const struct a2150_board *thisboard;
 	struct a2150_private *devpriv;
 	struct comedi_subdevice *s;
-	unsigned int irq = it->options[1];
-	unsigned int dma = it->options[2];
 	static const int timeout = 2000;
 	int i;
 	int ret;
@@ -712,31 +723,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	thisboard = dev->board_ptr;
 	dev->board_name = thisboard->name;
 
-	if ((irq >= 3 && irq <= 7) || (irq >= 9 && irq <= 12) ||
-	    irq == 14 || irq == 15) {
-		ret = request_irq(irq, a2150_interrupt, 0,
-				  dev->board_name, dev);
-		if (ret == 0) {
-			devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
-			dev->irq = irq;
-		}
-	}
-
-	if (dev->irq && dma <= 7 && dma != 4) {
-		ret = request_dma(dma, dev->board_name);
-		if (ret == 0) {
-			devpriv->dma = dma;
-			devpriv->dma_buffer = kmalloc(A2150_DMA_BUFFER_SIZE,
-						      GFP_KERNEL | GFP_DMA);
-			if (!devpriv->dma_buffer)
-				return -ENOMEM;
-
-			disable_dma(dma);
-			set_dma_mode(dma, DMA_MODE_READ);
-
-			devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
-		}
-	}
+	/* an IRQ and DMA are required to support async commands */
+	a2150_alloc_irq_and_dma(dev, it);
 
 	ret = comedi_alloc_subdevices(dev, 1);
 	if (ret)
@@ -750,7 +738,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	s->maxdata = 0xffff;
 	s->range_table = &range_a2150;
 	s->insn_read = a2150_ai_rinsn;
-	if (dev->irq && devpriv->dma) {
+	if (dev->irq) {
 		dev->read_subdev = s;
 		s->subdev_flags |= SDF_CMD_READ;
 		s->len_chanlist = s->n_chan;
@@ -791,15 +779,9 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 static void a2150_detach(struct comedi_device *dev)
 {
-	struct a2150_private *devpriv = dev->private;
-
 	if (dev->iobase)
 		outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
-	if (devpriv) {
-		if (devpriv->dma)
-			free_dma(devpriv->dma);
-		kfree(devpriv->dma_buffer);
-	}
+	a2150_free_dma(dev);
 	comedi_legacy_detach(dev);
 };
 
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
index 05370a4a74a5..9eeaf3c5a858 100644
--- a/drivers/staging/comedi/drivers/ni_at_ao.c
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -19,8 +19,7 @@
 /*
  * Driver: ni_at_ao
  * Description: National Instruments AT-AO-6/10
- * Devices: (National Instruments) AT-AO-6 [at-ao-6]
- *          (National Instruments) AT-AO-10 [at-ao-10]
+ * Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
  * Status: should work
  * Author: David A. Schleef <ds@schleef.org>
  * Updated: Sun Dec 26 12:26:28 EST 2004
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
index 0c5ff287dcef..301f154be813 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -300,7 +300,6 @@ static int ni_atmio_attach(struct comedi_device *dev,
 			   struct comedi_devconfig *it)
 {
 	const struct ni_board_struct *boardtype;
-	struct ni_private *devpriv;
 	struct pnp_dev *isapnp_dev;
 	int ret;
 	unsigned long iobase;
@@ -310,7 +309,6 @@ static int ni_atmio_attach(struct comedi_device *dev,
 	ret = ni_alloc_private(dev);
 	if (ret)
 		return ret;
-	devpriv = dev->private;
 
 	iobase = it->options[0];
 	irq = it->options[1];
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index 5e472cb7fbd7..8f6396edd21c 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -51,10 +51,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 
-#include "../comedidev.h"
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
+#include "../comedi_pcmcia.h"
 
 /* daqcard700 registers */
 #define DIO_W		0x04	/* WO 8bit */
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index 8cfabdbaa30c..a208cb348437 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -32,11 +32,7 @@ the PCMCIA interface.
 */
 
 #include <linux/module.h>
-#include "../comedidev.h"
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
+#include "../comedi_pcmcia.h"
 
 #include "8255.h"
 
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index 1fbfdb4c80c0..a916047791b8 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -17,9 +17,8 @@
 /*
  * Driver: ni_labpc
  * Description: National Instruments Lab-PC (& compatibles)
- * Devices: (National Instruments) Lab-PC-1200 [lab-pc-1200]
- *	    (National Instruments) Lab-PC-1200AI [lab-pc-1200ai]
- *	    (National Instruments) Lab-PC+ [lab-pc+]
+ * Devices: [National Instruments] Lab-PC-1200 (lab-pc-1200),
+ *   Lab-PC-1200AI (lab-pc-1200ai), Lab-PC+ (lab-pc+)
  * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
  * Status: works
  *
@@ -85,15 +84,10 @@ static const struct labpc_boardinfo labpc_boards[] = {
 
 static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-	struct labpc_private *devpriv;
 	unsigned int irq = it->options[1];
 	unsigned int dma_chan = it->options[2];
 	int ret;
 
-	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-	if (!devpriv)
-		return -ENOMEM;
-
 	ret = comedi_request_region(dev, it->options[0], 0x20);
 	if (ret)
 		return ret;
@@ -110,11 +104,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 static void labpc_detach(struct comedi_device *dev)
 {
-	struct labpc_private *devpriv = dev->private;
-
-	if (devpriv)
-		labpc_free_dma_chan(dev);
-
+	labpc_free_dma_chan(dev);
 	comedi_legacy_detach(dev);
 }
 
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
index ac2c01f9dfdc..be89ae479afc 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.h
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -35,6 +35,8 @@ struct labpc_boardinfo {
 };
 
 struct labpc_private {
+	struct comedi_isadma *dma;
+
 	/*  number of data points left to be taken */
 	unsigned long long count;
 	/*  software copys of bits written to command registers */
@@ -61,11 +63,7 @@ struct labpc_private {
 	 * conversions
 	 */
 	unsigned int divisor_b1;
-	unsigned int dma_chan;	/*  dma channel to use */
-	u16 *dma_buffer;	/*  buffer ai will dma into */
-	phys_addr_t dma_addr;
-	/* transfer size in bytes for current transfer */
-	unsigned int dma_transfer_size;
+
 	/* we are using dma/fifo-half-full/etc. */
 	enum transfer_type current_transfer;
 	/*
diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c
index d89d5852aeea..b88ee2614bfe 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_common.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_common.c
@@ -368,10 +368,6 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
 			     enum scan_mode mode)
 {
 	struct labpc_private *devpriv = dev->private;
-	/* max value for 16 bit counter in mode 2 */
-	const int max_counter_value = 0x10000;
-	/* min value for 16 bit counter in mode 2 */
-	const int min_counter_value = 2;
 	unsigned int base_period;
 	unsigned int scan_period;
 	unsigned int convert_period;
@@ -388,11 +384,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
 		 * clock speed on convert and scan counters)
 		 */
 		devpriv->divisor_b0 = (scan_period - 1) /
-		    (I8254_OSC_BASE_2MHZ * max_counter_value) + 1;
-		if (devpriv->divisor_b0 < min_counter_value)
-			devpriv->divisor_b0 = min_counter_value;
-		if (devpriv->divisor_b0 > max_counter_value)
-			devpriv->divisor_b0 = max_counter_value;
+		    (I8254_OSC_BASE_2MHZ * 0x10000) + 1;
+
+		cfc_check_trigger_arg_min(&devpriv->divisor_b0, 2);
+		cfc_check_trigger_arg_max(&devpriv->divisor_b0, 0x10000);
 
 		base_period = I8254_OSC_BASE_2MHZ * devpriv->divisor_b0;
 
@@ -400,16 +395,16 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
 		switch (cmd->flags & CMDF_ROUND_MASK) {
 		default:
 		case CMDF_ROUND_NEAREST:
-			devpriv->divisor_a0 =
-			    (convert_period + (base_period / 2)) / base_period;
-			devpriv->divisor_b1 =
-			    (scan_period + (base_period / 2)) / base_period;
+			devpriv->divisor_a0 = DIV_ROUND_CLOSEST(convert_period,
+								base_period);
+			devpriv->divisor_b1 = DIV_ROUND_CLOSEST(scan_period,
+								base_period);
 			break;
 		case CMDF_ROUND_UP:
-			devpriv->divisor_a0 =
-			    (convert_period + (base_period - 1)) / base_period;
-			devpriv->divisor_b1 =
-			    (scan_period + (base_period - 1)) / base_period;
+			devpriv->divisor_a0 = DIV_ROUND_UP(convert_period,
+							   base_period);
+			devpriv->divisor_b1 = DIV_ROUND_UP(scan_period,
+							   base_period);
 			break;
 		case CMDF_ROUND_DOWN:
 			devpriv->divisor_a0 = convert_period / base_period;
@@ -417,14 +412,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
 			break;
 		}
 		/*  make sure a0 and b1 values are acceptable */
-		if (devpriv->divisor_a0 < min_counter_value)
-			devpriv->divisor_a0 = min_counter_value;
-		if (devpriv->divisor_a0 > max_counter_value)
-			devpriv->divisor_a0 = max_counter_value;
-		if (devpriv->divisor_b1 < min_counter_value)
-			devpriv->divisor_b1 = min_counter_value;
-		if (devpriv->divisor_b1 > max_counter_value)
-			devpriv->divisor_b1 = max_counter_value;
+		cfc_check_trigger_arg_min(&devpriv->divisor_a0, 2);
+		cfc_check_trigger_arg_max(&devpriv->divisor_a0, 0x10000);
+		cfc_check_trigger_arg_min(&devpriv->divisor_b1, 2);
+		cfc_check_trigger_arg_max(&devpriv->divisor_b1, 0x10000);
 		/*  write corrected timings to command */
 		labpc_set_ai_convert_period(cmd, mode,
 					    base_period * devpriv->divisor_a0);
@@ -687,7 +678,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	}
 
 	/* figure out what method we will use to transfer data */
-	if (labpc_have_dma_chan(dev) &&
+	if (devpriv->dma &&
 	    /* dma unsafe at RT priority,
 	     * and too much setup time for CMDF_WAKE_EOS */
 	    (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0)
@@ -823,7 +814,7 @@ static int labpc_drain_fifo(struct comedi_device *dev)
 	}
 	if (i == timeout) {
 		dev_err(dev->class_dev, "ai timeout, fifo never empties\n");
-		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
 		return -1;
 	}
 
@@ -875,7 +866,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
 	if (devpriv->stat1 & STAT1_OVERRUN) {
 		/* clear error interrupt */
 		devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
-		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
 		comedi_handle_events(dev, s);
 		dev_err(dev->class_dev, "overrun\n");
 		return IRQ_HANDLED;
@@ -895,7 +886,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
 	if (devpriv->stat1 & STAT1_OVERFLOW) {
 		/*  clear error interrupt */
 		devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
-		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		async->events |= COMEDI_CB_ERROR;
 		comedi_handle_events(dev, s);
 		dev_err(dev->class_dev, "overflow\n");
 		return IRQ_HANDLED;
@@ -1215,11 +1206,15 @@ int labpc_common_attach(struct comedi_device *dev,
 			unsigned int irq, unsigned long isr_flags)
 {
 	const struct labpc_boardinfo *board = dev->board_ptr;
-	struct labpc_private *devpriv = dev->private;
+	struct labpc_private *devpriv;
 	struct comedi_subdevice *s;
 	int ret;
 	int i;
 
+	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+	if (!devpriv)
+		return -ENOMEM;
+
 	if (dev->mmio) {
 		devpriv->read_byte = labpc_readb;
 		devpriv->write_byte = labpc_writeb;
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index 0a8b3223f74e..746c4cd9978d 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -54,19 +54,11 @@ NI manuals:
 */
 
 #include <linux/module.h>
-#include "../comedidev.h"
 
-#include <linux/delay.h>
+#include "../comedi_pcmcia.h"
 
-#include "8253.h"
-#include "8255.h"
-#include "comedi_fc.h"
 #include "ni_labpc.h"
 
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-
 static const struct labpc_boardinfo labpc_cs_boards[] = {
 	{
 		.name			= "daqcard-1200",
@@ -80,7 +72,6 @@ static int labpc_auto_attach(struct comedi_device *dev,
 			     unsigned long context)
 {
 	struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
-	struct labpc_private *devpriv;
 	int ret;
 
 	/* The ni_labpc driver needs the board_ptr */
@@ -96,10 +87,6 @@ static int labpc_auto_attach(struct comedi_device *dev,
 	if (!link->irq)
 		return -EINVAL;
 
-	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-	if (!devpriv)
-		return -ENOMEM;
-
 	return labpc_common_attach(dev, link->irq, IRQF_SHARED);
 }
 
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
index 6d386050e59d..6b4ccd86b3d0 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c
@@ -19,23 +19,25 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
-#include "../comedidev.h"
 
-#include <asm/dma.h>
+#include "../comedidev.h"
 
+#include "comedi_isadma.h"
 #include "comedi_fc.h"
 #include "ni_labpc.h"
 #include "ni_labpc_regs.h"
 #include "ni_labpc_isadma.h"
 
 /* size in bytes of dma buffer */
-static const int dma_buffer_size = 0xff00;
-/* 2 bytes per sample */
-static const int sample_size = 2;
+#define LABPC_ISADMA_BUFFER_SIZE	0xff00
 
 /* utility function that suggests a dma transfer size in bytes */
-static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
+static unsigned int labpc_suggest_transfer_size(struct comedi_device *dev,
+						struct comedi_subdevice *s,
+						unsigned int maxbytes)
 {
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int sample_size = comedi_bytes_per_sample(s);
 	unsigned int size;
 	unsigned int freq;
 
@@ -49,8 +51,8 @@ static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
 	size = (freq / 3) * sample_size;
 
 	/* set a minimum and maximum size allowed */
-	if (size > dma_buffer_size)
-		size = dma_buffer_size - dma_buffer_size % sample_size;
+	if (size > maxbytes)
+		size = maxbytes;
 	else if (size < sample_size)
 		size = sample_size;
 
@@ -60,23 +62,18 @@ static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
 void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct labpc_private *devpriv = dev->private;
+	struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
 	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned long irq_flags;
-
-	irq_flags = claim_dma_lock();
-	disable_dma(devpriv->dma_chan);
-	/* clear flip-flop to make sure 2-byte registers for
-	 * count and address get set correctly */
-	clear_dma_ff(devpriv->dma_chan);
-	set_dma_addr(devpriv->dma_chan, devpriv->dma_addr);
+	unsigned int sample_size = comedi_bytes_per_sample(s);
+
 	/* set appropriate size of transfer */
-	devpriv->dma_transfer_size = labpc_suggest_transfer_size(cmd);
+	desc->size = labpc_suggest_transfer_size(dev, s, desc->maxsize);
 	if (cmd->stop_src == TRIG_COUNT &&
-	    devpriv->count * sample_size < devpriv->dma_transfer_size)
-		devpriv->dma_transfer_size = devpriv->count * sample_size;
-	set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
-	enable_dma(devpriv->dma_chan);
-	release_dma_lock(irq_flags);
+	    devpriv->count * sample_size < desc->size)
+		desc->size = devpriv->count * sample_size;
+
+	comedi_isadma_program(desc);
+
 	/* set CMD3 bits for caller to enable DMA and interrupt */
 	devpriv->cmd3 |= (CMD3_DMAEN | CMD3_DMATCINTEN);
 }
@@ -85,61 +82,55 @@ EXPORT_SYMBOL_GPL(labpc_setup_dma);
 void labpc_drain_dma(struct comedi_device *dev)
 {
 	struct labpc_private *devpriv = dev->private;
+	struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
 	struct comedi_subdevice *s = dev->read_subdev;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
-	int status;
-	unsigned long flags;
-	unsigned int max_points, num_points, residue, leftover;
+	unsigned int max_samples = comedi_bytes_to_samples(s, desc->size);
+	unsigned int residue;
+	unsigned int nsamples;
+	unsigned int leftover;
 
-	status = devpriv->stat1;
-
-	flags = claim_dma_lock();
-	disable_dma(devpriv->dma_chan);
-	/* clear flip-flop to make sure 2-byte registers for
-	 * count and address get set correctly */
-	clear_dma_ff(devpriv->dma_chan);
-
-	/* figure out how many points to read */
-	max_points = devpriv->dma_transfer_size / sample_size;
-	/* residue is the number of points left to be done on the dma
+	/*
+	 * residue is the number of bytes left to be done on the dma
 	 * transfer.  It should always be zero at this point unless
 	 * the stop_src is set to external triggering.
 	 */
-	residue = get_dma_residue(devpriv->dma_chan) / sample_size;
-	num_points = max_points - residue;
-	if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_points)
-		num_points = devpriv->count;
-
-	/* figure out how many points will be stored next time */
-	leftover = 0;
-	if (cmd->stop_src != TRIG_COUNT) {
-		leftover = devpriv->dma_transfer_size / sample_size;
-	} else if (devpriv->count > num_points) {
-		leftover = devpriv->count - num_points;
-		if (leftover > max_points)
-			leftover = max_points;
-	}
-
-	comedi_buf_write_samples(s, devpriv->dma_buffer, num_points);
+	residue = comedi_isadma_disable(desc->chan);
 
-	if (cmd->stop_src == TRIG_COUNT)
-		devpriv->count -= num_points;
+	/*
+	 * Figure out how many samples to read for this transfer and
+	 * how many will be stored for next time.
+	 */
+	nsamples = max_samples - comedi_bytes_to_samples(s, residue);
+	if (cmd->stop_src == TRIG_COUNT) {
+		if (devpriv->count <= nsamples) {
+			nsamples = devpriv->count;
+			leftover = 0;
+		} else {
+			leftover = devpriv->count - nsamples;
+			if (leftover > max_samples)
+				leftover = max_samples;
+		}
+		devpriv->count -= nsamples;
+	} else {
+		leftover = max_samples;
+	}
+	desc->size = comedi_samples_to_bytes(s, leftover);
 
-	/* set address and count for next transfer */
-	set_dma_addr(devpriv->dma_chan, devpriv->dma_addr);
-	set_dma_count(devpriv->dma_chan, leftover * sample_size);
-	release_dma_lock(flags);
+	comedi_buf_write_samples(s, desc->virt_addr, nsamples);
 }
 EXPORT_SYMBOL_GPL(labpc_drain_dma);
 
 static void handle_isa_dma(struct comedi_device *dev)
 {
 	struct labpc_private *devpriv = dev->private;
+	struct comedi_isadma_desc *desc = &devpriv->dma->desc[0];
 
 	labpc_drain_dma(dev);
 
-	enable_dma(devpriv->dma_chan);
+	if (desc->size)
+		comedi_isadma_program(desc);
 
 	/* clear dma tc interrupt */
 	devpriv->write_byte(dev, 0x1, DMATC_CLEAR_REG);
@@ -160,36 +151,18 @@ void labpc_handle_dma_status(struct comedi_device *dev)
 }
 EXPORT_SYMBOL_GPL(labpc_handle_dma_status);
 
-int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan)
+void labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan)
 {
 	struct labpc_private *devpriv = dev->private;
-	void *dma_buffer;
-	unsigned long dma_flags;
-	int ret;
 
+	/* only DMA channels 3 and 1 are valid */
 	if (dma_chan != 1 && dma_chan != 3)
-		return -EINVAL;
-
-	dma_buffer = kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
-	if (!dma_buffer)
-		return -ENOMEM;
-
-	ret = request_dma(dma_chan, dev->board_name);
-	if (ret) {
-		kfree(dma_buffer);
-		return ret;
-	}
-
-	devpriv->dma_buffer = dma_buffer;
-	devpriv->dma_chan = dma_chan;
-	devpriv->dma_addr = virt_to_bus(devpriv->dma_buffer);
-
-	dma_flags = claim_dma_lock();
-	disable_dma(devpriv->dma_chan);
-	set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
-	release_dma_lock(dma_flags);
+		return;
 
-	return 0;
+	/* DMA uses 1 buffer */
+	devpriv->dma = comedi_isadma_alloc(dev, 1, dma_chan, dma_chan,
+					   LABPC_ISADMA_BUFFER_SIZE,
+					   COMEDI_ISADMA_READ);
 }
 EXPORT_SYMBOL_GPL(labpc_init_dma_chan);
 
@@ -197,12 +170,8 @@ void labpc_free_dma_chan(struct comedi_device *dev)
 {
 	struct labpc_private *devpriv = dev->private;
 
-	kfree(devpriv->dma_buffer);
-	devpriv->dma_buffer = NULL;
-	if (devpriv->dma_chan) {
-		free_dma(devpriv->dma_chan);
-		devpriv->dma_chan = 0;
-	}
+	if (devpriv)
+		comedi_isadma_free(devpriv->dma);
 }
 EXPORT_SYMBOL_GPL(labpc_free_dma_chan);
 
diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.h b/drivers/staging/comedi/drivers/ni_labpc_isadma.h
index 771af4bd5a76..b8a1b0ee6290 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_isadma.h
+++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.h
@@ -5,18 +5,9 @@
 #ifndef _NI_LABPC_ISADMA_H
 #define _NI_LABPC_ISADMA_H
 
-#define NI_LABPC_HAVE_ISA_DMA	IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISADMA)
+#if IS_ENABLED(CONFIG_COMEDI_NI_LABPC_ISADMA)
 
-#if NI_LABPC_HAVE_ISA_DMA
-
-static inline bool labpc_have_dma_chan(struct comedi_device *dev)
-{
-	struct labpc_private *devpriv = dev->private;
-
-	return (bool)devpriv->dma_chan;
-}
-
-int labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan);
+void labpc_init_dma_chan(struct comedi_device *dev, unsigned int dma_chan);
 void labpc_free_dma_chan(struct comedi_device *dev);
 void labpc_setup_dma(struct comedi_device *dev, struct comedi_subdevice *s);
 void labpc_drain_dma(struct comedi_device *dev);
@@ -24,15 +15,9 @@ void labpc_handle_dma_status(struct comedi_device *dev);
 
 #else
 
-static inline bool labpc_have_dma_chan(struct comedi_device *dev)
-{
-	return false;
-}
-
-static inline int labpc_init_dma_chan(struct comedi_device *dev,
-				      unsigned int dma_chan)
+static inline void labpc_init_dma_chan(struct comedi_device *dev,
+				       unsigned int dma_chan)
 {
-	return -ENOTSUPP;
 }
 
 static inline void labpc_free_dma_chan(struct comedi_device *dev)
diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c
index 3fc420406564..0407ff681dfd 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_pci.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c
@@ -17,7 +17,7 @@
 /*
  * Driver: ni_labpc_pci
  * Description: National Instruments Lab-PC PCI-1200
- * Devices: (National Instruments) PCI-1200 [ni_pci-1200]
+ * Devices: [National Instruments] PCI-1200 (ni_pci-1200)
  * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
  * Status: works
  *
@@ -79,7 +79,6 @@ static int labpc_pci_auto_attach(struct comedi_device *dev,
 {
 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 	const struct labpc_boardinfo *board = NULL;
-	struct labpc_private *devpriv;
 	int ret;
 
 	if (context < ARRAY_SIZE(labpc_pci_boards))
@@ -101,10 +100,6 @@ static int labpc_pci_auto_attach(struct comedi_device *dev,
 	if (!dev->mmio)
 		return -ENOMEM;
 
-	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-	if (!devpriv)
-		return -ENOMEM;
-
 	return labpc_common_attach(dev, pcidev->irq, IRQF_SHARED);
 }
 
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index 11e70173712d..b6ddc015dedf 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -1478,7 +1478,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
 		dev_err(dev->class_dev,
 			"unknown mite interrupt (ai_mite_status=%08x)\n",
 			ai_mite_status);
-		s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+		s->async->events |= COMEDI_CB_ERROR;
 		/* disable_irq(dev->irq); */
 	}
 #endif
@@ -1491,8 +1491,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
 			/* we probably aren't even running a command now,
 			 * so it's a good idea to be careful. */
 			if (comedi_is_subdevice_running(s)) {
-				s->async->events |=
-				    COMEDI_CB_ERROR | COMEDI_CB_EOA;
+				s->async->events |= COMEDI_CB_ERROR;
 				comedi_handle_events(dev, s);
 			}
 			return;
@@ -1579,7 +1578,7 @@ static void handle_b_interrupt(struct comedi_device *dev,
 		dev_err(dev->class_dev,
 			"unknown mite interrupt (ao_mite_status=%08x)\n",
 			ao_mite_status);
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		s->async->events |= COMEDI_CB_ERROR;
 	}
 #endif
 
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index 9b201e48233e..e3d821bf2d6a 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -37,16 +37,12 @@ See the notes in the ni_atmio.o driver.
 */
 
 #include <linux/module.h>
-#include "../comedidev.h"
-
 #include <linux/delay.h>
 
+#include "../comedi_pcmcia.h"
 #include "ni_stc.h"
 #include "8255.h"
 
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-
 /*
  *  AT specific setup
  */
@@ -163,7 +159,6 @@ static int mio_cs_auto_attach(struct comedi_device *dev,
 {
 	struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
 	static const struct ni_board_struct *board;
-	struct ni_private *devpriv;
 	int ret;
 
 	board = ni_getboardtype(dev, link);
@@ -188,8 +183,6 @@ static int mio_cs_auto_attach(struct comedi_device *dev,
 	if (ret)
 		return ret;
 
-	devpriv = dev->private;
-
 	return ni_E_init(dev, 0, 1);
 }
 
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index db7e8aac67b5..db399fe8c301 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -418,7 +418,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 				 CHSR_DRQ1 | CHSR_MRDY)) {
 			dev_dbg(dev->class_dev,
 				"unknown mite interrupt, disabling IRQ\n");
-			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+			async->events |= COMEDI_CB_ERROR;
 			disable_irq(dev->irq);
 		}
 	}
@@ -460,7 +460,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 			break;
 		} else if (flags & Waited) {
 			writeb(ClearWaited, dev->mmio + Group_1_First_Clear);
-			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+			async->events |= COMEDI_CB_ERROR;
 			break;
 		} else if (flags & PrimaryTC) {
 			writeb(ClearPrimaryTC,
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
index 0525292c1d8b..c20c51bef3e7 100644
--- a/drivers/staging/comedi/drivers/ni_tio.c
+++ b/drivers/staging/comedi/drivers/ni_tio.c
@@ -16,29 +16,28 @@
 */
 
 /*
-Driver: ni_tio
-Description: National Instruments general purpose counters
-Devices:
-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: Thu Nov 16 09:50:32 EST 2006
-Status: works
-
-This module is not used directly by end-users.  Rather, it
-is used by other drivers (for example ni_660x and ni_pcimio)
-to provide support for NI's general purpose counters.  It was
-originally based on the counter code from ni_660x.c and
-ni_mio_common.c.
-
-References:
-DAQ 660x Register-Level Programmer Manual  (NI 370505A-01)
-DAQ 6601/6602 User Manual (NI 322137B-01)
-340934b.pdf  DAQ-STC reference manual
+ * Module: ni_tio
+ * Description: National Instruments general purpose counters
+ * 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: Thu Nov 16 09:50:32 EST 2006
+ * Status: works
+ *
+ * This module is not used directly by end-users.  Rather, it
+ * is used by other drivers (for example ni_660x and ni_pcimio)
+ * to provide support for NI's general purpose counters.  It was
+ * originally based on the counter code from ni_660x.c and
+ * ni_mio_common.c.
+ *
+ * References:
+ * DAQ 660x Register-Level Programmer Manual  (NI 370505A-01)
+ * DAQ 6601/6602 User Manual (NI 322137B-01)
+ * 340934b.pdf  DAQ-STC reference manual
+ */
 
-*/
 /*
 TODO:
 	Support use of both banks X and Y
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
index 6037bec77ef1..d36c3abd3120 100644
--- a/drivers/staging/comedi/drivers/ni_tiocmd.c
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -16,29 +16,28 @@
 */
 
 /*
-Driver: ni_tiocmd
-Description: National Instruments general purpose counters command support
-Devices:
-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, 11 Apr 2008 12:32:35 +0100
-Status: works
-
-This module is not used directly by end-users.  Rather, it
-is used by other drivers (for example ni_660x and ni_pcimio)
-to provide command support for NI's general purpose counters.
-It was originally split out of ni_tio.c to stop the 'ni_tio'
-module depending on the 'mite' module.
-
-References:
-DAQ 660x Register-Level Programmer Manual  (NI 370505A-01)
-DAQ 6601/6602 User Manual (NI 322137B-01)
-340934b.pdf  DAQ-STC reference manual
+ * Module: ni_tiocmd
+ * Description: National Instruments general purpose counters command support
+ * 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, 11 Apr 2008 12:32:35 +0100
+ * Status: works
+ *
+ * This module is not used directly by end-users.  Rather, it
+ * is used by other drivers (for example ni_660x and ni_pcimio)
+ * to provide command support for NI's general purpose counters.
+ * It was originally split out of ni_tio.c to stop the 'ni_tio'
+ * module depending on the 'mite' module.
+ *
+ * References:
+ * DAQ 660x Register-Level Programmer Manual  (NI 370505A-01)
+ * DAQ 6601/6602 User Manual (NI 322137B-01)
+ * 340934b.pdf  DAQ-STC reference manual
+ */
 
-*/
 /*
 TODO:
 	Support use of both banks X and Y
diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c
index 3b5a1b90366d..5f649f88d55c 100644
--- a/drivers/staging/comedi/drivers/ni_usb6501.c
+++ b/drivers/staging/comedi/drivers/ni_usb6501.c
@@ -96,9 +96,8 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/usb.h>
 
-#include "../comedidev.h"
+#include "../comedi_usb.h"
 
 #define	NI6501_TIMEOUT	1000
 
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index 938aebc8e0ea..cb7e4c37b8b9 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -22,10 +22,8 @@
 /*
  * Driver: pcl711
  * Description: Advantech PCL-711 and 711b, ADLink ACL-8112
- * Devices: (Advantech) PCL-711 [pcl711]
- *	    (Advantech) PCL-711B [pcl711b]
- *	    (AdLink) ACL-8112HG [acl8112hg]
- *	    (AdLink) ACL-8112DG [acl8112dg]
+ * Devices: [Advantech] PCL-711 (pcl711), PCL-711B (pcl711b),
+ *   [ADLink] ACL-8112HG (acl8112hg), ACL-8112DG (acl8112dg)
  * Author: David A. Schleef <ds@schleef.org>
  *	   Janne Jalkanen <jalkanen@cs.hut.fi>
  *	   Eric Bunn <ebu@cs.hut.fi>
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
index fcc440855e66..74b07e1744c7 100644
--- a/drivers/staging/comedi/drivers/pcl724.c
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -8,14 +8,10 @@
 /*
  * Driver: pcl724
  * Description: Comedi driver for 8255 based ISA DIO boards
- * Devices: (Advantech) PCL-724 [pcl724]
- *	    (Advantech) PCL-722 [pcl722]
- *	    (Advantech) PCL-731 [pcl731]
- *	    (ADLink) ACL-7122 [acl7122]
- *	    (ADLink) ACL-7124 [acl7124]
- *	    (ADLink) PET-48DIO [pet48dio]
- *	    (WinSystems) PCM-IO48 [pcmio48]
- *	    (Diamond Systems) ONYX-MM-DIO [onyx-mm-dio]
+ * Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
+ *  [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio),
+ *  [WinSystems] PCM-IO48 (pcmio48),
+ *  [Diamond Systems] ONYX-MM-DIO (onyx-mm-dio)
  * Author: Michal Dobes <dobes@tesnet.cz>
  * Status: untested
  *
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
index 86f713fdf1d0..40798150cfd8 100644
--- a/drivers/staging/comedi/drivers/pcl726.c
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -21,11 +21,8 @@
  * Description: Advantech PCL-726 & compatibles
  * Author: David A. Schleef <ds@schleef.org>
  * Status: untested
- * Devices: (Advantech) PCL-726 [pcl726]
- *	    (Advantech) PCL-727 [pcl727]
- *	    (Advantech) PCL-728 [pcl728]
- *	    (ADLink) ACL-6126 [acl6126]
- *	    (ADLink) ACL-6128 [acl6128]
+ * Devices: [Advantech] PCL-726 (pcl726), PCL-727 (pcl727), PCL-728 (pcl728),
+ *   [ADLink] ACL-6126 (acl6126), ACL-6128 (acl6128)
  *
  * Configuration Options:
  *   [0]  - IO Base
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
index a6c5770b2808..ce958eef2a61 100644
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -7,19 +7,12 @@
 /*
  * Driver: pcl730
  * Description: Advantech PCL-730 (& compatibles)
- * Devices: (Advantech) PCL-730 [pcl730]
- *	    (ICP) ISO-730 [iso730]
- *	    (Adlink) ACL-7130 [acl7130]
- *	    (Advantech) PCM-3730 [pcm3730]
- *	    (Advantech) PCL-725 [pcl725]
- *	    (ICP) P8R8-DIO [p16r16dio]
- *	    (Adlink) ACL-7225b [acl7225b]
- *	    (ICP) P16R16-DIO [p16r16dio]
- *	    (Advantech) PCL-733 [pcl733]
- *	    (Advantech) PCL-734 [pcl734]
- *	    (Diamond Systems) OPMM-1616-XT [opmm-1616-xt]
- *	    (Diamond Systems) PEARL-MM-P [prearl-mm-p]
- *	    (Diamond Systems) IR104-PBF [ir104-pbf]
+ * Devices: [Advantech] PCL-730 (pcl730), PCM-3730 (pcm3730), PCL-725 (pcl725),
+ *   PCL-733 (pcl733), PCL-734 (pcl734),
+ *   [ADLink] ACL-7130 (acl7130), ACL-7225b (acl7225b),
+ *   [ICP] ISO-730 (iso730), P8R8-DIO (p8r8dio), P16R16-DIO (p16r16dio),
+ *   [Diamond Systems] OPMM-1616-XT (opmm-1616-xt), PEARL-MM-P (pearl-mm-p),
+ *   IR104-PBF (ir104-pbf),
  * Author: José Luis Sánchez (jsanchezv@teleline.es)
  * Status: untested
  *
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index ac243ca5e0f8..3ffb1ea2ecc8 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -111,12 +111,12 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/gfp.h>
-#include "../comedidev.h"
-
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <asm/dma.h>
 
+#include "../comedidev.h"
+
+#include "comedi_isadma.h"
 #include "comedi_fc.h"
 #include "8253.h"
 
@@ -507,19 +507,11 @@ static const struct pcl812_board boardtypes[] = {
 };
 
 struct pcl812_private {
-	unsigned char dma;	/*  >0 use dma ( usedDMA channel) */
+	struct comedi_isadma *dma;
 	unsigned char range_correction;	/*  =1 we must add 1 to range number */
 	unsigned int last_ai_chanspec;
 	unsigned char mode_reg_int;	/*  there is stored INT number for some card */
 	unsigned int ai_poll_ptr;	/*  how many sampes transfer poll */
-	unsigned int dmapages;
-	unsigned int hwdmasize;
-	unsigned long dmabuf[2];	/*  PTR to DMA buf */
-	unsigned int hwdmaptr[2];	/*  HW PTR to DMA buf */
-	unsigned int dmabytestomove[2];	/*  how many bytes DMA transfer */
-	int next_dma_buf;	/*  which buffer is next to use */
-	unsigned int dma_runs_to_end;	/*  how many times we must switch DMA buffers */
-	unsigned int last_dma_run;	/*  how many bytes to transfer on last DMA buffer */
 	unsigned int max_812_ai_mode0_rangewait;	/*  setling time for gain */
 	unsigned int divisor1;
 	unsigned int divisor2;
@@ -546,90 +538,32 @@ static void pcl812_start_pacer(struct comedi_device *dev, bool load_timers)
 }
 
 static void pcl812_ai_setup_dma(struct comedi_device *dev,
-				struct comedi_subdevice *s)
+				struct comedi_subdevice *s,
+				unsigned int unread_samples)
 {
 	struct pcl812_private *devpriv = dev->private;
-	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned int dma_flags;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
 	unsigned int bytes;
+	unsigned int max_samples;
+	unsigned int nsamples;
 
-	/*  we use EOS, so adapt DMA buffer to one scan */
-	if (devpriv->ai_eos) {
-		devpriv->dmabytestomove[0] = comedi_bytes_per_scan(s);
-		devpriv->dmabytestomove[1] = comedi_bytes_per_scan(s);
-		devpriv->dma_runs_to_end = 1;
-	} else {
-		devpriv->dmabytestomove[0] = devpriv->hwdmasize;
-		devpriv->dmabytestomove[1] = devpriv->hwdmasize;
-		if (s->async->prealloc_bufsz < devpriv->hwdmasize) {
-			devpriv->dmabytestomove[0] =
-				s->async->prealloc_bufsz;
-			devpriv->dmabytestomove[1] =
-				s->async->prealloc_bufsz;
-		}
-		if (cmd->stop_src == TRIG_NONE) {
-			devpriv->dma_runs_to_end = 1;
-		} else {
-			/*  how many samples we must transfer? */
-			bytes = cmd->stop_arg * comedi_bytes_per_scan(s);
-
-			/*  how many DMA pages we must fill */
-			devpriv->dma_runs_to_end =
-				bytes / devpriv->dmabytestomove[0];
-
-			/* on last dma transfer must be moved */
-			devpriv->last_dma_run =
-				bytes % devpriv->dmabytestomove[0];
-			if (devpriv->dma_runs_to_end == 0)
-				devpriv->dmabytestomove[0] =
-					devpriv->last_dma_run;
-			devpriv->dma_runs_to_end--;
-		}
-	}
-	if (devpriv->dmabytestomove[0] > devpriv->hwdmasize) {
-		devpriv->dmabytestomove[0] = devpriv->hwdmasize;
-		devpriv->ai_eos = 0;
-	}
-	if (devpriv->dmabytestomove[1] > devpriv->hwdmasize) {
-		devpriv->dmabytestomove[1] = devpriv->hwdmasize;
-		devpriv->ai_eos = 0;
-	}
-	devpriv->next_dma_buf = 0;
-	set_dma_mode(devpriv->dma, DMA_MODE_READ);
-	dma_flags = claim_dma_lock();
-	clear_dma_ff(devpriv->dma);
-	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
-	set_dma_count(devpriv->dma, devpriv->dmabytestomove[0]);
-	release_dma_lock(dma_flags);
-	enable_dma(devpriv->dma);
-}
+	comedi_isadma_disable(dma->chan);
 
-static void pcl812_ai_setup_next_dma(struct comedi_device *dev,
-				     struct comedi_subdevice *s)
-{
-	struct pcl812_private *devpriv = dev->private;
-	unsigned long dma_flags;
-
-	devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
-	disable_dma(devpriv->dma);
-	set_dma_mode(devpriv->dma, DMA_MODE_READ);
-	dma_flags = claim_dma_lock();
-	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[devpriv->next_dma_buf]);
-	if (devpriv->ai_eos) {
-		set_dma_count(devpriv->dma,
-			      devpriv->dmabytestomove[devpriv->next_dma_buf]);
-	} else {
-		if (devpriv->dma_runs_to_end) {
-			set_dma_count(devpriv->dma,
-				      devpriv->dmabytestomove[devpriv->
-							      next_dma_buf]);
-		} else {
-			set_dma_count(devpriv->dma, devpriv->last_dma_run);
-		}
-		devpriv->dma_runs_to_end--;
+	/* if using EOS, adapt DMA buffer to one scan */
+	bytes = devpriv->ai_eos ? comedi_bytes_per_scan(s) : desc->maxsize;
+	max_samples = comedi_bytes_to_samples(s, bytes);
+
+	/*
+	 * Determine dma size based on the buffer size plus the number of
+	 * unread samples and the number of samples remaining in the command.
+	 */
+	nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
+	if (nsamples > unread_samples) {
+		nsamples -= unread_samples;
+		desc->size = comedi_samples_to_bytes(s, nsamples);
+		comedi_isadma_program(desc);
 	}
-	release_dma_lock(dma_flags);
-	enable_dma(devpriv->dma);
 }
 
 static void pcl812_ai_set_chan_range(struct comedi_device *dev,
@@ -786,6 +720,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
 static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pcl812_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int ctrl = 0;
 	unsigned int i;
@@ -794,7 +729,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	pcl812_ai_set_chan_range(dev, cmd->chanlist[0], 1);
 
-	if (devpriv->dma) {	/*  check if we can use DMA transfer */
+	if (dma) {	/*  check if we can use DMA transfer */
 		devpriv->ai_dma = 1;
 		for (i = 1; i < cmd->chanlist_len; i++)
 			if (cmd->chanlist[0] != cmd->chanlist[i]) {
@@ -817,8 +752,11 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			devpriv->ai_dma = 0;
 	}
 
-	if (devpriv->ai_dma)
-		pcl812_ai_setup_dma(dev, s);
+	if (devpriv->ai_dma) {
+		/* setup and enable dma for the first buffer */
+		dma->cur_dma = 0;
+		pcl812_ai_setup_dma(dev, s, 0);
+	}
 
 	switch (cmd->convert_src) {
 	case TRIG_TIMER:
@@ -859,7 +797,7 @@ static void pcl812_handle_eoc(struct comedi_device *dev,
 
 	if (pcl812_ai_eoc(dev, s, NULL, 0)) {
 		dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n");
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		s->async->events |= COMEDI_CB_ERROR;
 		return;
 	}
 
@@ -895,19 +833,21 @@ static void pcl812_handle_dma(struct comedi_device *dev,
 			      struct comedi_subdevice *s)
 {
 	struct pcl812_private *devpriv = dev->private;
-	int len, bufptr;
-	unsigned short *ptr;
-
-	ptr = (unsigned short *)devpriv->dmabuf[devpriv->next_dma_buf];
-	len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
-	    devpriv->ai_poll_ptr;
-
-	pcl812_ai_setup_next_dma(dev, s);
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
+	unsigned int nsamples;
+	int bufptr;
 
+	nsamples = comedi_bytes_to_samples(s, desc->size) -
+		   devpriv->ai_poll_ptr;
 	bufptr = devpriv->ai_poll_ptr;
 	devpriv->ai_poll_ptr = 0;
 
-	transfer_from_dma_buf(dev, s, ptr, bufptr, len);
+	/* restart dma with the next buffer */
+	dma->cur_dma = 1 - dma->cur_dma;
+	pcl812_ai_setup_dma(dev, s, nsamples);
+
+	transfer_from_dma_buf(dev, s, desc->virt_addr, bufptr, nsamples);
 }
 
 static irqreturn_t pcl812_interrupt(int irq, void *d)
@@ -935,45 +875,37 @@ static irqreturn_t pcl812_interrupt(int irq, void *d)
 static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pcl812_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc;
 	unsigned long flags;
-	unsigned int top1, top2, i;
+	unsigned int poll;
+	int ret;
 
+	/* poll is valid only for DMA transfer */
 	if (!devpriv->ai_dma)
-		return 0;	/*  poll is valid only for DMA transfer */
+		return 0;
 
 	spin_lock_irqsave(&dev->spinlock, flags);
 
-	for (i = 0; i < 10; i++) {
-		/*  where is now DMA */
-		top1 = get_dma_residue(devpriv->ai_dma);
-		top2 = get_dma_residue(devpriv->ai_dma);
-		if (top1 == top2)
-			break;
-	}
-
-	if (top1 != top2) {
-		spin_unlock_irqrestore(&dev->spinlock, flags);
-		return 0;
-	}
-	/*  where is now DMA in buffer */
-	top1 = devpriv->dmabytestomove[1 - devpriv->next_dma_buf] - top1;
-	top1 >>= 1;		/*  sample position */
-	top2 = top1 - devpriv->ai_poll_ptr;
-	if (top2 < 1) {		/*  no new samples */
-		spin_unlock_irqrestore(&dev->spinlock, flags);
-		return 0;
+	poll = comedi_isadma_poll(dma);
+	poll = comedi_bytes_to_samples(s, poll);
+	if (poll > devpriv->ai_poll_ptr) {
+		desc = &dma->desc[dma->cur_dma];
+		transfer_from_dma_buf(dev, s, desc->virt_addr,
+				      devpriv->ai_poll_ptr,
+				      poll - devpriv->ai_poll_ptr);
+		/* new buffer position */
+		devpriv->ai_poll_ptr = poll;
+
+		ret = comedi_buf_n_bytes_ready(s);
+	} else {
+		/* no new samples */
+		ret = 0;
 	}
 
-	transfer_from_dma_buf(dev, s,
-			      (void *)devpriv->dmabuf[1 -
-						      devpriv->next_dma_buf],
-			      devpriv->ai_poll_ptr, top2);
-
-	devpriv->ai_poll_ptr = top1;	/*  new buffer position */
-
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
-	return comedi_buf_n_bytes_ready(s);
+	return ret;
 }
 
 static int pcl812_ai_cancel(struct comedi_device *dev,
@@ -982,7 +914,7 @@ static int pcl812_ai_cancel(struct comedi_device *dev,
 	struct pcl812_private *devpriv = dev->private;
 
 	if (devpriv->ai_dma)
-		disable_dma(devpriv->dma);
+		comedi_isadma_disable(devpriv->dma->chan);
 
 	outb(devpriv->mode_reg_int | PCL812_CTRL_DISABLE_TRIG,
 	     dev->iobase + PCL812_CTRL_REG);
@@ -1192,6 +1124,27 @@ static void pcl812_set_ai_range_table(struct comedi_device *dev,
 	}
 }
 
+static void pcl812_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
+{
+	struct pcl812_private *devpriv = dev->private;
+
+	/* only DMA channels 3 and 1 are valid */
+	if (!(dma_chan == 3 || dma_chan == 1))
+		return;
+
+	/* DMA uses two 8K buffers */
+	devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
+					   PAGE_SIZE * 2, COMEDI_ISADMA_READ);
+}
+
+static void pcl812_free_dma(struct comedi_device *dev)
+{
+	struct pcl812_private *devpriv = dev->private;
+
+	if (devpriv)
+		comedi_isadma_free(devpriv->dma);
+}
+
 static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	const struct pcl812_board *board = dev->board_ptr;
@@ -1200,7 +1153,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	int n_subdevices;
 	int subdev;
 	int ret;
-	int i;
 
 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 	if (!devpriv)
@@ -1218,31 +1170,8 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 
 	/* we need an IRQ to do DMA on channel 3 or 1 */
-	if (dev->irq && board->has_dma &&
-	    (it->options[2] == 3 || it->options[2] == 1)) {
-		ret = request_dma(it->options[2], dev->board_name);
-		if (ret) {
-			dev_err(dev->class_dev,
-				"unable to request DMA channel %d\n",
-				it->options[2]);
-			return -EBUSY;
-		}
-		devpriv->dma = it->options[2];
-
-		devpriv->dmapages = 1;	/* we want 8KB */
-		devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE;
-
-		for (i = 0; i < 2; i++) {
-			unsigned long dmabuf;
-
-			dmabuf =  __get_dma_pages(GFP_KERNEL, devpriv->dmapages);
-			if (!dmabuf)
-				return -ENOMEM;
-
-			devpriv->dmabuf[i] = dmabuf;
-			devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf);
-		}
-	}
+	if (dev->irq && board->has_dma)
+		 pcl812_alloc_dma(dev, it->options[2]);
 
 	/* differential analog inputs? */
 	switch (board->board_type) {
@@ -1384,16 +1313,7 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 static void pcl812_detach(struct comedi_device *dev)
 {
-	struct pcl812_private *devpriv = dev->private;
-
-	if (devpriv) {
-		if (devpriv->dmabuf[0])
-			free_pages(devpriv->dmabuf[0], devpriv->dmapages);
-		if (devpriv->dmabuf[1])
-			free_pages(devpriv->dmabuf[1], devpriv->dmapages);
-		if (devpriv->dma)
-			free_dma(devpriv->dma);
-	}
+	pcl812_free_dma(dev);
 	comedi_legacy_detach(dev);
 }
 
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 73deb4bd5c93..da35edfccbc3 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -33,14 +33,14 @@ Configuration Options:
 */
 
 #include <linux/module.h>
-#include "../comedidev.h"
-
 #include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
 
+#include "../comedidev.h"
+
+#include "comedi_isadma.h"
 #include "comedi_fc.h"
 #include "8253.h"
 
@@ -114,14 +114,7 @@ static const struct pcl816_board boardtypes[] = {
 };
 
 struct pcl816_private {
-	unsigned int dma;	/*  used DMA, 0=don't use DMA */
-	unsigned int dmapages;
-	unsigned int hwdmasize;
-	unsigned long dmabuf[2];	/*  pointers to begin of DMA buffers */
-	unsigned int hwdmaptr[2];	/*  hardware address of DMA buffers */
-	int next_dma_buf;	/*  which DMA buffer will be used next round */
-	long dma_runs_to_end;	/*  how many we must permorm DMA transfer to end of record */
-	unsigned long last_dma_run;	/*  how many bytes we must transfer on last DMA page */
+	struct comedi_isadma *dma;
 	unsigned int ai_poll_ptr;	/*  how many sampes transfer poll */
 	unsigned int divisor1;
 	unsigned int divisor2;
@@ -149,63 +142,27 @@ static void pcl816_start_pacer(struct comedi_device *dev, bool load_counters)
 }
 
 static void pcl816_ai_setup_dma(struct comedi_device *dev,
-				struct comedi_subdevice *s)
-{
-	struct pcl816_private *devpriv = dev->private;
-	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned int dma_flags;
-	unsigned int bytes;
-
-	bytes = devpriv->hwdmasize;
-	if (cmd->stop_src == TRIG_COUNT) {
-		/*  how many */
-		bytes = cmd->stop_arg * comedi_bytes_per_scan(s);
-
-		/*  how many DMA pages we must fill */
-		devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize;
-
-		/* on last dma transfer must be moved */
-		devpriv->last_dma_run = bytes % devpriv->hwdmasize;
-		devpriv->dma_runs_to_end--;
-		if (devpriv->dma_runs_to_end >= 0)
-			bytes = devpriv->hwdmasize;
-	} else
-		devpriv->dma_runs_to_end = -1;
-
-	devpriv->next_dma_buf = 0;
-	set_dma_mode(devpriv->dma, DMA_MODE_READ);
-	dma_flags = claim_dma_lock();
-	clear_dma_ff(devpriv->dma);
-	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
-	set_dma_count(devpriv->dma, bytes);
-	release_dma_lock(dma_flags);
-	enable_dma(devpriv->dma);
-}
-
-static void pcl816_ai_setup_next_dma(struct comedi_device *dev,
-				     struct comedi_subdevice *s)
+				struct comedi_subdevice *s,
+				unsigned int unread_samples)
 {
 	struct pcl816_private *devpriv = dev->private;
-	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned long dma_flags;
-
-	disable_dma(devpriv->dma);
-	if (devpriv->dma_runs_to_end > -1 || cmd->stop_src == TRIG_NONE) {
-		/* switch dma bufs */
-		devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
-		set_dma_mode(devpriv->dma, DMA_MODE_READ);
-		dma_flags = claim_dma_lock();
-		set_dma_addr(devpriv->dma,
-			     devpriv->hwdmaptr[devpriv->next_dma_buf]);
-		if (devpriv->dma_runs_to_end)
-			set_dma_count(devpriv->dma, devpriv->hwdmasize);
-		else
-			set_dma_count(devpriv->dma, devpriv->last_dma_run);
-		release_dma_lock(dma_flags);
-		enable_dma(devpriv->dma);
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
+	unsigned int max_samples = comedi_bytes_to_samples(s, desc->maxsize);
+	unsigned int nsamples;
+
+	comedi_isadma_disable(dma->chan);
+
+	/*
+	 * Determine dma size based on the buffer maxsize plus the number of
+	 * unread samples and the number of samples remaining in the command.
+	 */
+	nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
+	if (nsamples > unread_samples) {
+		nsamples -= unread_samples;
+		desc->size = comedi_samples_to_bytes(s, nsamples);
+		comedi_isadma_program(desc);
 	}
-
-	devpriv->dma_runs_to_end--;
 }
 
 static void pcl816_ai_set_chan_range(struct comedi_device *dev,
@@ -318,9 +275,10 @@ static irqreturn_t pcl816_interrupt(int irq, void *d)
 	struct comedi_device *dev = d;
 	struct comedi_subdevice *s = dev->read_subdev;
 	struct pcl816_private *devpriv = dev->private;
-	unsigned short *ptr;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
+	unsigned int nsamples;
 	unsigned int bufptr;
-	unsigned int len;
 
 	if (!dev->attached || !devpriv->ai_cmd_running) {
 		pcl816_ai_clear_eoc(dev);
@@ -333,15 +291,16 @@ static irqreturn_t pcl816_interrupt(int irq, void *d)
 		return IRQ_HANDLED;
 	}
 
-	ptr = (unsigned short *)devpriv->dmabuf[devpriv->next_dma_buf];
-
-	pcl816_ai_setup_next_dma(dev, s);
-
-	len = (devpriv->hwdmasize >> 1) - devpriv->ai_poll_ptr;
+	nsamples = comedi_bytes_to_samples(s, desc->size) -
+		   devpriv->ai_poll_ptr;
 	bufptr = devpriv->ai_poll_ptr;
 	devpriv->ai_poll_ptr = 0;
 
-	transfer_from_dma_buf(dev, s, ptr, bufptr, len);
+	/* restart dma with the next buffer */
+	dma->cur_dma = 1 - dma->cur_dma;
+	pcl816_ai_setup_dma(dev, s, nsamples);
+
+	transfer_from_dma_buf(dev, s, desc->virt_addr, bufptr, nsamples);
 
 	pcl816_ai_clear_eoc(dev);
 
@@ -483,6 +442,7 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
 static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pcl816_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int ctrl;
 	unsigned int seglen;
@@ -502,7 +462,9 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->ai_poll_ptr = 0;
 	devpriv->ai_cmd_canceled = 0;
 
-	pcl816_ai_setup_dma(dev, s);
+	/* setup and enable dma for the first buffer */
+	dma->cur_dma = 0;
+	pcl816_ai_setup_dma(dev, s, 0);
 
 	pcl816_start_pacer(dev, true);
 
@@ -513,7 +475,8 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		ctrl |= PCL816_CTRL_EXT_TRIG;
 
 	outb(ctrl, dev->iobase + PCL816_CTRL_REG);
-	outb((devpriv->dma << 4) | dev->irq, dev->iobase + PCL816_STATUS_REG);
+	outb((dma->chan << 4) | dev->irq,
+	     dev->iobase + PCL816_STATUS_REG);
 
 	return 0;
 }
@@ -521,42 +484,34 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct pcl816_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc;
 	unsigned long flags;
-	unsigned int top1, top2, i;
+	unsigned int poll;
+	int ret;
 
 	spin_lock_irqsave(&dev->spinlock, flags);
 
-	for (i = 0; i < 20; i++) {
-		top1 = get_dma_residue(devpriv->dma);	/*  where is now DMA */
-		top2 = get_dma_residue(devpriv->dma);
-		if (top1 == top2)
-			break;
-	}
-	if (top1 != top2) {
-		spin_unlock_irqrestore(&dev->spinlock, flags);
-		return 0;
-	}
-
-	/*  where is now DMA in buffer */
-	top1 = devpriv->hwdmasize - top1;
-	top1 >>= 1;		/*  sample position */
-	top2 = top1 - devpriv->ai_poll_ptr;
-	if (top2 < 1) {		/*  no new samples */
-		spin_unlock_irqrestore(&dev->spinlock, flags);
-		return 0;
-	}
+	poll = comedi_isadma_poll(dma);
+	poll = comedi_bytes_to_samples(s, poll);
+	if (poll > devpriv->ai_poll_ptr) {
+		desc = &dma->desc[dma->cur_dma];
+		transfer_from_dma_buf(dev, s, desc->virt_addr,
+				      devpriv->ai_poll_ptr,
+				      poll - devpriv->ai_poll_ptr);
+		/* new buffer position */
+		devpriv->ai_poll_ptr = poll;
 
-	transfer_from_dma_buf(dev, s,
-			      (unsigned short *)devpriv->dmabuf[devpriv->
-								next_dma_buf],
-			      devpriv->ai_poll_ptr, top2);
+		comedi_handle_events(dev, s);
 
-	devpriv->ai_poll_ptr = top1;	/*  new buffer position */
+		ret = comedi_buf_n_bytes_ready(s);
+	} else {
+		/* no new samples */
+		ret = 0;
+	}
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
-	comedi_handle_events(dev, s);
-
-	return comedi_buf_n_bytes_ready(s);
+	return ret;
 }
 
 static int pcl816_ai_cancel(struct comedi_device *dev,
@@ -657,13 +612,44 @@ static void pcl816_reset(struct comedi_device *dev)
 	outb(0, dev->iobase + PCL816_DO_DI_MSB_REG);
 }
 
+static void pcl816_alloc_irq_and_dma(struct comedi_device *dev,
+				     struct comedi_devconfig *it)
+{
+	struct pcl816_private *devpriv = dev->private;
+	unsigned int irq_num = it->options[1];
+	unsigned int dma_chan = it->options[2];
+
+	/* only IRQs 2-7 and DMA channels 3 and 1 are valid */
+	if (!(irq_num >= 2 && irq_num <= 7) ||
+	    !(dma_chan == 3 || dma_chan == 1))
+		return;
+
+	if (request_irq(irq_num, pcl816_interrupt, 0, dev->board_name, dev))
+		return;
+
+	/* DMA uses two 16K buffers */
+	devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
+					   PAGE_SIZE * 4, COMEDI_ISADMA_READ);
+	if (!devpriv->dma)
+		free_irq(irq_num, dev);
+	else
+		dev->irq = irq_num;
+}
+
+static void pcl816_free_dma(struct comedi_device *dev)
+{
+	struct pcl816_private *devpriv = dev->private;
+
+	if (devpriv)
+		comedi_isadma_free(devpriv->dma);
+}
+
 static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	const struct pcl816_board *board = dev->board_ptr;
 	struct pcl816_private *devpriv;
 	struct comedi_subdevice *s;
 	int ret;
-	int i;
 
 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 	if (!devpriv)
@@ -673,39 +659,8 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	if (ret)
 		return ret;
 
-	/* we can use IRQ 2-7 for async command support */
-	if (it->options[1] >= 2 && it->options[1] <= 7) {
-		ret = request_irq(it->options[1], pcl816_interrupt, 0,
-				  dev->board_name, dev);
-		if (ret == 0)
-			dev->irq = it->options[1];
-	}
-
-	/* we need an IRQ to do DMA on channel 3 or 1 */
-	if (dev->irq && (it->options[2] == 3 || it->options[2] == 1)) {
-		ret = request_dma(it->options[2], dev->board_name);
-		if (ret) {
-			dev_err(dev->class_dev,
-				"unable to request DMA channel %d\n",
-				it->options[2]);
-			return -EBUSY;
-		}
-		devpriv->dma = it->options[2];
-
-		devpriv->dmapages = 2;	/* we need 16KB */
-		devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE;
-
-		for (i = 0; i < 2; i++) {
-			unsigned long dmabuf;
-
-			dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages);
-			if (!dmabuf)
-				return -ENOMEM;
-
-			devpriv->dmabuf[i] = dmabuf;
-			devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf);
-		}
-	}
+	/* an IRQ and DMA are required to support async commands */
+	pcl816_alloc_irq_and_dma(dev, it);
 
 	ret = comedi_alloc_subdevices(dev, 4);
 	if (ret)
@@ -718,7 +673,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	s->maxdata	= board->ai_maxdata;
 	s->range_table	= &range_pcl816;
 	s->insn_read	= pcl816_ai_insn_read;
-	if (devpriv->dma) {
+	if (dev->irq) {
 		dev->read_subdev = s;
 		s->subdev_flags	|= SDF_CMD_READ;
 		s->len_chanlist	= board->ai_chanlist;
@@ -764,18 +719,11 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 static void pcl816_detach(struct comedi_device *dev)
 {
-	struct pcl816_private *devpriv = dev->private;
-
 	if (dev->private) {
 		pcl816_ai_cancel(dev, dev->read_subdev);
 		pcl816_reset(dev);
-		if (devpriv->dma)
-			free_dma(devpriv->dma);
-		if (devpriv->dmabuf[0])
-			free_pages(devpriv->dmabuf[0], devpriv->dmapages);
-		if (devpriv->dmabuf[1])
-			free_pages(devpriv->dmabuf[1], devpriv->dmapages);
 	}
+	pcl816_free_dma(dev);
 	comedi_legacy_detach(dev);
 }
 
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index 8edea35532a9..7e4cdea5fe59 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -1,112 +1,105 @@
 /*
-   comedi/drivers/pcl818.c
-
-   Author:  Michal Dobes <dobes@tesnet.cz>
-
-   hardware driver for Advantech cards:
-    card:   PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818, PCL-718
-    driver: pcl818l,  pcl818h,  pcl818hd,  pcl818hg,  pcl818,  pcl718
-*/
-/*
-Driver: pcl818
-Description: Advantech PCL-818 cards, PCL-718
-Author: Michal Dobes <dobes@tesnet.cz>
-Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
-  PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
-  PCL-718 (pcl718)
-Status: works
-
-All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
-Differences are only at maximal sample speed, range list and FIFO
-support.
-The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
-only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
-PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
-but this code is untested.
-A word or two about DMA. Driver support DMA operations at two ways:
-1) DMA uses two buffers and after one is filled then is generated
-   INT and DMA restart with second buffer. With this mode I'm unable run
-   more that 80Ksamples/secs without data dropouts on K6/233.
-2) DMA uses one buffer and run in autoinit mode and the data are
-   from DMA buffer moved on the fly with 2kHz interrupts from RTC.
-   This mode is used if the interrupt 8 is available for allocation.
-   If not, then first DMA mode is used. With this I can run at
-   full speed one card (100ksamples/secs) or two cards with
-   60ksamples/secs each (more is problem on account of ISA limitations).
-   To use this mode you must have compiled  kernel with disabled
-   "Enhanced Real Time Clock Support".
-   Maybe you can have problems if you use xntpd or similar.
-   If you've data dropouts with DMA mode 2 then:
-    a) disable IDE DMA
-    b) switch text mode console to fb.
-
-   Options for PCL-818L:
-    [0] - IO Base
-    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
-    [2] - DMA	(0=disable, 1, 3)
-    [3] - 0, 10=10MHz clock for 8254
-              1= 1MHz clock for 8254
-    [4] - 0,  5=A/D input  -5V.. +5V
-          1, 10=A/D input -10V..+10V
-    [5] - 0,  5=D/A output 0-5V  (internal reference -5V)
-          1, 10=D/A output 0-10V (internal reference -10V)
-	  2    =D/A output unknown (external reference)
-
-   Options for PCL-818, PCL-818H:
-    [0] - IO Base
-    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
-    [2] - DMA	(0=disable, 1, 3)
-    [3] - 0, 10=10MHz clock for 8254
-              1= 1MHz clock for 8254
-    [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
-          1, 10=D/A output 0-10V (internal reference -10V)
-	  2    =D/A output unknown (external reference)
-
-   Options for PCL-818HD, PCL-818HG:
-    [0] - IO Base
-    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
-    [2] - DMA/FIFO  (-1=use FIFO, 0=disable both FIFO and DMA,
-                      1=use DMA ch 1, 3=use DMA ch 3)
-    [3] - 0, 10=10MHz clock for 8254
-              1= 1MHz clock for 8254
-    [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
-          1, 10=D/A output 0-10V (internal reference -10V)
-   	  2    =D/A output unknown (external reference)
-
-   Options for PCL-718:
-    [0] - IO Base
-    [1] - IRQ	(0=disable, 2, 3, 4, 5, 6, 7)
-    [2] - DMA	(0=disable, 1, 3)
-    [3] - 0, 10=10MHz clock for 8254
-              1= 1MHz clock for 8254
-    [4] -     0=A/D Range is +/-10V
-	      1=             +/-5V
-	      2=             +/-2.5V
-	      3=             +/-1V
-	      4=             +/-0.5V
-	      5=  	     user defined bipolar
-	      6=	     0-10V
-	      7=	     0-5V
- 	      8=	     0-2V
-	      9=	     0-1V
-	     10=	     user defined unipolar
-    [5] - 0,  5=D/A outputs 0-5V  (internal reference -5V)
-          1, 10=D/A outputs 0-10V (internal reference -10V)
-	      2=D/A outputs unknown (external reference)
-    [6] - 0, 60=max  60kHz A/D sampling
-          1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
-
-*/
+ * comedi/drivers/pcl818.c
+ *
+ * Driver: pcl818
+ * Description: Advantech PCL-818 cards, PCL-718
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ * Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
+ *   PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
+ *   PCL-718 (pcl718)
+ * Status: works
+ *
+ * All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
+ * Differences are only at maximal sample speed, range list and FIFO
+ * support.
+ * The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
+ * only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
+ * PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
+ * but this code is untested.
+ * A word or two about DMA. Driver support DMA operations at two ways:
+ * 1) DMA uses two buffers and after one is filled then is generated
+ *    INT and DMA restart with second buffer. With this mode I'm unable run
+ *    more that 80Ksamples/secs without data dropouts on K6/233.
+ * 2) DMA uses one buffer and run in autoinit mode and the data are
+ *    from DMA buffer moved on the fly with 2kHz interrupts from RTC.
+ *    This mode is used if the interrupt 8 is available for allocation.
+ *    If not, then first DMA mode is used. With this I can run at
+ *    full speed one card (100ksamples/secs) or two cards with
+ *    60ksamples/secs each (more is problem on account of ISA limitations).
+ *    To use this mode you must have compiled  kernel with disabled
+ *    "Enhanced Real Time Clock Support".
+ *    Maybe you can have problems if you use xntpd or similar.
+ *    If you've data dropouts with DMA mode 2 then:
+ *     a) disable IDE DMA
+ *     b) switch text mode console to fb.
+ *
+ *  Options for PCL-818L:
+ *  [0] - IO Base
+ *  [1] - IRQ        (0=disable, 2, 3, 4, 5, 6, 7)
+ *  [2] - DMA        (0=disable, 1, 3)
+ *  [3] - 0, 10=10MHz clock for 8254
+ *            1= 1MHz clock for 8254
+ *  [4] - 0,  5=A/D input  -5V.. +5V
+ *        1, 10=A/D input -10V..+10V
+ *  [5] - 0,  5=D/A output 0-5V  (internal reference -5V)
+ *        1, 10=D/A output 0-10V (internal reference -10V)
+ *        2    =D/A output unknown (external reference)
+ *
+ *  Options for PCL-818, PCL-818H:
+ *  [0] - IO Base
+ *  [1] - IRQ        (0=disable, 2, 3, 4, 5, 6, 7)
+ *  [2] - DMA        (0=disable, 1, 3)
+ *  [3] - 0, 10=10MHz clock for 8254
+ *            1= 1MHz clock for 8254
+ *  [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
+ *        1, 10=D/A output 0-10V (internal reference -10V)
+ *        2    =D/A output unknown (external reference)
+ *
+ *  Options for PCL-818HD, PCL-818HG:
+ *  [0] - IO Base
+ *  [1] - IRQ        (0=disable, 2, 3, 4, 5, 6, 7)
+ *  [2] - DMA/FIFO  (-1=use FIFO, 0=disable both FIFO and DMA,
+ *                    1=use DMA ch 1, 3=use DMA ch 3)
+ *  [3] - 0, 10=10MHz clock for 8254
+ *            1= 1MHz clock for 8254
+ *  [4] - 0,  5=D/A output 0-5V  (internal reference -5V)
+ *        1, 10=D/A output 0-10V (internal reference -10V)
+ *        2    =D/A output unknown (external reference)
+ *
+ *  Options for PCL-718:
+ *  [0] - IO Base
+ *  [1] - IRQ        (0=disable, 2, 3, 4, 5, 6, 7)
+ *  [2] - DMA        (0=disable, 1, 3)
+ *  [3] - 0, 10=10MHz clock for 8254
+ *            1= 1MHz clock for 8254
+ *  [4] -     0=A/D Range is +/-10V
+ *            1=             +/-5V
+ *            2=             +/-2.5V
+ *            3=             +/-1V
+ *            4=             +/-0.5V
+ *            5=             user defined bipolar
+ *            6=             0-10V
+ *            7=             0-5V
+ *            8=             0-2V
+ *            9=             0-1V
+ *           10=             user defined unipolar
+ *  [5] - 0,  5=D/A outputs 0-5V  (internal reference -5V)
+ *        1, 10=D/A outputs 0-10V (internal reference -10V)
+ *            2=D/A outputs unknown (external reference)
+ *  [6] - 0, 60=max  60kHz A/D sampling
+ *        1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
+ *
+ */
 
 #include <linux/module.h>
 #include <linux/gfp.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
-#include <asm/dma.h>
 
 #include "../comedidev.h"
 
+#include "comedi_isadma.h"
 #include "comedi_fc.h"
 #include "8253.h"
 
@@ -303,20 +296,14 @@ static const struct pcl818_board boardtypes[] = {
 };
 
 struct pcl818_private {
-	unsigned int dma;	/*  used DMA, 0=don't use DMA */
-	unsigned int dmapages;
-	unsigned int hwdmasize;
-	unsigned long dmabuf[2];	/*  pointers to begin of DMA buffers */
-	unsigned int hwdmaptr[2];	/*  hardware address of DMA buffers */
-	int next_dma_buf;	/*  which DMA buffer will be used next round */
-	long dma_runs_to_end;	/*  how many we must permorm DMA transfer to end of record */
-	unsigned long last_dma_run;	/*  how many bytes we must transfer on last DMA page */
-	unsigned int ns_min;	/*  manimal allowed delay between samples (in us) for actual card */
+	struct comedi_isadma *dma;
+	/*  manimal allowed delay between samples (in us) for actual card */
+	unsigned int ns_min;
 	int i8253_osc_base;	/*  1/frequency of on board oscilator in ns */
-	unsigned int act_chanlist[16];	/*  MUX setting for actual AI operations */
+	/*  MUX setting for actual AI operations */
+	unsigned int act_chanlist[16];
 	unsigned int act_chanlist_len;	/*  how long is actual MUX list */
 	unsigned int act_chanlist_pos;	/*  actual position in MUX list */
-	unsigned int ai_data_len;	/*  len of data buffer */
 	unsigned int divisor1;
 	unsigned int divisor2;
 	unsigned int usefifo:1;
@@ -340,58 +327,27 @@ static void pcl818_start_pacer(struct comedi_device *dev, bool load_counters)
 }
 
 static void pcl818_ai_setup_dma(struct comedi_device *dev,
-				struct comedi_subdevice *s)
-{
-	struct pcl818_private *devpriv = dev->private;
-	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned int flags;
-	unsigned int bytes;
-
-	disable_dma(devpriv->dma);	/*  disable dma */
-	bytes = devpriv->hwdmasize;
-	if (cmd->stop_src == TRIG_COUNT) {
-		bytes = cmd->stop_arg * comedi_bytes_per_scan(s);
-		devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize;
-		devpriv->last_dma_run = bytes % devpriv->hwdmasize;
-		devpriv->dma_runs_to_end--;
-		if (devpriv->dma_runs_to_end >= 0)
-			bytes = devpriv->hwdmasize;
-	}
-
-	devpriv->next_dma_buf = 0;
-	set_dma_mode(devpriv->dma, DMA_MODE_READ);
-	flags = claim_dma_lock();
-	clear_dma_ff(devpriv->dma);
-	set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
-	set_dma_count(devpriv->dma, bytes);
-	release_dma_lock(flags);
-	enable_dma(devpriv->dma);
-}
-
-static void pcl818_ai_setup_next_dma(struct comedi_device *dev,
-				     struct comedi_subdevice *s)
+				struct comedi_subdevice *s,
+				unsigned int unread_samples)
 {
 	struct pcl818_private *devpriv = dev->private;
-	struct comedi_cmd *cmd = &s->async->cmd;
-	unsigned long flags;
-
-	disable_dma(devpriv->dma);
-	devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
-	if (devpriv->dma_runs_to_end > -1 || cmd->stop_src == TRIG_NONE) {
-		/* switch dma bufs */
-		set_dma_mode(devpriv->dma, DMA_MODE_READ);
-		flags = claim_dma_lock();
-		set_dma_addr(devpriv->dma,
-			     devpriv->hwdmaptr[devpriv->next_dma_buf]);
-		if (devpriv->dma_runs_to_end || cmd->stop_src == TRIG_NONE)
-			set_dma_count(devpriv->dma, devpriv->hwdmasize);
-		else
-			set_dma_count(devpriv->dma, devpriv->last_dma_run);
-		release_dma_lock(flags);
-		enable_dma(devpriv->dma);
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
+	unsigned int max_samples = comedi_bytes_to_samples(s, desc->maxsize);
+	unsigned int nsamples;
+
+	comedi_isadma_disable(dma->chan);
+
+	/*
+	 * Determine dma size based on the buffer maxsize plus the number of
+	 * unread samples and the number of samples remaining in the command.
+	 */
+	nsamples = comedi_nsamples_left(s, max_samples + unread_samples);
+	if (nsamples > unread_samples) {
+		nsamples -= unread_samples;
+		desc->size = comedi_samples_to_bytes(s, nsamples);
+		comedi_isadma_program(desc);
 	}
-
-	devpriv->dma_runs_to_end--;
 }
 
 static void pcl818_ai_set_chan_range(struct comedi_device *dev,
@@ -493,11 +449,12 @@ static int pcl818_ai_eoc(struct comedi_device *dev,
 	return -EBUSY;
 }
 
-static bool pcl818_ai_dropout(struct comedi_device *dev,
-			      struct comedi_subdevice *s,
-			      unsigned int chan)
+static bool pcl818_ai_write_sample(struct comedi_device *dev,
+				   struct comedi_subdevice *s,
+				   unsigned int chan, unsigned int val)
 {
 	struct pcl818_private *devpriv = dev->private;
+	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int expected_chan;
 
 	expected_chan = devpriv->act_chanlist[devpriv->act_chanlist_pos];
@@ -507,17 +464,11 @@ static bool pcl818_ai_dropout(struct comedi_device *dev,
 			(devpriv->dma) ? "DMA" :
 			(devpriv->usefifo) ? "FIFO" : "IRQ",
 			chan, expected_chan);
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
-		return true;
+		s->async->events |= COMEDI_CB_ERROR;
+		return false;
 	}
-	return false;
-}
 
-static bool pcl818_ai_next_chan(struct comedi_device *dev,
-				struct comedi_subdevice *s)
-{
-	struct pcl818_private *devpriv = dev->private;
-	struct comedi_cmd *cmd = &s->async->cmd;
+	comedi_buf_write_samples(s, &val, 1);
 
 	devpriv->act_chanlist_pos++;
 	if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
@@ -540,47 +491,35 @@ static void pcl818_handle_eoc(struct comedi_device *dev,
 
 	if (pcl818_ai_eoc(dev, s, NULL, 0)) {
 		dev_err(dev->class_dev, "A/D mode1/3 IRQ without DRDY!\n");
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		s->async->events |= COMEDI_CB_ERROR;
 		return;
 	}
 
 	val = pcl818_ai_get_sample(dev, s, &chan);
-
-	if (pcl818_ai_dropout(dev, s, chan))
-		return;
-
-	comedi_buf_write_samples(s, &val, 1);
-
-	pcl818_ai_next_chan(dev, s);
+	pcl818_ai_write_sample(dev, s, chan, val);
 }
 
 static void pcl818_handle_dma(struct comedi_device *dev,
 			      struct comedi_subdevice *s)
 {
 	struct pcl818_private *devpriv = dev->private;
-	unsigned short *ptr;
+	struct comedi_isadma *dma = devpriv->dma;
+	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
+	unsigned short *ptr = desc->virt_addr;
+	unsigned int nsamples = comedi_bytes_to_samples(s, desc->size);
 	unsigned int chan;
 	unsigned int val;
-	int i, len, bufptr;
-
-	pcl818_ai_setup_next_dma(dev, s);
-
-	ptr = (unsigned short *)devpriv->dmabuf[1 - devpriv->next_dma_buf];
+	int i;
 
-	len = devpriv->hwdmasize >> 1;
-	bufptr = 0;
+	/* restart dma with the next buffer */
+	dma->cur_dma = 1 - dma->cur_dma;
+	pcl818_ai_setup_dma(dev, s, nsamples);
 
-	for (i = 0; i < len; i++) {
-		val = ptr[bufptr++];
+	for (i = 0; i < nsamples; i++) {
+		val = ptr[i];
 		chan = val & 0xf;
 		val = (val >> 4) & s->maxdata;
-
-		if (pcl818_ai_dropout(dev, s, chan))
-			break;
-
-		comedi_buf_write_samples(s, &val, 1);
-
-		if (!pcl818_ai_next_chan(dev, s))
+		if (!pcl818_ai_write_sample(dev, s, chan, val))
 			break;
 	}
 }
@@ -597,14 +536,14 @@ static void pcl818_handle_fifo(struct comedi_device *dev,
 
 	if (status & 4) {
 		dev_err(dev->class_dev, "A/D mode1/3 FIFO overflow!\n");
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		s->async->events |= COMEDI_CB_ERROR;
 		return;
 	}
 
 	if (status & 1) {
 		dev_err(dev->class_dev,
 			"A/D mode1/3 FIFO interrupt without data!\n");
-		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+		s->async->events |= COMEDI_CB_ERROR;
 		return;
 	}
 
@@ -615,13 +554,7 @@ static void pcl818_handle_fifo(struct comedi_device *dev,
 
 	for (i = 0; i < len; i++) {
 		val = pcl818_ai_get_fifo_sample(dev, s, &chan);
-
-		if (pcl818_ai_dropout(dev, s, chan))
-			break;
-
-		comedi_buf_write_samples(s, &val, 1);
-
-		if (!pcl818_ai_next_chan(dev, s))
+		if (!pcl818_ai_write_sample(dev, s, chan, val))
 			break;
 	}
 }
@@ -687,7 +620,8 @@ static int check_channel_list(struct comedi_device *dev,
 				break;
 			nowmustbechan =
 			    (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
-			if (nowmustbechan != CR_CHAN(chanlist[i])) {	/*  channel list isn't continuous :-( */
+			if (nowmustbechan != CR_CHAN(chanlist[i])) {
+				/*  channel list isn't continuous :-( */
 				dev_dbg(dev->class_dev,
 					"channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n",
 					i, CR_CHAN(chanlist[i]), nowmustbechan,
@@ -804,6 +738,7 @@ static int pcl818_ai_cmd(struct comedi_device *dev,
 			 struct comedi_subdevice *s)
 {
 	struct pcl818_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int ctrl = 0;
 	unsigned int seglen;
@@ -818,11 +753,9 @@ static int pcl818_ai_cmd(struct comedi_device *dev,
 		return -EINVAL;
 	pcl818_ai_setup_chanlist(dev, cmd->chanlist, seglen);
 
-	devpriv->ai_data_len = s->async->prealloc_bufsz;
 	devpriv->ai_cmd_running = 1;
 	devpriv->ai_cmd_canceled = 0;
 	devpriv->act_chanlist_pos = 0;
-	devpriv->dma_runs_to_end = 0;
 
 	if (cmd->convert_src == TRIG_TIMER)
 		ctrl |= PCL818_CTRL_PACER_TRIG;
@@ -831,8 +764,10 @@ static int pcl818_ai_cmd(struct comedi_device *dev,
 
 	outb(PCL818_CNTENABLE_PACER_ENA, dev->iobase + PCL818_CNTENABLE_REG);
 
-	if (devpriv->dma) {
-		pcl818_ai_setup_dma(dev, s);
+	if (dma) {
+		/* setup and enable dma for the first buffer */
+		dma->cur_dma = 0;
+		pcl818_ai_setup_dma(dev, s, 0);
 
 		ctrl |= PCL818_CTRL_INTE | PCL818_CTRL_IRQ(dev->irq) |
 			PCL818_CTRL_DMAE;
@@ -854,12 +789,13 @@ static int pcl818_ai_cancel(struct comedi_device *dev,
 			    struct comedi_subdevice *s)
 {
 	struct pcl818_private *devpriv = dev->private;
+	struct comedi_isadma *dma = devpriv->dma;
 	struct comedi_cmd *cmd = &s->async->cmd;
 
 	if (!devpriv->ai_cmd_running)
 		return 0;
 
-	if (devpriv->dma) {
+	if (dma) {
 		if (cmd->stop_src == TRIG_NONE ||
 		    (cmd->stop_src == TRIG_COUNT &&
 		     s->async->scans_done < cmd->stop_arg)) {
@@ -872,7 +808,7 @@ static int pcl818_ai_cancel(struct comedi_device *dev,
 				return 0;
 			}
 		}
-		disable_dma(devpriv->dma);
+		comedi_isadma_disable(dma->chan);
 	}
 
 	outb(PCL818_CTRL_DISABLE_TRIG, dev->iobase + PCL818_CTRL_REG);
@@ -1054,13 +990,33 @@ static void pcl818_set_ai_range_table(struct comedi_device *dev,
 	}
 }
 
+static void pcl818_alloc_dma(struct comedi_device *dev, unsigned int dma_chan)
+{
+	struct pcl818_private *devpriv = dev->private;
+
+	/* only DMA channels 3 and 1 are valid */
+	if (!(dma_chan == 3 || dma_chan == 1))
+		return;
+
+	/* DMA uses two 16K buffers */
+	devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan, dma_chan,
+					   PAGE_SIZE * 4, COMEDI_ISADMA_READ);
+}
+
+static void pcl818_free_dma(struct comedi_device *dev)
+{
+	struct pcl818_private *devpriv = dev->private;
+
+	if (devpriv)
+		comedi_isadma_free(devpriv->dma);
+}
+
 static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	const struct pcl818_board *board = dev->board_ptr;
 	struct pcl818_private *devpriv;
 	struct comedi_subdevice *s;
 	int ret;
-	int i;
 
 	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 	if (!devpriv)
@@ -1084,31 +1040,8 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		devpriv->usefifo = 1;
 
 	/* we need an IRQ to do DMA on channel 3 or 1 */
-	if (dev->irq && board->has_dma &&
-	    (it->options[2] == 3 || it->options[2] == 1)) {
-		ret = request_dma(it->options[2], dev->board_name);
-		if (ret) {
-			dev_err(dev->class_dev,
-				"unable to request DMA channel %d\n",
-				it->options[2]);
-			return -EBUSY;
-		}
-		devpriv->dma = it->options[2];
-
-		devpriv->dmapages = 2;	/* we need 16KB */
-		devpriv->hwdmasize = (1 << devpriv->dmapages) * PAGE_SIZE;
-
-		for (i = 0; i < 2; i++) {
-			unsigned long dmabuf;
-
-			dmabuf = __get_dma_pages(GFP_KERNEL, devpriv->dmapages);
-			if (!dmabuf)
-				return -ENOMEM;
-
-			devpriv->dmabuf[i] = dmabuf;
-			devpriv->hwdmaptr[i] = virt_to_bus((void *)dmabuf);
-		}
-	}
+	if (dev->irq && board->has_dma)
+		pcl818_alloc_dma(dev, it->options[2]);
 
 	ret = comedi_alloc_subdevices(dev, 4);
 	if (ret)
@@ -1194,8 +1127,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	devpriv->ns_min = board->ns_min;
 
 	if (!board->is_818) {
-		if ((it->options[6] == 1) || (it->options[6] == 100))
-			devpriv->ns_min = 10000;	/* extended PCL718 to 100kHz DAC */
+		if ((it->options[6] == 1) || (it->options[6] == 100)) {
+			/* extended PCL718 to 100kHz DAC */
+			devpriv->ns_min = 10000;
+		}
 	}
 
 	pcl818_reset(dev);
@@ -1210,13 +1145,8 @@ static void pcl818_detach(struct comedi_device *dev)
 	if (devpriv) {
 		pcl818_ai_cancel(dev, dev->read_subdev);
 		pcl818_reset(dev);
-		if (devpriv->dma)
-			free_dma(devpriv->dma);
-		if (devpriv->dmabuf[0])
-			free_pages(devpriv->dmabuf[0], devpriv->dmapages);
-		if (devpriv->dmabuf[1])
-			free_pages(devpriv->dmabuf[1], devpriv->dmapages);
 	}
+	pcl818_free_dma(dev);
 	comedi_legacy_detach(dev);
 }
 
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
index e3ac8ac6190e..12f94fe82f5b 100644
--- a/drivers/staging/comedi/drivers/pcmad.c
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -19,8 +19,7 @@
 /*
  * Driver: pcmad
  * Description: Winsystems PCM-A/D12, PCM-A/D16
- * Devices: (Winsystems) PCM-A/D12 [pcmad12]
- *	    (Winsystems) PCM-A/D16 [pcmad16]
+ * Devices: [Winsystems] PCM-A/D12 (pcmad12), PCM-A/D16 (pcmad16)
  * Author: ds
  * Status: untested
  *
diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c
index 59108c06cedc..d86c5e2cd0c7 100644
--- a/drivers/staging/comedi/drivers/pcmda12.c
+++ b/drivers/staging/comedi/drivers/pcmda12.c
@@ -19,7 +19,7 @@
 /*
  * Driver: pcmda12
  * Description: A driver for the Winsystems PCM-D/A-12
- * Devices: (Winsystems) PCM-D/A-12 [pcmda12]
+ * Devices: [Winsystems] PCM-D/A-12 (pcmda12)
  * Author: Calin Culianu <calin@ajvar.org>
  * Updated: Fri, 13 Jan 2006 12:01:01 -0500
  * Status: works
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index f0059e935da0..2c0e7ecbf494 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -19,7 +19,7 @@
 /*
  * Driver: pcmmio
  * Description: A driver for the PCM-MIO multifunction board
- * Devices: (Winsystems) PCM-MIO [pcmmio]
+ * Devices: [Winsystems] PCM-MIO (pcmmio)
  * Author: Calin Culianu <calin@ajvar.org>
  * Updated: Wed, May 16 2007 16:21:10 -0500
  * Status: works
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 0f5483b6147f..a1641d981812 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -19,8 +19,7 @@
 /*
  * Driver: pcmuio
  * Description: Winsystems PC-104 based 48/96-channel DIO boards.
- * Devices: (Winsystems) PCM-UIO48A [pcmuio48]
- *	    (Winsystems) PCM-UIO96A [pcmuio96]
+ * Devices: [Winsystems] PCM-UIO48A (pcmuio48), PCM-UIO96A (pcmuio96)
  * Author: Calin Culianu <calin@ajvar.org>
  * Updated: Fri, 13 Jan 2006 12:01:01 -0500
  * Status: works
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index 96098110b0b3..8387fd0e4b7e 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -48,15 +48,10 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308
 */
 
 #include <linux/module.h>
-#include "../comedidev.h"
 #include <linux/semaphore.h>
-
-#include <pcmcia/cistpl.h>
-#include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-
 #include <linux/completion.h>
 
+#include "../comedi_pcmcia.h"
 #include "comedi_fc.h"
 
 struct daqp_private {
@@ -210,8 +205,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id)
 			unsigned short data;
 
 			if (status & DAQP_STATUS_DATA_LOST) {
-				s->async->events |=
-				    COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
+				s->async->events |= COMEDI_CB_OVERFLOW;
 				dev_warn(dev->class_dev, "data lost\n");
 				break;
 			}
@@ -239,7 +233,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id)
 		if (loop_limit <= 0) {
 			dev_warn(dev->class_dev,
 				 "loop_limit reached in daqp_interrupt()\n");
-			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+			s->async->events |= COMEDI_CB_ERROR;
 		}
 
 		comedi_handle_events(dev, s);
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 581aa58d9c0a..c94ad12ed446 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -19,10 +19,8 @@
 /*
  * Driver: rtd520
  * Description: Real Time Devices PCI4520/DM7520
- * Devices: (Real Time Devices) DM7520HR-1 [DM7520]
- *	    (Real Time Devices) DM7520HR-8 [DM7520]
- *	    (Real Time Devices) PCI4520 [PCI4520]
- *	    (Real Time Devices) PCI4520-8 [PCI4520]
+ * Devices: [Real Time Devices] DM7520HR-1 (DM7520), DM7520HR-8,
+ *   PCI4520 (PCI4520), PCI4520-8
  * Author: Dan Christian
  * Status: Works. Only tested on DM7520-8. Not SMP safe.
  *
@@ -1014,10 +1012,8 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	readw(dev->mmio + LAS0_CLEAR);
 
 	/* TODO: allow multiple interrupt sources */
-	if (devpriv->xfer_count > 0)	/* transfer every N samples */
-		writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
-	else				/* 1/2 FIFO transfers */
-		writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
+	/* transfer every N samples */
+	writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
 
 	/* BUG: start_src is ASSUMED to be TRIG_NOW */
 	/* BUG? it seems like things are running before the "start" */
@@ -1031,8 +1027,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct rtd_private *devpriv = dev->private;
-	u32 overrun;
-	u16 status;
 
 	/* pacer stop source: SOFTWARE */
 	writel(0, dev->mmio + LAS0_PACER_STOP);
@@ -1040,8 +1034,6 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 	writel(0, dev->mmio + LAS0_ADC_CONVERSION);
 	writew(0, dev->mmio + LAS0_IT);
 	devpriv->ai_count = 0;	/* stop and don't transfer any more */
-	status = readw(dev->mmio + LAS0_IT);
-	overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
 	writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
 	return 0;
 }
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
index 67b4b378bd01..340ac776e951 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -19,8 +19,7 @@
 /*
  * Driver: rti800
  * Description: Analog Devices RTI-800/815
- * Devices: (Analog Devices) RTI-800 [rti800]
- *	    (Analog Devices) RTI-815 [rti815]
+ * Devices: [Analog Devices] RTI-800 (rti800), RTI-815 (rti815)
  * Author: David A. Schleef <ds@schleef.org>
  * Status: unknown
  * Updated: Fri, 05 Sep 2008 14:50:44 +0100
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
index 96c3974207ae..6db58fcfd496 100644
--- a/drivers/staging/comedi/drivers/rti802.c
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -20,7 +20,7 @@
  * Driver: rti802
  * Description: Analog Devices RTI-802
  * Author: Anders Blomdell <anders.blomdell@control.lth.se>
- * Devices: (Analog Devices) RTI-802 [rti802]
+ * Devices: [Analog Devices] RTI-802 (rti802)
  * Status: works
  *
  * Configuration Options:
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 14932c5f3798..fc497dd92021 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -118,7 +118,7 @@ static void s626_mc_enable(struct comedi_device *dev,
 static void s626_mc_disable(struct comedi_device *dev,
 			    unsigned int cmd, unsigned int reg)
 {
-	writel(cmd << 16 , dev->mmio + reg);
+	writel(cmd << 16, dev->mmio + reg);
 	mmiowb();
 }
 
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 4737dbf8e01d..1cd7403a4e9c 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -16,10 +16,11 @@
 /*
  * Driver: usbdux
  * Description: University of Stirling USB DAQ & INCITE Technology Limited
- * Devices: (ITL) USB-DUX [usbdux]
+ * Devices: [ITL] USB-DUX (usbdux)
  * Author: Bernd Porr <mail@berndporr.me.uk>
  * Updated: 10 Oct 2014
  * Status: Stable
+ *
  * Connection scheme for the counter at the digital port:
  * 0=/CLK0, 1=UP/DOWN0, 2=RESET0, 4=/CLK1, 5=UP/DOWN1, 6=RESET1.
  * The sampling rate of the counter is approximately 500Hz.
@@ -79,11 +80,10 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/input.h>
-#include <linux/usb.h>
 #include <linux/fcntl.h>
 #include <linux/compiler.h>
 
-#include "../comedidev.h"
+#include "../comedi_usb.h"
 
 #include "comedi_fc.h"
 
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index ddc4cb9d5ed4..7ce27c16c2f9 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -15,7 +15,7 @@
 /*
  * Driver: usbduxfast
  * Description: University of Stirling USB DAQ & INCITE Technology Limited
- * Devices: (ITL) USB-DUX [usbduxfast]
+ * Devices: [ITL] USB-DUX-FAST (usbduxfast)
  * Author: Bernd Porr <mail@berndporr.me.uk>
  * Updated: 10 Oct 2014
  * Status: stable
@@ -46,11 +46,10 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/input.h>
-#include <linux/usb.h>
 #include <linux/fcntl.h>
 #include <linux/compiler.h>
 #include "comedi_fc.h"
-#include "../comedidev.h"
+#include "../comedi_usb.h"
 
 /*
  * timeout for the USB-transfer
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c
index dc19435b6520..394969b7458c 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -16,7 +16,7 @@
 /*
  * Driver: usbduxsigma
  * Description: University of Stirling USB DAQ & INCITE Technology Limited
- * Devices: (ITL) USB-DUX [usbduxsigma]
+ * Devices: [ITL] USB-DUX-SIGMA (usbduxsigma)
  * Author: Bernd Porr <mail@berndporr.me.uk>
  * Updated: 10 Oct 2014
  * Status: stable
@@ -45,13 +45,12 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/input.h>
-#include <linux/usb.h>
 #include <linux/fcntl.h>
 #include <linux/compiler.h>
 #include <asm/unaligned.h>
 
 #include "comedi_fc.h"
-#include "../comedidev.h"
+#include "../comedi_usb.h"
 
 /* timeout for the USB-transfer in ms*/
 #define BULK_TIMEOUT 1000
@@ -215,7 +214,6 @@ static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
 	struct usbduxsigma_private *devpriv = dev->private;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
-	unsigned int dio_state;
 	uint32_t val;
 	int ret;
 	int i;
@@ -224,9 +222,6 @@ static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
 	if (devpriv->ai_counter == 0) {
 		devpriv->ai_counter = devpriv->ai_timer;
 
-		/* get the state of the dio pins to allow external trigger */
-		dio_state = be32_to_cpu(devpriv->in_buf[0]);
-
 		/* get the data from the USB bus and hand it over to comedi */
 		for (i = 0; i < cmd->chanlist_len; i++) {
 			/* transfer data, note first byte is the DIO state */
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index a19a56ee0eef..e37118321a27 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -18,21 +18,22 @@
     GNU General Public License for more details.
 */
 /*
-Driver: vmk80xx
-Description: Velleman USB Board Low-Level Driver
-Devices: K8055/K8061 aka VM110/VM140
-Author: Manuel Gebele <forensixs@gmx.de>
-Updated: Sun, 10 May 2009 11:14:59 +0200
-Status: works
-
-Supports:
- - analog input
- - analog output
- - digital input
- - digital output
- - counter
- - pwm
-*/
+ * Driver: vmk80xx
+ * Description: Velleman USB Board Low-Level Driver
+ * Devices: [Velleman] K8055 (K8055/VM110), K8061 (K8061/VM140),
+ *   VM110 (K8055/VM110), VM140 (K8061/VM140)
+ * Author: Manuel Gebele <forensixs@gmx.de>
+ * Updated: Sun, 10 May 2009 11:14:59 +0200
+ * Status: works
+ *
+ * Supports:
+ *  - analog input
+ *  - analog output
+ *  - digital input
+ *  - digital output
+ *  - counter
+ *  - pwm
+ */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -41,10 +42,9 @@ Supports:
 #include <linux/input.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
-#include <linux/usb.h>
 #include <linux/uaccess.h>
 
-#include "../comedidev.h"
+#include "../comedi_usb.h"
 
 enum {
 	DEVICE_VMK8055,
@@ -550,41 +550,35 @@ static int vmk80xx_cnt_insn_config(struct comedi_device *dev,
 				   unsigned int *data)
 {
 	struct vmk80xx_private *devpriv = dev->private;
-	unsigned int insn_cmd;
-	int chan;
+	unsigned int chan = CR_CHAN(insn->chanspec);
 	int cmd;
 	int reg;
-	int n;
-
-	insn_cmd = data[0];
-	if (insn_cmd != INSN_CONFIG_RESET && insn_cmd != GPCT_RESET)
-		return -EINVAL;
+	int ret;
 
 	down(&devpriv->limit_sem);
-
-	chan = CR_CHAN(insn->chanspec);
-
-	if (devpriv->model == VMK8055_MODEL) {
-		if (!chan) {
-			cmd = VMK8055_CMD_RST_CNT1;
-			reg = VMK8055_CNT1_REG;
+	switch (data[0]) {
+	case INSN_CONFIG_RESET:
+		if (devpriv->model == VMK8055_MODEL) {
+			if (!chan) {
+				cmd = VMK8055_CMD_RST_CNT1;
+				reg = VMK8055_CNT1_REG;
+			} else {
+				cmd = VMK8055_CMD_RST_CNT2;
+				reg = VMK8055_CNT2_REG;
+			}
+			devpriv->usb_tx_buf[reg] = 0x00;
 		} else {
-			cmd = VMK8055_CMD_RST_CNT2;
-			reg = VMK8055_CNT2_REG;
+			cmd = VMK8061_CMD_RST_CNT;
 		}
-
-		devpriv->usb_tx_buf[reg] = 0x00;
-	} else {
-		cmd = VMK8061_CMD_RST_CNT;
+		ret = vmk80xx_write_packet(dev, cmd);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
 	}
-
-	for (n = 0; n < insn->n; n++)
-		if (vmk80xx_write_packet(dev, cmd))
-			break;
-
 	up(&devpriv->limit_sem);
 
-	return n;
+	return ret ? ret : insn->n;
 }
 
 static int vmk80xx_cnt_insn_write(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/z8536.h b/drivers/staging/comedi/drivers/z8536.h
new file mode 100644
index 000000000000..7be53109cc8d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/z8536.h
@@ -0,0 +1,202 @@
+/*
+ * Z8536 CIO Internal registers
+ */
+
+#ifndef _Z8536_H
+#define _Z8536_H
+
+/* Master Interrupt Control register */
+#define Z8536_INT_CTRL_REG		0x00
+#define Z8536_INT_CTRL_MIE		BIT(7)	/* Master Interrupt Enable */
+#define Z8536_INT_CTRL_DLC		BIT(6)	/* Disable Lower Chain */
+#define Z8536_INT_CTRL_NV		BIT(5)	/* No Vector */
+#define Z8536_INT_CTRL_PA_VIS		BIT(4)	/* Port A Vect Inc Status */
+#define Z8536_INT_CTRL_PB_VIS		BIT(3)	/* Port B Vect Inc Status */
+#define Z8536_INT_CTRL_VT_VIS		BIT(2)	/* C/T Vect Inc Status */
+#define Z8536_INT_CTRL_RJA		BIT(1)	/* Right Justified Addresses */
+#define Z8536_INT_CTRL_RESET		BIT(0)	/* Reset */
+
+/* Master Configuration Control register */
+#define Z8536_CFG_CTRL_REG		0x01
+#define Z8536_CFG_CTRL_PBE		BIT(7)	/* Port B Enable */
+#define Z8536_CFG_CTRL_CT1E		BIT(6)	/* C/T 1 Enable */
+#define Z8536_CFG_CTRL_CT2E		BIT(5)	/* C/T 2 Enable */
+#define Z8536_CFG_CTRL_PCE_CT3E		BIT(4)	/* Port C & C/T 3 Enable */
+#define Z8536_CFG_CTRL_PLC		BIT(3)	/* Port A/B Link Control */
+#define Z8536_CFG_CTRL_PAE		BIT(2)	/* Port A Enable */
+#define Z8536_CFG_CTRL_LC_INDEP		(0 << 0)/* C/Ts Independent */
+#define Z8536_CFG_CTRL_LC_GATE		(1 << 0)/* C/T 1 Out Gates C/T 2 */
+#define Z8536_CFG_CTRL_LC_TRIG		(2 << 0)/* C/T 1 Out Triggers C/T 2 */
+#define Z8536_CFG_CTRL_LC_CLK		(3 << 0)/* C/T 1 Out Clocks C/T 2 */
+#define Z8536_CFG_CTRL_LC_MASK		(3 << 0)/* C/T Link Control mask */
+
+/* Interrupt Vector registers */
+#define Z8536_PA_INT_VECT_REG		0x02
+#define Z8536_PB_INT_VECT_REG		0x03
+#define Z8536_CT_INT_VECT_REG		0x04
+#define Z8536_CURR_INT_VECT_REG		0x1f
+
+/* Port A/B & Counter/Timer 1/2/3 Command and Status registers */
+#define Z8536_PA_CMDSTAT_REG		0x08
+#define Z8536_PB_CMDSTAT_REG		0x09
+#define Z8536_CT1_CMDSTAT_REG		0x0a
+#define Z8536_CT2_CMDSTAT_REG		0x0b
+#define Z8536_CT3_CMDSTAT_REG		0x0c
+#define Z8536_CT_CMDSTAT_REG(x)		(0x0a + (x))
+#define Z8536_CMD_NULL			(0 << 5)/* Null Code */
+#define Z8536_CMD_CLR_IP_IUS		(1 << 5)/* Clear IP & IUS */
+#define Z8536_CMD_SET_IUS		(2 << 5)/* Set IUS */
+#define Z8536_CMD_CLR_IUS		(3 << 5)/* Clear IUS */
+#define Z8536_CMD_SET_IP		(4 << 5)/* Set IP */
+#define Z8536_CMD_CLR_IP		(5 << 5)/* Clear IP */
+#define Z8536_CMD_SET_IE		(6 << 5)/* Set IE */
+#define Z8536_CMD_CLR_IE		(7 << 5)/* Clear IE */
+#define Z8536_CMD_MASK			(7 << 5)
+
+#define Z8536_STAT_IUS			BIT(7)	/* Interrupt Under Service */
+#define Z8536_STAT_IE			BIT(6)	/* Interrupt Enable */
+#define Z8536_STAT_IP			BIT(5)	/* Interrupt Pending */
+#define Z8536_STAT_ERR			BIT(4)	/* Interrupt Error */
+#define Z8536_STAT_IE_IP		(Z8536_STAT_IE | Z8536_STAT_IP)
+
+#define Z8536_PAB_STAT_ORE		BIT(3)	/* Output Register Empty */
+#define Z8536_PAB_STAT_IRF		BIT(2)	/* Input Register Full */
+#define Z8536_PAB_STAT_PMF		BIT(1)	/* Pattern Match Flag */
+#define Z8536_PAB_CMDSTAT_IOE		BIT(0)	/* Interrupt On Error */
+
+#define Z8536_CT_CMD_RCC		BIT(3)	/* Read Counter Control */
+#define Z8536_CT_CMDSTAT_GCB		BIT(2)	/* Gate Command Bit */
+#define Z8536_CT_CMD_TCB		BIT(1)	/* Trigger Command Bit */
+#define Z8536_CT_STAT_CIP		BIT(0)	/* Count In Progress */
+
+/* Port Data registers */
+#define Z8536_PA_DATA_REG		0x0d
+#define Z8536_PB_DATA_REG		0x0e
+#define Z8536_PC_DATA_REG		0x0f
+
+/* Counter/Timer 1/2/3 Current Count registers */
+#define Z8536_CT1_VAL_MSB_REG		0x10
+#define Z8536_CT1_VAL_LSB_REG		0x11
+#define Z8536_CT2_VAL_MSB_REG		0x12
+#define Z8536_CT2_VAL_LSB_REG		0x13
+#define Z8536_CT3_VAL_MSB_REG		0x14
+#define Z8536_CT3_VAL_LSB_REG		0x15
+#define Z8536_CT_VAL_MSB_REG(x)		(0x10 + ((x) * 2))
+#define Z8536_CT_VAL_LSB_REG(x)		(0x11 + ((x) * 2))
+
+/* Counter/Timer 1/2/3 Time Constant registers */
+#define Z8536_CT1_RELOAD_MSB_REG	0x16
+#define Z8536_CT1_RELOAD_LSB_REG	0x17
+#define Z8536_CT2_RELOAD_MSB_REG	0x18
+#define Z8536_CT2_RELOAD_LSB_REG	0x19
+#define Z8536_CT3_RELOAD_MSB_REG	0x1a
+#define Z8536_CT3_RELOAD_LSB_REG	0x1b
+#define Z8536_CT_RELOAD_MSB_REG(x)	(0x16 + ((x) * 2))
+#define Z8536_CT_RELOAD_LSB_REG(x)	(0x17 + ((x) * 2))
+
+/* Counter/Timer 1/2/3 Mode Specification registers */
+#define Z8536_CT1_MODE_REG		0x1c
+#define Z8536_CT2_MODE_REG		0x1d
+#define Z8536_CT3_MODE_REG		0x1e
+#define Z8536_CT_MODE_REG(x)		(0x1c + (x))
+#define Z8536_CT_MODE_CSC		BIT(7)	/* Continuous/Single Cycle */
+#define Z8536_CT_MODE_EOE		BIT(6)	/* External Output Enable */
+#define Z8536_CT_MODE_ECE		BIT(5)	/* External Count Enable */
+#define Z8536_CT_MODE_ETE		BIT(4)	/* External Trigger Enable */
+#define Z8536_CT_MODE_EGE		BIT(3)	/* External Gate Enable */
+#define Z8536_CT_MODE_REB		BIT(2)	/* Retrigger Enable Bit */
+#define Z8536_CT_MODE_DCS_PULSE		(0 << 0)/* Duty Cycle - Pulse */
+#define Z8536_CT_MODE_DCS_ONESHOT	(1 << 0)/* Duty Cycle - One-Shot */
+#define Z8536_CT_MODE_DCS_SQRWAVE	(2 << 0)/* Duty Cycle - Square Wave */
+#define Z8536_CT_MODE_DCS_DO_NOT_USE	(3 << 0)/* Duty Cycle - Do Not Use */
+#define Z8536_CT_MODE_DCS_MASK		(3 << 0)/* Duty Cycle mask */
+
+/* Port A/B Mode Specification registers */
+#define Z8536_PA_MODE_REG		0x20
+#define Z8536_PB_MODE_REG		0x28
+#define Z8536_PAB_MODE_PTS_BIT		(0 << 6)/* Bit Port */
+#define Z8536_PAB_MODE_PTS_INPUT	(1 << 6)/* Input Port */
+#define Z8536_PAB_MODE_PTS_OUTPUT	(2 << 6)/* Output Port */
+#define Z8536_PAB_MODE_PTS_BIDIR	(3 << 6)/* Bidirectional Port */
+#define Z8536_PAB_MODE_PTS_MASK		(3 << 6)/* Port Type Select mask */
+#define Z8536_PAB_MODE_ITB		BIT(5)	/* Interrupt on Two Bytes */
+#define Z8536_PAB_MODE_SB		BIT(4)	/* Single Buffered mode */
+#define Z8536_PAB_MODE_IMO		BIT(3)	/* Interrupt on Match Only */
+#define Z8536_PAB_MODE_PMS_DISABLE	(0 << 1)/* Disable Pattern Match */
+#define Z8536_PAB_MODE_PMS_AND		(1 << 1)/* "AND" mode */
+#define Z8536_PAB_MODE_PMS_OR		(2 << 1)/* "OR" mode */
+#define Z8536_PAB_MODE_PMS_OR_PEV	(3 << 1)/* "OR-Priority" mode */
+#define Z8536_PAB_MODE_PMS_MASK		(3 << 1)/* Pattern Mode mask */
+#define Z8536_PAB_MODE_LPM		BIT(0)	/* Latch on Pattern Match */
+#define Z8536_PAB_MODE_DTE		BIT(0)	/* Deskew Timer Enabled */
+
+/* Port A/B Handshake Specification registers */
+#define Z8536_PA_HANDSHAKE_REG		0x21
+#define Z8536_PB_HANDSHAKE_REG		0x29
+#define Z8536_PAB_HANDSHAKE_HST_INTER	(0 << 6)/* Interlocked Handshake */
+#define Z8536_PAB_HANDSHAKE_HST_STROBED	(1 << 6)/* Strobed Handshake */
+#define Z8536_PAB_HANDSHAKE_HST_PULSED	(2 << 6)/* Pulsed Handshake */
+#define Z8536_PAB_HANDSHAKE_HST_3WIRE	(3 << 6)/* Three-Wire Handshake */
+#define Z8536_PAB_HANDSHAKE_HST_MASK	(3 << 6)/* Handshake Type mask */
+#define Z8536_PAB_HANDSHAKE_RWS_DISABLE	(0 << 3)/* Req/Wait Disabled */
+#define Z8536_PAB_HANDSHAKE_RWS_OUTWAIT	(1 << 3)/* Output Wait */
+#define Z8536_PAB_HANDSHAKE_RWS_INWAIT	(3 << 3)/* Input Wait */
+#define Z8536_PAB_HANDSHAKE_RWS_SPREQ	(4 << 3)/* Special Request */
+#define Z8536_PAB_HANDSHAKE_RWS_OUTREQ	(5 << 4)/* Output Request */
+#define Z8536_PAB_HANDSHAKE_RWS_INREQ	(7 << 3)/* Input Request */
+#define Z8536_PAB_HANDSHAKE_RWS_MASK	(7 << 3)/* Req/Wait mask */
+#define Z8536_PAB_HANDSHAKE_DESKEW(x)	((x) << 0)/* Deskew Time */
+#define Z8536_PAB_HANDSHAKE_DESKEW_MASK	(3 << 0)/* Deskew Time mask */
+
+/*
+ * Port A/B/C Data Path Polarity registers
+ *
+ *	0 = Non-Inverting
+ *	1 = Inverting
+ */
+#define Z8536_PA_DPP_REG		0x22
+#define Z8536_PB_DPP_REG		0x2a
+#define Z8536_PC_DPP_REG		0x05
+
+/*
+ * Port A/B/C Data Direction registers
+ *
+ *	0 = Output bit
+ *	1 = Input bit
+ */
+#define Z8536_PA_DD_REG			0x23
+#define Z8536_PB_DD_REG			0x2b
+#define Z8536_PC_DD_REG			0x06
+
+/*
+ * Port A/B/C Special I/O Control registers
+ *
+ *	0 = Normal Input or Output
+ *	1 = Output with open drain or Input with 1's catcher
+ */
+#define Z8536_PA_SIO_REG		0x24
+#define Z8536_PB_SIO_REG		0x2c
+#define Z8536_PC_SIO_REG		0x07
+
+/*
+ * Port A/B Pattern Polarity/Transition/Mask registers
+ *
+ *	PM PT PP  Pattern Specification
+ *	-- -- --  -------------------------------------
+ *	 0  0  x  Bit masked off
+ *	 0  1  x  Any transition
+ *	 1  0  0  Zero (low-level)
+ *	 1  0  1  One (high-level)
+ *	 1  1  0  One-to-zero transition (falling-edge)
+ *	 1  1  1  Zero-to-one transition (rising-edge)
+ */
+#define Z8536_PA_PP_REG			0x25
+#define Z8536_PB_PP_REG			0x2d
+
+#define Z8536_PA_PT_REG			0x26
+#define Z8536_PB_PT_REG			0x2e
+
+#define Z8536_PA_PM_REG			0x27
+#define Z8536_PB_PM_REG			0x2f
+
+#endif	/* _Z8536_H */
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index 8777f958c041..973f544e85e1 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -95,7 +95,7 @@ static int comedi_do_insn(struct comedi_device *dev,
 
 	if (s->type == COMEDI_SUBD_UNUSED) {
 		dev_err(dev->class_dev,
-			"%d not useable subdevice\n", insn->subdev);
+			"%d not usable subdevice\n", insn->subdev);
 		ret = -EIO;
 		goto error;
 	}
diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c
index 9a1dc56f21d1..6a393b24bdd9 100644
--- a/drivers/staging/comedi/range.c
+++ b/drivers/staging/comedi/range.c
@@ -1,20 +1,20 @@
 /*
-    module/range.c
-    comedi routines for voltage ranges
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-*/
+ * comedi/range.c
+ * comedi routines for voltage ranges
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
 
 #include <linux/uaccess.h>
 #include "comedidev.h"
@@ -42,18 +42,18 @@ const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none} } };
 EXPORT_SYMBOL_GPL(range_unknown);
 
 /*
-	COMEDI_RANGEINFO
-	range information ioctl
-
-	arg:
-		pointer to rangeinfo structure
-
-	reads:
-		range info structure
-
-	writes:
-		n struct comedi_krange structures to rangeinfo->range_ptr
-*/
+ * COMEDI_RANGEINFO ioctl
+ * range information
+ *
+ * arg:
+ *	pointer to comedi_rangeinfo structure
+ *
+ * reads:
+ *	comedi_rangeinfo structure
+ *
+ * writes:
+ *	array of comedi_krange structures to rangeinfo->range_ptr pointer
+ */
 int do_rangeinfo_ioctl(struct comedi_device *dev,
 		       struct comedi_rangeinfo __user *arg)
 {
diff --git a/drivers/staging/cptm1217/Kconfig b/drivers/staging/cptm1217/Kconfig
deleted file mode 100644
index 43b1cc0a50a5..000000000000
--- a/drivers/staging/cptm1217/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-config TOUCHSCREEN_CLEARPAD_TM1217
-	tristate "Synaptics Clearpad TM1217"
-	depends on I2C
-	depends on GPIOLIB
-	depends on INPUT
-	help
-	  Say Y here if you have a Synaptics Clearpad TM1217 Controller
-
-	  If unsure, say N.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called clearpad_tm1217.
diff --git a/drivers/staging/cptm1217/Makefile b/drivers/staging/cptm1217/Makefile
deleted file mode 100644
index 8961fafa80e7..000000000000
--- a/drivers/staging/cptm1217/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217)	+= clearpad_tm1217.o
-
diff --git a/drivers/staging/cptm1217/TODO b/drivers/staging/cptm1217/TODO
deleted file mode 100644
index 303922465e4d..000000000000
--- a/drivers/staging/cptm1217/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
-- Wait for the official upstream general clearpad drivers as promised over
-  the past few months
-- Merge any device support needed from this driver into it
-- Delete this driver
-
diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c
deleted file mode 100644
index 7f265ce0dd13..000000000000
--- a/drivers/staging/cptm1217/clearpad_tm1217.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * clearpad_tm1217.c - Touch Screen driver for Synaptics Clearpad
- * TM1217 controller
- *
- * Copyright (C) 2008 Intel Corp
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; ifnot, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * Questions/Comments/Bug fixes to Ramesh Agarwal (ramesh.agarwal@intel.com)
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/timer.h>
-#include <linux/gpio.h>
-#include <linux/hrtimer.h>
-#include <linux/kthread.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include "cp_tm1217.h"
-
-#define CPTM1217_DEVICE_NAME		"cptm1217"
-#define CPTM1217_DRIVER_NAME		CPTM1217_DEVICE_NAME
-
-#define MAX_TOUCH_SUPPORTED		2
-#define TOUCH_SUPPORTED			1
-#define SAMPLING_FREQ			80	/* Frequency in HZ */
-#define DELAY_BTWIN_SAMPLE		(1000 / SAMPLING_FREQ)
-#define WAIT_FOR_RESPONSE		5	/* 5msec just works */
-#define MAX_RETRIES			5	/* As above */
-#define INCREMENTAL_DELAY		5	/* As above */
-
-/* Regster Definitions */
-#define TMA1217_DEV_STATUS		0x13	/* Device Status */
-#define TMA1217_INT_STATUS		0x14	/* Interrupt Status */
-
-/* Controller can detect up to 2 possible finger touches.
- * Each finger touch provides  12 bit X Y co-ordinates, the values are split
- * across 2 registers, and an 8 bit  Z value */
-#define TMA1217_FINGER_STATE		0x18 /* Finger State */
-#define TMA1217_FINGER1_X_HIGHER8	0x19 /* Higher 8 bit of X coordinate */
-#define TMA1217_FINGER1_Y_HIGHER8	0x1A /* Higher 8 bit of Y coordinate */
-#define TMA1217_FINGER1_XY_LOWER4	0x1B /* Lower 4 bits of X and Y */
-#define TMA1217_FINGER1_Z_VALUE		0x1D /* 8 bit Z value for finger 1 */
-#define TMA1217_FINGER2_X_HIGHER8	0x1E /* Higher 8 bit of X coordinate */
-#define TMA1217_FINGER2_Y_HIGHER8	0x1F /* Higher 8 bit of Y coordinate */
-#define TMA1217_FINGER2_XY_LOWER4	0x20 /* Lower 4 bits of X and Y */
-#define TMA1217_FINGER2_Z_VALUE		0x22 /* 8 bit Z value for finger 2 */
-#define TMA1217_DEVICE_CTRL		0x23 /* Device Control */
-#define TMA1217_INTERRUPT_ENABLE	0x24 /* Interrupt Enable */
-#define TMA1217_REPORT_MODE		0x2B /* Reporting Mode */
-#define TMA1217_MAX_X_LOWER8		0x31 /* Bit 0-7 for Max X */
-#define TMA1217_MAX_X_HIGHER4		0x32 /* Bit 8-11 for Max X */
-#define TMA1217_MAX_Y_LOWER8		0x33 /* Bit 0-7 for Max Y */
-#define TMA1217_MAX_Y_HIGHER4		0x34 /* Bit 8-11 for Max Y */
-#define TMA1217_DEVICE_CMD_RESET	0x67 /* Device CMD reg for reset */
-#define TMA1217_DEVICE_CMD_REZERO	0x69 /* Device CMD reg for rezero */
-
-#define TMA1217_MANUFACTURER_ID		0x73 /* Manufacturer Id */
-#define TMA1217_PRODUCT_FAMILY		0x75 /* Product Family */
-#define TMA1217_FIRMWARE_REVISION	0x76 /* Firmware Revision */
-#define TMA1217_SERIAL_NO_HIGH		0x7C /* Bit 8-15 of device serial no. */
-#define TMA1217_SERIAL_NO_LOW		0x7D /* Bit 0-7 of device serial no. */
-#define TMA1217_PRODUCT_ID_START	0x7E /* Start address for 10 byte ID */
-#define TMA1217_DEVICE_CAPABILITY	0x8B /* Reporting capability */
-
-
-/*
- * The touch position structure.
- */
-struct touch_state {
-	int	x;
-	int	y;
-	bool button;
-};
-
-/* Device Specific info given by the controller */
-struct cp_dev_info {
-	u16	maxX;
-	u16	maxY;
-};
-
-/* Vendor related info given by the controller */
-struct cp_vendor_info {
-	u8	vendor_id;
-	u8	product_family;
-	u8	firmware_rev;
-	u16	serial_no;
-};
-
-/*
- * Private structure to store the device details
- */
-struct cp_tm1217_device {
-	struct i2c_client	*client;
-	struct device		*dev;
-	struct cp_vendor_info	vinfo;
-	struct cp_dev_info	dinfo;
-	struct input_dev_info {
-		char			phys[32];
-		char			name[128];
-		struct input_dev	*input;
-		struct touch_state	touch;
-	} cp_input_info[MAX_TOUCH_SUPPORTED];
-
-	int	thread_running;
-	struct mutex	thread_mutex;
-
-	int gpio;
-};
-
-
-/* The following functions are used to read/write registers on the device
- * as per the RMI prorocol. Technically, a page select should be written
- * before doing read/write but since the register offsets are below 0xFF
- * we can use the default value of page which is 0x00
- */
-static int cp_tm1217_read(struct cp_tm1217_device *ts,
-				u8 *req, int size)
-{
-	int i, retval;
-
-	/* Send the address */
-	retval = i2c_master_send(ts->client, &req[0], 1);
-	if (retval != 1) {
-		dev_err(ts->dev, "cp_tm1217: I2C send failed\n");
-		return retval;
-	}
-	msleep(WAIT_FOR_RESPONSE);
-	for (i = 0; i < MAX_RETRIES; i++) {
-		retval = i2c_master_recv(ts->client, &req[1], size);
-		if (retval == size)
-			break;
-
-		msleep(INCREMENTAL_DELAY);
-		dev_dbg(ts->dev, "cp_tm1217: Retry count is %d\n", i);
-	}
-	if (retval != size)
-		dev_err(ts->dev, "cp_tm1217: Read from device failed\n");
-
-	return retval;
-}
-
-static int cp_tm1217_write(struct cp_tm1217_device *ts,
-				u8 *req, int size)
-{
-	int retval;
-
-	/* Send the address and the data to be written */
-	retval = i2c_master_send(ts->client, &req[0], size + 1);
-	if (retval != size + 1) {
-		dev_err(ts->dev, "cp_tm1217: I2C write  failed: %d\n", retval);
-		return retval;
-	}
-	/* Wait for the write to complete. TBD why this is required */
-	msleep(WAIT_FOR_RESPONSE);
-
-	return size;
-}
-
-static int cp_tm1217_mask_interrupt(struct cp_tm1217_device *ts)
-{
-	u8 req[2];
-	int retval;
-
-	req[0] = TMA1217_INTERRUPT_ENABLE;
-	req[1] = 0x0;
-	retval = cp_tm1217_write(ts, req, 1);
-	if (retval != 1)
-		return -EIO;
-
-	return 0;
-}
-
-static int cp_tm1217_unmask_interrupt(struct cp_tm1217_device *ts)
-{
-	u8 req[2];
-	int retval;
-
-	req[0] = TMA1217_INTERRUPT_ENABLE;
-	req[1] = 0xa;
-	retval = cp_tm1217_write(ts, req, 1);
-	if (retval != 1)
-		return -EIO;
-
-	return 0;
-}
-
-static void process_touch(struct cp_tm1217_device *ts, int index)
-{
-	int retval;
-	struct input_dev_info *input_info =
-		(struct input_dev_info *)&ts->cp_input_info[index];
-	u8 xy_data[6];
-
-	if (index == 0)
-		xy_data[0] = TMA1217_FINGER1_X_HIGHER8;
-	else
-		xy_data[0] = TMA1217_FINGER2_X_HIGHER8;
-
-	retval = cp_tm1217_read(ts, xy_data, 5);
-	if (retval < 5) {
-		dev_err(ts->dev, "cp_tm1217: XY read from device failed\n");
-		return;
-	}
-
-	/* Note: Currently not using the Z values but may be requried in
-	   the future. */
-	input_info->touch.x = (xy_data[1] << 4)
-					| (xy_data[3] & 0x0F);
-	input_info->touch.y = (xy_data[2] << 4)
-					| ((xy_data[3] & 0xF0) >> 4);
-	input_report_abs(input_info->input, ABS_X, input_info->touch.x);
-	input_report_abs(input_info->input, ABS_Y, input_info->touch.y);
-	input_sync(input_info->input);
-}
-
-static void cp_tm1217_get_data(struct cp_tm1217_device *ts)
-{
-	u8 req[2];
-	int retval, i, finger_touched = 0;
-
-	do {
-		req[0] = TMA1217_FINGER_STATE;
-		retval = cp_tm1217_read(ts, req, 1);
-		if (retval != 1) {
-			dev_err(ts->dev,
-				"cp_tm1217: Read from device failed\n");
-			continue;
-		}
-		finger_touched = 0;
-		/* Start sampling until the pressure is below
-		  threshold */
-		for (i = 0; i < TOUCH_SUPPORTED; i++) {
-			if (req[1] & 0x3) {
-				finger_touched++;
-				if (ts->cp_input_info[i].touch.button == 0) {
-					/* send the button touch event */
-					input_report_key(
-						ts->cp_input_info[i].input,
-						BTN_TOUCH, 1);
-					ts->cp_input_info[i].touch.button = 1;
-				}
-				process_touch(ts, i);
-			} else {
-				if (ts->cp_input_info[i].touch.button == 1) {
-					/* send the button release event */
-					input_report_key(
-						ts->cp_input_info[i].input,
-						BTN_TOUCH, 0);
-					input_sync(ts->cp_input_info[i].input);
-					ts->cp_input_info[i].touch.button = 0;
-				}
-			}
-			req[1] = req[1] >> 2;
-		}
-		msleep(DELAY_BTWIN_SAMPLE);
-	} while (finger_touched > 0);
-}
-
-static irqreturn_t cp_tm1217_sample_thread(int irq, void *handle)
-{
-	struct cp_tm1217_device *ts = handle;
-	u8 req[2];
-	int retval;
-
-	/* Chedk if another thread is already running */
-	mutex_lock(&ts->thread_mutex);
-	if (ts->thread_running == 1) {
-		mutex_unlock(&ts->thread_mutex);
-		return IRQ_HANDLED;
-	}
-
-	ts->thread_running = 1;
-	mutex_unlock(&ts->thread_mutex);
-
-	/* Mask the interrupts */
-	retval = cp_tm1217_mask_interrupt(ts);
-
-	/* Read the Interrupt Status register to find the cause of the
-	   Interrupt */
-	req[0] = TMA1217_INT_STATUS;
-	retval = cp_tm1217_read(ts, req, 1);
-	if (retval != 1)
-		goto exit_thread;
-
-	if (!(req[1] & 0x8))
-		goto exit_thread;
-
-	cp_tm1217_get_data(ts);
-
-exit_thread:
-	/* Unmask the interrupts before going to sleep */
-	retval = cp_tm1217_unmask_interrupt(ts);
-
-	mutex_lock(&ts->thread_mutex);
-	ts->thread_running = 0;
-	mutex_unlock(&ts->thread_mutex);
-
-	return IRQ_HANDLED;
-}
-
-static int cp_tm1217_init_data(struct cp_tm1217_device *ts)
-{
-	int retval;
-	u8	req[2];
-
-	/* Read the vendor id/ fw revision etc. Ignoring return check as this
-	   is non critical info  */
-	req[0] = TMA1217_MANUFACTURER_ID;
-	retval = cp_tm1217_read(ts, req, 1);
-	ts->vinfo.vendor_id = req[1];
-
-	req[0] = TMA1217_PRODUCT_FAMILY;
-	retval = cp_tm1217_read(ts, req, 1);
-	ts->vinfo.product_family = req[1];
-
-	req[0] = TMA1217_FIRMWARE_REVISION;
-	retval = cp_tm1217_read(ts, req, 1);
-	ts->vinfo.firmware_rev = req[1];
-
-	req[0] = TMA1217_SERIAL_NO_HIGH;
-	retval = cp_tm1217_read(ts, req, 1);
-	ts->vinfo.serial_no = (req[1] << 8);
-
-	req[0] = TMA1217_SERIAL_NO_LOW;
-	retval = cp_tm1217_read(ts, req, 1);
-	ts->vinfo.serial_no = ts->vinfo.serial_no | req[1];
-
-	req[0] = TMA1217_MAX_X_HIGHER4;
-	retval = cp_tm1217_read(ts, req, 1);
-	ts->dinfo.maxX = (req[1] & 0xF) << 8;
-
-	req[0] = TMA1217_MAX_X_LOWER8;
-	retval = cp_tm1217_read(ts, req, 1);
-	ts->dinfo.maxX = ts->dinfo.maxX | req[1];
-
-	req[0] = TMA1217_MAX_Y_HIGHER4;
-	retval = cp_tm1217_read(ts, req, 1);
-	ts->dinfo.maxY = (req[1] & 0xF) << 8;
-
-	req[0] = TMA1217_MAX_Y_LOWER8;
-	retval = cp_tm1217_read(ts, req, 1);
-	ts->dinfo.maxY = ts->dinfo.maxY | req[1];
-
-	return 0;
-
-}
-
-/*
- *	Set up a GPIO for use as the interrupt. We can't simply do this at
- *	boot time because the GPIO drivers themselves may not be around at
- *	boot/firmware set up time to do the work. Instead defer it to driver
- *	detection.
- */
-
-static int cp_tm1217_setup_gpio_irq(struct cp_tm1217_device *ts)
-{
-	int retval;
-
-	/* Hook up the irq handler */
-	retval = gpio_request(ts->gpio, "cp_tm1217_touch");
-	if (retval < 0) {
-		dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n",
-								retval);
-		return retval;
-	}
-
-	retval = gpio_direction_input(ts->gpio);
-	if (retval < 0) {
-		dev_err(ts->dev,
-		"cp_tm1217: GPIO direction configuration failed, error %d\n",
-								retval);
-		gpio_free(ts->gpio);
-		return retval;
-	}
-
-	retval = gpio_to_irq(ts->gpio);
-	if (retval < 0) {
-		dev_err(ts->dev,
-			"cp_tm1217: GPIO to IRQ failed, error %d\n", retval);
-		gpio_free(ts->gpio);
-	}
-	dev_dbg(ts->dev,
-		"cp_tm1217: Got IRQ number is %d for GPIO %d\n",
-		retval, ts->gpio);
-	return retval;
-}
-
-static int cp_tm1217_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
-{
-	struct cp_tm1217_device *ts;
-	struct input_dev *input_dev;
-	struct input_dev_info	*input_info;
-	struct cp_tm1217_platform_data *pdata;
-	u8 req[2];
-	int i, retval;
-
-	/* No pdata is fine - we then use "normal" IRQ mode */
-
-	pdata = client->dev.platform_data;
-
-	ts = kzalloc(sizeof(struct cp_tm1217_device), GFP_KERNEL);
-	if (!ts)
-		return -ENOMEM;
-
-	ts->client = client;
-	ts->dev = &client->dev;
-	i2c_set_clientdata(client, ts);
-
-	ts->thread_running = 0;
-	mutex_init(&ts->thread_mutex);
-
-	/* Reset the Controller */
-	req[0] = TMA1217_DEVICE_CMD_RESET;
-	req[1] = 0x1;
-	retval = cp_tm1217_write(ts, req, 1);
-	if (retval != 1) {
-		dev_err(ts->dev, "cp_tm1217: Controller reset failed\n");
-		kfree(ts);
-		return -EIO;
-	}
-
-	/* Clear up the interrupt status from reset. */
-	req[0] = TMA1217_INT_STATUS;
-	retval = cp_tm1217_read(ts, req, 1);
-
-	/* Mask all the interrupts */
-	retval = cp_tm1217_mask_interrupt(ts);
-
-	/* Read the controller information */
-	cp_tm1217_init_data(ts);
-
-	/* The following code will register multiple event devices when
-	   multi-pointer is enabled, the code has not been tested
-	   with MPX */
-	for (i = 0; i < TOUCH_SUPPORTED; i++) {
-		input_dev = input_allocate_device();
-		if (input_dev == NULL) {
-			retval = -ENOMEM;
-			goto fail;
-		}
-		input_info = &ts->cp_input_info[i];
-		snprintf(input_info->name, sizeof(input_info->name),
-			"cp_tm1217_touchscreen_%d", i);
-		input_dev->name = input_info->name;
-		snprintf(input_info->phys, sizeof(input_info->phys),
-			"%s/input%d", dev_name(&client->dev), i);
-
-		input_dev->phys = input_info->phys;
-		input_dev->id.bustype = BUS_I2C;
-
-		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-		input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
-
-		input_set_abs_params(input_dev, ABS_X, 0, ts->dinfo.maxX, 0, 0);
-		input_set_abs_params(input_dev, ABS_Y, 0, ts->dinfo.maxY, 0, 0);
-
-		retval = input_register_device(input_dev);
-		if (retval) {
-			dev_err(ts->dev,
-				"Input dev registration failed for %s\n",
-					input_dev->name);
-			input_free_device(input_dev);
-			goto fail;
-		}
-		input_info->input = input_dev;
-	}
-
-	/* Setup the reporting mode to send an interrupt only when
-	   finger arrives or departs. */
-	req[0] = TMA1217_REPORT_MODE;
-	req[1] = 0x02;
-	retval = cp_tm1217_write(ts, req, 1);
-
-	/* Setup the device to no sleep mode for now and make it configured */
-	req[0] = TMA1217_DEVICE_CTRL;
-	req[1] = 0x84;
-	retval = cp_tm1217_write(ts, req, 1);
-
-	/* Check for the status of the device */
-	req[0] = TMA1217_DEV_STATUS;
-	retval = cp_tm1217_read(ts, req, 1);
-	if (req[1] != 0) {
-		dev_err(ts->dev,
-			"cp_tm1217: Device Status 0x%x != 0: config failed\n",
-			req[1]);
-
-		retval = -EIO;
-		goto fail;
-	}
-
-	if (pdata && pdata->gpio) {
-		ts->gpio = pdata->gpio;
-		retval = cp_tm1217_setup_gpio_irq(ts);
-	} else
-		retval = client->irq;
-
-	if (retval < 0) {
-		dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n",
-								retval);
-		goto fail;
-	}
-
-	client->irq = retval;
-
-
-	retval = request_threaded_irq(client->irq,
-		NULL, cp_tm1217_sample_thread,
-		IRQF_TRIGGER_FALLING, "cp_tm1217_touch", ts);
-	if (retval < 0) {
-		dev_err(ts->dev, "cp_tm1217: Request IRQ error %d\n", retval);
-		goto fail_gpio;
-	}
-
-	/* Unmask the interrupts */
-	retval = cp_tm1217_unmask_interrupt(ts);
-	if (retval == 0)
-		return 0;
-
-	free_irq(client->irq, ts);
-fail_gpio:
-	if (ts->gpio)
-		gpio_free(ts->gpio);
-fail:
-	/* Clean up before returning failure */
-	for (i = 0; i < TOUCH_SUPPORTED; i++) {
-		if (ts->cp_input_info[i].input)
-			input_unregister_device(ts->cp_input_info[i].input);
-	}
-	kfree(ts);
-	return retval;
-
-}
-
-#ifdef CONFIG_PM_SLEEP
-
-/*
- * cp_tm1217 suspend
- *
- */
-static int cp_tm1217_suspend(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct cp_tm1217_device *ts = i2c_get_clientdata(client);
-	u8 req[2];
-	int retval;
-
-	/* Put the controller to sleep */
-	req[0] = TMA1217_DEVICE_CTRL;
-	retval = cp_tm1217_read(ts, req, 1);
-	req[1] = (req[1] & 0xF8) | 0x1;
-	retval = cp_tm1217_write(ts, req, 1);
-
-	if (device_may_wakeup(&client->dev))
-		enable_irq_wake(client->irq);
-
-	return 0;
-}
-
-/*
- * cp_tm1217_resume
- *
- */
-static int cp_tm1217_resume(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct cp_tm1217_device *ts = i2c_get_clientdata(client);
-	u8 req[2];
-	int retval;
-
-	/* Take the controller out of sleep */
-	req[0] = TMA1217_DEVICE_CTRL;
-	retval = cp_tm1217_read(ts, req, 1);
-	req[1] = (req[1] & 0xF8) | 0x4;
-	retval = cp_tm1217_write(ts, req, 1);
-
-	/* Restore the register settings sinc the power to the
-	   could have been cut off */
-
-	/* Setup the reporting mode to send an interrupt only when
-	   finger arrives or departs. */
-	req[0] = TMA1217_REPORT_MODE;
-	req[1] = 0x02;
-	retval = cp_tm1217_write(ts, req, 1);
-
-	/* Setup the device to no sleep mode for now and make it configured */
-	req[0] = TMA1217_DEVICE_CTRL;
-	req[1] = 0x84;
-	retval = cp_tm1217_write(ts, req, 1);
-
-	/* Setup the interrupt mask */
-	retval = cp_tm1217_unmask_interrupt(ts);
-
-	if (device_may_wakeup(&client->dev))
-		disable_irq_wake(client->irq);
-
-	return 0;
-}
-
-#endif
-
-static SIMPLE_DEV_PM_OPS(cp_tm1217_pm_ops, cp_tm1217_suspend,
-	cp_tm1217_resume);
-
-/*
- * cp_tm1217_remove
- *
- */
-static int cp_tm1217_remove(struct i2c_client *client)
-{
-	struct cp_tm1217_device *ts = i2c_get_clientdata(client);
-	int i;
-
-	free_irq(client->irq, ts);
-	if (ts->gpio)
-		gpio_free(ts->gpio);
-	for (i = 0; i < TOUCH_SUPPORTED; i++)
-		input_unregister_device(ts->cp_input_info[i].input);
-	kfree(ts);
-	return 0;
-}
-
-static struct i2c_device_id cp_tm1217_idtable[] = {
-	{ CPTM1217_DEVICE_NAME, 0 },
-	{ }
-};
-
-MODULE_DEVICE_TABLE(i2c, cp_tm1217_idtable);
-
-static struct i2c_driver cp_tm1217_driver = {
-	.driver = {
-		.owner	= THIS_MODULE,
-		.name	= CPTM1217_DRIVER_NAME,
-		.pm	= &cp_tm1217_pm_ops,
-	},
-	.id_table	= cp_tm1217_idtable,
-	.probe		= cp_tm1217_probe,
-	.remove		= cp_tm1217_remove,
-};
-
-module_i2c_driver(cp_tm1217_driver);
-
-MODULE_AUTHOR("Ramesh Agarwal <ramesh.agarwal@intel.com>");
-MODULE_DESCRIPTION("Synaptics TM1217 TouchScreen Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/cptm1217/cp_tm1217.h b/drivers/staging/cptm1217/cp_tm1217.h
deleted file mode 100644
index 30bad357a055..000000000000
--- a/drivers/staging/cptm1217/cp_tm1217.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __LINUX_I2C_CP_TM1217_H
-#define __LINUX_I2C_CP_TM1217_H
-
-struct cp_tm1217_platform_data {
-	int gpio;		/* If not set uses the IRQ resource 0 */
-};
-
-#endif
diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c
index bdb5317e3d9d..7184747e0652 100644
--- a/drivers/staging/dgap/dgap.c
+++ b/drivers/staging/dgap/dgap.c
@@ -978,8 +978,8 @@ static int dgap_parsefile(char **in)
 				brd->u.board.conc1++;
 
 			conc_type = dgap_gettok(in);
-			if (conc_type == 0 || conc_type != CX ||
-			    conc_type != EPC) {
+			if (conc_type == 0 || (conc_type != CX &&
+			    conc_type != EPC)) {
 				pr_err("failed to set a type of concentratros");
 				return -1;
 			}
@@ -1019,8 +1019,8 @@ static int dgap_parsefile(char **in)
 				brd->u.board.module1++;
 
 			module_type = dgap_gettok(in);
-			if (module_type == 0 || module_type != PORTS ||
-			    module_type != MODEM) {
+			if (module_type == 0 || (module_type != PORTS &&
+			    module_type != MODEM)) {
 				pr_err("failed to set a type of module");
 				return -1;
 			}
@@ -1400,27 +1400,27 @@ static int dgap_remap(struct board_t *brd)
 		return -ENOMEM;
 
 	if (!request_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000,
-					"dgap")) {
-		release_mem_region(brd->membase, 0x200000);
-		return -ENOMEM;
-	}
+					"dgap"))
+		goto err_req_mem;
 
 	brd->re_map_membase = ioremap(brd->membase, 0x200000);
-	if (!brd->re_map_membase) {
-		release_mem_region(brd->membase, 0x200000);
-		release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
-		return -ENOMEM;
-	}
+	if (!brd->re_map_membase)
+		goto err_remap_mem;
 
 	brd->re_map_port = ioremap((brd->membase + PCI_IO_OFFSET), 0x200000);
-	if (!brd->re_map_port) {
-		release_mem_region(brd->membase, 0x200000);
-		release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
-		iounmap(brd->re_map_membase);
-		return -ENOMEM;
-	}
+	if (!brd->re_map_port)
+		goto err_remap_port;
 
 	return 0;
+
+err_remap_port:
+	iounmap(brd->re_map_membase);
+err_remap_mem:
+	release_mem_region(brd->membase + PCI_IO_OFFSET, 0x200000);
+err_req_mem:
+	release_mem_region(brd->membase, 0x200000);
+
+	return -ENOMEM;
 }
 
 static void dgap_unmap(struct board_t *brd)
diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c
index ba98ff348112..f177d3a258c2 100644
--- a/drivers/staging/dgnc/dgnc_driver.c
+++ b/drivers/staging/dgnc/dgnc_driver.c
@@ -97,12 +97,12 @@ static uint		dgnc_poll_stop;				/* Used to tell poller to stop */
 static struct timer_list dgnc_poll_timer;
 
 
-static struct pci_device_id dgnc_pci_tbl[] = {
-	{	DIGI_VID, PCI_DEVICE_CLASSIC_4_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	0 },
-	{	DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	1 },
-	{	DIGI_VID, PCI_DEVICE_CLASSIC_8_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	2 },
-	{	DIGI_VID, PCI_DEVICE_CLASSIC_8_422_DID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,	3 },
-	{0,}						/* 0 terminated list. */
+static const struct pci_device_id dgnc_pci_tbl[] = {
+	{PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_4_DID),     .driver_data = 0},
+	{PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID), .driver_data = 1},
+	{PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_8_DID),     .driver_data = 2},
+	{PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_8_422_DID), .driver_data = 3},
+	{0,}
 };
 MODULE_DEVICE_TABLE(pci, dgnc_pci_tbl);
 
@@ -238,6 +238,7 @@ static int dgnc_start(void)
 {
 	int rc = 0;
 	unsigned long flags;
+	struct device *dev;
 
 	/* make sure that the globals are init'd before we do anything else */
 	dgnc_init_globals();
@@ -257,9 +258,20 @@ static int dgnc_start(void)
 	dgnc_Major = rc;
 
 	dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt");
-	device_create(dgnc_class, NULL,
-		MKDEV(dgnc_Major, 0),
-		NULL, "dgnc_mgmt");
+	if (IS_ERR(dgnc_class)) {
+		rc = PTR_ERR(dgnc_class);
+		pr_err(DRVSTR ": Can't create dgnc_mgmt class (%d)\n", rc);
+		goto failed_class;
+	}
+
+	dev = device_create(dgnc_class, NULL,
+			MKDEV(dgnc_Major, 0),
+			NULL, "dgnc_mgmt");
+	if (IS_ERR(dev)) {
+		rc = PTR_ERR(dev);
+		pr_err(DRVSTR ": Can't create device (%d)\n", rc);
+		goto failed_device;
+	}
 
 	/*
 	 * Init any global tty stuff.
@@ -268,7 +280,7 @@ static int dgnc_start(void)
 
 	if (rc < 0) {
 		pr_err(DRVSTR ": tty preinit - not enough memory (%d)\n", rc);
-		return rc;
+		goto failed_tty;
 	}
 
 	/* Start the poller */
@@ -282,6 +294,14 @@ static int dgnc_start(void)
 
 	add_timer(&dgnc_poll_timer);
 
+	return 0;
+
+failed_tty:
+	device_destroy(dgnc_class, MKDEV(dgnc_Major, 0));
+failed_device:
+	class_destroy(dgnc_class);
+failed_class:
+	unregister_chrdev(dgnc_Major, "dgnc");
 	return rc;
 }
 
diff --git a/drivers/staging/dgnc/dgnc_utils.c b/drivers/staging/dgnc/dgnc_utils.c
index 61efc13ec160..80b51332292c 100644
--- a/drivers/staging/dgnc/dgnc_utils.c
+++ b/drivers/staging/dgnc/dgnc_utils.c
@@ -12,7 +12,7 @@
  */
 int dgnc_ms_sleep(ulong ms)
 {
-	current->state = TASK_INTERRUPTIBLE;
+	__set_current_state(TASK_INTERRUPTIBLE);
 	schedule_timeout((ms * HZ) / 1000);
 	return signal_pending(current);
 }
diff --git a/drivers/staging/dgnc/digi.h b/drivers/staging/dgnc/digi.h
index 3181a3590465..d6e0b9f6b24a 100644
--- a/drivers/staging/dgnc/digi.h
+++ b/drivers/staging/dgnc/digi.h
@@ -38,8 +38,8 @@
 
 #if !defined(TIOCMODG)
 
-#define	TIOCMODG	('d'<<8) | 250		/* get modem ctrl state	*/
-#define	TIOCMODS	('d'<<8) | 251		/* set modem ctrl state	*/
+#define	TIOCMODG	(('d'<<8) | 250)	/* get modem ctrl state	*/
+#define	TIOCMODS	(('d'<<8) | 251)	/* set modem ctrl state	*/
 
 #ifndef TIOCM_LE
 #define		TIOCM_LE	0x01		/* line enable		*/
@@ -58,44 +58,44 @@
 #endif
 
 #if !defined(TIOCMSET)
-#define	TIOCMSET	('d'<<8) | 252		/* set modem ctrl state	*/
-#define	TIOCMGET	('d'<<8) | 253		/* set modem ctrl state	*/
+#define	TIOCMSET	(('d'<<8) | 252)	/* set modem ctrl state	*/
+#define	TIOCMGET	(('d'<<8) | 253)	/* set modem ctrl state	*/
 #endif
 
 #if !defined(TIOCMBIC)
-#define	TIOCMBIC	('d'<<8) | 254		/* set modem ctrl state */
-#define	TIOCMBIS	('d'<<8) | 255		/* set modem ctrl state */
+#define	TIOCMBIC	(('d'<<8) | 254)	/* set modem ctrl state */
+#define	TIOCMBIS	(('d'<<8) | 255)	/* set modem ctrl state */
 #endif
 
 
 #if !defined(TIOCSDTR)
-#define	TIOCSDTR	('e'<<8) | 0		/* set DTR		*/
-#define	TIOCCDTR	('e'<<8) | 1		/* clear DTR		*/
+#define	TIOCSDTR	(('e'<<8) | 0)		/* set DTR		*/
+#define	TIOCCDTR	(('e'<<8) | 1)		/* clear DTR		*/
 #endif
 
 /************************************************************************
  * Ioctl command arguments for DIGI parameters.
  ************************************************************************/
-#define DIGI_GETA	('e'<<8) | 94		/* Read params		*/
+#define DIGI_GETA	(('e'<<8) | 94)		/* Read params		*/
 
-#define DIGI_SETA	('e'<<8) | 95		/* Set params		*/
-#define DIGI_SETAW	('e'<<8) | 96		/* Drain & set params	*/
-#define DIGI_SETAF	('e'<<8) | 97		/* Drain, flush & set params */
+#define DIGI_SETA	(('e'<<8) | 95)		/* Set params		*/
+#define DIGI_SETAW	(('e'<<8) | 96)		/* Drain & set params	*/
+#define DIGI_SETAF	(('e'<<8) | 97)		/* Drain, flush & set params */
 
-#define DIGI_KME	('e'<<8) | 98		/* Read/Write Host	*/
+#define DIGI_KME	(('e'<<8) | 98)		/* Read/Write Host	*/
 						/* Adapter Memory	*/
 
-#define	DIGI_GETFLOW	('e'<<8) | 99		/* Get startc/stopc flow */
+#define	DIGI_GETFLOW	(('e'<<8) | 99)		/* Get startc/stopc flow */
 						/* control characters	 */
-#define	DIGI_SETFLOW	('e'<<8) | 100		/* Set startc/stopc flow */
+#define	DIGI_SETFLOW	(('e'<<8) | 100)	/* Set startc/stopc flow */
 						/* control characters	 */
-#define	DIGI_GETAFLOW	('e'<<8) | 101		/* Get Aux. startc/stopc */
+#define	DIGI_GETAFLOW	(('e'<<8) | 101)	/* Get Aux. startc/stopc */
 						/* flow control chars	 */
-#define	DIGI_SETAFLOW	('e'<<8) | 102		/* Set Aux. startc/stopc */
+#define	DIGI_SETAFLOW	(('e'<<8) | 102)	/* Set Aux. startc/stopc */
 						/* flow control chars	 */
 
-#define DIGI_GEDELAY	('d'<<8) | 246		/* Get edelay */
-#define DIGI_SEDELAY	('d'<<8) | 247		/* Set edelay */
+#define DIGI_GEDELAY	(('d'<<8) | 246)	/* Get edelay */
+#define DIGI_SEDELAY	(('d'<<8) | 247)	/* Set edelay */
 
 struct	digiflow_t {
 	unsigned char	startc;				/* flow cntl start char	*/
@@ -104,8 +104,8 @@ struct	digiflow_t {
 
 
 #ifdef	FLOW_2200
-#define	F2200_GETA	('e'<<8) | 104		/* Get 2x36 flow cntl flags */
-#define	F2200_SETAW	('e'<<8) | 105		/* Set 2x36 flow cntl flags */
+#define	F2200_GETA	(('e'<<8) | 104)	/* Get 2x36 flow cntl flags */
+#define	F2200_SETAW	(('e'<<8) | 105)	/* Set 2x36 flow cntl flags */
 #define		F2200_MASK	0x03		/* 2200 flow cntl bit mask  */
 #define		FCNTL_2200	0x01		/* 2x36 terminal flow cntl  */
 #define		PCNTL_2200	0x02		/* 2x36 printer flow cntl   */
@@ -241,7 +241,7 @@ struct digi_dinfo {
 	char		dinfo_version[16];	/* driver version       */
 };
 
-#define	DIGI_GETDD	('d'<<8) | 248		/* get driver info      */
+#define	DIGI_GETDD	(('d'<<8) | 248)	/* get driver info      */
 
 /************************************************************************
  * Structure used with ioctl commands for per-board information
@@ -261,7 +261,7 @@ struct digi_info {
 	char		info_reserved[7];	/* for future expansion    */
 };
 
-#define	DIGI_GETBD	('d'<<8) | 249		/* get board info          */
+#define	DIGI_GETBD	(('d'<<8) | 249)	/* get board info          */
 
 struct digi_stat {
 	unsigned int	info_chan;		/* Channel number (0 based)  */
@@ -276,7 +276,7 @@ struct digi_stat {
 	unsigned int	info_reserved[8];	/* for future expansion    */
 };
 
-#define	DIGI_GETSTAT	('d'<<8) | 244		/* get board info          */
+#define	DIGI_GETSTAT	(('d'<<8) | 244)	/* get board info          */
 /************************************************************************
  *
  * Structure used with ioctl commands for per-channel information
@@ -339,7 +339,7 @@ struct digi_getcounter {
 #define INFO_CH_WLOW	0x0020
 #define INFO_XXBUF_BUSY 0x0040
 
-#define	DIGI_GETCH	('d'<<8) | 245		/* get board info          */
+#define	DIGI_GETCH	(('d'<<8) | 245)	/* get board info          */
 
 /* Board type definitions */
 
@@ -384,15 +384,15 @@ struct digi_getcounter {
 #define BD_TRIBOOT	0x8
 #define	BD_BADKME	0x80
 
-#define DIGI_SPOLL            ('d'<<8) | 254  /* change poller rate   */
+#define DIGI_SPOLL            (('d'<<8) | 254)  /* change poller rate   */
 
 #define DIGI_SETCUSTOMBAUD	_IOW('e', 106, int)	/* Set integer baud rate */
 #define DIGI_GETCUSTOMBAUD	_IOR('e', 107, int)	/* Get integer baud rate */
 
-#define DIGI_REALPORT_GETBUFFERS ('e'<<8) | 108
-#define DIGI_REALPORT_SENDIMMEDIATE ('e'<<8) | 109
-#define DIGI_REALPORT_GETCOUNTERS ('e'<<8) | 110
-#define DIGI_REALPORT_GETEVENTS ('e'<<8) | 111
+#define DIGI_REALPORT_GETBUFFERS (('e'<<8) | 108)
+#define DIGI_REALPORT_SENDIMMEDIATE (('e'<<8) | 109)
+#define DIGI_REALPORT_GETCOUNTERS (('e'<<8) | 110)
+#define DIGI_REALPORT_GETEVENTS (('e'<<8) | 111)
 
 #define EV_OPU		0x0001		/* !<Output paused by client */
 #define EV_OPS		0x0002		/* !<Output paused by reqular sw flowctrl */
diff --git a/drivers/staging/dgnc/dpacompat.h b/drivers/staging/dgnc/dpacompat.h
index b2d2dc08f869..33cb394524b8 100644
--- a/drivers/staging/dgnc/dpacompat.h
+++ b/drivers/staging/dgnc/dpacompat.h
@@ -51,7 +51,7 @@ struct ni_info {
 
 #define RW_READ		1
 #define RW_WRITE        2
-#define DIGI_KME        ('e'<<8) | 98           /* Read/Write Host */
+#define DIGI_KME        (('e'<<8) | 98)         /* Read/Write Host */
 
 #define SUBTYPE         0007
 #define T_PCXI          0000
@@ -106,10 +106,10 @@ struct ni_info {
 
 /* Ioctls needed for dpa operation */
 
-#define DIGI_GETDD      ('d'<<8) | 248          /* get driver info      */
-#define DIGI_GETBD      ('d'<<8) | 249          /* get board info       */
-#define DIGI_GET_NI_INFO ('d'<<8) | 250		/* nonintelligent state snfo */
+#define DIGI_GETDD      (('d'<<8) | 248)       /* get driver info      */
+#define DIGI_GETBD      (('d'<<8) | 249)       /* get board info       */
+#define DIGI_GET_NI_INFO (('d'<<8) | 250)	/* nonintelligent state snfo */
 
 /* Other special ioctls */
-#define DIGI_TIMERIRQ ('d'<<8) | 251		/* Enable/disable RS_TIMER use */
-#define DIGI_LOOPBACK ('d'<<8) | 252		/* Enable/disable UART internal loopback */
+#define DIGI_TIMERIRQ (('d'<<8) | 251)		/* Enable/disable RS_TIMER use */
+#define DIGI_LOOPBACK (('d'<<8) | 252)		/* Enable/disable UART internal loopback */
diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c
index bd70ea05708b..4be646ce8a12 100644
--- a/drivers/staging/emxx_udc/emxx_udc.c
+++ b/drivers/staging/emxx_udc/emxx_udc.c
@@ -3249,42 +3249,6 @@ static const char *gp_ep_name[NUM_ENDPOINTS] = {
 };
 
 /*-------------------------------------------------------------------------*/
-static void __init nbu2ss_drv_set_ep_info(
-	struct nbu2ss_udc	*udc,
-	struct nbu2ss_ep	*ep,
-	const char *name)
-{
-	ep->udc = udc;
-	ep->desc = NULL;
-
-	ep->ep.driver_data = NULL;
-	ep->ep.name = name;
-	ep->ep.ops = &nbu2ss_ep_ops;
-
-	if (isdigit(name[2])) {
-
-		long	num;
-		int	res;
-		char	tempbuf[2];
-
-		tempbuf[0] = name[2];
-		tempbuf[1] = '\0';
-		res = kstrtol(tempbuf, 16, &num);
-
-		if (num == 0)
-			ep->ep.maxpacket = EP0_PACKETSIZE;
-		else
-			ep->ep.maxpacket = EP_PACKETSIZE;
-
-	} else {
-		ep->ep.maxpacket = EP_PACKETSIZE;
-	}
-
-	list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
-	INIT_LIST_HEAD(&ep->queue);
-}
-
-/*-------------------------------------------------------------------------*/
 static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
 {
 	int	i;
@@ -3292,9 +3256,21 @@ static void __init nbu2ss_drv_ep_init(struct nbu2ss_udc *udc)
 	INIT_LIST_HEAD(&udc->gadget.ep_list);
 	udc->gadget.ep0 = &udc->ep[0].ep;
 
+	for (i = 0; i < NUM_ENDPOINTS; i++) {
+		struct nbu2ss_ep *ep = &udc->ep[i];
 
-	for (i = 0; i < NUM_ENDPOINTS; i++)
-		nbu2ss_drv_set_ep_info(udc, &udc->ep[i], gp_ep_name[i]);
+		ep->udc = udc;
+		ep->desc = NULL;
+
+		ep->ep.driver_data = NULL;
+		ep->ep.name = gp_ep_name[i];
+		ep->ep.ops = &nbu2ss_ep_ops;
+
+		ep->ep.maxpacket = (i == 0 ? EP0_PACKETSIZE : EP_PACKETSIZE);
+
+		list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+		INIT_LIST_HEAD(&ep->queue);
+	}
 
 	list_del_init(&udc->ep[0].ep.ep_list);
 }
diff --git a/drivers/staging/fbtft/Kconfig b/drivers/staging/fbtft/Kconfig
new file mode 100644
index 000000000000..995a9101a080
--- /dev/null
+++ b/drivers/staging/fbtft/Kconfig
@@ -0,0 +1,169 @@
+menuconfig FB_TFT
+	tristate "Support for small TFT LCD display modules"
+	depends on FB && SPI && GPIOLIB
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select FB_SYS_FOPS
+	select FB_DEFERRED_IO
+	select FB_BACKLIGHT
+
+config FB_TFT_AGM1264K_FL
+	tristate "FB driver for the AGM1264K-FL LCD display"
+	depends on FB_TFT
+	help
+	  Framebuffer support for the AGM1264K-FL LCD display (two Samsung KS0108 compatable chips)
+
+config FB_TFT_BD663474
+	tristate "FB driver for the BD663474 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for BD663474
+
+config FB_TFT_HX8340BN
+	tristate "FB driver for the HX8340BN LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for HX8340BN
+
+config FB_TFT_HX8347D
+	tristate "FB driver for the HX8347D LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for HX8347D
+
+config FB_TFT_HX8353D
+	tristate "FB driver for the HX8353D LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for HX8353D
+
+config FB_TFT_ILI9320
+	tristate "FB driver for the ILI9320 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for ILI9320
+
+config FB_TFT_ILI9325
+	tristate "FB driver for the ILI9325 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for ILI9325
+
+config FB_TFT_ILI9340
+	tristate "FB driver for the ILI9340 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for ILI9340
+
+config FB_TFT_ILI9341
+	tristate "FB driver for the ILI9341 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for ILI9341
+
+config FB_TFT_ILI9481
+	tristate "FB driver for the ILI9481 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for ILI9481
+
+config FB_TFT_ILI9486
+	tristate "FB driver for the ILI9486 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for ILI9486
+
+config FB_TFT_PCD8544
+	tristate "FB driver for the PCD8544 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for PCD8544
+
+config FB_TFT_RA8875
+        tristate "FB driver for the RA8875 LCD Controller"
+        depends on FB_TFT
+	help
+	  Generic Framebuffer support for RA8875
+
+config FB_TFT_S6D02A1
+	tristate "FB driver for the S6D02A1 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for S6D02A1
+
+config FB_TFT_S6D1121
+	tristate "FB driver for the S6D1211 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for S6D1121
+
+config FB_TFT_SSD1289
+	tristate "FB driver for the SSD1289 LCD Controller"
+	depends on FB_TFT
+	help
+	  Framebuffer support for SSD1289
+
+config FB_TFT_SSD1306
+	tristate "FB driver for the SSD1306 OLED Controller"
+	depends on FB_TFT
+	help
+	  Framebuffer support for SSD1306
+
+config FB_TFT_SSD1331
+	tristate "FB driver for the SSD1331 LCD Controller"
+	depends on FB_TFT
+	help
+	  Framebuffer support for SSD1331
+
+config FB_TFT_SSD1351
+	tristate "FB driver for the SSD1351 LCD Controller"
+	depends on FB_TFT
+	help
+	  Framebuffer support for SSD1351
+
+config FB_TFT_ST7735R
+	tristate "FB driver for the ST7735R LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for ST7735R
+
+config FB_TFT_TINYLCD
+	tristate "FB driver for tinylcd.com display"
+	depends on FB_TFT
+	help
+	  Custom Framebuffer support for tinylcd.com display
+
+config FB_TFT_TLS8204
+	tristate "FB driver for the TLS8204 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for TLS8204
+
+config FB_TFT_UC1701
+	tristate "FB driver for the UC1701 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for UC1701
+
+config FB_TFT_UPD161704
+	tristate "FB driver for the uPD161704 LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for uPD161704
+
+config FB_TFT_WATTEROTT
+	tristate "FB driver for the WATTEROTT LCD Controller"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for WATTEROTT
+
+config FB_FLEX
+	tristate "Generic FB driver for TFT LCD displays"
+	depends on FB_TFT
+	help
+	  Generic Framebuffer support for TFT LCD displays.
+
+config FB_TFT_FBTFT_DEVICE
+	tristate "Module to for adding FBTFT devices"
+	depends on FB_TFT
diff --git a/drivers/staging/fbtft/Makefile b/drivers/staging/fbtft/Makefile
new file mode 100644
index 000000000000..e773f0fdcfe8
--- /dev/null
+++ b/drivers/staging/fbtft/Makefile
@@ -0,0 +1,34 @@
+# Core module
+obj-$(CONFIG_FB_TFT)             += fbtft.o
+fbtft-y                          += fbtft-core.o fbtft-sysfs.o fbtft-bus.o fbtft-io.o
+
+# drivers
+obj-$(CONFIG_FB_TFT_AGM1264K_FL) += fb_agm1264k-fl.o
+obj-$(CONFIG_FB_TFT_BD663474)    += fb_bd663474.o
+obj-$(CONFIG_FB_TFT_HX8340BN)    += fb_hx8340bn.o
+obj-$(CONFIG_FB_TFT_HX8347D)     += fb_hx8347d.o
+obj-$(CONFIG_FB_TFT_HX8353D)     += fb_hx8353d.o
+obj-$(CONFIG_FB_TFT_ILI9320)     += fb_ili9320.o
+obj-$(CONFIG_FB_TFT_ILI9325)     += fb_ili9325.o
+obj-$(CONFIG_FB_TFT_ILI9340)     += fb_ili9340.o
+obj-$(CONFIG_FB_TFT_ILI9341)     += fb_ili9341.o
+obj-$(CONFIG_FB_TFT_ILI9481)     += fb_ili9481.o
+obj-$(CONFIG_FB_TFT_ILI9486)     += fb_ili9486.o
+obj-$(CONFIG_FB_TFT_PCD8544)     += fb_pcd8544.o
+obj-$(CONFIG_FB_TFT_RA8875)      += fb_ra8875.o
+obj-$(CONFIG_FB_TFT_S6D02A1)     += fb_s6d02a1.o
+obj-$(CONFIG_FB_TFT_S6D1121)     += fb_s6d1121.o
+obj-$(CONFIG_FB_TFT_SSD1289)     += fb_ssd1289.o
+obj-$(CONFIG_FB_TFT_SSD1306)     += fb_ssd1306.o
+obj-$(CONFIG_FB_TFT_SSD1331)     += fb_ssd1331.o
+obj-$(CONFIG_FB_TFT_SSD1351)     += fb_ssd1351.o
+obj-$(CONFIG_FB_TFT_ST7735R)     += fb_st7735r.o
+obj-$(CONFIG_FB_TFT_TINYLCD)     += fb_tinylcd.o
+obj-$(CONFIG_FB_TFT_TLS8204)     += fb_tls8204.o
+obj-$(CONFIG_FB_TFT_UC1701)      += fb_uc1701.o
+obj-$(CONFIG_FB_TFT_UPD161704)   += fb_upd161704.o
+obj-$(CONFIG_FB_TFT_WATTEROTT)   += fb_watterott.o
+obj-$(CONFIG_FB_FLEX)            += flexfb.o
+
+# Device modules
+obj-$(CONFIG_FB_TFT_FBTFT_DEVICE) += fbtft_device.o
diff --git a/drivers/staging/fbtft/README b/drivers/staging/fbtft/README
new file mode 100644
index 000000000000..bc89b5805f7b
--- /dev/null
+++ b/drivers/staging/fbtft/README
@@ -0,0 +1,32 @@
+  FBTFT
+=========
+
+Linux Framebuffer drivers for small TFT LCD display modules.
+The module 'fbtft' makes writing drivers for some of these displays very easy.
+
+Development is done on a Raspberry Pi running the Raspbian "wheezy" distribution.
+
+INSTALLATION
+  Download kernel sources
+
+  From Linux 3.15  
+    cd drivers/video/fbdev/fbtft
+    git clone https://github.com/notro/fbtft.git
+    
+    Add to drivers/video/fbdev/Kconfig:   source "drivers/video/fbdev/fbtft/Kconfig"
+    Add to drivers/video/fbdev/Makefile:  obj-y += fbtft/
+  
+  Before Linux 3.15  
+    cd drivers/video
+    git clone https://github.com/notro/fbtft.git
+    
+    Add to drivers/video/Kconfig:   source "drivers/video/fbtft/Kconfig"
+    Add to drivers/video/Makefile:  obj-y += fbtft/
+  
+  Enable driver(s) in menuconfig and build the kernel
+
+
+See wiki for more information: https://github.com/notro/fbtft/wiki
+
+
+Source: https://github.com/notro/fbtft/
diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c
new file mode 100644
index 000000000000..9cc7d25cf0e5
--- /dev/null
+++ b/drivers/staging/fbtft/fb_agm1264k-fl.c
@@ -0,0 +1,462 @@
+/*
+ * FB driver for Two KS0108 LCD controllers in AGM1264K-FL display
+ *
+ * Copyright (C) 2014 ololoshka2871
+ *
+ * This program is 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/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+
+#include "fbtft.h"
+
+/* Uncomment text line to use negative image on display */
+/*#define NEGATIVE*/
+
+#define WHITE		0xff
+#define BLACK		0
+
+#define DRVNAME		"fb_agm1264k-fl"
+#define WIDTH		64
+#define HEIGHT		64
+#define TOTALWIDTH	(WIDTH * 2)	 /* because 2 x ks0108 in one display */
+#define FPS			20
+
+#define EPIN		gpio.wr
+#define RS			gpio.dc
+#define RW			gpio.aux[2]
+#define CS0			gpio.aux[0]
+#define CS1			gpio.aux[1]
+
+
+/* diffusing error (“Floyd-Steinberg”) */
+#define DIFFUSING_MATRIX_WIDTH	2
+#define DIFFUSING_MATRIX_HEIGHT	2
+
+static const signed char
+diffusing_matrix[DIFFUSING_MATRIX_WIDTH][DIFFUSING_MATRIX_HEIGHT] = {
+	{-1, 3},
+	{3, 2},
+};
+
+static const unsigned char gamma_correction_table[] = {
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6,
+6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13,
+13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21,
+22, 22, 23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32,
+33, 33, 34, 35, 35, 36, 37, 38, 39, 39, 40, 41, 42, 43, 43, 44, 45,
+46, 47, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 81,
+82, 83, 84, 85, 87, 88, 89, 90, 91, 93, 94, 95, 97, 98, 99, 100, 102,
+103, 105, 106, 107, 109, 110, 111, 113, 114, 116, 117, 119, 120, 121,
+123, 124, 126, 127, 129, 130, 132, 133, 135, 137, 138, 140, 141, 143,
+145, 146, 148, 149, 151, 153, 154, 156, 158, 159, 161, 163, 165, 166,
+168, 170, 172, 173, 175, 177, 179, 181, 182, 184, 186, 188, 190, 192,
+194, 196, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219,
+221, 223, 225, 227, 229, 231, 234, 236, 238, 240, 242, 244, 246, 248,
+251, 253, 255
+};
+
+static int init_display(struct fbtft_par *par)
+{
+	u8 i;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	for (i = 0; i < 2; ++i) {
+		write_reg(par, i, 0x3f); /* display on */
+		write_reg(par, i, 0x40); /* set x to 0 */
+		write_reg(par, i, 0xb0); /* set page to 0 */
+		write_reg(par, i, 0xc0); /* set start line to 0 */
+	}
+
+	return 0;
+}
+
+static void reset(struct fbtft_par *par)
+{
+	if (par->gpio.reset == -1)
+		return;
+
+	fbtft_dev_dbg(DEBUG_RESET, par, par->info->device, "%s()\n", __func__);
+
+	gpio_set_value(par->gpio.reset, 0);
+	udelay(20);
+	gpio_set_value(par->gpio.reset, 1);
+	mdelay(120);
+}
+
+/* Check if all necessary GPIOS defined */
+static int verify_gpios(struct fbtft_par *par)
+{
+	int i;
+
+	fbtft_dev_dbg(DEBUG_VERIFY_GPIOS, par, par->info->device,
+		"%s()\n", __func__);
+
+	if (par->EPIN < 0) {
+		dev_err(par->info->device,
+			"Missing info about 'wr' (aka E) gpio. Aborting.\n");
+		return -EINVAL;
+	}
+	for (i = 0; i < 8; ++i) {
+		if (par->gpio.db[i] < 0) {
+			dev_err(par->info->device,
+				"Missing info about 'db[%i]' gpio. Aborting.\n",
+				i);
+			return -EINVAL;
+		}
+	}
+	if (par->CS0 < 0) {
+		dev_err(par->info->device,
+			"Missing info about 'cs0' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+	if (par->CS1 < 0) {
+		dev_err(par->info->device,
+			"Missing info about 'cs1' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+	if (par->RW < 0) {
+		dev_err(par->info->device,
+			"Missing info about 'rw' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned long
+request_gpios_match(struct fbtft_par *par, const struct fbtft_gpio *gpio)
+{
+	fbtft_dev_dbg(DEBUG_REQUEST_GPIOS_MATCH, par, par->info->device,
+		"%s('%s')\n", __func__, gpio->name);
+
+	if (strcasecmp(gpio->name, "wr") == 0) {
+		/* left ks0108 E pin */
+		par->EPIN = gpio->gpio;
+		return GPIOF_OUT_INIT_LOW;
+	} else if (strcasecmp(gpio->name, "cs0") == 0) {
+		/* left ks0108 controller pin */
+		par->CS0 = gpio->gpio;
+		return GPIOF_OUT_INIT_HIGH;
+	} else if (strcasecmp(gpio->name, "cs1") == 0) {
+		/* right ks0108 controller pin */
+		par->CS1 = gpio->gpio;
+		return GPIOF_OUT_INIT_HIGH;
+	}
+
+	/* if write (rw = 0) e(1->0) perform write */
+	/* if read (rw = 1) e(0->1) set data on D0-7*/
+	else if (strcasecmp(gpio->name, "rw") == 0) {
+		par->RW = gpio->gpio;
+		return GPIOF_OUT_INIT_LOW;
+	}
+
+	return FBTFT_GPIO_NO_MATCH;
+}
+
+/* This function oses to enter commands
+ * first byte - destination controller 0 or 1
+ * folowing - commands
+ */
+static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
+{
+	va_list args;
+	int i, ret;
+	u8 *buf = (u8 *)par->buf;
+
+	if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
+		va_start(args, len);
+		for (i = 0; i < len; i++)
+			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__);
+	}
+
+	va_start(args, len);
+
+	*buf = (u8)va_arg(args, unsigned int);
+
+	if (*buf > 1) {
+		va_end(args);
+		dev_err(par->info->device, "%s: Incorrect chip sellect request (%d)\n",
+			__func__, *buf);
+		return;
+	}
+
+	/* select chip */
+	if (*buf) {
+		/* cs1 */
+		gpio_set_value(par->CS0, 1);
+		gpio_set_value(par->CS1, 0);
+	} else {
+		/* cs0 */
+		gpio_set_value(par->CS0, 0);
+		gpio_set_value(par->CS1, 1);
+	}
+
+	gpio_set_value(par->RS, 0); /* RS->0 (command mode) */
+	len--;
+
+	if (len) {
+		i = len;
+		while (i--)
+			*buf++ = (u8)va_arg(args, unsigned int);
+		ret = par->fbtftops.write(par, par->buf, len * (sizeof(u8)));
+		if (ret < 0) {
+			va_end(args);
+			dev_err(par->info->device, "%s: write() failed and returned %d\n",
+				__func__, ret);
+			return;
+		}
+	}
+
+	va_end(args);
+}
+
+static struct
+{
+	int xs, ys_page, xe, ye_page;
+} addr_win;
+
+/* save display writing zone */
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	addr_win.xs = xs;
+	addr_win.ys_page = ys / 8;
+	addr_win.xe = xe;
+	addr_win.ye_page = ye / 8;
+
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys_page=%d, xe=%d, ye_page=%d)\n", __func__,
+		addr_win.xs, addr_win.ys_page, addr_win.xe, addr_win.ye_page);
+}
+
+static void
+construct_line_bitmap(struct fbtft_par *par, u8 *dest, signed short *src,
+						int xs, int xe, int y)
+{
+	int x, i;
+
+	for (x = xs; x < xe; ++x) {
+		u8 res = 0;
+
+		for (i = 0; i < 8; i++)
+			if (src[(y * 8 + i) * par->info->var.xres + x])
+				res |= 1 << i;
+#ifdef NEGATIVE
+		*dest++ = res;
+#else
+		*dest++ = ~res;
+#endif
+	}
+}
+
+static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+{
+	u16 *vmem16 = (u16 *)par->info->screen_base;
+	u8 *buf = par->txbuf.buf;
+	int x, y;
+	int ret = 0;
+
+	/* buffer to convert RGB565 -> grayscale16 -> Ditherd image 1bpp */
+	signed short *convert_buf = kmalloc(par->info->var.xres *
+		par->info->var.yres * sizeof(signed short), GFP_NOIO);
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
+
+	/* converting to grayscale16 */
+	for (x = 0; x < par->info->var.xres; ++x)
+		for (y = 0; y < par->info->var.yres; ++y) {
+			u16 pixel = vmem16[y *  par->info->var.xres + x];
+			u16 b = pixel & 0x1f;
+			u16 g = (pixel & (0x3f << 5)) >> 5;
+			u16 r = (pixel & (0x1f << (5 + 6))) >> (5 + 6);
+
+			pixel = (299 * r + 587 * g + 114 * b) / 200;
+			if (pixel > 255)
+				pixel = 255;
+
+			/* gamma-correction by table */
+			convert_buf[y *  par->info->var.xres + x] =
+				(signed short)gamma_correction_table[pixel];
+		}
+
+	/* Image Dithering */
+	for (x = 0; x < par->info->var.xres; ++x)
+		for (y = 0; y < par->info->var.yres; ++y) {
+			signed short pixel =
+				convert_buf[y *  par->info->var.xres + x];
+			signed short error_b = pixel - BLACK;
+			signed short error_w = pixel - WHITE;
+			signed short error;
+			u16 i, j;
+
+			/* what color close? */
+			if (abs(error_b) >= abs(error_w)) {
+				/* white */
+				error = error_w;
+				pixel = 0xff;
+			} else {
+				/* black */
+				error = error_b;
+				pixel = 0;
+			}
+
+			error /= 8;
+
+			/* diffusion matrix row */
+			for (i = 0; i < DIFFUSING_MATRIX_WIDTH; ++i)
+				/* diffusion matrix column */
+				for (j = 0; j < DIFFUSING_MATRIX_HEIGHT; ++j) {
+					signed short *write_pos;
+					signed char coeff;
+
+					/* skip pixels out of zone */
+					if (x + i < 0 ||
+						x + i >= par->info->var.xres
+						|| y + j >= par->info->var.yres)
+						continue;
+					write_pos = &convert_buf[
+						(y + j) * par->info->var.xres +
+						x + i];
+					coeff = diffusing_matrix[i][j];
+					if (coeff == -1)
+						/* pixel itself */
+						*write_pos = pixel;
+					else {
+						signed short p = *write_pos +
+							error * coeff;
+
+						if (p > WHITE)
+							p = WHITE;
+						if (p < BLACK)
+							p = BLACK;
+						*write_pos = p;
+					}
+				}
+		}
+
+	 /* 1 string = 2 pages */
+	 for (y = addr_win.ys_page; y <= addr_win.ye_page; ++y) {
+		/* 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);
+
+			len = par->info->var.xres / 2 - addr_win.xs;
+
+			/* select left side (sc0)
+			 * set addr
+			 */
+			write_reg(par, 0x00, (1 << 6) | (u8)addr_win.xs);
+			write_reg(par, 0x00, (0x17 << 3) | (u8)y);
+
+			/* write bitmap */
+			gpio_set_value(par->RS, 1); /* RS->1 (data mode) */
+			ret = par->fbtftops.write(par, buf, len);
+			if (ret < 0)
+				dev_err(par->info->device,
+					"%s: write failed and returned: %d\n",
+					__func__, ret);
+		}
+		/* 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);
+
+			len = addr_win.xe + 1 - par->info->var.xres / 2;
+
+			/* select right side (sc1)
+			 * set addr
+			 */
+			write_reg(par, 0x01, (1 << 6));
+			write_reg(par, 0x01, (0x17 << 3) | (u8)y);
+
+			/* write bitmap */
+			gpio_set_value(par->RS, 1); /* RS->1 (data mode) */
+			par->fbtftops.write(par, buf, len);
+			if (ret < 0)
+				dev_err(par->info->device,
+					"%s: write failed and returned: %d\n",
+					__func__, ret);
+		}
+	}
+	kfree(convert_buf);
+
+	gpio_set_value(par->CS0, 1);
+	gpio_set_value(par->CS1, 1);
+
+	return ret;
+}
+
+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);
+
+	gpio_set_value(par->RW, 0); /* set write mode */
+
+
+	while (len--) {
+		u8 i, data;
+
+		data = *(u8 *) buf++;
+
+		/* set data bus */
+		for (i = 0; i < 8; ++i)
+			gpio_set_value(par->gpio.db[i], data & (1 << i));
+		/* set E */
+		gpio_set_value(par->EPIN, 1);
+		udelay(5);
+		/* unset E - write */
+		gpio_set_value(par->EPIN, 0);
+		udelay(1);
+	}
+
+	return 0;
+}
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = TOTALWIDTH,
+	.height = HEIGHT,
+	.fps = FPS,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.verify_gpios = verify_gpios,
+		.request_gpios_match = request_gpios_match,
+		.reset = reset,
+		.write = write,
+		.write_register = write_reg8_bus8,
+		.write_vmem = write_vmem,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "displaytronic,fb_agm1264k-fl", &display);
+
+MODULE_ALIAS("platform:" DRVNAME);
+
+MODULE_DESCRIPTION("Two KS0108 LCD controllers in AGM1264K-FL display");
+MODULE_AUTHOR("ololoshka2871");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c
new file mode 100644
index 000000000000..7e00c609c7fe
--- /dev/null
+++ b/drivers/staging/fbtft/fb_bd663474.c
@@ -0,0 +1,193 @@
+/*
+ * FB driver for the uPD161704 LCD Controller
+ *
+ * Copyright (C) 2014 Seong-Woo Kim
+ *
+ * Based on fb_ili9325.c by Noralf Tronnes
+ * Based on ili9325.c by Jeroen Domburg
+ * Init code from UTFT library by Henning Karlsen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_bd663474"
+#define WIDTH		240
+#define HEIGHT		320
+#define BPP		16
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	if (par->gpio.cs != -1)
+		gpio_set_value(par->gpio.cs, 0);  /* Activate chip */
+
+	par->fbtftops.reset(par);
+
+	/* Initialization sequence from Lib_UTFT */
+
+	/* oscillator start */
+	write_reg(par, 0x000,0x0001);	/*oscillator 0: stop, 1: operation */
+	mdelay(10);
+
+	/* Power settings */
+	write_reg(par, 0x100, 0x0000 ); /* power supply setup */
+	write_reg(par, 0x101, 0x0000 );
+	write_reg(par, 0x102, 0x3110 );
+	write_reg(par, 0x103, 0xe200 );
+	write_reg(par, 0x110, 0x009d );
+	write_reg(par, 0x111, 0x0022 );
+	write_reg(par, 0x100, 0x0120 );
+	mdelay( 20 );
+
+	write_reg(par, 0x100, 0x3120 );
+	mdelay( 80 );
+	/* Display control */
+	write_reg(par, 0x001, 0x0100 );
+	write_reg(par, 0x002, 0x0000 );
+	write_reg(par, 0x003, 0x1230 );
+	write_reg(par, 0x006, 0x0000 );
+	write_reg(par, 0x007, 0x0101 );
+	write_reg(par, 0x008, 0x0808 );
+	write_reg(par, 0x009, 0x0000 );
+	write_reg(par, 0x00b, 0x0000 );
+	write_reg(par, 0x00c, 0x0000 );
+	write_reg(par, 0x00d, 0x0018 );
+	/* LTPS control settings */
+	write_reg(par, 0x012, 0x0000 );
+	write_reg(par, 0x013, 0x0000 );
+	write_reg(par, 0x018, 0x0000 );
+	write_reg(par, 0x019, 0x0000 );
+
+	write_reg(par, 0x203, 0x0000 );
+	write_reg(par, 0x204, 0x0000 );
+
+	write_reg(par, 0x210, 0x0000 );
+	write_reg(par, 0x211, 0x00ef );
+	write_reg(par, 0x212, 0x0000 );
+	write_reg(par, 0x213, 0x013f );
+	write_reg(par, 0x214, 0x0000 );
+	write_reg(par, 0x215, 0x0000 );
+	write_reg(par, 0x216, 0x0000 );
+	write_reg(par, 0x217, 0x0000 );
+
+	/* Gray scale settings */
+	write_reg(par, 0x300, 0x5343);
+	write_reg(par, 0x301, 0x1021);
+	write_reg(par, 0x302, 0x0003);
+	write_reg(par, 0x303, 0x0011);
+	write_reg(par, 0x304, 0x050a);
+	write_reg(par, 0x305, 0x4342);
+	write_reg(par, 0x306, 0x1100);
+	write_reg(par, 0x307, 0x0003);
+	write_reg(par, 0x308, 0x1201);
+	write_reg(par, 0x309, 0x050a);
+
+	/* RAM access settings */
+	write_reg(par, 0x400, 0x4027 );
+	write_reg(par, 0x401, 0x0000 );
+	write_reg(par, 0x402, 0x0000 );  /* First screen drive position (1) */
+	write_reg(par, 0x403, 0x013f );  /* First screen drive position (2) */
+	write_reg(par, 0x404, 0x0000 );
+
+	write_reg(par, 0x200, 0x0000 );
+	write_reg(par, 0x201, 0x0000 );
+	write_reg(par, 0x100, 0x7120 );
+	write_reg(par, 0x007, 0x0103 );
+	mdelay( 10 );
+	write_reg(par, 0x007, 0x0113 );
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+	switch (par->info->var.rotate) {
+	/* R200h = Horizontal GRAM Start Address */
+	/* R201h = Vertical GRAM Start Address */
+	case 0:
+		write_reg(par, 0x0200, xs);
+		write_reg(par, 0x0201, ys);
+		break;
+	case 180:
+		write_reg(par, 0x0200, WIDTH - 1 - xs);
+		write_reg(par, 0x0201, HEIGHT - 1 - ys);
+		break;
+	case 270:
+		write_reg(par, 0x0200, WIDTH - 1 - ys);
+		write_reg(par, 0x0201, xs);
+		break;
+	case 90:
+		write_reg(par, 0x0200, ys);
+		write_reg(par, 0x0201, HEIGHT - 1 - xs);
+		break;
+	}
+	write_reg(par, 0x202); /* Write Data to GRAM */
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	/* AM: GRAM update direction */
+	case 0:
+		write_reg(par, 0x003, 0x1230);
+		break;
+	case 180:
+		write_reg(par, 0x003, 0x1200);
+		break;
+	case 270:
+		write_reg(par, 0x003, 0x1228);
+		break;
+	case 90:
+		write_reg(par, 0x003, 0x1218);
+		break;
+	}
+
+	return 0;
+}
+
+static struct fbtft_display display = {
+	.regwidth = 16,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.bpp = BPP,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "hitachi,bd663474", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:bd663474");
+MODULE_ALIAS("platform:bd663474");
+
+MODULE_DESCRIPTION("FB driver for the uPD161704 LCD Controller");
+MODULE_AUTHOR("Seong-Woo Kim");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_hx8340bn.c b/drivers/staging/fbtft/fb_hx8340bn.c
new file mode 100644
index 000000000000..3939502f2c81
--- /dev/null
+++ b/drivers/staging/fbtft/fb_hx8340bn.c
@@ -0,0 +1,229 @@
+/*
+ * FB driver for the HX8340BN LCD Controller
+ *
+ * This display uses 9-bit SPI: Data/Command bit + 8 data bits
+ * For platforms that doesn't support 9-bit, the driver is capable
+ * of emulating this using 8-bit transfer.
+ * This is done by transfering eight 9-bit words in 9 bytes.
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_hx8340bn"
+#define WIDTH		176
+#define HEIGHT		220
+#define TXBUFLEN	(4 * PAGE_SIZE)
+#define DEFAULT_GAMMA	"1 3 0E 5 0 2 09 0 6 1 7 1 0 2 2\n" \
+			"3 3 17 8 4 7 05 7 6 0 3 1 6 0 0 "
+
+
+static bool emulate;
+module_param(emulate, bool, 0);
+MODULE_PARM_DESC(emulate, "Force emulation in 9-bit mode");
+
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	/* BTL221722-276L startup sequence, from datasheet */
+
+	/* SETEXTCOM: Set extended command set (C1h)
+	   This command is used to set extended command set access enable.
+	   Enable: After command (C1h), must write: ffh,83h,40h */
+	write_reg(par, 0xC1, 0xFF, 0x83, 0x40);
+
+	/* Sleep out
+	   This command turns off sleep mode.
+	   In this mode the DC/DC converter is enabled, Internal oscillator
+	   is started, and panel scanning is started. */
+	write_reg(par, 0x11);
+	mdelay(150);
+
+	/* Undoc'd register? */
+	write_reg(par, 0xCA, 0x70, 0x00, 0xD9);
+
+	/* SETOSC: Set Internal Oscillator (B0h)
+	   This command is used to set internal oscillator related settings */
+	/*	OSC_EN: Enable internal oscillator */
+	/*	Internal oscillator frequency: 125% x 2.52MHz */
+	write_reg(par, 0xB0, 0x01, 0x11);
+
+	/* Drive ability setting */
+	write_reg(par, 0xC9, 0x90, 0x49, 0x10, 0x28, 0x28, 0x10, 0x00, 0x06);
+	mdelay(20);
+
+	/* SETPWCTR5: Set Power Control 5(B5h)
+	   This command is used to set VCOM Low and VCOM High Voltage */
+	/* VCOMH 0110101 :  3.925 */
+	/* VCOML 0100000 : -1.700 */
+	/* 45h=69  VCOMH: "VMH" + 5d   VCOML: "VMH" + 5d */
+	write_reg(par, 0xB5, 0x35, 0x20, 0x45);
+
+	/* SETPWCTR4: Set Power Control 4(B4h)
+		VRH[4:0]:	Specify the VREG1 voltage adjusting.
+				VREG1 voltage is for gamma voltage setting.
+		BT[2:0]:	Switch the output factor of step-up circuit 2
+				for VGH and VGL voltage generation. */
+	write_reg(par, 0xB4, 0x33, 0x25, 0x4C);
+	mdelay(10);
+
+	/* Interface Pixel Format (3Ah)
+	   This command is used to define the format of RGB picture data,
+	   which is to be transfer via the system and RGB interface. */
+	/* RGB interface: 16 Bit/Pixel	*/
+	write_reg(par, 0x3A, 0x05);
+
+	/* Display on (29h)
+	   This command is used to recover from DISPLAY OFF mode.
+	   Output from the Frame Memory is enabled. */
+	write_reg(par, 0x29);
+	mdelay(10);
+
+	return 0;
+}
+
+void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	write_reg(par, FBTFT_CASET, 0x00, xs, 0x00, xe);
+	write_reg(par, FBTFT_RASET, 0x00, ys, 0x00, ye);
+	write_reg(par, FBTFT_RAMWR);
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* MADCTL - Memory data access control */
+	/* RGB/BGR can be set with H/W pin SRGB and MADCTL BGR bit */
+#define MY (1 << 7)
+#define MX (1 << 6)
+#define MV (1 << 5)
+	switch (par->info->var.rotate) {
+	case 0:
+		write_reg(par, 0x36, (par->bgr << 3));
+		break;
+	case 270:
+		write_reg(par, 0x36, MX | MV | (par->bgr << 3));
+		break;
+	case 180:
+		write_reg(par, 0x36, MX | MY | (par->bgr << 3));
+		break;
+	case 90:
+		write_reg(par, 0x36, MY | MV | (par->bgr << 3));
+		break;
+	}
+
+	return 0;
+}
+
+/*
+  Gamma Curve selection, GC (only GC0 can be customized):
+    0 = 2.2, 1 = 1.8, 2 = 2.5, 3 = 1.0
+  Gamma string format:
+    OP0 OP1 CP0 CP1 CP2 CP3 CP4 MP0 MP1 MP2 MP3 MP4 MP5 CGM0 CGM1
+    ON0 ON1 CN0 CN1 CN2 CN3 CN4 MN0 MN1 MN2 MN3 MN4 MN5 XXXX  GC
+*/
+#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	unsigned long mask[] = {
+		0b1111, 0b1111, 0b11111, 0b1111, 0b1111, 0b1111, 0b11111,
+		0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b11, 0b11,
+		0b1111, 0b1111, 0b11111, 0b1111, 0b1111, 0b1111, 0b11111,
+		0b111, 0b111, 0b111, 0b111, 0b111, 0b111, 0b0, 0b0 };
+	int i, j;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	for (i = 0; i < par->gamma.num_curves; i++)
+		for (j = 0; j < par->gamma.num_values; j++)
+			CURVE(i, j) &= mask[i * par->gamma.num_values + j];
+
+	write_reg(par, 0x26, 1 << CURVE(1, 14)); /* Gamma Set (26h) */
+
+	if (CURVE(1, 14))
+		return 0; /* only GC0 can be customized */
+
+	write_reg(par, 0xC2,
+		(CURVE(0, 8) << 4) | CURVE(0, 7),
+		(CURVE(0, 10) << 4) | CURVE(0, 9),
+		(CURVE(0, 12) << 4) | CURVE(0, 11),
+		CURVE(0, 2),
+		(CURVE(0, 4) << 4) | CURVE(0, 3),
+		CURVE(0, 5),
+		CURVE(0, 6),
+		(CURVE(0, 1) << 4) | CURVE(0, 0),
+		(CURVE(0, 14) << 2) | CURVE(0, 13));
+
+	write_reg(par, 0xC3,
+		(CURVE(1, 8) << 4) | CURVE(1, 7),
+		(CURVE(1, 10) << 4) | CURVE(1, 9),
+		(CURVE(1, 12) << 4) | CURVE(1, 11),
+		CURVE(1, 2),
+		(CURVE(1, 4) << 4) | CURVE(1, 3),
+		CURVE(1, 5),
+		CURVE(1, 6),
+		(CURVE(1, 1) << 4) | CURVE(1, 0));
+
+	mdelay(10);
+
+	return 0;
+}
+#undef CURVE
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.txbuflen = TXBUFLEN,
+	.gamma_num = 2,
+	.gamma_len = 15,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.set_gamma = set_gamma,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8340bn", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:hx8340bn");
+MODULE_ALIAS("platform:hx8340bn");
+
+MODULE_DESCRIPTION("FB driver for the HX8340BN LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_hx8347d.c b/drivers/staging/fbtft/fb_hx8347d.c
new file mode 100644
index 000000000000..8139a8f587b7
--- /dev/null
+++ b/drivers/staging/fbtft/fb_hx8347d.c
@@ -0,0 +1,181 @@
+/*
+ * FB driver for the HX8347D LCD Controller
+ *
+ * Copyright (C) 2013 Christian Vogelgsang
+ *
+ * Based on driver code found here: https://github.com/watterott/r61505u-Adapter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_hx8347d"
+#define WIDTH		320
+#define HEIGHT		240
+#define DEFAULT_GAMMA	"0 0 0 0 0 0 0 0 0 0 0 0 0 0\n" \
+			"0 0 0 0 0 0 0 0 0 0 0 0 0 0"
+
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	/* driving ability */
+	write_reg(par, 0xEA, 0x00);
+	write_reg(par, 0xEB, 0x20);
+	write_reg(par, 0xEC, 0x0C);
+	write_reg(par, 0xED, 0xC4);
+	write_reg(par, 0xE8, 0x40);
+	write_reg(par, 0xE9, 0x38);
+	write_reg(par, 0xF1, 0x01);
+	write_reg(par, 0xF2, 0x10);
+	write_reg(par, 0x27, 0xA3);
+
+	/* power voltage */
+	write_reg(par, 0x1B, 0x1B);
+	write_reg(par, 0x1A, 0x01);
+	write_reg(par, 0x24, 0x2F);
+	write_reg(par, 0x25, 0x57);
+
+	/* VCOM offset */
+	write_reg(par, 0x23, 0x8D); /* for flicker adjust */
+
+	/* power on */
+	write_reg(par, 0x18, 0x36);
+	write_reg(par, 0x19, 0x01); /* start osc */
+	write_reg(par, 0x01, 0x00); /* wakeup */
+	write_reg(par, 0x1F, 0x88);
+	mdelay(5);
+	write_reg(par, 0x1F, 0x80);
+	mdelay(5);
+	write_reg(par, 0x1F, 0x90);
+	mdelay(5);
+	write_reg(par, 0x1F, 0xD0);
+	mdelay(5);
+
+	/* color selection */
+	write_reg(par, 0x17, 0x05); /* 65k */
+
+	/*panel characteristic */
+	write_reg(par, 0x36, 0x00);
+
+	/*display on */
+	write_reg(par, 0x28, 0x38);
+	mdelay(40);
+	write_reg(par, 0x28, 0x3C);
+
+	/* orientation */
+	write_reg(par, 0x16, 0x60 | (par->bgr << 3));
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	write_reg(par, 0x02, (xs >> 8) & 0xFF);
+	write_reg(par, 0x03, xs & 0xFF);
+	write_reg(par, 0x04, (xe >> 8) & 0xFF);
+	write_reg(par, 0x05, xe & 0xFF);
+	write_reg(par, 0x06, (ys >> 8) & 0xFF);
+	write_reg(par, 0x07, ys & 0xFF);
+	write_reg(par, 0x08, (ye >> 8) & 0xFF);
+	write_reg(par, 0x09, ye & 0xFF);
+	write_reg(par, 0x22);
+}
+
+/*
+  Gamma string format:
+    VRP0 VRP1 VRP2 VRP3 VRP4 VRP5 PRP0 PRP1 PKP0 PKP1 PKP2 PKP3 PKP4 CGM
+    VRN0 VRN1 VRN2 VRN3 VRN4 VRN5 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 CGM
+*/
+#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	unsigned long mask[] = {
+		0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111,
+		0b1111111, 0b1111111,
+		0b11111, 0b11111, 0b11111, 0b11111, 0b11111,
+		0b1111};
+	int i, j;
+	int acc = 0;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	for (i = 0; i < par->gamma.num_curves; i++)
+		for (j = 0; j < par->gamma.num_values; j++) {
+			acc += CURVE(i, j);
+			CURVE(i, j) &= mask[j];
+		}
+
+	if (acc == 0) /* skip if all values are zero */
+		return 0;
+
+	for (i = 0; i < par->gamma.num_curves; i++) {
+		write_reg(par, 0x40 + (i * 0x10), CURVE(i, 0));
+		write_reg(par, 0x41 + (i * 0x10), CURVE(i, 1));
+		write_reg(par, 0x42 + (i * 0x10), CURVE(i, 2));
+		write_reg(par, 0x43 + (i * 0x10), CURVE(i, 3));
+		write_reg(par, 0x44 + (i * 0x10), CURVE(i, 4));
+		write_reg(par, 0x45 + (i * 0x10), CURVE(i, 5));
+		write_reg(par, 0x46 + (i * 0x10), CURVE(i, 6));
+		write_reg(par, 0x47 + (i * 0x10), CURVE(i, 7));
+		write_reg(par, 0x48 + (i * 0x10), CURVE(i, 8));
+		write_reg(par, 0x49 + (i * 0x10), CURVE(i, 9));
+		write_reg(par, 0x4A + (i * 0x10), CURVE(i, 10));
+		write_reg(par, 0x4B + (i * 0x10), CURVE(i, 11));
+		write_reg(par, 0x4C + (i * 0x10), CURVE(i, 12));
+	}
+	write_reg(par, 0x5D, (CURVE(1, 0) << 4) | CURVE(0, 0));
+
+	return 0;
+}
+#undef CURVE
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.gamma_num = 2,
+	.gamma_len = 14,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_gamma = set_gamma,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8347d", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:hx8347d");
+MODULE_ALIAS("platform:hx8347d");
+
+MODULE_DESCRIPTION("FB driver for the HX8347D LCD Controller");
+MODULE_AUTHOR("Christian Vogelgsang");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_hx8353d.c b/drivers/staging/fbtft/fb_hx8353d.c
new file mode 100644
index 000000000000..c9512dc5f4d3
--- /dev/null
+++ b/drivers/staging/fbtft/fb_hx8353d.c
@@ -0,0 +1,166 @@
+/*
+ * FB driver for the HX8353D LCD Controller
+ *
+ * Copyright (c) 2014 Petr Olivka
+ * Copyright (c) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME "fb_hx8353d"
+#define DEFAULT_GAMMA "50 77 40 08 BF 00 03 0F 00 01 73 00 72 03 B0 0F 08 00 0F"
+
+static int init_display(struct fbtft_par *par)
+{
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+	mdelay(150);
+
+	/* SETEXTC */
+	write_reg(par, 0xB9, 0xFF, 0x83, 0x53);
+
+	/* RADJ */
+	write_reg(par, 0xB0, 0x3C, 0x01);
+
+	/* VCOM */
+	write_reg(par, 0xB6, 0x94, 0x6C, 0x50);
+
+	/* PWR */
+	write_reg(par, 0xB1, 0x00, 0x01, 0x1B, 0x03, 0x01, 0x08, 0x77, 0x89);
+
+	/* COLMOD */
+	write_reg(par, 0x3A, 0x05);
+
+	/* MEM ACCESS */
+	write_reg(par, 0x36, 0xC0);
+
+	/* SLPOUT - Sleep out & booster on */
+	write_reg(par, 0x11);
+	mdelay(150);
+
+	/* DISPON - Display On */
+	write_reg(par, 0x29);
+
+	/* RGBSET */
+	write_reg(par, 0x2D,
+		 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+		32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
+		 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+		16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+		32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+		48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+		 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
+		32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62);
+
+	return 0;
+};
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* column address */
+	write_reg(par, 0x2a, xs >> 8, xs & 0xff, xe >> 8, xe & 0xff);
+
+	/* row adress */
+	write_reg(par, 0x2b, ys >> 8, ys & 0xff, ye >> 8, ye & 0xff);
+
+	/* memory write */
+	write_reg(par, 0x2c);
+}
+
+#define my (1 << 7)
+#define mx (1 << 6)
+#define mv (1 << 5)
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* madctl - memory data access control
+	     rgb/bgr:
+	     1. mode selection pin srgb
+		rgb h/w pin for color filter setting: 0=rgb, 1=bgr
+	     2. madctl rgb bit
+		rgb-bgr order color filter panel: 0=rgb, 1=bgr */
+	switch (par->info->var.rotate) {
+	case 0:
+		write_reg(par, 0x36, mx | my | (par->bgr << 3));
+		break;
+	case 270:
+		write_reg(par, 0x36, my | mv | (par->bgr << 3));
+		break;
+	case 180:
+		write_reg(par, 0x36, (par->bgr << 3));
+		break;
+	case 90:
+		write_reg(par, 0x36, mx | mv | (par->bgr << 3));
+		break;
+	}
+
+	return 0;
+}
+
+/*
+  gamma string format:
+*/
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	write_reg(par, 0xE0,
+		curves[0], curves[1], curves[2], curves[3],
+		curves[4], curves[5], curves[6], curves[7],
+		curves[8], curves[9], curves[10], curves[11],
+		curves[12], curves[13], curves[14], curves[15],
+		curves[16], curves[17], curves[18]);
+
+	return 0;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = 128,
+	.height = 160,
+	.gamma_num = 1,
+	.gamma_len = 19,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.set_gamma = set_gamma,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8353d", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:hx8353d");
+MODULE_ALIAS("platform:hx8353d");
+
+MODULE_DESCRIPTION("FB driver for the HX8353D LCD Controller");
+MODULE_AUTHOR("Petr Olivka");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c
new file mode 100644
index 000000000000..b26d89368da7
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9320.c
@@ -0,0 +1,234 @@
+/*
+ * FB driver for the ILI9320 LCD Controller
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_ili9320"
+#define WIDTH		240
+#define HEIGHT		320
+#define DEFAULT_GAMMA	"07 07 6 0 0 0 5 5 4 0\n" \
+			"07 08 4 7 5 1 2 0 7 7"
+
+
+static unsigned read_devicecode(struct fbtft_par *par)
+{
+	int ret;
+	u8 rxbuf[8] = {0, };
+
+	write_reg(par, 0x0000);
+	ret = par->fbtftops.read(par, rxbuf, 4);
+	return (rxbuf[2] << 8) | rxbuf[3];
+}
+
+static int init_display(struct fbtft_par *par)
+{
+	unsigned devcode;
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	devcode = read_devicecode(par);
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "Device code: 0x%04X\n",
+		devcode);
+	if ((devcode != 0x0000) && (devcode != 0x9320))
+		dev_warn(par->info->device,
+			"Unrecognized Device code: 0x%04X (expected 0x9320)\n",
+			devcode);
+
+	/* Initialization sequence from ILI9320 Application Notes */
+
+	/* *********** Start Initial Sequence ********* */
+	write_reg(par, 0x00E5, 0x8000); /* Set the Vcore voltage and this setting is must. */
+	write_reg(par, 0x0000, 0x0001); /* Start internal OSC. */
+	write_reg(par, 0x0001, 0x0100); /* set SS and SM bit */
+	write_reg(par, 0x0002, 0x0700); /* set 1 line inversion */
+	write_reg(par, 0x0004, 0x0000); /* Resize register */
+	write_reg(par, 0x0008, 0x0202); /* set the back and front porch */
+	write_reg(par, 0x0009, 0x0000); /* set non-display area refresh cycle */
+	write_reg(par, 0x000A, 0x0000); /* FMARK function */
+	write_reg(par, 0x000C, 0x0000); /* RGB interface setting */
+	write_reg(par, 0x000D, 0x0000); /* Frame marker Position */
+	write_reg(par, 0x000F, 0x0000); /* RGB interface polarity */
+
+	/* ***********Power On sequence *************** */
+	write_reg(par, 0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+	write_reg(par, 0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */
+	write_reg(par, 0x0012, 0x0000); /* VREG1OUT voltage */
+	write_reg(par, 0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
+	mdelay(200); /* Dis-charge capacitor power voltage */
+	write_reg(par, 0x0010, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+	write_reg(par, 0x0011, 0x0031); /* R11h=0x0031 at VCI=3.3V DC1[2:0], DC0[2:0], VC[2:0] */
+	mdelay(50);
+	write_reg(par, 0x0012, 0x0138); /* R12h=0x0138 at VCI=3.3V VREG1OUT voltage */
+	mdelay(50);
+	write_reg(par, 0x0013, 0x1800); /* R13h=0x1800 at VCI=3.3V VDV[4:0] for VCOM amplitude */
+	write_reg(par, 0x0029, 0x0008); /* R29h=0x0008 at VCI=3.3V VCM[4:0] for VCOMH */
+	mdelay(50);
+	write_reg(par, 0x0020, 0x0000); /* GRAM horizontal Address */
+	write_reg(par, 0x0021, 0x0000); /* GRAM Vertical Address */
+
+	/* ------------------ Set GRAM area --------------- */
+	write_reg(par, 0x0050, 0x0000); /* Horizontal GRAM Start Address */
+	write_reg(par, 0x0051, 0x00EF); /* Horizontal GRAM End Address */
+	write_reg(par, 0x0052, 0x0000); /* Vertical GRAM Start Address */
+	write_reg(par, 0x0053, 0x013F); /* Vertical GRAM Start Address */
+	write_reg(par, 0x0060, 0x2700); /* Gate Scan Line */
+	write_reg(par, 0x0061, 0x0001); /* NDL,VLE, REV */
+	write_reg(par, 0x006A, 0x0000); /* set scrolling line */
+
+	/* -------------- Partial Display Control --------- */
+	write_reg(par, 0x0080, 0x0000);
+	write_reg(par, 0x0081, 0x0000);
+	write_reg(par, 0x0082, 0x0000);
+	write_reg(par, 0x0083, 0x0000);
+	write_reg(par, 0x0084, 0x0000);
+	write_reg(par, 0x0085, 0x0000);
+
+	/* -------------- Panel Control ------------------- */
+	write_reg(par, 0x0090, 0x0010);
+	write_reg(par, 0x0092, 0x0000);
+	write_reg(par, 0x0093, 0x0003);
+	write_reg(par, 0x0095, 0x0110);
+	write_reg(par, 0x0097, 0x0000);
+	write_reg(par, 0x0098, 0x0000);
+	write_reg(par, 0x0007, 0x0173); /* 262K color and display ON */
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	switch (par->info->var.rotate) {
+	/* R20h = Horizontal GRAM Start Address */
+	/* R21h = Vertical GRAM Start Address */
+	case 0:
+		write_reg(par, 0x0020, xs);
+		write_reg(par, 0x0021, ys);
+		break;
+	case 180:
+		write_reg(par, 0x0020, WIDTH - 1 - xs);
+		write_reg(par, 0x0021, HEIGHT - 1 - ys);
+		break;
+	case 270:
+		write_reg(par, 0x0020, WIDTH - 1 - ys);
+		write_reg(par, 0x0021, xs);
+		break;
+	case 90:
+		write_reg(par, 0x0020, ys);
+		write_reg(par, 0x0021, HEIGHT - 1 - xs);
+		break;
+	}
+	write_reg(par, 0x0022); /* Write Data to GRAM */
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	case 0:
+		write_reg(par, 0x3, (par->bgr << 12) | 0x30);
+		break;
+	case 270:
+		write_reg(par, 0x3, (par->bgr << 12) | 0x28);
+		break;
+	case 180:
+		write_reg(par, 0x3, (par->bgr << 12) | 0x00);
+		break;
+	case 90:
+		write_reg(par, 0x3, (par->bgr << 12) | 0x18);
+		break;
+	}
+	return 0;
+}
+
+/*
+  Gamma string format:
+    VRP0 VRP1 RP0 RP1 KP0 KP1 KP2 KP3 KP4 KP5
+    VRN0 VRN1 RN0 RN1 KN0 KN1 KN2 KN3 KN4 KN5
+*/
+#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	unsigned long mask[] = {
+		0b11111, 0b11111, 0b111, 0b111, 0b111,
+		0b111, 0b111, 0b111, 0b111, 0b111,
+		0b11111, 0b11111, 0b111, 0b111, 0b111,
+		0b111, 0b111, 0b111, 0b111, 0b111 };
+	int i, j;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	for (i = 0; i < 2; i++)
+		for (j = 0; j < 10; j++)
+			CURVE(i, j) &= mask[i*par->gamma.num_values + j];
+
+	write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
+	write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
+	write_reg(par, 0x0032, CURVE(0, 9) << 8 | CURVE(0, 8));
+	write_reg(par, 0x0035, CURVE(0, 3) << 8 | CURVE(0, 2));
+	write_reg(par, 0x0036, CURVE(0, 1) << 8 | CURVE(0, 0));
+
+	write_reg(par, 0x0037, CURVE(1, 5) << 8 | CURVE(1, 4));
+	write_reg(par, 0x0038, CURVE(1, 7) << 8 | CURVE(1, 6));
+	write_reg(par, 0x0039, CURVE(1, 9) << 8 | CURVE(1, 8));
+	write_reg(par, 0x003C, CURVE(1, 3) << 8 | CURVE(1, 2));
+	write_reg(par, 0x003D, CURVE(1, 1) << 8 | CURVE(1, 0));
+
+	return 0;
+}
+#undef CURVE
+
+
+static struct fbtft_display display = {
+	.regwidth = 16,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.gamma_num = 2,
+	.gamma_len = 10,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.set_gamma = set_gamma,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9320", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ili9320");
+MODULE_ALIAS("platform:ili9320");
+
+MODULE_DESCRIPTION("FB driver for the ILI9320 LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c
new file mode 100644
index 000000000000..5f88145fac9b
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9325.c
@@ -0,0 +1,291 @@
+/*
+ * FB driver for the ILI9325 LCD Controller
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * Based on ili9325.c by Jeroen Domburg
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_ili9325"
+#define WIDTH		240
+#define HEIGHT		320
+#define BPP		16
+#define FPS		20
+#define DEFAULT_GAMMA	"0F 00 7 2 0 0 6 5 4 1\n" \
+			"04 16 2 7 6 3 2 1 7 7"
+
+
+static unsigned bt = 6; /* VGL=Vci*4 , VGH=Vci*4 */
+module_param(bt, uint, 0);
+MODULE_PARM_DESC(bt, "Sets the factor used in the step-up circuits");
+
+static unsigned vc = 0b011; /* Vci1=Vci*0.80 */
+module_param(vc, uint, 0);
+MODULE_PARM_DESC(vc,
+"Sets the ratio factor of Vci to generate the reference voltages Vci1");
+
+static unsigned vrh = 0b1101; /* VREG1OUT=Vci*1.85 */
+module_param(vrh, uint, 0);
+MODULE_PARM_DESC(vrh,
+"Set the amplifying rate (1.6 ~ 1.9) of Vci applied to output the VREG1OUT");
+
+static unsigned vdv = 0b10010; /* VCOMH amplitude=VREG1OUT*0.98 */
+module_param(vdv, uint, 0);
+MODULE_PARM_DESC(vdv,
+"Select the factor of VREG1OUT to set the amplitude of Vcom");
+
+static unsigned vcm = 0b001010; /* VCOMH=VREG1OUT*0.735 */
+module_param(vcm, uint, 0);
+MODULE_PARM_DESC(vcm, "Set the internal VcomH voltage");
+
+
+/*
+Verify that this configuration is within the Voltage limits
+
+Display module configuration: Vcc = IOVcc = Vci = 3.3V
+
+ Voltages
+----------
+Vci                                =   3.3
+Vci1           =  Vci * 0.80       =   2.64
+DDVDH          =  Vci1 * 2         =   5.28
+VCL            = -Vci1             =  -2.64
+VREG1OUT       =  Vci * 1.85       =   4.88
+VCOMH          =  VREG1OUT * 0.735 =   3.59
+VCOM amplitude =  VREG1OUT * 0.98  =   4.79
+VGH            =  Vci * 4          =  13.2
+VGL            = -Vci * 4          = -13.2
+
+ Limits
+--------
+Power supplies
+1.65 < IOVcc < 3.30   =>  1.65 < 3.3 < 3.30
+2.40 < Vcc   < 3.30   =>  2.40 < 3.3 < 3.30
+2.50 < Vci   < 3.30   =>  2.50 < 3.3 < 3.30
+
+Source/VCOM power supply voltage
+ 4.50 < DDVDH < 6.0   =>  4.50 <  5.28 <  6.0
+-3.0  < VCL   < -2.0  =>  -3.0 < -2.64 < -2.0
+VCI - VCL < 6.0       =>  5.94 < 6.0
+
+Gate driver output voltage
+ 10  < VGH   < 20     =>   10 <  13.2  < 20
+-15  < VGL   < -5     =>  -15 < -13.2  < -5
+VGH - VGL < 32        =>   26.4 < 32
+
+VCOM driver output voltage
+VCOMH - VCOML < 6.0   =>  4.79 < 6.0
+*/
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	if (par->gpio.cs != -1)
+		gpio_set_value(par->gpio.cs, 0);  /* Activate chip */
+
+	bt &= 0b111;
+	vc &= 0b111;
+	vrh &= 0b1111;
+	vdv &= 0b11111;
+	vcm &= 0b111111;
+
+	/* Initialization sequence from ILI9325 Application Notes */
+
+	/* ----------- Start Initial Sequence ----------- */
+	write_reg(par, 0x00E3, 0x3008); /* Set internal timing */
+	write_reg(par, 0x00E7, 0x0012); /* Set internal timing */
+	write_reg(par, 0x00EF, 0x1231); /* Set internal timing */
+	write_reg(par, 0x0001, 0x0100); /* set SS and SM bit */
+	write_reg(par, 0x0002, 0x0700); /* set 1 line inversion */
+	write_reg(par, 0x0004, 0x0000); /* Resize register */
+	write_reg(par, 0x0008, 0x0207); /* set the back porch and front porch */
+	write_reg(par, 0x0009, 0x0000); /* set non-display area refresh cycle */
+	write_reg(par, 0x000A, 0x0000); /* FMARK function */
+	write_reg(par, 0x000C, 0x0000); /* RGB interface setting */
+	write_reg(par, 0x000D, 0x0000); /* Frame marker Position */
+	write_reg(par, 0x000F, 0x0000); /* RGB interface polarity */
+
+	/* ----------- Power On sequence ----------- */
+	write_reg(par, 0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+	write_reg(par, 0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */
+	write_reg(par, 0x0012, 0x0000); /* VREG1OUT voltage */
+	write_reg(par, 0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
+	mdelay(200); /* Dis-charge capacitor power voltage */
+	write_reg(par, 0x0010, /* SAP, BT[3:0], AP, DSTB, SLP, STB */
+		(1 << 12) | (bt << 8) | (1 << 7) | (0b001 << 4));
+	write_reg(par, 0x0011, 0x220 | vc); /* DC1[2:0], DC0[2:0], VC[2:0] */
+	mdelay(50); /* Delay 50ms */
+	write_reg(par, 0x0012, vrh); /* Internal reference voltage= Vci; */
+	mdelay(50); /* Delay 50ms */
+	write_reg(par, 0x0013, vdv << 8); /* Set VDV[4:0] for VCOM amplitude */
+	write_reg(par, 0x0029, vcm); /* Set VCM[5:0] for VCOMH */
+	write_reg(par, 0x002B, 0x000C); /* Set Frame Rate */
+	mdelay(50); /* Delay 50ms */
+	write_reg(par, 0x0020, 0x0000); /* GRAM horizontal Address */
+	write_reg(par, 0x0021, 0x0000); /* GRAM Vertical Address */
+
+	/*------------------ Set GRAM area --------------- */
+	write_reg(par, 0x0050, 0x0000); /* Horizontal GRAM Start Address */
+	write_reg(par, 0x0051, 0x00EF); /* Horizontal GRAM End Address */
+	write_reg(par, 0x0052, 0x0000); /* Vertical GRAM Start Address */
+	write_reg(par, 0x0053, 0x013F); /* Vertical GRAM Start Address */
+	write_reg(par, 0x0060, 0xA700); /* Gate Scan Line */
+	write_reg(par, 0x0061, 0x0001); /* NDL,VLE, REV */
+	write_reg(par, 0x006A, 0x0000); /* set scrolling line */
+
+	/*-------------- Partial Display Control --------- */
+	write_reg(par, 0x0080, 0x0000);
+	write_reg(par, 0x0081, 0x0000);
+	write_reg(par, 0x0082, 0x0000);
+	write_reg(par, 0x0083, 0x0000);
+	write_reg(par, 0x0084, 0x0000);
+	write_reg(par, 0x0085, 0x0000);
+
+	/*-------------- Panel Control ------------------- */
+	write_reg(par, 0x0090, 0x0010);
+	write_reg(par, 0x0092, 0x0600);
+	write_reg(par, 0x0007, 0x0133); /* 262K color and display ON */
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+	switch (par->info->var.rotate) {
+	/* R20h = Horizontal GRAM Start Address */
+	/* R21h = Vertical GRAM Start Address */
+	case 0:
+		write_reg(par, 0x0020, xs);
+		write_reg(par, 0x0021, ys);
+		break;
+	case 180:
+		write_reg(par, 0x0020, WIDTH - 1 - xs);
+		write_reg(par, 0x0021, HEIGHT - 1 - ys);
+		break;
+	case 270:
+		write_reg(par, 0x0020, WIDTH - 1 - ys);
+		write_reg(par, 0x0021, xs);
+		break;
+	case 90:
+		write_reg(par, 0x0020, ys);
+		write_reg(par, 0x0021, HEIGHT - 1 - xs);
+		break;
+	}
+	write_reg(par, 0x0022); /* Write Data to GRAM */
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	/* AM: GRAM update direction */
+	case 0:
+		write_reg(par, 0x03, 0x0030 | (par->bgr << 12));
+		break;
+	case 180:
+		write_reg(par, 0x03, 0x0000 | (par->bgr << 12));
+		break;
+	case 270:
+		write_reg(par, 0x03, 0x0028 | (par->bgr << 12));
+		break;
+	case 90:
+		write_reg(par, 0x03, 0x0018 | (par->bgr << 12));
+		break;
+	}
+
+	return 0;
+}
+
+/*
+  Gamma string format:
+    VRP0 VRP1 RP0 RP1 KP0 KP1 KP2 KP3 KP4 KP5
+    VRN0 VRN1 RN0 RN1 KN0 KN1 KN2 KN3 KN4 KN5
+*/
+#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	unsigned long mask[] = {
+		0b11111, 0b11111, 0b111, 0b111, 0b111,
+		0b111, 0b111, 0b111, 0b111, 0b111,
+		0b11111, 0b11111, 0b111, 0b111, 0b111,
+		0b111, 0b111, 0b111, 0b111, 0b111 };
+	int i, j;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	for (i = 0; i < 2; i++)
+		for (j = 0; j < 10; j++)
+			CURVE(i, j) &= mask[i*par->gamma.num_values + j];
+
+	write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
+	write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
+	write_reg(par, 0x0032, CURVE(0, 9) << 8 | CURVE(0, 8));
+	write_reg(par, 0x0035, CURVE(0, 3) << 8 | CURVE(0, 2));
+	write_reg(par, 0x0036, CURVE(0, 1) << 8 | CURVE(0, 0));
+
+	write_reg(par, 0x0037, CURVE(1, 5) << 8 | CURVE(1, 4));
+	write_reg(par, 0x0038, CURVE(1, 7) << 8 | CURVE(1, 6));
+	write_reg(par, 0x0039, CURVE(1, 9) << 8 | CURVE(1, 8));
+	write_reg(par, 0x003C, CURVE(1, 3) << 8 | CURVE(1, 2));
+	write_reg(par, 0x003D, CURVE(1, 1) << 8 | CURVE(1, 0));
+
+	return 0;
+}
+#undef CURVE
+
+
+static struct fbtft_display display = {
+	.regwidth = 16,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.bpp = BPP,
+	.fps = FPS,
+	.gamma_num = 2,
+	.gamma_len = 10,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.set_gamma = set_gamma,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9325", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ili9325");
+MODULE_ALIAS("platform:ili9325");
+
+MODULE_DESCRIPTION("FB driver for the ILI9325 LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9340.c b/drivers/staging/fbtft/fb_ili9340.c
new file mode 100644
index 000000000000..985687d94ec2
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9340.c
@@ -0,0 +1,163 @@
+/*
+ * FB driver for the ILI9340 LCD Controller
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_ili9340"
+#define WIDTH		240
+#define HEIGHT		320
+
+
+/* Init sequence taken from: Arduino Library for the Adafruit 2.2" display */
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	write_reg(par, 0xEF, 0x03, 0x80, 0x02);
+	write_reg(par, 0xCF, 0x00 , 0XC1 , 0X30);
+	write_reg(par, 0xED, 0x64 , 0x03 , 0X12 , 0X81);
+	write_reg(par, 0xE8, 0x85 , 0x00 , 0x78);
+	write_reg(par, 0xCB, 0x39 , 0x2C , 0x00 , 0x34 , 0x02);
+	write_reg(par, 0xF7, 0x20);
+	write_reg(par, 0xEA, 0x00 , 0x00);
+
+	/* Power Control 1 */
+	write_reg(par, 0xC0, 0x23);
+
+	/* Power Control 2 */
+	write_reg(par, 0xC1, 0x10);
+
+	/* VCOM Control 1 */
+	write_reg(par, 0xC5, 0x3e, 0x28);
+
+	/* VCOM Control 2 */
+	write_reg(par, 0xC7, 0x86);
+
+	/* COLMOD: Pixel Format Set */
+	/* 16 bits/pixel */
+	write_reg(par, 0x3A, 0x55);
+
+	/* Frame Rate Control */
+	/* Division ratio = fosc, Frame Rate = 79Hz */
+	write_reg(par, 0xB1, 0x00, 0x18);
+
+	/* Display Function Control */
+	write_reg(par, 0xB6, 0x08, 0x82, 0x27);
+
+	/* Gamma Function Disable */
+	write_reg(par, 0xF2, 0x00);
+
+	/* Gamma curve selected  */
+	write_reg(par, 0x26, 0x01);
+
+	/* Positive Gamma Correction */
+	write_reg(par, 0xE0,
+		0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1,
+		0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00);
+
+	/* Negative Gamma Correction */
+	write_reg(par, 0xE1,
+		0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1,
+		0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F);
+
+	/* Sleep OUT */
+	write_reg(par, 0x11);
+
+	mdelay(120);
+
+	/* Display ON */
+	write_reg(par, 0x29);
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* Column address */
+	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
+
+	/* Row adress */
+	write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
+
+	/* Memory write */
+	write_reg(par, 0x2C);
+}
+
+#define ILI9340_MADCTL_MV  0x20
+#define ILI9340_MADCTL_MX  0x40
+#define ILI9340_MADCTL_MY  0x80
+static int set_var(struct fbtft_par *par)
+{
+	u8 val;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	case 270:
+		val = ILI9340_MADCTL_MV;
+		break;
+	case 180:
+		val = ILI9340_MADCTL_MY;
+		break;
+	case 90:
+		val = ILI9340_MADCTL_MV | ILI9340_MADCTL_MY | ILI9340_MADCTL_MX;
+		break;
+	default:
+		val = ILI9340_MADCTL_MX;
+		break;
+	}
+	/* Memory Access Control  */
+	write_reg(par, 0x36, val | (par->bgr << 3));
+
+	return 0;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9340", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ili9340");
+MODULE_ALIAS("platform:ili9340");
+
+MODULE_DESCRIPTION("FB driver for the ILI9340 LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9341.c b/drivers/staging/fbtft/fb_ili9341.c
new file mode 100644
index 000000000000..225b2d84371f
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9341.c
@@ -0,0 +1,179 @@
+/*
+ * FB driver for the ILI9341 LCD display controller
+ *
+ * This display uses 9-bit SPI: Data/Command bit + 8 data bits
+ * For platforms that doesn't support 9-bit, the driver is capable
+ * of emulating this using 8-bit transfer.
+ * This is done by transfering eight 9-bit words in 9 bytes.
+ *
+ * Copyright (C) 2013 Christian Vogelgsang
+ * Based on adafruit22fb.c by Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_ili9341"
+#define WIDTH		240
+#define HEIGHT		320
+#define TXBUFLEN	(4 * PAGE_SIZE)
+#define DEFAULT_GAMMA	"1F 1A 18 0A 0F 06 45 87 32 0A 07 02 07 05 00\n" \
+			"00 25 27 05 10 09 3A 78 4D 05 18 0D 38 3A 1F"
+
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	/* startup sequence for MI0283QT-9A */
+	write_reg(par, 0x01); /* software reset */
+	mdelay(5);
+	write_reg(par, 0x28); /* display off */
+	/* --------------------------------------------------------- */
+	write_reg(par, 0xCF, 0x00, 0x83, 0x30);
+	write_reg(par, 0xED, 0x64, 0x03, 0x12, 0x81);
+	write_reg(par, 0xE8, 0x85, 0x01, 0x79);
+	write_reg(par, 0xCB, 0x39, 0X2C, 0x00, 0x34, 0x02);
+	write_reg(par, 0xF7, 0x20);
+	write_reg(par, 0xEA, 0x00, 0x00);
+	/* ------------power control-------------------------------- */
+	write_reg(par, 0xC0, 0x26);
+	write_reg(par, 0xC1, 0x11);
+	/* ------------VCOM --------- */
+	write_reg(par, 0xC5, 0x35, 0x3E);
+	write_reg(par, 0xC7, 0xBE);
+	/* ------------memory access control------------------------ */
+	write_reg(par, 0x3A, 0x55); /* 16bit pixel */
+	/* ------------frame rate----------------------------------- */
+	write_reg(par, 0xB1, 0x00, 0x1B);
+	/* ------------Gamma---------------------------------------- */
+	/* write_reg(par, 0xF2, 0x08); */ /* Gamma Function Disable */
+	write_reg(par, 0x26, 0x01);
+	/* ------------display-------------------------------------- */
+	write_reg(par, 0xB7, 0x07); /* entry mode set */
+	write_reg(par, 0xB6, 0x0A, 0x82, 0x27, 0x00);
+	write_reg(par, 0x11); /* sleep out */
+	mdelay(100);
+	write_reg(par, 0x29); /* display on */
+	mdelay(20);
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* Column address set */
+	write_reg(par, 0x2A,
+		(xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
+
+	/* Row adress set */
+	write_reg(par, 0x2B,
+		(ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF);
+
+	/* Memory write */
+	write_reg(par, 0x2C);
+}
+
+#define MEM_Y   (7) /* MY row address order */
+#define MEM_X   (6) /* MX column address order */
+#define MEM_V   (5) /* MV row / column exchange */
+#define MEM_L   (4) /* ML vertical refresh order */
+#define MEM_H   (2) /* MH horizontal refresh order */
+#define MEM_BGR (3) /* RGB-BGR Order */
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	case 0:
+		write_reg(par, 0x36, (1 << MEM_X) | (par->bgr << MEM_BGR));
+		break;
+	case 270:
+		write_reg(par, 0x36,
+			(1<<MEM_V) | (1 << MEM_L) | (par->bgr << MEM_BGR));
+		break;
+	case 180:
+		write_reg(par, 0x36, (1 << MEM_Y) | (par->bgr << MEM_BGR));
+		break;
+	case 90:
+		write_reg(par, 0x36, (1 << MEM_Y) | (1 << MEM_X) |
+				     (1 << MEM_V) | (par->bgr << MEM_BGR));
+		break;
+	}
+
+	return 0;
+}
+
+/*
+  Gamma string format:
+    Positive: Par1 Par2 [...] Par15
+    Negative: Par1 Par2 [...] Par15
+*/
+#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	int i;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	for (i = 0; i < par->gamma.num_curves; i++)
+		write_reg(par, 0xE0 + i,
+			CURVE(i, 0), CURVE(i, 1), CURVE(i, 2),
+			CURVE(i, 3), CURVE(i, 4), CURVE(i, 5),
+			CURVE(i, 6), CURVE(i, 7), CURVE(i, 8),
+			CURVE(i, 9), CURVE(i, 10), CURVE(i, 11),
+			CURVE(i, 12), CURVE(i, 13), CURVE(i, 14));
+
+	return 0;
+}
+#undef CURVE
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.txbuflen = TXBUFLEN,
+	.gamma_num = 2,
+	.gamma_len = 15,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.set_gamma = set_gamma,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9341", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ili9341");
+MODULE_ALIAS("platform:ili9341");
+
+MODULE_DESCRIPTION("FB driver for the ILI9341 LCD display controller");
+MODULE_AUTHOR("Christian Vogelgsang");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9481.c b/drivers/staging/fbtft/fb_ili9481.c
new file mode 100644
index 000000000000..725157a1ac41
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9481.c
@@ -0,0 +1,117 @@
+/*
+ * FB driver for the ILI9481 LCD Controller
+ *
+ * Copyright (c) 2014 Petr Olivka
+ * Copyright (c) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME	"fb_ili9481"
+#define WIDTH		320
+#define HEIGHT		480
+
+static int default_init_sequence[] = {
+
+	/* SLP_OUT - Sleep out */
+	-1, 0x11,
+	-2, 50,
+	/* Power setting */
+	-1, 0xD0, 0x07, 0x42, 0x18,
+	/* VCOM */
+	-1, 0xD1, 0x00, 0x07, 0x10,
+	/* Power setting for norm. mode */
+	-1, 0xD2, 0x01, 0x02,
+	/* Panel driving setting */
+	-1, 0xC0, 0x10, 0x3B, 0x00, 0x02, 0x11,
+	/* Frame rate & inv. */
+	-1, 0xC5, 0x03,
+	/* Pixel format */
+	-1, 0x3A, 0x55,
+	/* Gamma */
+	-1, 0xC8, 0x00, 0x32, 0x36, 0x45, 0x06, 0x16,
+		  0x37, 0x75, 0x77, 0x54, 0x0C, 0x00,
+	/* DISP_ON */
+	-1, 0x29,
+	-3
+};
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* column address */
+	write_reg(par, 0x2a, xs >> 8, xs & 0xff, xe >> 8, xe & 0xff);
+
+	/* row adress */
+	write_reg(par, 0x2b, ys >> 8, ys & 0xff, ye >> 8, ye & 0xff);
+
+	/* memory write */
+	write_reg(par, 0x2c);
+}
+
+#define HFLIP 0x01
+#define VFLIP 0x02
+#define ROWxCOL 0x20
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	case 270:
+		write_reg(par, 0x36, ROWxCOL | HFLIP | VFLIP | (par->bgr << 3));
+		break;
+	case 180:
+		write_reg(par, 0x36, VFLIP | (par->bgr << 3));
+		break;
+	case 90:
+		write_reg(par, 0x36, ROWxCOL | (par->bgr << 3));
+		break;
+	default:
+		write_reg(par, 0x36, HFLIP | (par->bgr << 3));
+		break;
+	}
+
+	return 0;
+}
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.init_sequence = default_init_sequence,
+	.fbtftops = {
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9481", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ili9481");
+MODULE_ALIAS("platform:ili9481");
+
+MODULE_DESCRIPTION("FB driver for the ILI9481 LCD Controller");
+MODULE_AUTHOR("Petr Olivka");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ili9486.c b/drivers/staging/fbtft/fb_ili9486.c
new file mode 100644
index 000000000000..95b89999d32a
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ili9486.c
@@ -0,0 +1,121 @@
+/*
+ * FB driver for the ILI9486 LCD Controller
+ *
+ * Copyright (C) 2014 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_ili9486"
+#define WIDTH		320
+#define HEIGHT		480
+
+
+/* this init sequence matches PiScreen */
+static int default_init_sequence[] = {
+	/* Interface Mode Control */
+	-1, 0xb0, 0x0,
+	/* Sleep OUT */
+	-1, 0x11,
+	-2, 250,
+	/* Interface Pixel Format */
+	-1, 0x3A, 0x55,
+	/* Power Control 3 */
+	-1, 0xC2, 0x44,
+	/* VCOM Control 1 */
+	-1, 0xC5, 0x00, 0x00, 0x00, 0x00,
+	/* PGAMCTRL(Positive Gamma Control) */
+	-1, 0xE0, 0x0F, 0x1F, 0x1C, 0x0C, 0x0F, 0x08, 0x48, 0x98,
+	          0x37, 0x0A, 0x13, 0x04, 0x11, 0x0D, 0x00,
+	/* NGAMCTRL(Negative Gamma Control) */
+	-1, 0xE1, 0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75,
+	          0x37, 0x06, 0x10, 0x03, 0x24, 0x20, 0x00,
+	/* Digital Gamma Control 1 */
+	-1, 0xE2, 0x0F, 0x32, 0x2E, 0x0B, 0x0D, 0x05, 0x47, 0x75,
+	          0x37, 0x06, 0x10, 0x03, 0x24, 0x20, 0x00,
+	/* Sleep OUT */
+	-1, 0x11,
+	/* Display ON */
+	-1, 0x29,
+	/* end marker */
+	-3
+};
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* Column address */
+	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
+
+	/* Row adress */
+	write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
+
+	/* Memory write */
+	write_reg(par, 0x2C);
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	case 0:
+		write_reg(par, 0x36, 0x80 | (par->bgr << 3));
+		break;
+	case 90:
+		write_reg(par, 0x36, 0x20 | (par->bgr << 3));
+		break;
+	case 180:
+		write_reg(par, 0x36, 0x40 | (par->bgr << 3));
+		break;
+	case 270:
+		write_reg(par, 0x36, 0xE0 | (par->bgr << 3));
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.init_sequence = default_init_sequence,
+	.fbtftops = {
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9486", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ili9486");
+MODULE_ALIAS("platform:ili9486");
+
+MODULE_DESCRIPTION("FB driver for the ILI9486 LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c
new file mode 100644
index 000000000000..8b9ebfb49ef8
--- /dev/null
+++ b/drivers/staging/fbtft/fb_pcd8544.c
@@ -0,0 +1,177 @@
+/*
+ * FB driver for the PCD8544 LCD Controller
+ *
+ * The display is monochrome and the video memory is RGB565.
+ * Any pixel value except 0 turns the pixel on.
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME	       "fb_pcd8544"
+#define WIDTH          84
+#define HEIGHT         48
+#define TXBUFLEN       (84*6)
+#define DEFAULT_GAMMA  "40" /* gamma is used to control contrast in this driver */
+
+static unsigned tc;
+module_param(tc, uint, 0);
+MODULE_PARM_DESC(tc, "TC[1:0] Temperature coefficient: 0-3 (default: 0)");
+
+static unsigned bs = 4;
+module_param(bs, uint, 0);
+MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
+
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	/* Function set */
+	write_reg(par, 0x21); /* 5:1  1
+	                         2:0  PD - Powerdown control: chip is active
+							 1:0  V  - Entry mode: horizontal addressing
+							 0:1  H  - Extended instruction set control: extended
+						  */
+
+	/* H=1 Temperature control */
+	write_reg(par, 0x04 | (tc & 0x3)); /*
+	                         2:1  1
+	                         1:x  TC1 - Temperature Coefficient: 0x10
+							 0:x  TC0
+						  */
+
+	/* H=1 Bias system */
+	write_reg(par, 0x10 | (bs & 0x7)); /*
+	                         4:1  1
+	                         3:0  0
+							 2:x  BS2 - Bias System
+							 1:x  BS1
+							 0:x  BS0
+	                      */
+
+	/* Function set */
+	write_reg(par, 0x22); /* 5:1  1
+	                         2:0  PD - Powerdown control: chip is active
+							 1:1  V  - Entry mode: vertical addressing
+							 0:0  H  - Extended instruction set control: basic
+						  */
+
+	/* H=0 Display control */
+	write_reg(par, 0x08 | 4); /*
+	                         3:1  1
+	                         2:1  D  - DE: 10=normal mode
+							 1:0  0
+							 0:0  E
+						  */
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* H=0 Set X address of RAM */
+	write_reg(par, 0x80); /* 7:1  1
+	                         6-0: X[6:0] - 0x00
+	                      */
+
+	/* H=0 Set Y address of RAM */
+	write_reg(par, 0x40); /* 7:0  0
+	                         6:1  1
+	                         2-0: Y[2:0] - 0x0
+	                      */
+}
+
+static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+{
+	u16 *vmem16 = (u16 *)par->info->screen_base;
+	u8 *buf = par->txbuf.buf;
+	int x, y, i;
+	int ret = 0;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
+
+	for (x = 0; x < 84; x++) {
+		for (y = 0; y < 6; y++) {
+			*buf = 0x00;
+			for (i = 0; i < 8; i++) {
+				*buf |= (vmem16[(y*8+i)*84+x] ? 1 : 0) << i;
+			}
+			buf++;
+		}
+	}
+
+	/* Write data */
+	gpio_set_value(par->gpio.dc, 1);
+	ret = par->fbtftops.write(par, par->txbuf.buf, 6*84);
+	if (ret < 0)
+		dev_err(par->info->device, "%s: write failed and returned: %d\n", __func__, ret);
+
+	return ret;
+}
+
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	curves[0] &= 0x7F;
+
+	write_reg(par, 0x23); /* turn on extended instruction set */
+	write_reg(par, 0x80 | curves[0]);
+	write_reg(par, 0x22); /* turn off extended instruction set */
+
+	return 0;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.txbuflen = TXBUFLEN,
+	.gamma_num = 1,
+	.gamma_len = 1,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.write_vmem = write_vmem,
+		.set_gamma = set_gamma,
+	},
+	.backlight = 1,
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "philips,pdc8544", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("spi:pdc8544");
+
+MODULE_DESCRIPTION("FB driver for the PCD8544 LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c
new file mode 100644
index 000000000000..c323c06344fd
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ra8875.c
@@ -0,0 +1,331 @@
+/******************************************************************************
+
+  ProjectName: FBTFT driver                       ***** *****
+	       for the RA8875 LCD Controller     *     *      ************
+						*   **   **   *           *
+  Copyright © by Pf@nne & NOTRO                *   *   *   *   *   ****	   *
+						*   *       *   *   *   *   *
+  Last modification by:                        *   *       *   *   ****    *
+  - Pf@nne (pf@nne-mail.de)                     *   *     *****           *
+						 *   *        *   *******
+						  *****      *   *
+  Date    : 10.06.2014                                      *   *
+  Version : V1.13                                          *****
+  Revison : 5
+
+*******************************************************************************
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <linux/gpio.h>
+#include "fbtft.h"
+
+#define DRVNAME "fb_ra8875"
+
+static int write_spi(struct fbtft_par *par, void *buf, size_t len)
+{
+	struct spi_transfer t = {
+		.tx_buf = buf,
+		.len = len,
+		.speed_hz = 1000000,
+	};
+	struct spi_message m;
+
+	fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
+		"%s(len=%d): ", __func__, len);
+
+	if (!par->spi) {
+		dev_err(par->info->device,
+			"%s: par->spi is unexpectedly NULL\n", __func__);
+		return -1;
+	}
+
+	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);
+}
+
+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__);
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
+		"display size %dx%d\n", par->info->var.xres, par->info->var.yres);
+
+	par->fbtftops.reset(par);
+
+	if ((par->info->var.xres == 320) && (par->info->var.yres == 240)) {
+		/* PLL clock frequency */
+		write_reg(par, 0x88 , 0x0A);
+		write_reg(par, 0x89 , 0x02);
+		mdelay(10);
+		/* color deep / MCU Interface */
+		write_reg(par, 0x10 , 0x0C);
+		/* pixel clock period  */
+		write_reg(par, 0x04 , 0x03);
+		mdelay(1);
+		/* horizontal settings */
+		write_reg(par, 0x14 , 0x27);
+		write_reg(par, 0x15 , 0x00);
+		write_reg(par, 0x16 , 0x05);
+		write_reg(par, 0x17 , 0x04);
+		write_reg(par, 0x18 , 0x03);
+		/* vertical settings */
+		write_reg(par, 0x19 , 0xEF);
+		write_reg(par, 0x1A , 0x00);
+		write_reg(par, 0x1B , 0x05);
+		write_reg(par, 0x1C , 0x00);
+		write_reg(par, 0x1D , 0x0E);
+		write_reg(par, 0x1E , 0x00);
+		write_reg(par, 0x1F , 0x02);
+	} else if ((par->info->var.xres == 480) && (par->info->var.yres == 272)) {
+		/* PLL clock frequency  */
+		write_reg(par, 0x88 , 0x0A);
+		write_reg(par, 0x89 , 0x02);
+		mdelay(10);
+		/* color deep / MCU Interface */
+		write_reg(par, 0x10 , 0x0C);
+		/* pixel clock period  */
+		write_reg(par, 0x04 , 0x82);
+		mdelay(1);
+		/* horizontal settings */
+		write_reg(par, 0x14 , 0x3B);
+		write_reg(par, 0x15 , 0x00);
+		write_reg(par, 0x16 , 0x01);
+		write_reg(par, 0x17 , 0x00);
+		write_reg(par, 0x18 , 0x05);
+		/* vertical settings */
+		write_reg(par, 0x19 , 0x0F);
+		write_reg(par, 0x1A , 0x01);
+		write_reg(par, 0x1B , 0x02);
+		write_reg(par, 0x1C , 0x00);
+		write_reg(par, 0x1D , 0x07);
+		write_reg(par, 0x1E , 0x00);
+		write_reg(par, 0x1F , 0x09);
+	} else if ((par->info->var.xres == 640) && (par->info->var.yres == 480)) {
+		/* PLL clock frequency */
+		write_reg(par, 0x88 , 0x0B);
+		write_reg(par, 0x89 , 0x02);
+		mdelay(10);
+		/* color deep / MCU Interface */
+		write_reg(par, 0x10 , 0x0C);
+		/* pixel clock period */
+		write_reg(par, 0x04 , 0x01);
+		mdelay(1);
+		/* horizontal settings */
+		write_reg(par, 0x14 , 0x4F);
+		write_reg(par, 0x15 , 0x05);
+		write_reg(par, 0x16 , 0x0F);
+		write_reg(par, 0x17 , 0x01);
+		write_reg(par, 0x18 , 0x00);
+		/* vertical settings */
+		write_reg(par, 0x19 , 0xDF);
+		write_reg(par, 0x1A , 0x01);
+		write_reg(par, 0x1B , 0x0A);
+		write_reg(par, 0x1C , 0x00);
+		write_reg(par, 0x1D , 0x0E);
+		write_reg(par, 0x1E , 0x00);
+		write_reg(par, 0x1F , 0x01);
+	} else if ((par->info->var.xres == 800) && (par->info->var.yres == 480)) {
+		/* PLL clock frequency */
+		write_reg(par, 0x88 , 0x0B);
+		write_reg(par, 0x89 , 0x02);
+		mdelay(10);
+		/* color deep / MCU Interface */
+		write_reg(par, 0x10 , 0x0C);
+		/* pixel clock period */
+		write_reg(par, 0x04 , 0x81);
+		mdelay(1);
+		/* horizontal settings */
+		write_reg(par, 0x14 , 0x63);
+		write_reg(par, 0x15 , 0x03);
+		write_reg(par, 0x16 , 0x03);
+		write_reg(par, 0x17 , 0x02);
+		write_reg(par, 0x18 , 0x00);
+		/* vertical settings */
+		write_reg(par, 0x19 , 0xDF);
+		write_reg(par, 0x1A , 0x01);
+		write_reg(par, 0x1B , 0x14);
+		write_reg(par, 0x1C , 0x00);
+		write_reg(par, 0x1D , 0x06);
+		write_reg(par, 0x1E , 0x00);
+		write_reg(par, 0x1F , 0x01);
+	} else {
+		dev_err(par->info->device, "display size is not supported!!");
+		return -1;
+	}
+
+	/* PWM clock */
+	write_reg(par, 0x8a , 0x81);
+	write_reg(par, 0x8b , 0xFF);
+	mdelay(10);
+
+	/* Display ON */
+	write_reg(par, 0x01 , 0x80);
+	mdelay(10);
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* Set_Active_Window */
+	write_reg(par, 0x30 , xs & 0x00FF);
+	write_reg(par, 0x31 , (xs & 0xFF00) >> 8);
+	write_reg(par, 0x32 , ys & 0x00FF);
+	write_reg(par, 0x33 , (ys & 0xFF00) >> 8);
+	write_reg(par, 0x34 , (xs+xe) & 0x00FF);
+	write_reg(par, 0x35 , ((xs+xe) & 0xFF00) >> 8);
+	write_reg(par, 0x36 , (ys+ye) & 0x00FF);
+	write_reg(par, 0x37 , ((ys+ye) & 0xFF00) >> 8);
+
+	/* Set_Memory_Write_Cursor */
+	write_reg(par, 0x46,  xs & 0xff);
+	write_reg(par, 0x47, (xs >> 8) & 0x03);
+	write_reg(par, 0x48,  ys & 0xff);
+	write_reg(par, 0x49, (ys >> 8) & 0x01);
+
+	write_reg(par, 0x02);
+}
+
+static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
+{
+	va_list args;
+	int i, ret;
+	u8 *buf = (u8 *)par->buf;
+
+	/* slow down spi-speed for writing registers */
+	par->fbtftops.write = write_spi;
+
+	if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
+		va_start(args, len);
+		for (i = 0; i < len; i++)
+			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__);
+	}
+
+	va_start(args, len);
+	*buf++ = 0x80;
+	*buf = (u8)va_arg(args, unsigned int);
+	ret = par->fbtftops.write(par, par->buf, 2);
+	if (ret < 0) {
+		va_end(args);
+		dev_err(par->info->device, "%s: write() failed and returned %dn",
+			__func__, ret);
+		return;
+	}
+	len--;
+
+	udelay(100);
+
+	if (len) {
+		buf = (u8 *)par->buf;
+		*buf++ = 0x00;
+		i = len;
+		while (i--)
+			*buf++ = (u8)va_arg(args, unsigned int);
+
+		ret = par->fbtftops.write(par, par->buf, len + 1);
+		if (ret < 0) {
+			va_end(args);
+			dev_err(par->info->device, "%s: write() failed and returned %dn",
+				__func__, ret);
+			return;
+		}
+	}
+	va_end(args);
+
+	/* restore user spi-speed */
+	par->fbtftops.write = fbtft_write_spi;
+	udelay(100);
+}
+
+static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
+{
+	u16 *vmem16;
+	u16 *txbuf16 = (u16 *)par->txbuf.buf;
+	size_t remain;
+	size_t to_copy;
+	size_t tx_array_size;
+	int i;
+	int ret = 0;
+	size_t startbyte_size = 0;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
+		__func__, offset, len);
+
+	remain = len / 2;
+	vmem16 = (u16 *)(par->info->screen_base + offset);
+	tx_array_size = par->txbuf.len / 2;
+		txbuf16 = (u16 *)(par->txbuf.buf + 1);
+		tx_array_size -= 2;
+		*(u8 *)(par->txbuf.buf) = 0x00;
+		startbyte_size = 1;
+
+	while (remain) {
+		to_copy = remain > tx_array_size ? tx_array_size : remain;
+		dev_dbg(par->info->device, "    to_copy=%zu, remain=%zu\n",
+			to_copy, remain - to_copy);
+
+		for (i = 0; i < to_copy; i++)
+			txbuf16[i] = cpu_to_be16(vmem16[i]);
+
+		vmem16 = vmem16 + to_copy;
+		ret = par->fbtftops.write(par, par->txbuf.buf,
+			startbyte_size + to_copy * 2);
+		if (ret < 0)
+			return ret;
+		remain -= to_copy;
+	}
+
+	return ret;
+}
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.write_register = write_reg8_bus8,
+		.write_vmem = write_vmem16_bus8,
+		.write = write_spi,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "raio,ra8875", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ra8875");
+MODULE_ALIAS("platform:ra8875");
+
+MODULE_DESCRIPTION("FB driver for the RA8875 LCD Controller");
+MODULE_AUTHOR("Pf@nne");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_s6d02a1.c b/drivers/staging/fbtft/fb_s6d02a1.c
new file mode 100644
index 000000000000..e412a42443e5
--- /dev/null
+++ b/drivers/staging/fbtft/fb_s6d02a1.c
@@ -0,0 +1,168 @@
+/*
+ * FB driver for the S6D02A1 LCD Controller
+ *
+ * Based on fb_st7735r.c by Noralf Tronnes
+ * Init code from UTFT library by Henning Karlsen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include "fbtft.h"
+
+#define DRVNAME "fb_s6d02a1"
+
+static int default_init_sequence[] = {
+
+	-1, 0xf0, 0x5a, 0x5a,
+
+	-1, 0xfc, 0x5a, 0x5a,
+
+	-1, 0xfa, 0x02, 0x1f, 0x00, 0x10, 0x22, 0x30, 0x38, 0x3A, 0x3A, 0x3A, 0x3A, 0x3A, 0x3d, 0x02, 0x01,
+
+	-1, 0xfb, 0x21, 0x00, 0x02, 0x04, 0x07, 0x0a, 0x0b, 0x0c, 0x0c, 0x16, 0x1e, 0x30, 0x3f, 0x01, 0x02,
+
+	/* power setting sequence */
+	-1, 0xfd, 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x01, 0x01, 0x00, 0x1f, 0x1f,
+
+	-1, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00,
+
+	-1, 0xf5, 0x00, 0x70, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x66, 0x06,
+
+	-1, 0xf6, 0x02, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x01, 0x00,
+
+	-1, 0xf2, 0x00, 0x01, 0x03, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x08, 0x08,
+
+	-1, 0xf8, 0x11,
+
+	-1, 0xf7, 0xc8, 0x20, 0x00, 0x00,
+
+	-1, 0xf3, 0x00, 0x00,
+
+	-1, 0x11,
+	-2, 50,
+
+	-1, 0xf3, 0x00, 0x01,
+	-2, 50,
+	-1, 0xf3, 0x00, 0x03,
+	-2, 50,
+	-1, 0xf3, 0x00, 0x07,
+	-2, 50,
+	-1, 0xf3, 0x00, 0x0f,
+	-2, 50,
+
+	-1, 0xf4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00,
+	-2, 50,
+
+	-1, 0xf3, 0x00, 0x1f,
+	-2, 50,
+	-1, 0xf3, 0x00, 0x7f,
+	-2, 50,
+
+	-1, 0xf3, 0x00, 0xff,
+	-2, 50,
+
+	-1, 0xfd, 0x00, 0x00, 0x00, 0x17, 0x10, 0x00, 0x00, 0x01, 0x00, 0x16, 0x16,
+
+	-1, 0xf4, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x07, 0x00, 0x3C, 0x36, 0x00, 0x3C, 0x36, 0x00,
+
+	/* initializing sequence */
+
+	-1, 0x36, 0x08,
+
+	-1, 0x35, 0x00,
+
+	-1, 0x3a, 0x05,
+
+	/* gamma setting sequence */
+	-1, 0x26, 0x01,	/* preset gamma curves, possible values 0x01, 0x02, 0x04, 0x08 */
+
+	-2, 150,
+	-1, 0x29,
+	-1, 0x2c,
+	/* end marker */
+	-3
+
+};
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* Column address */
+	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
+
+	/* Row adress */
+	write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
+
+	/* Memory write */
+	write_reg(par, 0x2C);
+}
+
+#define MY (1 << 7)
+#define MX (1 << 6)
+#define MV (1 << 5)
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* MADCTL - Memory data access control
+	     RGB/BGR:
+		1. Mode selection pin SRGB
+			RGB H/W pin for color filter setting: 0=RGB, 1=BGR
+		2. MADCTL RGB bit
+			RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR */
+	switch (par->info->var.rotate) {
+	case 0:
+		write_reg(par, 0x36, MX | MY | (par->bgr << 3));
+		break;
+	case 270:
+		write_reg(par, 0x36, MY | MV | (par->bgr << 3));
+		break;
+	case 180:
+		write_reg(par, 0x36, (par->bgr << 3));
+		break;
+	case 90:
+		write_reg(par, 0x36, MX | MV | (par->bgr << 3));
+		break;
+	}
+
+	return 0;
+}
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = 128,
+	.height = 160,
+	.init_sequence = default_init_sequence,
+	.fbtftops = {
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "samsung,s6d02a1", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:s6d02a1");
+MODULE_ALIAS("platform:s6d02a1");
+
+MODULE_DESCRIPTION("FB driver for the S6D02A1 LCD Controller");
+MODULE_AUTHOR("WOLFGANG BUENING");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c
new file mode 100644
index 000000000000..1ef8c1ad827e
--- /dev/null
+++ b/drivers/staging/fbtft/fb_s6d1121.c
@@ -0,0 +1,208 @@
+/*
+ * FB driver for the S6D1121 LCD Controller
+ *
+ * Copyright (C) 2013 Roman Rolinsky
+ *
+ * Based on fb_ili9325.c by Noralf Tronnes
+ * Based on ili9325.c by Jeroen Domburg
+ * Init code from UTFT library by Henning Karlsen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_s6d1121"
+#define WIDTH		240
+#define HEIGHT		320
+#define BPP		16
+#define FPS		20
+#define DEFAULT_GAMMA	"26 09 24 2C 1F 23 24 25 22 26 25 23 0D 00\n" \
+			"1C 1A 13 1D 0B 11 12 10 13 15 36 19 00 0D"
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	if (par->gpio.cs != -1)
+		gpio_set_value(par->gpio.cs, 0);  /* Activate chip */
+
+	/* Initialization sequence from Lib_UTFT */
+
+	write_reg(par, 0x0011, 0x2004);
+	write_reg(par, 0x0013, 0xCC00);
+	write_reg(par, 0x0015, 0x2600);
+	write_reg(par, 0x0014, 0x252A);
+	write_reg(par, 0x0012, 0x0033);
+	write_reg(par, 0x0013, 0xCC04);
+	write_reg(par, 0x0013, 0xCC06);
+	write_reg(par, 0x0013, 0xCC4F);
+	write_reg(par, 0x0013, 0x674F);
+	write_reg(par, 0x0011, 0x2003);
+	write_reg(par, 0x0016, 0x0007);
+	write_reg(par, 0x0002, 0x0013);
+	write_reg(par, 0x0003, 0x0003);
+	write_reg(par, 0x0001, 0x0127);
+	write_reg(par, 0x0008, 0x0303);
+	write_reg(par, 0x000A, 0x000B);
+	write_reg(par, 0x000B, 0x0003);
+	write_reg(par, 0x000C, 0x0000);
+	write_reg(par, 0x0041, 0x0000);
+	write_reg(par, 0x0050, 0x0000);
+	write_reg(par, 0x0060, 0x0005);
+	write_reg(par, 0x0070, 0x000B);
+	write_reg(par, 0x0071, 0x0000);
+	write_reg(par, 0x0078, 0x0000);
+	write_reg(par, 0x007A, 0x0000);
+	write_reg(par, 0x0079, 0x0007);
+	write_reg(par, 0x0007, 0x0051);
+	write_reg(par, 0x0007, 0x0053);
+	write_reg(par, 0x0079, 0x0000);
+
+	write_reg(par, 0x0022); /* Write Data to GRAM */
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+	switch (par->info->var.rotate) {
+	/* R20h = Horizontal GRAM Start Address */
+	/* R21h = Vertical GRAM Start Address */
+	case 0:
+		write_reg(par, 0x0020, xs);
+		write_reg(par, 0x0021, ys);
+		break;
+	case 180:
+		write_reg(par, 0x0020, WIDTH - 1 - xs);
+		write_reg(par, 0x0021, HEIGHT - 1 - ys);
+		break;
+	case 270:
+		write_reg(par, 0x0020, WIDTH - 1 - ys);
+		write_reg(par, 0x0021, xs);
+		break;
+	case 90:
+		write_reg(par, 0x0020, ys);
+		write_reg(par, 0x0021, HEIGHT - 1 - xs);
+		break;
+	}
+	write_reg(par, 0x0022); /* Write Data to GRAM */
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	/* AM: GRAM update direction */
+	case 0:
+		write_reg(par, 0x03, 0x0003 | (par->bgr << 12));
+		break;
+	case 180:
+		write_reg(par, 0x03, 0x0000 | (par->bgr << 12));
+		break;
+	case 270:
+		write_reg(par, 0x03, 0x000A | (par->bgr << 12));
+		break;
+	case 90:
+		write_reg(par, 0x03, 0x0009 | (par->bgr << 12));
+		break;
+	}
+
+	return 0;
+}
+
+/*
+  Gamma string format:
+    PKP0 PKP1 PKP2 PKP3 PKP4 PKP5 PKP6 PKP7 PKP8 PKP9 PKP10 PKP11 VRP0 VRP1
+    PKN0 PKN1 PKN2 PKN3 PKN4 PKN5 PKN6 PKN7 PRN8 PRN9 PRN10 PRN11 VRN0 VRN1
+*/
+#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	unsigned long mask[] = {
+		0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 
+		0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111,
+		0b11111, 0b11111,
+		0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111,
+		0b111111, 0b111111, 0b111111, 0b111111, 0b111111, 0b111111,
+		0b11111, 0b11111 };
+	int i, j;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	for (i = 0; i < 2; i++)
+		for (j = 0; j < 14; j++)
+			CURVE(i, j) &= mask[i*par->gamma.num_values + j];
+
+	write_reg(par, 0x0030, CURVE(0, 1) << 8 | CURVE(0, 0));
+	write_reg(par, 0x0031, CURVE(0, 3) << 8 | CURVE(0, 2));
+	write_reg(par, 0x0032, CURVE(0, 5) << 8 | CURVE(0, 3));
+	write_reg(par, 0x0033, CURVE(0, 7) << 8 | CURVE(0, 6));
+	write_reg(par, 0x0034, CURVE(0, 9) << 8 | CURVE(0, 8));
+	write_reg(par, 0x0035, CURVE(0, 11) << 8 | CURVE(0, 10));
+
+	write_reg(par, 0x0036, CURVE(1, 1) << 8 | CURVE(1, 0));
+	write_reg(par, 0x0037, CURVE(1, 3) << 8 | CURVE(1, 2));
+	write_reg(par, 0x0038, CURVE(1, 5) << 8 | CURVE(1, 4));
+	write_reg(par, 0x0039, CURVE(1, 7) << 8 | CURVE(1, 6));
+	write_reg(par, 0x003A, CURVE(1, 9) << 8 | CURVE(1, 8));
+	write_reg(par, 0x003B, CURVE(1, 11) << 8 | CURVE(1, 10));
+
+	write_reg(par, 0x003C, CURVE(0, 13) << 8 | CURVE(0, 12));
+	write_reg(par, 0x003D, CURVE(1, 13) << 8 | CURVE(1, 12));
+
+	return 0;
+}
+#undef CURVE
+
+
+static struct fbtft_display display = {
+	.regwidth = 16,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.bpp = BPP,
+	.fps = FPS,
+	.gamma_num = 2,
+	.gamma_len = 14,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.set_gamma = set_gamma,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "samsung,s6d1121", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:s6d1121");
+MODULE_ALIAS("platform:s6d1121");
+
+MODULE_DESCRIPTION("FB driver for the S6D1121 LCD Controller");
+MODULE_AUTHOR("Roman Rolinsky");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c
new file mode 100644
index 000000000000..ef46fbca2700
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ssd1289.c
@@ -0,0 +1,206 @@
+/*
+ * FB driver for the SSD1289 LCD Controller
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * Init sequence taken from ITDB02_Graph16.cpp - (C)2010-2011 Henning Karlsen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_ssd1289"
+#define WIDTH		240
+#define HEIGHT		320
+#define DEFAULT_GAMMA	"02 03 2 5 7 7 4 2 4 2\n" \
+			"02 03 2 5 7 5 4 2 4 2"
+
+static unsigned reg11 = 0x6040;
+module_param(reg11, uint, 0);
+MODULE_PARM_DESC(reg11, "Register 11h value");
+
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	if (par->gpio.cs != -1)
+		gpio_set_value(par->gpio.cs, 0);  /* Activate chip */
+
+	write_reg(par, 0x00, 0x0001);
+	write_reg(par, 0x03, 0xA8A4);
+	write_reg(par, 0x0C, 0x0000);
+	write_reg(par, 0x0D, 0x080C);
+	write_reg(par, 0x0E, 0x2B00);
+	write_reg(par, 0x1E, 0x00B7);
+	write_reg(par, 0x01,
+		(1 << 13) | (par->bgr << 11) | (1 << 9) | (HEIGHT - 1));
+	write_reg(par, 0x02, 0x0600);
+	write_reg(par, 0x10, 0x0000);
+	write_reg(par, 0x05, 0x0000);
+	write_reg(par, 0x06, 0x0000);
+	write_reg(par, 0x16, 0xEF1C);
+	write_reg(par, 0x17, 0x0003);
+	write_reg(par, 0x07, 0x0233);
+	write_reg(par, 0x0B, 0x0000);
+	write_reg(par, 0x0F, 0x0000);
+	write_reg(par, 0x41, 0x0000);
+	write_reg(par, 0x42, 0x0000);
+	write_reg(par, 0x48, 0x0000);
+	write_reg(par, 0x49, 0x013F);
+	write_reg(par, 0x4A, 0x0000);
+	write_reg(par, 0x4B, 0x0000);
+	write_reg(par, 0x44, 0xEF00);
+	write_reg(par, 0x45, 0x0000);
+	write_reg(par, 0x46, 0x013F);
+	write_reg(par, 0x23, 0x0000);
+	write_reg(par, 0x24, 0x0000);
+	write_reg(par, 0x25, 0x8000);
+	write_reg(par, 0x4f, 0x0000);
+	write_reg(par, 0x4e, 0x0000);
+	write_reg(par, 0x22);
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	switch (par->info->var.rotate) {
+	/* R4Eh - Set GDDRAM X address counter */
+	/* R4Fh - Set GDDRAM Y address counter */
+	case 0:
+		write_reg(par, 0x4e, xs);
+		write_reg(par, 0x4f, ys);
+		break;
+	case 180:
+		write_reg(par, 0x4e, par->info->var.xres - 1 - xs);
+		write_reg(par, 0x4f, par->info->var.yres - 1 - ys);
+		break;
+	case 270:
+		write_reg(par, 0x4e, par->info->var.yres - 1 - ys);
+		write_reg(par, 0x4f, xs);
+		break;
+	case 90:
+		write_reg(par, 0x4e, ys);
+		write_reg(par, 0x4f, par->info->var.xres - 1 - xs);
+		break;
+	}
+
+	/* R22h - RAM data write */
+	write_reg(par, 0x22);
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	if (par->fbtftops.init_display != init_display) {
+		/* don't risk messing up register 11h */
+		fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
+			"%s: skipping since custom init_display() is used\n",
+			__func__);
+		return 0;
+	}
+
+	switch (par->info->var.rotate) {
+	case 0:
+		write_reg(par, 0x11, reg11 | 0b110000);
+		break;
+	case 270:
+		write_reg(par, 0x11, reg11 | 0b101000);
+		break;
+	case 180:
+		write_reg(par, 0x11, reg11 | 0b000000);
+		break;
+	case 90:
+		write_reg(par, 0x11, reg11 | 0b011000);
+		break;
+	}
+
+	return 0;
+}
+
+/*
+  Gamma string format:
+    VRP0 VRP1 PRP0 PRP1 PKP0 PKP1 PKP2 PKP3 PKP4 PKP5
+    VRN0 VRN1 PRN0 PRN1 PKN0 PKN1 PKN2 PKN3 PKN4 PKN5
+*/
+#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	unsigned long mask[] = {
+		0b11111, 0b11111, 0b111, 0b111, 0b111,
+		0b111, 0b111, 0b111, 0b111, 0b111,
+		0b11111, 0b11111, 0b111, 0b111, 0b111,
+		0b111, 0b111, 0b111, 0b111, 0b111 };
+	int i, j;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	for (i = 0; i < 2; i++)
+		for (j = 0; j < 10; j++)
+			CURVE(i, j) &= mask[i*par->gamma.num_values + j];
+
+	write_reg(par, 0x0030, CURVE(0, 5) << 8 | CURVE(0, 4));
+	write_reg(par, 0x0031, CURVE(0, 7) << 8 | CURVE(0, 6));
+	write_reg(par, 0x0032, CURVE(0, 9) << 8 | CURVE(0, 8));
+	write_reg(par, 0x0033, CURVE(0, 3) << 8 | CURVE(0, 2));
+	write_reg(par, 0x0034, CURVE(1, 5) << 8 | CURVE(1, 4));
+	write_reg(par, 0x0035, CURVE(1, 7) << 8 | CURVE(1, 6));
+	write_reg(par, 0x0036, CURVE(1, 9) << 8 | CURVE(1, 8));
+	write_reg(par, 0x0037, CURVE(1, 3) << 8 | CURVE(1, 2));
+	write_reg(par, 0x003A, CURVE(0, 1) << 8 | CURVE(0, 0));
+	write_reg(par, 0x003B, CURVE(1, 1) << 8 | CURVE(1, 0));
+
+	return 0;
+}
+#undef CURVE
+
+
+static struct fbtft_display display = {
+	.regwidth = 16,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.gamma_num = 2,
+	.gamma_len = 10,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.set_gamma = set_gamma,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1289", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ssd1289");
+MODULE_ALIAS("platform:ssd1289");
+
+MODULE_DESCRIPTION("FB driver for the SSD1289 LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c
new file mode 100644
index 000000000000..5ea195b0de1b
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ssd1306.c
@@ -0,0 +1,229 @@
+/*
+ * FB driver for the SSD1306 OLED Controller
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_ssd1306"
+#define WIDTH		128
+#define HEIGHT		64
+
+
+/*
+  write_reg() caveat:
+
+     This doesn't work because D/C has to be LOW for both values:
+       write_reg(par, val1, val2);
+
+     Do it like this:
+       write_reg(par, val1);
+       write_reg(par, val2);
+*/
+
+/* Init sequence taken from the Adafruit SSD1306 Arduino library */
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	if (par->gamma.curves[0] == 0) {
+		mutex_lock(&par->gamma.lock);
+		if (par->info->var.yres == 64)
+			par->gamma.curves[0] = 0xCF;
+		else
+			par->gamma.curves[0] = 0x8F;
+		mutex_unlock(&par->gamma.lock);
+	}
+
+	/* Set Display OFF */
+	write_reg(par, 0xAE);
+
+	/* Set Display Clock Divide Ratio/ Oscillator Frequency */
+	write_reg(par, 0xD5);
+	write_reg(par, 0x80);
+
+	/* Set Multiplex Ratio */
+	write_reg(par, 0xA8);
+	if (par->info->var.yres == 64)
+		write_reg(par, 0x3F);
+	else
+		write_reg(par, 0x1F);
+
+	/* Set Display Offset */
+	write_reg(par, 0xD3);
+	write_reg(par, 0x0);
+
+	/* Set Display Start Line */
+	write_reg(par, 0x40 | 0x0);
+
+	/* Charge Pump Setting */
+	write_reg(par, 0x8D);
+	/* A[2] = 1b, Enable charge pump during display on */
+	write_reg(par, 0x14);
+
+	/* Set Memory Addressing Mode */
+	write_reg(par, 0x20);
+	/* Vertical addressing mode  */
+	write_reg(par, 0x01);
+
+	/*Set Segment Re-map */
+	/* column address 127 is mapped to SEG0 */
+	write_reg(par, 0xA0 | 0x1);
+
+	/* Set COM Output Scan Direction */
+	/* remapped mode. Scan from COM[N-1] to COM0 */
+	write_reg(par, 0xC8);
+
+	/* Set COM Pins Hardware Configuration */
+	write_reg(par, 0xDA);
+	if (par->info->var.yres == 64)
+		/* A[4]=1b, Alternative COM pin configuration */
+		write_reg(par, 0x12);
+	else
+		/* A[4]=0b, Sequential COM pin configuration */
+		write_reg(par, 0x02);
+
+	/* Set Pre-charge Period */
+	write_reg(par, 0xD9);
+	write_reg(par, 0xF1);
+
+	/* Set VCOMH Deselect Level */
+	write_reg(par, 0xDB);
+	/* according to the datasheet, this value is out of bounds */
+	write_reg(par, 0x40);
+
+	/* Entire Display ON */
+	/* Resume to RAM content display. Output follows RAM content */
+	write_reg(par, 0xA4);
+
+	/* Set Normal Display
+	   0 in RAM: OFF in display panel
+	   1 in RAM: ON in display panel */
+	write_reg(par, 0xA6);
+
+	/* Set Display ON */
+	write_reg(par, 0xAF);
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* Set Lower Column Start Address for Page Addressing Mode */
+	write_reg(par, 0x00 | 0x0);
+	/* Set Higher Column Start Address for Page Addressing Mode */
+	write_reg(par, 0x10 | 0x0);
+	/* Set Display Start Line */
+	write_reg(par, 0x40 | 0x0);
+}
+
+static int blank(struct fbtft_par *par, bool on)
+{
+	fbtft_par_dbg(DEBUG_BLANK, par, "%s(blank=%s)\n",
+		__func__, on ? "true" : "false");
+
+	if (on)
+		write_reg(par, 0xAE);
+	else
+		write_reg(par, 0xAF);
+	return 0;
+}
+
+/* Gamma is used to control Contrast */
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	curves[0] &= 0xFF;
+
+	/* Set Contrast Control for BANK0 */
+	write_reg(par, 0x81);
+	write_reg(par, curves[0]);
+
+	return 0;
+}
+
+static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+{
+	u16 *vmem16 = (u16 *)par->info->screen_base;
+	u8 *buf = par->txbuf.buf;
+	int x, y, i;
+	int ret = 0;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
+
+	for (x = 0; x < par->info->var.xres; x++) {
+		for (y = 0; y < par->info->var.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++;
+		}
+	}
+
+	/* 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);
+	if (ret < 0)
+		dev_err(par->info->device,
+			"%s: write failed and returned: %d\n", __func__, ret);
+
+	return ret;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.gamma_num = 1,
+	.gamma_len = 1,
+	.gamma = "00",
+	.fbtftops = {
+		.write_vmem = write_vmem,
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.blank = blank,
+		.set_gamma = set_gamma,
+	},
+};
+
+
+FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1306", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ssd1306");
+MODULE_ALIAS("platform:ssd1306");
+
+MODULE_DESCRIPTION("SSD1306 OLED Driver");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c
new file mode 100644
index 000000000000..da7464f90e37
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ssd1331.c
@@ -0,0 +1,205 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_ssd1331"
+#define WIDTH		96
+#define HEIGHT		64
+#define GAMMA_NUM	1
+#define GAMMA_LEN	63
+#define DEFAULT_GAMMA	"0 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2" \
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	write_reg(par, 0xae); /* Display Off */
+	write_reg(par, 0xa0, 0x70 | (par->bgr << 2)); /* Set Colour Depth */
+	write_reg(par, 0x72); // RGB colour
+	write_reg(par, 0xa1, 0x00); /* Set Display Start Line */
+	write_reg(par, 0xa2, 0x00); /* Set Display Offset */
+	write_reg(par, 0xa4); /* NORMALDISPLAY */
+	write_reg(par, 0xa8, 0x3f); // Set multiplex
+	write_reg(par, 0xad, 0x8e); // Set master
+	// write_reg(par, 0xb0, 0x0b); // Set power mode
+	write_reg(par, 0xb1, 0x31); // Precharge
+	write_reg(par, 0xb3, 0xf0); // Clock div
+	write_reg(par, 0x8a, 0x64); // Precharge A
+	write_reg(par, 0x8b, 0x78); // Precharge B
+	write_reg(par, 0x8c, 0x64); // Precharge C
+	write_reg(par, 0xbb, 0x3a); // Precharge level
+	write_reg(par, 0xbe, 0x3e); // vcomh
+	write_reg(par, 0x87, 0x06); // Master current
+	write_reg(par, 0x81, 0x91); // Contrast A
+	write_reg(par, 0x82, 0x50); // Contrast B
+	write_reg(par, 0x83, 0x7d); // Contrast C
+	write_reg(par, 0xaf); /* Set Sleep Mode Display On */
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	write_reg(par, 0x15, xs, xe);
+	write_reg(par, 0x75, ys, ye);
+}
+
+static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
+{
+	va_list args;
+	int i, ret;
+	u8 *buf = (u8 *)par->buf;
+
+	if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
+		va_start(args, len);
+		for (i = 0; i < len; i++) {
+			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__);
+	}
+
+	va_start(args, len);
+
+	*buf = (u8)va_arg(args, unsigned int);
+	if (par->gpio.dc != -1)
+		gpio_set_value(par->gpio.dc, 0);
+	ret = par->fbtftops.write(par, par->buf, sizeof(u8));
+	if (ret < 0) {
+		va_end(args);
+		dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret);
+		return;
+	}
+	len--;
+
+	if (len) {
+		i = len;
+		while (i--) {
+			*buf++ = (u8)va_arg(args, unsigned int);
+		}
+		ret = par->fbtftops.write(par, par->buf, len * (sizeof(u8)));
+		if (ret < 0) {
+			va_end(args);
+			dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret);
+			return;
+		}
+	}
+	if (par->gpio.dc != -1)
+		gpio_set_value(par->gpio.dc, 1);
+	va_end(args);
+}
+
+/*
+	Grayscale Lookup Table
+	GS1 - GS63
+	The driver Gamma curve contains the relative values between the entries
+	in the Lookup table.
+
+	From datasheet:
+	8.8 Gray Scale Decoder
+
+		there are total 180 Gamma Settings (Setting 0 to Setting 180)
+		available for the Gray Scale table.
+
+		The gray scale is defined in incremental way, with reference
+		to the length of previous table entry:
+			Setting of GS1 has to be >= 0
+			Setting of GS2 has to be > Setting of GS1 +1
+			Setting of GS3 has to be > Setting of GS2 +1
+			:
+			Setting of GS63 has to be > Setting of GS62 +1
+
+
+*/
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	unsigned long tmp[GAMMA_NUM * GAMMA_LEN];
+	int i, acc = 0;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	for (i = 0; i < 63; i++) {
+		if (i > 0 && curves[i] < 2) {
+			dev_err(par->info->device,
+				"Illegal value in Grayscale Lookup Table at index %d. " \
+				"Must be greater than 1\n", i);
+			return -EINVAL;
+		}
+		acc += curves[i];
+		tmp[i] = acc;
+		if (acc > 180) {
+			dev_err(par->info->device,
+				"Illegal value(s) in Grayscale Lookup Table. " \
+				"At index=%d, the accumulated value has exceeded 180\n", i);
+			return -EINVAL;
+		}
+	}
+
+	write_reg(par, 0xB8,
+	tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7],
+	tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14], tmp[15],
+	tmp[16], tmp[17], tmp[18], tmp[19], tmp[20], tmp[21], tmp[22], tmp[23],
+	tmp[24], tmp[25], tmp[26], tmp[27], tmp[28], tmp[29], tmp[30], tmp[31],
+	tmp[32], tmp[33], tmp[34], tmp[35], tmp[36], tmp[37], tmp[38], tmp[39],
+	tmp[40], tmp[41], tmp[42], tmp[43], tmp[44], tmp[45], tmp[46], tmp[47],
+	tmp[48], tmp[49], tmp[50], tmp[51], tmp[52], tmp[53], tmp[54], tmp[55],
+	tmp[56], tmp[57], tmp[58], tmp[59], tmp[60], tmp[61], tmp[62]);
+
+	return 0;
+}
+
+static int blank(struct fbtft_par *par, bool on)
+{
+	fbtft_par_dbg(DEBUG_BLANK, par, "%s(blank=%s)\n",
+		__func__, on ? "true" : "false");
+	if (on)
+		write_reg(par, 0xAE);
+	else
+		write_reg(par, 0xAF);
+	return 0;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.gamma_num = GAMMA_NUM,
+	.gamma_len = GAMMA_LEN,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.write_register = write_reg8_bus8,
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_gamma = set_gamma,
+		.blank = blank,
+	},
+};
+
+FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1331", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ssd1331");
+MODULE_ALIAS("platform:ssd1331");
+
+MODULE_DESCRIPTION("SSD1331 OLED Driver");
+MODULE_AUTHOR("Alec Smecher (adapted from SSD1351 by James Davies)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c
new file mode 100644
index 000000000000..062d98660f63
--- /dev/null
+++ b/drivers/staging/fbtft/fb_ssd1351.c
@@ -0,0 +1,258 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_ssd1351"
+#define WIDTH		128
+#define HEIGHT		128
+#define GAMMA_NUM	1
+#define GAMMA_LEN	63
+#define DEFAULT_GAMMA	"0 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2 2 " \
+			"2 2 2 2 2 2 2" \
+
+static void register_onboard_backlight(struct fbtft_par *par);
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	if (par->pdata
+		&& par->pdata->display.backlight == FBTFT_ONBOARD_BACKLIGHT) {
+		/* module uses onboard GPIO for panel power */
+		par->fbtftops.register_backlight = register_onboard_backlight;
+	}
+
+	par->fbtftops.reset(par);
+
+	write_reg(par, 0xfd, 0x12); /* Command Lock */
+	write_reg(par, 0xfd, 0xb1); /* Command Lock */
+	write_reg(par, 0xae); /* Display Off */
+	write_reg(par, 0xb3, 0xf1); /* Front Clock Div */
+	write_reg(par, 0xca, 0x7f); /* Set Mux Ratio */
+	write_reg(par, 0x15, 0x00, 0x7f); /* Set Column Address */
+	write_reg(par, 0x75, 0x00, 0x7f); /* Set Row Address */
+	write_reg(par, 0xa1, 0x00); /* Set Display Start Line */
+	write_reg(par, 0xa2, 0x00); /* Set Display Offset */
+	write_reg(par, 0xb5, 0x00); /* Set GPIO */
+	write_reg(par, 0xab, 0x01); /* Set Function Selection */
+	write_reg(par, 0xb1, 0x32); /* Set Phase Length */
+	write_reg(par, 0xb4, 0xa0, 0xb5, 0x55); /* Set Segment Low Voltage */
+	write_reg(par, 0xbb, 0x17); /* Set Precharge Voltage */
+	write_reg(par, 0xbe, 0x05); /* Set VComH Voltage */
+	write_reg(par, 0xc1, 0xc8, 0x80, 0xc8); /* Set Contrast */
+	write_reg(par, 0xc7, 0x0f); /* Set Master Contrast */
+	write_reg(par, 0xb6, 0x01); /* Set Second Precharge Period */
+	write_reg(par, 0xa6); /* Set Display Mode Reset */
+	write_reg(par, 0xaf); /* Set Sleep Mode Display On */
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	write_reg(par, 0x15, xs, xe);
+	write_reg(par, 0x75, ys, ye);
+	write_reg(par, 0x5c);
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	unsigned remap;
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	if (par->fbtftops.init_display != init_display) {
+		/* don't risk messing up register A0h */
+		fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
+			"%s: skipping since custom init_display() is used\n",
+			__func__);
+		return 0;
+	}
+
+	remap = 0x60 | (par->bgr << 2); /* Set Colour Depth */
+
+	switch (par->info->var.rotate) {
+	case 0:
+		write_reg(par, 0xA0, remap | 0b00 | 1<<4);
+		break;
+	case 270:
+		write_reg(par, 0xA0, remap | 0b11 | 1<<4);
+		break;
+	case 180:
+		write_reg(par, 0xA0, remap | 0b10);
+		break;
+	case 90:
+		write_reg(par, 0xA0, remap | 0b01);
+		break;
+	}
+
+	return 0;
+}
+
+/*
+	Grayscale Lookup Table
+	GS1 - GS63
+	The driver Gamma curve contains the relative values between the entries
+	in the Lookup table.
+
+	From datasheet:
+	8.8 Gray Scale Decoder
+
+		there are total 180 Gamma Settings (Setting 0 to Setting 180)
+		available for the Gray Scale table.
+
+		The gray scale is defined in incremental way, with reference
+		to the length of previous table entry:
+			Setting of GS1 has to be >= 0
+			Setting of GS2 has to be > Setting of GS1 +1
+			Setting of GS3 has to be > Setting of GS2 +1
+			:
+			Setting of GS63 has to be > Setting of GS62 +1
+
+
+*/
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	unsigned long tmp[GAMMA_NUM * GAMMA_LEN];
+	int i, acc = 0;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	for (i = 0; i < 63; i++) {
+		if (i > 0 && curves[i] < 2) {
+			dev_err(par->info->device,
+				"Illegal value in Grayscale Lookup Table at index %d. " \
+				"Must be greater than 1\n", i);
+			return -EINVAL;
+		}
+		acc += curves[i];
+		tmp[i] = acc;
+		if (acc > 180) {
+			dev_err(par->info->device,
+				"Illegal value(s) in Grayscale Lookup Table. " \
+				"At index=%d, the accumulated value has exceeded 180\n", i);
+			return -EINVAL;
+		}
+	}
+
+	write_reg(par, 0xB8,
+	tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7],
+	tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14], tmp[15],
+	tmp[16], tmp[17], tmp[18], tmp[19], tmp[20], tmp[21], tmp[22], tmp[23],
+	tmp[24], tmp[25], tmp[26], tmp[27], tmp[28], tmp[29], tmp[30], tmp[31],
+	tmp[32], tmp[33], tmp[34], tmp[35], tmp[36], tmp[37], tmp[38], tmp[39],
+	tmp[40], tmp[41], tmp[42], tmp[43], tmp[44], tmp[45], tmp[46], tmp[47],
+	tmp[48], tmp[49], tmp[50], tmp[51], tmp[52], tmp[53], tmp[54], tmp[55],
+	tmp[56], tmp[57], tmp[58], tmp[59], tmp[60], tmp[61], tmp[62]);
+
+	return 0;
+}
+
+static int blank(struct fbtft_par *par, bool on)
+{
+	fbtft_par_dbg(DEBUG_BLANK, par, "%s(blank=%s)\n",
+		__func__, on ? "true" : "false");
+	if (on)
+		write_reg(par, 0xAE);
+	else
+		write_reg(par, 0xAF);
+	return 0;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.gamma_num = GAMMA_NUM,
+	.gamma_len = GAMMA_LEN,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.set_gamma = set_gamma,
+		.blank = blank,
+	},
+};
+
+#ifdef CONFIG_FB_BACKLIGHT
+static int update_onboard_backlight(struct backlight_device *bd)
+{
+	struct fbtft_par *par = bl_get_data(bd);
+	bool on;
+
+	fbtft_par_dbg(DEBUG_BACKLIGHT, par,
+		"%s: power=%d, fb_blank=%d\n",
+		__func__, bd->props.power, bd->props.fb_blank);
+
+	on = (bd->props.power == FB_BLANK_UNBLANK)
+		&& (bd->props.fb_blank == FB_BLANK_UNBLANK);
+	/* Onboard backlight connected to GPIO0 on SSD1351, GPIO1 unused */
+	write_reg(par, 0xB5, on ? 0x03 : 0x02);
+
+	return 0;
+}
+
+static void register_onboard_backlight(struct fbtft_par *par)
+{
+	struct backlight_device *bd;
+	struct backlight_properties bl_props = { 0, };
+	struct backlight_ops *bl_ops;
+
+	fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
+
+	bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops),
+				GFP_KERNEL);
+	if (!bl_ops) {
+		dev_err(par->info->device,
+			"%s: could not allocate memory for backlight operations.\n",
+			__func__);
+		return;
+	}
+
+	bl_ops->update_status = update_onboard_backlight;
+	bl_props.type = BACKLIGHT_RAW;
+	bl_props.power = FB_BLANK_POWERDOWN;
+
+	bd = backlight_device_register(dev_driver_string(par->info->device),
+				par->info->device, par, bl_ops, &bl_props);
+	if (IS_ERR(bd)) {
+		dev_err(par->info->device,
+			"cannot register backlight device (%ld)\n",
+			PTR_ERR(bd));
+		return;
+	}
+	par->info->bl_dev = bd;
+
+	if (!par->fbtftops.unregister_backlight)
+		par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
+}
+#else
+static void register_onboard_backlight(struct fbtft_par *par) { };
+#endif
+
+
+FBTFT_REGISTER_DRIVER(DRVNAME, "solomon,ssd1351", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:ssd1351");
+MODULE_ALIAS("platform:ssd1351");
+
+MODULE_DESCRIPTION("SSD1351 OLED Driver");
+MODULE_AUTHOR("James Davies");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_st7735r.c b/drivers/staging/fbtft/fb_st7735r.c
new file mode 100644
index 000000000000..b63aa38e51cf
--- /dev/null
+++ b/drivers/staging/fbtft/fb_st7735r.c
@@ -0,0 +1,195 @@
+/*
+ * FB driver for the ST7735R LCD Controller
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include "fbtft.h"
+
+#define DRVNAME "fb_st7735r"
+#define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
+                      "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
+
+
+static int default_init_sequence[] = {
+	/* SWRESET - Software reset */
+	-1, 0x01,                                
+	-2, 150,                               /* delay */
+
+	/* SLPOUT - Sleep out & booster on */
+	-1, 0x11,                          
+	-2, 500,                               /* delay */
+
+	/* FRMCTR1 - frame rate control: normal mode
+	     frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */
+	-1, 0xB1, 0x01, 0x2C, 0x2D, 
+
+	/* FRMCTR2 - frame rate control: idle mode
+	     frame rate = fosc / (1 x 2 + 40) * (LINE + 2C + 2D) */
+	-1, 0xB2, 0x01, 0x2C, 0x2D, 
+
+	/* FRMCTR3 - frame rate control - partial mode
+	     dot inversion mode, line inversion mode */
+	-1, 0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D,
+
+	/* INVCTR - display inversion control
+	     no inversion */
+	-1, 0xB4, 0x07,
+
+	/* PWCTR1 - Power Control
+	     -4.6V, AUTO mode */
+	-1, 0xC0, 0xA2, 0x02, 0x84,
+
+	/* PWCTR2 - Power Control
+	     VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */
+	-1, 0xC1, 0xC5,
+
+	/* PWCTR3 - Power Control
+	     Opamp current small, Boost frequency */
+	-1, 0xC2, 0x0A, 0x00,
+
+	/* PWCTR4 - Power Control
+	     BCLK/2, Opamp current small & Medium low */
+	-1, 0xC3,0x8A,0x2A,
+
+	/* PWCTR5 - Power Control */
+	-1, 0xC4, 0x8A, 0xEE,
+
+	/* VMCTR1 - Power Control */
+	-1, 0xC5, 0x0E,
+
+	/* INVOFF - Display inversion off */
+	-1, 0x20,
+
+	/* COLMOD - Interface pixel format */
+	-1, 0x3A, 0x05,
+
+	/* DISPON - Display On */
+	-1, 0x29,
+	-2, 100,                               /* delay */
+
+	/* NORON - Partial off (Normal) */
+	-1, 0x13,
+	-2, 10,                               /* delay */
+
+	/* end marker */
+	-3                                  
+};
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* Column address */
+	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
+
+	/* Row adress */
+	write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
+
+	/* Memory write */
+	write_reg(par, 0x2C);
+}
+
+#define MY (1 << 7)
+#define MX (1 << 6)
+#define MV (1 << 5)
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* MADCTL - Memory data access control
+	     RGB/BGR:
+	     1. Mode selection pin SRGB
+	        RGB H/W pin for color filter setting: 0=RGB, 1=BGR
+	     2. MADCTL RGB bit
+	        RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR */
+	switch (par->info->var.rotate) {
+	case 0:
+		write_reg(par, 0x36, MX | MY | (par->bgr << 3));
+		break;
+	case 270:
+		write_reg(par, 0x36, MY | MV | (par->bgr << 3));
+		break;
+	case 180:
+		write_reg(par, 0x36, (par->bgr << 3));
+		break;
+	case 90:
+		write_reg(par, 0x36, MX | MV | (par->bgr << 3));
+		break;
+	}
+
+	return 0;
+}
+
+/*
+  Gamma string format:
+    VRF0P VOS0P PK0P PK1P PK2P PK3P PK4P PK5P PK6P PK7P PK8P PK9P SELV0P SELV1P SELV62P SELV63P
+    VRF0N VOS0N PK0N PK1N PK2N PK3N PK4N PK5N PK6N PK7N PK8N PK9N SELV0N SELV1N SELV62N SELV63N
+*/
+#define CURVE(num, idx)  curves[num*par->gamma.num_values + idx]
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	int i,j;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	for (i = 0; i < par->gamma.num_curves; i++)
+		for (j = 0; j < par->gamma.num_values; j++)
+			CURVE(i,j) &= 0b111111;
+
+	for (i = 0; i < par->gamma.num_curves; i++)
+		write_reg(par, 0xE0 + i,
+			CURVE(i, 0), CURVE(i, 1), CURVE(i, 2), CURVE(i, 3),
+			CURVE(i, 4), CURVE(i, 5), CURVE(i, 6), CURVE(i, 7),
+			CURVE(i, 8), CURVE(i, 9), CURVE(i, 10), CURVE(i, 11),
+			CURVE(i, 12), CURVE(i, 13), CURVE(i, 14), CURVE(i,15));
+
+	return 0;
+}
+#undef CURVE
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = 128,
+	.height = 160,
+	.init_sequence = default_init_sequence,
+	.gamma_num = 2,
+	.gamma_len = 16,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.set_gamma = set_gamma,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:st7735r");
+MODULE_ALIAS("platform:st7735r");
+
+MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_tinylcd.c b/drivers/staging/fbtft/fb_tinylcd.c
new file mode 100644
index 000000000000..ca98bfb5c7df
--- /dev/null
+++ b/drivers/staging/fbtft/fb_tinylcd.c
@@ -0,0 +1,124 @@
+/*
+ * Custom FB driver for tinylcd.com display
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_tinylcd"
+#define WIDTH		320
+#define HEIGHT		480
+
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	write_reg(par, 0xB0, 0x80);
+	write_reg(par, 0xC0, 0x0A, 0x0A);
+	write_reg(par, 0xC1, 0x45, 0x07);
+	write_reg(par, 0xC2, 0x33);
+	write_reg(par, 0xC5, 0x00, 0x42, 0x80);
+	write_reg(par, 0xB1, 0xD0, 0x11);
+	write_reg(par, 0xB4, 0x02);
+	write_reg(par, 0xB6, 0x00, 0x22, 0x3B);
+	write_reg(par, 0xB7, 0x07);
+	write_reg(par, 0x36, 0x58);
+	write_reg(par, 0xF0, 0x36, 0xA5, 0xD3);
+	write_reg(par, 0xE5, 0x80);
+	write_reg(par, 0xE5, 0x01);
+	write_reg(par, 0xB3, 0x00);
+	write_reg(par, 0xE5, 0x00);
+	write_reg(par, 0xF0, 0x36, 0xA5, 0x53);
+	write_reg(par, 0xE0, 0x00, 0x35, 0x33, 0x00, 0x00, 0x00,
+	                     0x00, 0x35, 0x33, 0x00, 0x00, 0x00);
+	write_reg(par, 0x3A, 0x55);
+	write_reg(par, 0x11);
+	udelay(250);
+	write_reg(par, 0x29);
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* Column address */
+	write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
+
+	/* Row adress */
+	write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
+
+	/* Memory write */
+	write_reg(par, 0x2C);
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	case 270:
+		write_reg(par, 0xB6, 0x00, 0x02, 0x3B);
+		write_reg(par, 0x36, 0x28);
+		break;
+	case 180:
+		write_reg(par, 0xB6, 0x00, 0x22, 0x3B);
+		write_reg(par, 0x36, 0x58);
+		break;
+	case 90:
+		write_reg(par, 0xB6, 0x00, 0x22, 0x3B);
+		write_reg(par, 0x36, 0x38);
+		break;
+	default:
+		write_reg(par, 0xB6, 0x00, 0x22, 0x3B);
+		write_reg(par, 0x36, 0x08);
+		break;
+	}
+
+	return 0;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "neosec,tinylcd", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("spi:tinylcd");
+
+MODULE_DESCRIPTION("Custom FB driver for tinylcd.com display");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c
new file mode 100644
index 000000000000..8738c7a7bfda
--- /dev/null
+++ b/drivers/staging/fbtft/fb_tls8204.c
@@ -0,0 +1,176 @@
+/*
+ * FB driver for the TLS8204 LCD Controller
+ *
+ * The display is monochrome and the video memory is RGB565.
+ * Any pixel value except 0 turns the pixel on.
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ * Copyright (C) 2014 Michael Hope (adapted for the TLS8204)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_tls8204"
+#define WIDTH		84
+#define HEIGHT		48
+#define TXBUFLEN	WIDTH
+#define DEFAULT_GAMMA	"40" /* gamma is used to control contrast in this driver */
+
+static unsigned bs = 4;
+module_param(bs, uint, 0);
+MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	/* Enter extended command mode */
+	write_reg(par, 0x21); /* 5:1  1
+				 2:0  PD - Powerdown control: chip is active
+				 1:0  V  - Entry mode: horizontal addressing
+				 0:1  H  - Extended instruction set control: extended
+			      */
+
+	/* H=1 Bias system */
+	write_reg(par, 0x10 | (bs & 0x7)); /*
+				 4:1  1
+				 3:0  0
+				 2:x  BS2 - Bias System
+				 1:x  BS1
+				 0:x  BS0
+			      */
+
+	/* Set the address of the first display line. */
+	write_reg(par, 0x04 | (64 >> 6));
+	write_reg(par, 0x40 | (64 & 0x3F));
+
+	/* Enter H=0 standard command mode */
+	write_reg(par, 0x20);
+
+	/* H=0 Display control */
+	write_reg(par, 0x08 | 4); /*
+				 3:1  1
+				 2:1  D  - DE: 10=normal mode
+				 1:0  0
+				 0:0  E
+			      */
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* H=0 Set X address of RAM */
+	write_reg(par, 0x80); /* 7:1  1
+				 6-0: X[6:0] - 0x00
+			      */
+
+	/* H=0 Set Y address of RAM */
+	write_reg(par, 0x40); /* 7:0  0
+				 6:1  1
+				 2-0: Y[2:0] - 0x0
+			      */
+}
+
+static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+{
+	u16 *vmem16 = (u16 *)par->info->screen_base;
+	int x, y, i;
+	int ret = 0;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
+
+	for (y = 0; y < HEIGHT/8; y++) {
+		u8 *buf = par->txbuf.buf;
+		/* The display is 102x68 but the LCD is 84x48.  Set
+		   the write pointer at the start of each row. */
+		gpio_set_value(par->gpio.dc, 0);
+		write_reg(par, 0x80 | 0);
+		write_reg(par, 0x40 | y);
+
+		for (x = 0; x < WIDTH; x++) {
+			u8 ch = 0;
+			for (i = 0; i < 8*WIDTH; i += WIDTH) {
+				ch >>= 1;
+				if (vmem16[(y*8*WIDTH)+i+x])
+					ch |= 0x80;
+			}
+			*buf++ = ch;
+		}
+		/* Write the row */
+		gpio_set_value(par->gpio.dc, 1);
+		ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH);
+		if (ret < 0) {
+			dev_err(par->info->device,
+				"%s: write failed and returned: %d\n", __func__, ret);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int set_gamma(struct fbtft_par *par, unsigned long *curves)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* apply mask */
+	curves[0] &= 0x7F;
+
+	write_reg(par, 0x21); /* turn on extended instruction set */
+	write_reg(par, 0x80 | curves[0]);
+	write_reg(par, 0x20); /* turn off extended instruction set */
+
+	return 0;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.txbuflen = TXBUFLEN,
+	.gamma_num = 1,
+	.gamma_len = 1,
+	.gamma = DEFAULT_GAMMA,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.write_vmem = write_vmem,
+		.set_gamma = set_gamma,
+	},
+	.backlight = 1,
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "teralane,tls8204", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("spi:tls8204");
+
+MODULE_DESCRIPTION("FB driver for the TLS8204 LCD Controller");
+MODULE_AUTHOR("Michael Hope");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_uc1701.c b/drivers/staging/fbtft/fb_uc1701.c
new file mode 100644
index 000000000000..d70ac524278c
--- /dev/null
+++ b/drivers/staging/fbtft/fb_uc1701.c
@@ -0,0 +1,210 @@
+/*
+ * FB driver for the UC1701 LCD Controller
+ *
+ * The display is monochrome and the video memory is RGB565.
+ * Any pixel value except 0 turns the pixel on.
+ *
+ * Copyright (C) 2014 Juergen Holzmann
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME	"fb_uc1701"
+#define WIDTH	  102
+#define HEIGHT	 64
+#define PAGES	  (HEIGHT/8)
+
+/* 1: Display on/off */
+#define LCD_DISPLAY_ENABLE    0xAE
+/* 2: display start line set */
+#define LCD_START_LINE	0x40
+/* 3: Page address set (lower 4 bits select one of the pages) */
+#define LCD_PAGE_ADDRESS      0xB0
+/* 4: column address */
+#define LCD_COL_ADDRESS       0x10
+/* 8: select orientation */
+#define LCD_BOTTOMVIEW	0xA0
+/* 9: inverted display */
+#define LCD_DISPLAY_INVERT    0xA6
+/* 10: show memory content or switch all pixels on */
+#define LCD_ALL_PIXEL	 0xA4
+/* 11: lcd bias set */
+#define LCD_BIAS	      0xA2
+/* 14: Reset Controller */
+#define LCD_RESET_CMD	 0xE2
+/* 15: output mode select (turns display upside-down) */
+#define LCD_SCAN_DIR	  0xC0
+/* 16: power control set */
+#define LCD_POWER_CONTROL     0x28
+/* 17: voltage regulator resistor ratio set */
+#define LCD_VOLTAGE	   0x20
+/* 18: Volume mode set */
+#define LCD_VOLUME_MODE       0x81
+/* 22: NOP command */
+#define LCD_NO_OP	     0xE3
+/* 25: advanced program control */
+#define LCD_ADV_PROG_CTRL     0xFA
+/* 25: advanced program control2 */
+#define LCD_ADV_PROG_CTRL2    0x10
+#define LCD_TEMPCOMP_HIGH     0x80
+/* column offset for normal orientation */
+#define SHIFT_ADDR_NORMAL     0
+/* column offset for bottom view orientation */
+#define SHIFT_ADDR_TOPVIEW    30
+
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	/* softreset of LCD */
+	write_reg(par, LCD_RESET_CMD);
+	mdelay(10);
+
+	/* set startpoint */
+	/* LCD_START_LINE | (pos & 0x3F) */
+	write_reg(par, LCD_START_LINE);
+
+	/* select orientation BOTTOMVIEW */
+	write_reg(par, LCD_BOTTOMVIEW | 1);
+	/* output mode select (turns display upside-down) */
+	write_reg(par, LCD_SCAN_DIR | 0x00);
+
+	/* Normal Pixel mode */
+	write_reg(par, LCD_ALL_PIXEL | 0);
+
+	/* positive display */
+	write_reg(par, LCD_DISPLAY_INVERT | 0);
+
+	/* bias 1/9 */
+	write_reg(par, LCD_BIAS | 0);
+
+	/* power control mode: all features on */
+	/* LCD_POWER_CONTROL | (val&0x07) */
+	write_reg(par, LCD_POWER_CONTROL | 0x07);
+
+	/* set voltage regulator R/R */
+	/* LCD_VOLTAGE | (val&0x07) */
+	write_reg(par, LCD_VOLTAGE | 0x07);
+
+	/* volume mode set */
+	/* LCD_VOLUME_MODE,val&0x3f,LCD_NO_OP */
+	write_reg(par, LCD_VOLUME_MODE);
+	/* LCD_VOLUME_MODE,val&0x3f,LCD_NO_OP */
+	write_reg(par, 0x09);
+	/* ???? */
+	/* LCD_VOLUME_MODE,val&0x3f,LCD_NO_OP */
+	write_reg(par, LCD_NO_OP);
+
+	/* advanced program control */
+	write_reg(par, LCD_ADV_PROG_CTRL);
+	write_reg(par, LCD_ADV_PROG_CTRL2|LCD_TEMPCOMP_HIGH);
+
+	/* enable display */
+	write_reg(par, LCD_DISPLAY_ENABLE | 1);
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* goto address */
+	/* LCD_PAGE_ADDRESS | ((page) & 0x1F),
+	 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
+	 LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
+	write_reg(par, LCD_PAGE_ADDRESS);
+	/* LCD_PAGE_ADDRESS | ((page) & 0x1F),
+	 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
+	  LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
+	write_reg(par, 0x00);
+	/* LCD_PAGE_ADDRESS | ((page) & 0x1F),
+	 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
+	  LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
+	write_reg(par, LCD_COL_ADDRESS);
+}
+
+static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+{
+	u16 *vmem16 = (u16 *)par->info->screen_base;
+	u8 *buf = par->txbuf.buf;
+	int x, y, i;
+	int ret = 0;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
+
+	for (y = 0; y < PAGES; y++) {
+		buf = par->txbuf.buf;
+		for (x = 0; x < WIDTH; x++) {
+			*buf = 0x00;
+			for (i = 0; i < 8; i++)
+				*buf |= (vmem16[((y*8*WIDTH)+(i*WIDTH))+x] ? 1 : 0) << i;
+			buf++;
+		}
+		/* LCD_PAGE_ADDRESS | ((page) & 0x1F),
+		 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
+		  LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
+		write_reg(par, LCD_PAGE_ADDRESS|(u8)y);
+		/* LCD_PAGE_ADDRESS | ((page) & 0x1F),
+		 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
+		  LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
+		write_reg(par, 0x00);
+		/* LCD_PAGE_ADDRESS | ((page) & 0x1F),
+		 (((col)+SHIFT_ADDR_NORMAL) & 0x0F),
+		  LCD_COL_ADDRESS | ((((col)+SHIFT_ADDR_NORMAL)>>4) & 0x0F) */
+		write_reg(par, LCD_COL_ADDRESS);
+		gpio_set_value(par->gpio.dc, 1);
+		ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH);
+		gpio_set_value(par->gpio.dc, 0);
+	}
+
+	if (ret < 0)
+		dev_err(par->info->device, "%s: write failed and returned: %d\n", __func__, ret);
+
+	return ret;
+}
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.write_vmem = write_vmem,
+	},
+	.backlight = 1,
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "UltraChip,uc1701", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("spi:uc1701");
+
+MODULE_DESCRIPTION("FB driver for the UC1701 LCD Controller");
+MODULE_AUTHOR("Juergen Holzmann");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_upd161704.c b/drivers/staging/fbtft/fb_upd161704.c
new file mode 100644
index 000000000000..fff57b330ba2
--- /dev/null
+++ b/drivers/staging/fbtft/fb_upd161704.c
@@ -0,0 +1,206 @@
+/*
+ * FB driver for the uPD161704 LCD Controller
+ *
+ * Copyright (C) 2014 Seong-Woo Kim
+ *
+ * Based on fb_ili9325.c by Noralf Tronnes
+ * Based on ili9325.c by Jeroen Domburg
+ * Init code from UTFT library by Henning Karlsen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME		"fb_upd161704"
+#define WIDTH		240
+#define HEIGHT		320
+#define BPP		16
+
+static int init_display(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	par->fbtftops.reset(par);
+
+	if (par->gpio.cs != -1)
+		gpio_set_value(par->gpio.cs, 0);  /* Activate chip */
+
+	/* Initialization sequence from Lib_UTFT */
+
+	/* register reset */
+	write_reg(par, 0x0003,0x0001);	/* Soft reset */
+
+	/* oscillator start */
+	write_reg(par, 0x003A,0x0001);	/*Oscillator 0: stop, 1: operation */
+	udelay(100);
+
+	/* y-setting */
+	write_reg(par, 0x0024,0x007B);	/* amplitude setting */
+	udelay(10);
+	write_reg(par, 0x0025,0x003B);	/* amplitude setting */
+	write_reg(par, 0x0026,0x0034);	/* amplitude setting */
+	udelay(10);
+	write_reg(par, 0x0027,0x0004);	/* amplitude setting */
+	write_reg(par, 0x0052,0x0025);	/* circuit setting 1 */
+	udelay(10);
+	write_reg(par, 0x0053,0x0033);	/* circuit setting 2 */
+	write_reg(par, 0x0061,0x001C);	/* adjustment V10 positive polarity */
+	udelay(10);
+	write_reg(par, 0x0062,0x002C);	/* adjustment V9 negative polarity */
+	write_reg(par, 0x0063,0x0022);	/* adjustment V34 positive polarity */
+	udelay(10);
+	write_reg(par, 0x0064,0x0027);	/* adjustment V31 negative polarity */
+	udelay(10);
+	write_reg(par, 0x0065,0x0014);	/* adjustment V61 negative polarity */
+	udelay(10);
+	write_reg(par, 0x0066,0x0010);	/* adjustment V61 negative polarity */
+	
+	/* Basical clock for 1 line (BASECOUNT[7:0]) number specified */
+	write_reg(par, 0x002E,0x002D);
+	
+	/* Power supply setting */
+	write_reg(par, 0x0019,0x0000);	/* DC/DC output setting */
+	udelay(200);
+	write_reg(par, 0x001A,0x1000);	/* DC/DC frequency setting */
+	write_reg(par, 0x001B,0x0023);	/* DC/DC rising setting */
+	write_reg(par, 0x001C,0x0C01);	/* Regulator voltage setting */
+	write_reg(par, 0x001D,0x0000);	/* Regulator current setting */
+	write_reg(par, 0x001E,0x0009);	/* VCOM output setting */
+	write_reg(par, 0x001F,0x0035);	/* VCOM amplitude setting */
+	write_reg(par, 0x0020,0x0015);	/* VCOMM cencter setting */
+	write_reg(par, 0x0018,0x1E7B);	/* DC/DC operation setting */
+
+	/* windows setting */
+	write_reg(par, 0x0008,0x0000);	/* Minimum X address */
+	write_reg(par, 0x0009,0x00EF);	/* Maximum X address */
+	write_reg(par, 0x000a,0x0000);	/* Minimum Y address */
+	write_reg(par, 0x000b,0x013F);	/* Maximum Y address */
+
+	/* LCD display area setting */
+	write_reg(par, 0x0029,0x0000);	/* [LCDSIZE]  X MIN. size set */
+	write_reg(par, 0x002A,0x0000);	/* [LCDSIZE]  Y MIN. size set */
+	write_reg(par, 0x002B,0x00EF);	/* [LCDSIZE]  X MAX. size set */
+	write_reg(par, 0x002C,0x013F);	/* [LCDSIZE]  Y MAX. size set */
+
+	/* Gate scan setting */
+	write_reg(par, 0x0032,0x0002);
+	
+	/* n line inversion line number */
+	write_reg(par, 0x0033,0x0000);
+
+	/* Line inversion/frame inversion/interlace setting */
+	write_reg(par, 0x0037,0x0000);
+	
+	/* Gate scan operation setting register */
+	write_reg(par, 0x003B,0x0001);
+	
+	/* Color mode */
+	/*GS = 0: 260-k color (64 gray scale), GS = 1: 8 color (2 gray scale) */
+	write_reg(par, 0x0004,0x0000);
+
+	/* RAM control register */
+	write_reg(par, 0x0005,0x0000);	/*Window access 00:Normal, 10:Window */
+
+	/* Display setting register 2 */
+	write_reg(par, 0x0001,0x0000);
+
+	/* display setting */
+	write_reg(par, 0x0000,0x0000);	/* display on */
+
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+	switch (par->info->var.rotate) {
+	/* R20h = Horizontal GRAM Start Address */
+	/* R21h = Vertical GRAM Start Address */
+	case 0:
+		write_reg(par, 0x0006, xs);
+		write_reg(par, 0x0007, ys);
+		break;
+	case 180:
+		write_reg(par, 0x0006, WIDTH - 1 - xs);
+		write_reg(par, 0x0007, HEIGHT - 1 - ys);
+		break;
+	case 270:
+		write_reg(par, 0x0006, WIDTH - 1 - ys);
+		write_reg(par, 0x0007, xs);
+		break;
+	case 90:
+		write_reg(par, 0x0006, ys);
+		write_reg(par, 0x0007, HEIGHT - 1 - xs);
+		break;
+	}
+
+	write_reg(par, 0x0e); /* Write Data to GRAM */
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	switch (par->info->var.rotate) {
+	/* AM: GRAM update direction */
+	case 0:
+		write_reg(par, 0x01, 0x0000);
+		write_reg(par, 0x05, 0x0000);
+		break;
+	case 180:
+		write_reg(par, 0x01, 0x00C0);
+		write_reg(par, 0x05, 0x0000);
+		break;
+	case 270:
+		write_reg(par, 0x01, 0x0080);
+		write_reg(par, 0x05, 0x0001);
+		break;
+	case 90:
+		write_reg(par, 0x01, 0x0040);
+		write_reg(par, 0x05, 0x0001);
+		break;
+	}
+
+	return 0;
+}
+
+static struct fbtft_display display = {
+	.regwidth = 16,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.fbtftops = {
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "nec,upd161704", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+MODULE_ALIAS("platform:" DRVNAME);
+MODULE_ALIAS("spi:upd161704");
+MODULE_ALIAS("platform:upd161704");
+
+MODULE_DESCRIPTION("FB driver for the uPD161704 LCD Controller");
+MODULE_AUTHOR("Seong-Woo Kim");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c
new file mode 100644
index 000000000000..975b579359f3
--- /dev/null
+++ b/drivers/staging/fbtft/fb_watterott.c
@@ -0,0 +1,324 @@
+/*
+ * FB driver for the Watterott LCD Controller
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME			"fb_watterott"
+#define WIDTH			320
+#define HEIGHT			240
+#define FPS			5
+#define TXBUFLEN		1024
+#define DEFAULT_BRIGHTNESS	50
+
+#define CMD_VERSION		0x01
+#define CMD_LCD_LED		0x10
+#define CMD_LCD_RESET		0x11
+#define CMD_LCD_ORIENTATION	0x20
+#define CMD_LCD_DRAWIMAGE	0x27
+#define COLOR_RGB323		8
+#define COLOR_RGB332		9
+#define COLOR_RGB233		10
+#define COLOR_RGB565		16
+
+
+static short mode = 565;
+module_param(mode, short, 0);
+MODULE_PARM_DESC(mode, "RGB color transfer mode: 332, 565 (default)");
+
+static void write_reg8_bus8(struct fbtft_par *par, int len, ...)
+{
+	va_list args;
+	int i, ret;
+	u8 *buf = par->buf;
+
+	va_start(args, len);
+	for (i = 0; i < len; i++)
+		*buf++ = (u8)va_arg(args, unsigned int);
+	va_end(args);
+
+	fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par,
+		par->info->device, u8, par->buf, len, "%s: ", __func__);
+
+	ret = par->fbtftops.write(par, par->buf, len);
+	if (ret < 0) {
+		dev_err(par->info->device,
+			"%s: write() failed and returned %d\n", __func__, ret);
+		return;
+	}
+}
+
+static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+{
+	unsigned start_line, end_line;
+	u16 *vmem16 = (u16 *)(par->info->screen_base + offset);
+	u16 *pos = par->txbuf.buf + 1;
+	u16 *buf16 = par->txbuf.buf + 10;
+	int i, j;
+	int ret = 0;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
+
+	start_line = offset / par->info->fix.line_length;
+	end_line = start_line + (len / par->info->fix.line_length) - 1;
+
+	/* Set command header. pos: x, y, w, h */
+	((u8 *)par->txbuf.buf)[0] = CMD_LCD_DRAWIMAGE;
+	pos[0] = 0;
+	pos[2] = cpu_to_be16(par->info->var.xres);
+	pos[3] = cpu_to_be16(1);
+	((u8 *)par->txbuf.buf)[9] = COLOR_RGB565;
+
+	for (i = start_line; i <= end_line; i++) {
+		pos[1] = cpu_to_be16(i);
+		for (j = 0; j < par->info->var.xres; j++)
+			buf16[j] = cpu_to_be16(*vmem16++);
+		ret = par->fbtftops.write(par,
+			par->txbuf.buf, 10 + par->info->fix.line_length);
+		if (ret < 0)
+			return ret;
+		udelay(300);
+	}
+
+	return 0;
+}
+
+#define RGB565toRGB323(c) (((c&0xE000)>>8) | ((c&0600)>>6) | ((c&0x001C)>>2))
+#define RGB565toRGB332(c) (((c&0xE000)>>8) | ((c&0700)>>6) | ((c&0x0018)>>3))
+#define RGB565toRGB233(c) (((c&0xC000)>>8) | ((c&0700)>>5) | ((c&0x001C)>>2))
+
+static int write_vmem_8bit(struct fbtft_par *par, size_t offset, size_t len)
+{
+	unsigned start_line, end_line;
+	u16 *vmem16 = (u16 *)(par->info->screen_base + offset);
+	u16 *pos = par->txbuf.buf + 1;
+	u8 *buf8 = par->txbuf.buf + 10;
+	int i, j;
+	int ret = 0;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s()\n", __func__);
+
+	start_line = offset / par->info->fix.line_length;
+	end_line = start_line + (len / par->info->fix.line_length) - 1;
+
+	/* Set command header. pos: x, y, w, h */
+	((u8 *)par->txbuf.buf)[0] = CMD_LCD_DRAWIMAGE;
+	pos[0] = 0;
+	pos[2] = cpu_to_be16(par->info->var.xres);
+	pos[3] = cpu_to_be16(1);
+	((u8 *)par->txbuf.buf)[9] = COLOR_RGB332;
+
+	for (i = start_line; i <= end_line; i++) {
+		pos[1] = cpu_to_be16(i);
+		for (j = 0; j < par->info->var.xres; j++) {
+			buf8[j] = RGB565toRGB332(*vmem16);
+			vmem16++;
+		}
+		ret = par->fbtftops.write(par,
+			par->txbuf.buf, 10 + par->info->var.xres);
+		if (ret < 0)
+			return ret;
+		udelay(700);
+	}
+
+	return 0;
+}
+
+static unsigned firmware_version(struct fbtft_par *par)
+{
+	u8 rxbuf[4] = {0, };
+
+	write_reg(par, CMD_VERSION);
+	par->fbtftops.read(par, rxbuf, 4);
+	if (rxbuf[1] != '.')
+		return 0;
+
+	return (rxbuf[0] - '0') << 8 | (rxbuf[2] - '0') << 4 | (rxbuf[3] - '0');
+}
+
+static int init_display(struct fbtft_par *par)
+{
+	int ret;
+	unsigned version;
+	u8 save_mode;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* enable SPI interface by having CS and MOSI low during reset */
+	save_mode = par->spi->mode;
+	par->spi->mode |= SPI_CS_HIGH;
+	ret = par->spi->master->setup(par->spi); /* set CS inactive low */
+	if (ret) {
+		dev_err(par->info->device, "Could not set SPI_CS_HIGH\n");
+		return ret;
+	}
+	write_reg(par, 0x00); /* make sure mode is set */
+
+	mdelay(50);
+	par->fbtftops.reset(par);
+	mdelay(1000);
+	par->spi->mode = save_mode;
+	ret = par->spi->master->setup(par->spi);
+	if (ret) {
+		dev_err(par->info->device, "Could not restore SPI mode\n");
+		return ret;
+	}
+	write_reg(par, 0x00);
+
+	version = firmware_version(par);
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "Firmware version: %x.%02x\n",
+						version >> 8, version & 0xFF);
+
+	if (mode == 332)
+		par->fbtftops.write_vmem = write_vmem_8bit;
+	return 0;
+}
+
+static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	/* not used on this controller */
+}
+
+static int set_var(struct fbtft_par *par)
+{
+	u8 rotate;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* this controller rotates clock wise */
+	switch (par->info->var.rotate) {
+	case 90:
+		rotate = 27;
+		break;
+	case 180:
+		rotate = 18;
+		break;
+	case 270:
+		rotate = 9;
+		break;
+	default:
+		rotate = 0;
+	}
+	write_reg(par, CMD_LCD_ORIENTATION, rotate);
+
+	return 0;
+}
+
+static int verify_gpios(struct fbtft_par *par)
+{
+	if (par->gpio.reset < 0) {
+		dev_err(par->info->device, "Missing 'reset' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+#ifdef CONFIG_FB_BACKLIGHT
+static int backlight_chip_update_status(struct backlight_device *bd)
+{
+	struct fbtft_par *par = bl_get_data(bd);
+	int brightness = bd->props.brightness;
+
+	fbtft_par_dbg(DEBUG_BACKLIGHT, par,
+		"%s: brightness=%d, power=%d, fb_blank=%d\n",
+		__func__, bd->props.brightness, bd->props.power,
+		bd->props.fb_blank);
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		brightness = 0;
+
+	write_reg(par, CMD_LCD_LED, brightness);
+
+	return 0;
+}
+
+static void register_chip_backlight(struct fbtft_par *par)
+{
+	struct backlight_device *bd;
+	struct backlight_properties bl_props = { 0, };
+	struct backlight_ops *bl_ops;
+
+	fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
+
+	bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops),
+				GFP_KERNEL);
+	if (!bl_ops) {
+		dev_err(par->info->device,
+			"%s: could not allocate memory for backlight operations.\n",
+			__func__);
+		return;
+	}
+
+	bl_ops->update_status = backlight_chip_update_status;
+	bl_props.type = BACKLIGHT_RAW;
+	bl_props.power = FB_BLANK_POWERDOWN;
+	bl_props.max_brightness = 100;
+	bl_props.brightness = DEFAULT_BRIGHTNESS;
+
+	bd = backlight_device_register(dev_driver_string(par->info->device),
+				par->info->device, par, bl_ops, &bl_props);
+	if (IS_ERR(bd)) {
+		dev_err(par->info->device,
+			"cannot register backlight device (%ld)\n",
+			PTR_ERR(bd));
+		return;
+	}
+	par->info->bl_dev = bd;
+
+	if (!par->fbtftops.unregister_backlight)
+		par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
+}
+#else
+#define register_chip_backlight NULL
+#endif
+
+
+static struct fbtft_display display = {
+	.regwidth = 8,
+	.buswidth = 8,
+	.width = WIDTH,
+	.height = HEIGHT,
+	.fps = FPS,
+	.txbuflen = TXBUFLEN,
+	.fbtftops = {
+		.write_register = write_reg8_bus8,
+		.write_vmem = write_vmem,
+		.init_display = init_display,
+		.set_addr_win = set_addr_win,
+		.set_var = set_var,
+		.verify_gpios = verify_gpios,
+		.register_backlight = register_chip_backlight,
+	},
+};
+FBTFT_REGISTER_DRIVER(DRVNAME, "watterott,openlcd", &display);
+
+MODULE_ALIAS("spi:" DRVNAME);
+
+MODULE_DESCRIPTION("FB driver for the Watterott LCD Controller");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c
new file mode 100644
index 000000000000..b3cddb0b3d69
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft-bus.c
@@ -0,0 +1,256 @@
+#include <linux/export.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include "fbtft.h"
+
+
+
+
+/*****************************************************************************
+ *
+ *   void (*write_reg)(struct fbtft_par *par, int len, ...);
+ *
+ *****************************************************************************/
+
+#define define_fbtft_write_reg(func, type, modifier)                          \
+void func(struct fbtft_par *par, int len, ...)                                \
+{                                                                             \
+	va_list args;                                                         \
+	int i, ret;                                                           \
+	int offset = 0;                                                       \
+	type *buf = (type *)par->buf;                                         \
+									      \
+	if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {                    \
+		va_start(args, len);                                          \
+		for (i = 0; i < len; i++) {                                   \
+			buf[i] = (type)va_arg(args, unsigned int);            \
+		}                                                             \
+		va_end(args);                                                 \
+		fbtft_par_dbg_hex(DEBUG_WRITE_REGISTER, par, par->info->device, type, buf, len, "%s: ", __func__);   \
+	}                                                                     \
+									      \
+	va_start(args, len);                                                  \
+									      \
+	if (par->startbyte) {                                                 \
+		*(u8 *)par->buf = par->startbyte;                             \
+		buf = (type *)(par->buf + 1);                                 \
+		offset = 1;                                                   \
+	}                                                                     \
+									      \
+	*buf = modifier((type)va_arg(args, unsigned int));                    \
+	if (par->gpio.dc != -1)                                               \
+		gpio_set_value(par->gpio.dc, 0);                              \
+	ret = par->fbtftops.write(par, par->buf, sizeof(type)+offset);        \
+	if (ret < 0) {                                                        \
+		va_end(args);                                                 \
+		dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret); \
+		return;                                                       \
+	}                                                                     \
+	len--;                                                                \
+									      \
+	if (par->startbyte)                                                   \
+		*(u8 *)par->buf = par->startbyte | 0x2;                       \
+									      \
+	if (len) {                                                            \
+		i = len;                                                      \
+		while (i--) {                                                 \
+			*buf++ = modifier((type)va_arg(args, unsigned int));  \
+		}                                                             \
+		if (par->gpio.dc != -1)                                       \
+			gpio_set_value(par->gpio.dc, 1);                      \
+		ret = par->fbtftops.write(par, par->buf, len * (sizeof(type)+offset)); \
+		if (ret < 0) {                                                \
+			va_end(args);                                         \
+			dev_err(par->info->device, "%s: write() failed and returned %d\n", __func__, ret); \
+			return;                                               \
+		}                                                             \
+	}                                                                     \
+	va_end(args);                                                         \
+}                                                                             \
+EXPORT_SYMBOL(func);
+
+define_fbtft_write_reg(fbtft_write_reg8_bus8, u8, )
+define_fbtft_write_reg(fbtft_write_reg16_bus8, u16, cpu_to_be16)
+define_fbtft_write_reg(fbtft_write_reg16_bus16, u16, )
+
+void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...)
+{
+	va_list args;
+	int i, ret;
+	int pad = 0;
+	u16 *buf = (u16 *)par->buf;
+
+	if (unlikely(par->debug & DEBUG_WRITE_REGISTER)) {
+		va_start(args, len);
+		for (i = 0; i < len; i++)
+			*(((u8 *)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__);
+	}
+	if (len <= 0)
+		return;
+
+	if (par->spi && (par->spi->bits_per_word == 8)) {
+		/* we're emulating 9-bit, pad start of buffer with no-ops
+		   (assuming here that zero is a no-op) */
+		pad = (len % 4) ? 4 - (len % 4) : 0;
+		for (i = 0; i < pad; i++)
+			*buf++ = 0x000;
+	}
+
+	va_start(args, len);
+	*buf++ = (u8)va_arg(args, unsigned int);
+	i = len - 1;
+	while (i--) {
+		*buf = (u8)va_arg(args, unsigned int);
+		*buf++ |= 0x100; /* dc=1 */
+	}
+	va_end(args);
+	ret = par->fbtftops.write(par, par->buf, (len + pad) * sizeof(u16));
+	if (ret < 0) {
+		dev_err(par->info->device,
+			"%s: write() failed and returned %d\n", __func__, ret);
+		return;
+	}
+}
+EXPORT_SYMBOL(fbtft_write_reg8_bus9);
+
+
+
+
+/*****************************************************************************
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ *****************************************************************************/
+
+/* 16 bit pixel over 8-bit databus */
+int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
+{
+	u16 *vmem16;
+	u16 *txbuf16 = (u16 *)par->txbuf.buf;
+	size_t remain;
+	size_t to_copy;
+	size_t tx_array_size;
+	int i;
+	int ret = 0;
+	size_t startbyte_size = 0;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
+		__func__, offset, len);
+
+	remain = len / 2;
+	vmem16 = (u16 *)(par->info->screen_base + offset);
+
+	if (par->gpio.dc != -1)
+		gpio_set_value(par->gpio.dc, 1);
+
+	/* non buffered write */
+	if (!par->txbuf.buf)
+		return par->fbtftops.write(par, vmem16, len);
+
+	/* buffered write */
+	tx_array_size = par->txbuf.len / 2;
+
+	if (par->startbyte) {
+		txbuf16 = (u16 *)(par->txbuf.buf + 1);
+		tx_array_size -= 2;
+		*(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+		startbyte_size = 1;
+	}
+
+	while (remain) {
+		to_copy = remain > tx_array_size ? tx_array_size : remain;
+		dev_dbg(par->info->device, "    to_copy=%zu, remain=%zu\n",
+						to_copy, remain - to_copy);
+
+		for (i = 0; i < to_copy; i++)
+			txbuf16[i] = cpu_to_be16(vmem16[i]);
+
+		vmem16 = vmem16 + to_copy;
+		ret = par->fbtftops.write(par, par->txbuf.buf,
+						startbyte_size + to_copy * 2);
+		if (ret < 0)
+			return ret;
+		remain -= to_copy;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(fbtft_write_vmem16_bus8);
+
+/* 16 bit pixel over 9-bit SPI bus: dc + high byte, dc + low byte */
+int fbtft_write_vmem16_bus9(struct fbtft_par *par, size_t offset, size_t len)
+{
+	u8 *vmem8;
+	u16 *txbuf16 = par->txbuf.buf;
+	size_t remain;
+	size_t to_copy;
+	size_t tx_array_size;
+	int i;
+	int ret = 0;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
+		__func__, offset, len);
+
+	if (!par->txbuf.buf) {
+		dev_err(par->info->device, "%s: txbuf.buf is NULL\n", __func__);
+		return -1;
+	}
+
+	remain = len;
+	vmem8 = par->info->screen_base + offset;
+
+	tx_array_size = par->txbuf.len / 2;
+
+	while (remain) {
+		to_copy = remain > tx_array_size ? tx_array_size : remain;
+		dev_dbg(par->info->device, "    to_copy=%zu, remain=%zu\n",
+						to_copy, remain - to_copy);
+
+#ifdef __LITTLE_ENDIAN
+		for (i = 0; i < to_copy; i += 2) {
+			txbuf16[i]   = 0x0100 | vmem8[i+1];
+			txbuf16[i+1] = 0x0100 | vmem8[i];
+		}
+#else
+		for (i = 0; i < to_copy; i++)
+			txbuf16[i]   = 0x0100 | vmem8[i];
+#endif
+		vmem8 = vmem8 + to_copy;
+		ret = par->fbtftops.write(par, par->txbuf.buf, to_copy*2);
+		if (ret < 0)
+			return ret;
+		remain -= to_copy;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(fbtft_write_vmem16_bus9);
+
+int fbtft_write_vmem8_bus8(struct fbtft_par *par, size_t offset, size_t len)
+{
+	dev_err(par->info->device, "%s: function not implemented\n", __func__);
+	return -1;
+}
+EXPORT_SYMBOL(fbtft_write_vmem8_bus8);
+
+/* 16 bit pixel over 16-bit databus */
+int fbtft_write_vmem16_bus16(struct fbtft_par *par, size_t offset, size_t len)
+{
+	u16 *vmem16;
+
+	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
+		__func__, offset, len);
+
+	vmem16 = (u16 *)(par->info->screen_base + offset);
+
+	if (par->gpio.dc != -1)
+		gpio_set_value(par->gpio.dc, 1);
+
+	/* no need for buffered write with 16-bit bus */
+	return par->fbtftops.write(par, vmem16, len);
+}
+EXPORT_SYMBOL(fbtft_write_vmem16_bus16);
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
new file mode 100644
index 000000000000..37dcf7eb191a
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -0,0 +1,1521 @@
+/*
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This driver is inspired by:
+ *   st7735fb.c, Copyright (C) 2011, Matt Porter
+ *   broadsheetfb.c, Copyright (C) 2008, Jaya Kumar
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#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 "fbtft.h"
+
+extern void fbtft_sysfs_init(struct fbtft_par *par);
+extern void fbtft_sysfs_exit(struct fbtft_par *par);
+extern void fbtft_expand_debug_value(unsigned long *debug);
+extern int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves,
+						const char *str, int size);
+
+static unsigned long debug;
+module_param(debug, ulong , 0);
+MODULE_PARM_DESC(debug, "override device debug level");
+
+static bool dma = true;
+module_param(dma, bool, 0);
+MODULE_PARM_DESC(dma, "Use DMA buffer");
+
+
+void fbtft_dbg_hex(const struct device *dev, int groupsize,
+			void *buf, size_t len, const char *fmt, ...)
+{
+	va_list args;
+	static char textbuf[512];
+	char *text = textbuf;
+	size_t text_len;
+
+	va_start(args, fmt);
+	text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
+	va_end(args);
+
+	hex_dump_to_buffer(buf, len, 32, groupsize, text + text_len,
+				512 - text_len, false);
+
+	if (len > 32)
+		dev_info(dev, "%s ...\n", text);
+	else
+		dev_info(dev, "%s\n", text);
+}
+EXPORT_SYMBOL(fbtft_dbg_hex);
+
+static unsigned long fbtft_request_gpios_match(struct fbtft_par *par,
+					const struct fbtft_gpio *gpio)
+{
+	int ret;
+	long val;
+
+	fbtft_par_dbg(DEBUG_REQUEST_GPIOS_MATCH, par, "%s('%s')\n",
+		__func__, gpio->name);
+
+	if (strcasecmp(gpio->name, "reset") == 0) {
+		par->gpio.reset = gpio->gpio;
+		return GPIOF_OUT_INIT_HIGH;
+	} else if (strcasecmp(gpio->name, "dc") == 0) {
+		par->gpio.dc = gpio->gpio;
+		return GPIOF_OUT_INIT_LOW;
+	} else if (strcasecmp(gpio->name, "cs") == 0) {
+		par->gpio.cs = gpio->gpio;
+		return GPIOF_OUT_INIT_HIGH;
+	} else if (strcasecmp(gpio->name, "wr") == 0) {
+		par->gpio.wr = gpio->gpio;
+		return GPIOF_OUT_INIT_HIGH;
+	} else if (strcasecmp(gpio->name, "rd") == 0) {
+		par->gpio.rd = gpio->gpio;
+		return GPIOF_OUT_INIT_HIGH;
+	} else if (strcasecmp(gpio->name, "latch") == 0) {
+		par->gpio.latch = gpio->gpio;
+		return GPIOF_OUT_INIT_LOW;
+	} else if (gpio->name[0] == 'd' && gpio->name[1] == 'b') {
+		ret = kstrtol(&gpio->name[2], 10, &val);
+		if (ret == 0 && val < 16) {
+			par->gpio.db[val] = gpio->gpio;
+			return GPIOF_OUT_INIT_LOW;
+		}
+	} else if (strcasecmp(gpio->name, "led") == 0) {
+		par->gpio.led[0] = gpio->gpio;
+		return GPIOF_OUT_INIT_LOW;
+	} else if (strcasecmp(gpio->name, "led_") == 0) {
+		par->gpio.led[0] = gpio->gpio;
+		return GPIOF_OUT_INIT_HIGH;
+	}
+
+	return FBTFT_GPIO_NO_MATCH;
+}
+
+static int fbtft_request_gpios(struct fbtft_par *par)
+{
+	struct fbtft_platform_data *pdata = par->pdata;
+	const struct fbtft_gpio *gpio;
+	unsigned long flags;
+	int ret;
+
+	if (pdata && pdata->gpios) {
+		gpio = pdata->gpios;
+		while (gpio->name[0]) {
+			flags = FBTFT_GPIO_NO_MATCH;
+			/* if driver provides match function, try it first,
+			   if no match use our own */
+			if (par->fbtftops.request_gpios_match)
+				flags = par->fbtftops.request_gpios_match(par, gpio);
+			if (flags == FBTFT_GPIO_NO_MATCH)
+				flags = fbtft_request_gpios_match(par, gpio);
+			if (flags != FBTFT_GPIO_NO_MATCH) {
+				ret = devm_gpio_request_one(par->info->device,
+						gpio->gpio, flags,
+						par->info->device->driver->name);
+				if (ret < 0) {
+					dev_err(par->info->device,
+						"%s: gpio_request_one('%s'=%d) failed with %d\n",
+						__func__, gpio->name,
+						gpio->gpio, ret);
+					return ret;
+				}
+				fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par,
+					"%s: '%s' = GPIO%d\n",
+					__func__, gpio->name, gpio->gpio);
+			}
+			gpio++;
+		}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static int fbtft_request_one_gpio(struct fbtft_par *par,
+				  const char *name, int index, int *gpiop)
+{
+	struct device *dev = par->info->device;
+	struct device_node *node = dev->of_node;
+	int gpio, flags, ret = 0;
+	enum of_gpio_flags of_flags;
+
+	if (of_find_property(node, name, NULL)) {
+		gpio = of_get_named_gpio_flags(node, name, index, &of_flags);
+		if (gpio == -ENOENT)
+			return 0;
+		if (gpio == -EPROBE_DEFER)
+			return gpio;
+		if (gpio < 0) {
+			dev_err(dev,
+				"failed to get '%s' from DT\n", name);
+			return gpio;
+		}
+
+		/* active low translates to initially low */
+		flags = (of_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW :
+							GPIOF_OUT_INIT_HIGH;
+		ret = devm_gpio_request_one(dev, gpio, flags,
+						dev->driver->name);
+		if (ret) {
+			dev_err(dev,
+				"gpio_request_one('%s'=%d) failed with %d\n",
+				name, gpio, ret);
+			return ret;
+		}
+		if (gpiop)
+			*gpiop = gpio;
+		fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' = GPIO%d\n",
+							__func__, name, gpio);
+	}
+
+	return ret;
+}
+
+static int fbtft_request_gpios_dt(struct fbtft_par *par)
+{
+	int i;
+	int ret;
+
+	if (!par->info->device->of_node)
+		return -EINVAL;
+
+	ret = fbtft_request_one_gpio(par, "reset-gpios", 0, &par->gpio.reset);
+	if (ret)
+		return ret;
+	ret = fbtft_request_one_gpio(par, "dc-gpios", 0, &par->gpio.dc);
+	if (ret)
+		return ret;
+	ret = fbtft_request_one_gpio(par, "rd-gpios", 0, &par->gpio.rd);
+	if (ret)
+		return ret;
+	ret = fbtft_request_one_gpio(par, "wr-gpios", 0, &par->gpio.wr);
+	if (ret)
+		return ret;
+	ret = fbtft_request_one_gpio(par, "cs-gpios", 0, &par->gpio.cs);
+	if (ret)
+		return ret;
+	ret = fbtft_request_one_gpio(par, "latch-gpios", 0, &par->gpio.latch);
+	if (ret)
+		return ret;
+	for (i = 0; i < 16; i++) {
+		ret = fbtft_request_one_gpio(par, "db-gpios", i,
+						&par->gpio.db[i]);
+		if (ret)
+			return ret;
+		ret = fbtft_request_one_gpio(par, "led-gpios", i,
+						&par->gpio.led[i]);
+		if (ret)
+			return ret;
+		ret = fbtft_request_one_gpio(par, "aux-gpios", i,
+						&par->gpio.aux[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_FB_BACKLIGHT
+static int fbtft_backlight_update_status(struct backlight_device *bd)
+{
+	struct fbtft_par *par = bl_get_data(bd);
+	bool polarity = !!(bd->props.state & BL_CORE_DRIVER1);
+
+	fbtft_par_dbg(DEBUG_BACKLIGHT, par,
+		"%s: polarity=%d, power=%d, fb_blank=%d\n",
+		__func__, polarity, bd->props.power, bd->props.fb_blank);
+
+	if ((bd->props.power == FB_BLANK_UNBLANK) && (bd->props.fb_blank == FB_BLANK_UNBLANK))
+		gpio_set_value(par->gpio.led[0], polarity);
+	else
+		gpio_set_value(par->gpio.led[0], !polarity);
+
+	return 0;
+}
+
+static int fbtft_backlight_get_brightness(struct backlight_device *bd)
+{
+	return bd->props.brightness;
+}
+
+void fbtft_unregister_backlight(struct fbtft_par *par)
+{
+	const struct backlight_ops *bl_ops;
+
+	fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
+
+	if (par->info->bl_dev) {
+		par->info->bl_dev->props.power = FB_BLANK_POWERDOWN;
+		backlight_update_status(par->info->bl_dev);
+		bl_ops = par->info->bl_dev->ops;
+		backlight_device_unregister(par->info->bl_dev);
+		par->info->bl_dev = NULL;
+	}
+}
+
+void fbtft_register_backlight(struct fbtft_par *par)
+{
+	struct backlight_device *bd;
+	struct backlight_properties bl_props = { 0, };
+	struct backlight_ops *bl_ops;
+
+	fbtft_par_dbg(DEBUG_BACKLIGHT, par, "%s()\n", __func__);
+
+	if (par->gpio.led[0] == -1) {
+		fbtft_par_dbg(DEBUG_BACKLIGHT, par,
+			"%s(): led pin not set, exiting.\n", __func__);
+		return;
+	}
+
+	bl_ops = devm_kzalloc(par->info->device, sizeof(struct backlight_ops),
+				GFP_KERNEL);
+	if (!bl_ops) {
+		dev_err(par->info->device,
+			"%s: could not allocate memeory for backlight operations.\n",
+			__func__);
+		return;
+	}
+
+	bl_ops->get_brightness = fbtft_backlight_get_brightness;
+	bl_ops->update_status = fbtft_backlight_update_status;
+	bl_props.type = BACKLIGHT_RAW;
+	/* Assume backlight is off, get polarity from current state of pin */
+	bl_props.power = FB_BLANK_POWERDOWN;
+	if (!gpio_get_value(par->gpio.led[0]))
+		bl_props.state |= BL_CORE_DRIVER1;
+
+	bd = backlight_device_register(dev_driver_string(par->info->device),
+				par->info->device, par, bl_ops, &bl_props);
+	if (IS_ERR(bd)) {
+		dev_err(par->info->device,
+			"cannot register backlight device (%ld)\n",
+			PTR_ERR(bd));
+		return;
+	}
+	par->info->bl_dev = bd;
+
+	if (!par->fbtftops.unregister_backlight)
+		par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
+}
+#else
+void fbtft_register_backlight(struct fbtft_par *par) { };
+void fbtft_unregister_backlight(struct fbtft_par *par) { };
+#endif
+EXPORT_SYMBOL(fbtft_register_backlight);
+EXPORT_SYMBOL(fbtft_unregister_backlight);
+
+static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe,
+			       int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	/* Column address set */
+	write_reg(par, 0x2A,
+		(xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
+
+	/* Row adress set */
+	write_reg(par, 0x2B,
+		(ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF);
+
+	/* Memory write */
+	write_reg(par, 0x2C);
+}
+
+
+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);
+}
+
+
+static void fbtft_update_display(struct fbtft_par *par, unsigned start_line,
+				 unsigned end_line)
+{
+	size_t offset, len;
+	struct timespec ts_start, ts_end, ts_fps, ts_duration;
+	long fps_ms, fps_us, duration_ms, duration_us;
+	long fps, throughput;
+	bool timeit = false;
+	int ret = 0;
+
+	if (unlikely(par->debug & (DEBUG_TIME_FIRST_UPDATE | DEBUG_TIME_EACH_UPDATE))) {
+		if ((par->debug & DEBUG_TIME_EACH_UPDATE) || \
+				((par->debug & DEBUG_TIME_FIRST_UPDATE) && !par->first_update_done)) {
+			getnstimeofday(&ts_start);
+			timeit = true;
+		}
+	}
+
+	/* Sanity checks */
+	if (start_line > end_line) {
+		dev_warn(par->info->device,
+			"%s: start_line=%u is larger than end_line=%u. Shouldn't happen, will do full display update\n",
+			__func__, start_line, end_line);
+		start_line = 0;
+		end_line = par->info->var.yres - 1;
+	}
+	if (start_line > par->info->var.yres - 1 || end_line > par->info->var.yres - 1) {
+		dev_warn(par->info->device,
+			"%s: start_line=%u or end_line=%u is larger than max=%d. Shouldn't happen, will do full display update\n",
+			__func__, start_line, end_line, par->info->var.yres - 1);
+		start_line = 0;
+		end_line = par->info->var.yres - 1;
+	}
+
+	fbtft_par_dbg(DEBUG_UPDATE_DISPLAY, par, "%s(start_line=%u, end_line=%u)\n",
+		__func__, start_line, end_line);
+
+	if (par->fbtftops.set_addr_win)
+		par->fbtftops.set_addr_win(par, 0, start_line,
+				par->info->var.xres-1, end_line);
+
+	offset = start_line * par->info->fix.line_length;
+	len = (end_line - start_line + 1) * par->info->fix.line_length;
+	ret = par->fbtftops.write_vmem(par, offset, len);
+	if (ret < 0)
+		dev_err(par->info->device,
+			"%s: write_vmem failed to update display buffer\n",
+			__func__);
+
+	if (unlikely(timeit)) {
+		getnstimeofday(&ts_end);
+		if (par->update_time.tv_nsec == 0 && par->update_time.tv_sec == 0) {
+			par->update_time.tv_sec = ts_start.tv_sec;
+			par->update_time.tv_nsec = ts_start.tv_nsec;
+		}
+		ts_fps = timespec_sub(ts_start, par->update_time);
+		par->update_time.tv_sec = ts_start.tv_sec;
+		par->update_time.tv_nsec = ts_start.tv_nsec;
+		fps_ms = (ts_fps.tv_sec * 1000) + ((ts_fps.tv_nsec / 1000000) % 1000);
+		fps_us = (ts_fps.tv_nsec / 1000) % 1000;
+		fps = fps_ms * 1000 + fps_us;
+		fps = fps ? 1000000 / fps : 0;
+
+		ts_duration = timespec_sub(ts_end, ts_start);
+		duration_ms = (ts_duration.tv_sec * 1000) + ((ts_duration.tv_nsec / 1000000) % 1000);
+		duration_us = (ts_duration.tv_nsec / 1000) % 1000;
+		throughput = duration_ms * 1000 + duration_us;
+		throughput = throughput ? (len * 1000) / throughput : 0;
+		throughput = throughput * 1000 / 1024;
+
+		dev_info(par->info->device,
+			"Display update: %ld kB/s (%ld.%.3ld ms), fps=%ld (%ld.%.3ld ms)\n",
+			throughput, duration_ms, duration_us,
+			fps, fps_ms, fps_us);
+		par->first_update_done = true;
+	}
+}
+
+
+static void fbtft_mkdirty(struct fb_info *info, int y, int height)
+{
+	struct fbtft_par *par = info->par;
+	struct fb_deferred_io *fbdefio = info->fbdefio;
+
+	/* special case, needed ? */
+	if (y == -1) {
+		y = 0;
+		height = info->var.yres - 1;
+	}
+
+	/* Mark display lines/area as dirty */
+	spin_lock(&par->dirty_lock);
+	if (y < par->dirty_lines_start)
+		par->dirty_lines_start = y;
+	if (y + height - 1 > par->dirty_lines_end)
+		par->dirty_lines_end = y + height - 1;
+	spin_unlock(&par->dirty_lock);
+
+	/* Schedule deferred_io to update display (no-op if already on queue)*/
+	schedule_delayed_work(&info->deferred_work, fbdefio->delay);
+}
+
+static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
+{
+	struct fbtft_par *par = info->par;
+	unsigned dirty_lines_start, dirty_lines_end;
+	struct page *page;
+	unsigned long index;
+	unsigned y_low = 0, y_high = 0;
+	int count = 0;
+
+	spin_lock(&par->dirty_lock);
+	dirty_lines_start = par->dirty_lines_start;
+	dirty_lines_end = par->dirty_lines_end;
+	/* set display line markers as clean */
+	par->dirty_lines_start = par->info->var.yres - 1;
+	par->dirty_lines_end = 0;
+	spin_unlock(&par->dirty_lock);
+
+	/* Mark display lines as dirty */
+	list_for_each_entry(page, pagelist, lru) {
+		count++;
+		index = page->index << PAGE_SHIFT;
+		y_low = index / info->fix.line_length;
+		y_high = (index + PAGE_SIZE - 1) / info->fix.line_length;
+		fbtft_dev_dbg(DEBUG_DEFERRED_IO, par, info->device,
+			"page->index=%lu y_low=%d y_high=%d\n",
+			page->index, y_low, y_high);
+		if (y_high > info->var.yres - 1)
+			y_high = info->var.yres - 1;
+		if (y_low < dirty_lines_start)
+			dirty_lines_start = y_low;
+		if (y_high > dirty_lines_end)
+			dirty_lines_end = y_high;
+	}
+
+	par->fbtftops.update_display(info->par,
+					dirty_lines_start, dirty_lines_end);
+}
+
+
+static void fbtft_fb_fillrect(struct fb_info *info,
+			      const struct fb_fillrect *rect)
+{
+	struct fbtft_par *par = info->par;
+
+	fbtft_dev_dbg(DEBUG_FB_FILLRECT, par, info->dev,
+		"%s: dx=%d, dy=%d, width=%d, height=%d\n",
+		__func__, rect->dx, rect->dy, rect->width, rect->height);
+	sys_fillrect(info, rect);
+
+	par->fbtftops.mkdirty(info, rect->dy, rect->height);
+}
+
+static void fbtft_fb_copyarea(struct fb_info *info,
+			      const struct fb_copyarea *area)
+{
+	struct fbtft_par *par = info->par;
+
+	fbtft_dev_dbg(DEBUG_FB_COPYAREA, par, info->dev,
+		"%s: dx=%d, dy=%d, width=%d, height=%d\n",
+		__func__,  area->dx, area->dy, area->width, area->height);
+	sys_copyarea(info, area);
+
+	par->fbtftops.mkdirty(info, area->dy, area->height);
+}
+
+static void fbtft_fb_imageblit(struct fb_info *info,
+			       const struct fb_image *image)
+{
+	struct fbtft_par *par = info->par;
+
+	fbtft_dev_dbg(DEBUG_FB_IMAGEBLIT, par, info->dev,
+		"%s: dx=%d, dy=%d, width=%d, height=%d\n",
+		__func__,  image->dx, image->dy, image->width, image->height);
+	sys_imageblit(info, image);
+
+	par->fbtftops.mkdirty(info, image->dy, image->height);
+}
+
+static ssize_t fbtft_fb_write(struct fb_info *info, const char __user *buf,
+			      size_t count, loff_t *ppos)
+{
+	struct fbtft_par *par = info->par;
+	ssize_t res;
+
+	fbtft_dev_dbg(DEBUG_FB_WRITE, par, info->dev,
+		"%s: count=%zd, ppos=%llu\n", __func__,  count, *ppos);
+	res = fb_sys_write(info, buf, count, ppos);
+
+	/* TODO: only mark changed area
+	   update all for now */
+	par->fbtftops.mkdirty(info, -1, 0);
+
+	return res;
+}
+
+/* from pxafb.c */
+static unsigned int chan_to_field(unsigned chan, struct fb_bitfield *bf)
+{
+	chan &= 0xffff;
+	chan >>= 16 - bf->length;
+	return chan << bf->offset;
+}
+
+static int fbtft_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			      unsigned blue, unsigned transp,
+			      struct fb_info *info)
+{
+	struct fbtft_par *par = info->par;
+	unsigned val;
+	int ret = 1;
+
+	fbtft_dev_dbg(DEBUG_FB_SETCOLREG, par, info->dev,
+		"%s(regno=%u, red=0x%X, green=0x%X, blue=0x%X, trans=0x%X)\n",
+		__func__, regno, red, green, blue, transp);
+
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+		if (regno < 16) {
+			u32 *pal = info->pseudo_palette;
+
+			val  = chan_to_field(red,   &info->var.red);
+			val |= chan_to_field(green, &info->var.green);
+			val |= chan_to_field(blue,  &info->var.blue);
+
+			pal[regno] = val;
+			ret = 0;
+		}
+		break;
+
+	}
+	return ret;
+}
+
+static int fbtft_fb_blank(int blank, struct fb_info *info)
+{
+	struct fbtft_par *par = info->par;
+	int ret = -EINVAL;
+
+	fbtft_dev_dbg(DEBUG_FB_BLANK, par, info->dev, "%s(blank=%d)\n",
+		__func__, blank);
+
+	if (!par->fbtftops.blank)
+		return ret;
+
+	switch (blank) {
+	case FB_BLANK_POWERDOWN:
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+	case FB_BLANK_NORMAL:
+		ret = par->fbtftops.blank(par, true);
+		break;
+	case FB_BLANK_UNBLANK:
+		ret = par->fbtftops.blank(par, false);
+		break;
+	}
+	return ret;
+}
+
+static void fbtft_merge_fbtftops(struct fbtft_ops *dst, struct fbtft_ops *src)
+{
+	if (src->write)
+		dst->write = src->write;
+	if (src->read)
+		dst->read = src->read;
+	if (src->write_vmem)
+		dst->write_vmem = src->write_vmem;
+	if (src->write_register)
+		dst->write_register = src->write_register;
+	if (src->set_addr_win)
+		dst->set_addr_win = src->set_addr_win;
+	if (src->reset)
+		dst->reset = src->reset;
+	if (src->mkdirty)
+		dst->mkdirty = src->mkdirty;
+	if (src->update_display)
+		dst->update_display = src->update_display;
+	if (src->init_display)
+		dst->init_display = src->init_display;
+	if (src->blank)
+		dst->blank = src->blank;
+	if (src->request_gpios_match)
+		dst->request_gpios_match = src->request_gpios_match;
+	if (src->request_gpios)
+		dst->request_gpios = src->request_gpios;
+	if (src->verify_gpios)
+		dst->verify_gpios = src->verify_gpios;
+	if (src->register_backlight)
+		dst->register_backlight = src->register_backlight;
+	if (src->unregister_backlight)
+		dst->unregister_backlight = src->unregister_backlight;
+	if (src->set_var)
+		dst->set_var = src->set_var;
+	if (src->set_gamma)
+		dst->set_gamma = src->set_gamma;
+}
+
+/**
+ * fbtft_framebuffer_alloc - creates a new frame buffer info structure
+ *
+ * @display: pointer to structure describing the display
+ * @dev: pointer to the device for this fb, this can be NULL
+ *
+ * Creates a new frame buffer info structure.
+ *
+ * Also creates and populates the following structures:
+ *   info->fbops
+ *   info->fbdefio
+ *   info->pseudo_palette
+ *   par->fbtftops
+ *   par->txbuf
+ *
+ * Returns the new structure, or NULL if an error occurred.
+ *
+ */
+struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
+					struct device *dev)
+{
+	struct fb_info *info;
+	struct fbtft_par *par;
+	struct fb_ops *fbops = NULL;
+	struct fb_deferred_io *fbdefio = NULL;
+	struct fbtft_platform_data *pdata = dev->platform_data;
+	u8 *vmem = NULL;
+	void *txbuf = NULL;
+	void *buf = NULL;
+	unsigned width;
+	unsigned height;
+	int txbuflen = display->txbuflen;
+	unsigned bpp = display->bpp;
+	unsigned fps = display->fps;
+	int vmem_size, i;
+	int *init_sequence = display->init_sequence;
+	char *gamma = display->gamma;
+	unsigned long *gamma_curves = NULL;
+
+	/* sanity check */
+	if (display->gamma_num * display->gamma_len > FBTFT_GAMMA_MAX_VALUES_TOTAL) {
+		dev_err(dev,
+			"%s: FBTFT_GAMMA_MAX_VALUES_TOTAL=%d is exceeded\n",
+			__func__, FBTFT_GAMMA_MAX_VALUES_TOTAL);
+		return NULL;
+	}
+
+	/* defaults */
+	if (!fps)
+		fps = 20;
+	if (!bpp)
+		bpp = 16;
+
+	if (!pdata) {
+		dev_err(dev, "platform data is missing\n");
+		return NULL;
+	}
+
+	/* override driver values? */
+	if (pdata->fps)
+		fps = pdata->fps;
+	if (pdata->txbuflen)
+		txbuflen = pdata->txbuflen;
+	if (pdata->display.init_sequence)
+		init_sequence = pdata->display.init_sequence;
+	if (pdata->gamma)
+		gamma = pdata->gamma;
+	if (pdata->display.debug)
+		display->debug = pdata->display.debug;
+	if (pdata->display.backlight)
+		display->backlight = pdata->display.backlight;
+	if (pdata->display.width)
+		display->width = pdata->display.width;
+	if (pdata->display.height)
+		display->height = pdata->display.height;
+	if (pdata->display.buswidth)
+		display->buswidth = pdata->display.buswidth;
+	if (pdata->display.regwidth)
+		display->regwidth = pdata->display.regwidth;
+
+	display->debug |= debug;
+	fbtft_expand_debug_value(&display->debug);
+
+	switch (pdata->rotate) {
+	case 90:
+	case 270:
+		width =  display->height;
+		height = display->width;
+		break;
+	default:
+		width =  display->width;
+		height = display->height;
+	}
+
+	vmem_size = display->width * display->height * bpp / 8;
+	vmem = vzalloc(vmem_size);
+	if (!vmem)
+		goto alloc_fail;
+
+	fbops = devm_kzalloc(dev, sizeof(struct fb_ops), GFP_KERNEL);
+	if (!fbops)
+		goto alloc_fail;
+
+	fbdefio = devm_kzalloc(dev, sizeof(struct fb_deferred_io), GFP_KERNEL);
+	if (!fbdefio)
+		goto alloc_fail;
+
+	buf = devm_kzalloc(dev, 128, GFP_KERNEL);
+	if (!buf)
+		goto alloc_fail;
+
+	if (display->gamma_num && display->gamma_len) {
+		gamma_curves = devm_kzalloc(dev, display->gamma_num * display->gamma_len * sizeof(gamma_curves[0]),
+						GFP_KERNEL);
+		if (!gamma_curves)
+			goto alloc_fail;
+	}
+
+	info = framebuffer_alloc(sizeof(struct fbtft_par), dev);
+	if (!info)
+		goto alloc_fail;
+
+	info->screen_base = (u8 __force __iomem *)vmem;
+	info->fbops = fbops;
+	info->fbdefio = fbdefio;
+
+	fbops->owner        =      dev->driver->owner;
+	fbops->fb_read      =      fb_sys_read;
+	fbops->fb_write     =      fbtft_fb_write;
+	fbops->fb_fillrect  =      fbtft_fb_fillrect;
+	fbops->fb_copyarea  =      fbtft_fb_copyarea;
+	fbops->fb_imageblit =      fbtft_fb_imageblit;
+	fbops->fb_setcolreg =      fbtft_fb_setcolreg;
+	fbops->fb_blank     =      fbtft_fb_blank;
+
+	fbdefio->delay =           HZ/fps;
+	fbdefio->deferred_io =     fbtft_deferred_io;
+	fb_deferred_io_init(info);
+
+	strncpy(info->fix.id, dev->driver->name, 16);
+	info->fix.type =           FB_TYPE_PACKED_PIXELS;
+	info->fix.visual =         FB_VISUAL_TRUECOLOR;
+	info->fix.xpanstep =	   0;
+	info->fix.ypanstep =	   0;
+	info->fix.ywrapstep =	   0;
+	info->fix.line_length =    width*bpp/8;
+	info->fix.accel =          FB_ACCEL_NONE;
+	info->fix.smem_len =       vmem_size;
+
+	info->var.rotate =         pdata->rotate;
+	info->var.xres =           width;
+	info->var.yres =           height;
+	info->var.xres_virtual =   info->var.xres;
+	info->var.yres_virtual =   info->var.yres;
+	info->var.bits_per_pixel = bpp;
+	info->var.nonstd =         1;
+
+	/* RGB565 */
+	info->var.red.offset =     11;
+	info->var.red.length =     5;
+	info->var.green.offset =   5;
+	info->var.green.length =   6;
+	info->var.blue.offset =    0;
+	info->var.blue.length =    5;
+	info->var.transp.offset =  0;
+	info->var.transp.length =  0;
+
+	info->flags =              FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
+
+	par = info->par;
+	par->info = info;
+	par->pdata = dev->platform_data;
+	par->debug = display->debug;
+	par->buf = buf;
+	spin_lock_init(&par->dirty_lock);
+	par->bgr = pdata->bgr;
+	par->startbyte = pdata->startbyte;
+	par->init_sequence = init_sequence;
+	par->gamma.curves = gamma_curves;
+	par->gamma.num_curves = display->gamma_num;
+	par->gamma.num_values = display->gamma_len;
+	mutex_init(&par->gamma.lock);
+	info->pseudo_palette = par->pseudo_palette;
+
+	if (par->gamma.curves && gamma) {
+		if (fbtft_gamma_parse_str(par,
+			par->gamma.curves, gamma, strlen(gamma)))
+			goto alloc_fail;
+	}
+
+	/* Transmit buffer */
+	if (txbuflen == -1)
+		txbuflen = vmem_size + 2; /* add in case startbyte is used */
+
+#ifdef __LITTLE_ENDIAN
+	if ((!txbuflen) && (bpp > 8))
+		txbuflen = PAGE_SIZE; /* need buffer for byteswapping */
+#endif
+
+	if (txbuflen > 0) {
+		if (dma) {
+			dev->coherent_dma_mask = ~0;
+			txbuf = dmam_alloc_coherent(dev, txbuflen, &par->txbuf.dma, GFP_DMA);
+		} else {
+			txbuf = devm_kzalloc(par->info->device, txbuflen, GFP_KERNEL);
+		}
+		if (!txbuf)
+			goto alloc_fail;
+		par->txbuf.buf = txbuf;
+		par->txbuf.len = txbuflen;
+	}
+
+	/* Initialize gpios to disabled */
+	par->gpio.reset = -1;
+	par->gpio.dc = -1;
+	par->gpio.rd = -1;
+	par->gpio.wr = -1;
+	par->gpio.cs = -1;
+	par->gpio.latch = -1;
+	for (i = 0; i < 16; i++) {
+		par->gpio.db[i] = -1;
+		par->gpio.led[i] = -1;
+		par->gpio.aux[i] = -1;
+	}
+
+	/* default fbtft operations */
+	par->fbtftops.write = fbtft_write_spi;
+	par->fbtftops.read = fbtft_read_spi;
+	par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
+	par->fbtftops.write_register = fbtft_write_reg8_bus8;
+	par->fbtftops.set_addr_win = fbtft_set_addr_win;
+	par->fbtftops.reset = fbtft_reset;
+	par->fbtftops.mkdirty = fbtft_mkdirty;
+	par->fbtftops.update_display = fbtft_update_display;
+	par->fbtftops.request_gpios = fbtft_request_gpios;
+	if (display->backlight)
+		par->fbtftops.register_backlight = fbtft_register_backlight;
+
+	/* use driver provided functions */
+	fbtft_merge_fbtftops(&par->fbtftops, &display->fbtftops);
+
+	return info;
+
+alloc_fail:
+	vfree(vmem);
+
+	return NULL;
+}
+EXPORT_SYMBOL(fbtft_framebuffer_alloc);
+
+/**
+ * fbtft_framebuffer_release - frees up all memory used by the framebuffer
+ *
+ * @info: frame buffer info structure
+ *
+ */
+void fbtft_framebuffer_release(struct fb_info *info)
+{
+	fb_deferred_io_cleanup(info);
+	vfree(info->screen_base);
+	framebuffer_release(info);
+}
+EXPORT_SYMBOL(fbtft_framebuffer_release);
+
+/**
+ *	fbtft_register_framebuffer - registers a tft frame buffer device
+ *	@fb_info: frame buffer info structure
+ *
+ *  Sets SPI driverdata if needed
+ *  Requests needed gpios.
+ *  Initializes display
+ *  Updates display.
+ *	Registers a frame buffer device @fb_info.
+ *
+ *	Returns negative errno on error, or zero for success.
+ *
+ */
+int fbtft_register_framebuffer(struct fb_info *fb_info)
+{
+	int ret;
+	char text1[50] = "";
+	char text2[50] = "";
+	struct fbtft_par *par = fb_info->par;
+	struct spi_device *spi = par->spi;
+
+	/* sanity checks */
+	if (!par->fbtftops.init_display) {
+		dev_err(fb_info->device, "missing fbtftops.init_display()\n");
+		return -EINVAL;
+	}
+
+	if (spi)
+		spi_set_drvdata(spi, fb_info);
+	if (par->pdev)
+		platform_set_drvdata(par->pdev, fb_info);
+
+	ret = par->fbtftops.request_gpios(par);
+	if (ret < 0)
+		goto reg_fail;
+
+	if (par->fbtftops.verify_gpios) {
+		ret = par->fbtftops.verify_gpios(par);
+		if (ret < 0)
+			goto reg_fail;
+	}
+
+	ret = par->fbtftops.init_display(par);
+	if (ret < 0)
+		goto reg_fail;
+	if (par->fbtftops.set_var) {
+		ret = par->fbtftops.set_var(par);
+		if (ret < 0)
+			goto reg_fail;
+	}
+
+	/* update the entire display */
+	par->fbtftops.update_display(par, 0, par->info->var.yres - 1);
+
+	if (par->fbtftops.set_gamma && par->gamma.curves) {
+		ret = par->fbtftops.set_gamma(par, par->gamma.curves);
+		if (ret)
+			goto reg_fail;
+	}
+
+	if (par->fbtftops.register_backlight)
+		par->fbtftops.register_backlight(par);
+
+	ret = register_framebuffer(fb_info);
+	if (ret < 0)
+		goto reg_fail;
+
+	fbtft_sysfs_init(par);
+
+	if (par->txbuf.buf)
+		sprintf(text1, ", %d KiB %sbuffer memory",
+			par->txbuf.len >> 10, par->txbuf.dma ? "DMA " : "");
+	if (spi)
+		sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num,
+				spi->chip_select, spi->max_speed_hz/1000000);
+	dev_info(fb_info->dev,
+		"%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n",
+		fb_info->fix.id, fb_info->var.xres, fb_info->var.yres,
+		fb_info->fix.smem_len >> 10, text1,
+		HZ/fb_info->fbdefio->delay, text2);
+
+#ifdef CONFIG_FB_BACKLIGHT
+	/* Turn on backlight if available */
+	if (fb_info->bl_dev) {
+		fb_info->bl_dev->props.power = FB_BLANK_UNBLANK;
+		fb_info->bl_dev->ops->update_status(fb_info->bl_dev);
+	}
+#endif
+
+	return 0;
+
+reg_fail:
+	if (par->fbtftops.unregister_backlight)
+		par->fbtftops.unregister_backlight(par);
+	if (spi)
+		spi_set_drvdata(spi, NULL);
+	if (par->pdev)
+		platform_set_drvdata(par->pdev, NULL);
+
+	return ret;
+}
+EXPORT_SYMBOL(fbtft_register_framebuffer);
+
+/**
+ *	fbtft_unregister_framebuffer - releases a tft frame buffer device
+ *	@fb_info: frame buffer info structure
+ *
+ *  Frees SPI driverdata if needed
+ *  Frees gpios.
+ *	Unregisters frame buffer device.
+ *
+ */
+int fbtft_unregister_framebuffer(struct fb_info *fb_info)
+{
+	struct fbtft_par *par = fb_info->par;
+	struct spi_device *spi = par->spi;
+	int ret;
+
+	if (spi)
+		spi_set_drvdata(spi, NULL);
+	if (par->pdev)
+		platform_set_drvdata(par->pdev, NULL);
+	if (par->fbtftops.unregister_backlight)
+		par->fbtftops.unregister_backlight(par);
+	fbtft_sysfs_exit(par);
+	ret = unregister_framebuffer(fb_info);
+	return ret;
+}
+EXPORT_SYMBOL(fbtft_unregister_framebuffer);
+
+#ifdef CONFIG_OF
+/**
+ * fbtft_init_display_dt() - Device Tree init_display() function
+ * @par: Driver data
+ *
+ * Return: 0 if successful, negative if error
+ */
+static int fbtft_init_display_dt(struct fbtft_par *par)
+{
+	struct device_node *node = par->info->device->of_node;
+	struct property *prop;
+	const __be32 *p;
+	u32 val;
+	int buf[64], i, j;
+	char msg[128];
+	char str[16];
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	if (!node)
+		return -EINVAL;
+
+	prop = of_find_property(node, "init", NULL);
+	p = of_prop_next_u32(prop, NULL, &val);
+	if (!p)
+		return -EINVAL;
+	while (p) {
+		if (val & FBTFT_OF_INIT_CMD) {
+			val &= 0xFFFF;
+			i = 0;
+			while (p && !(val & 0xFFFF0000)) {
+				if (i > 63) {
+					dev_err(par->info->device,
+					"%s: Maximum register values exceeded\n",
+					__func__);
+					return -EINVAL;
+				}
+				buf[i++] = val;
+				p = of_prop_next_u32(prop, p, &val);
+			}
+			/* make debug message */
+			msg[0] = '\0';
+			for (j = 0; j < i; j++) {
+				snprintf(str, 128, " %02X", buf[j]);
+				strcat(msg, str);
+			}
+			fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
+				"init: write_register:%s\n", msg);
+
+			par->fbtftops.write_register(par, i,
+				buf[0], buf[1], buf[2], buf[3],
+				buf[4], buf[5], buf[6], buf[7],
+				buf[8], buf[9], buf[10], buf[11],
+				buf[12], buf[13], buf[14], buf[15],
+				buf[16], buf[17], buf[18], buf[19],
+				buf[20], buf[21], buf[22], buf[23],
+				buf[24], buf[25], buf[26], buf[27],
+				buf[28], buf[29], buf[30], buf[31],
+				buf[32], buf[33], buf[34], buf[35],
+				buf[36], buf[37], buf[38], buf[39],
+				buf[40], buf[41], buf[42], buf[43],
+				buf[44], buf[45], buf[46], buf[47],
+				buf[48], buf[49], buf[50], buf[51],
+				buf[52], buf[53], buf[54], buf[55],
+				buf[56], buf[57], buf[58], buf[59],
+				buf[60], buf[61], buf[62], buf[63]);
+		} else if (val & FBTFT_OF_INIT_DELAY) {
+			fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
+				"init: msleep(%u)\n", val & 0xFFFF);
+			msleep(val & 0xFFFF);
+			p = of_prop_next_u32(prop, p, &val);
+		} else {
+			dev_err(par->info->device, "illegal init value 0x%X\n",
+									val);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+#endif
+
+/**
+ * fbtft_init_display() - Generic init_display() function
+ * @par: Driver data
+ *
+ * Uses par->init_sequence to do the initialization
+ *
+ * Return: 0 if successful, negative if error
+ */
+int fbtft_init_display(struct fbtft_par *par)
+{
+	int buf[64];
+	char msg[128];
+	char str[16];
+	int i = 0;
+	int j;
+
+	fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
+
+	/* sanity check */
+	if (!par->init_sequence) {
+		dev_err(par->info->device,
+			"error: init_sequence is not set\n");
+		return -EINVAL;
+	}
+
+	/* make sure stop marker exists */
+	for (i = 0; i < FBTFT_MAX_INIT_SEQUENCE; i++)
+		if (par->init_sequence[i] == -3)
+			break;
+	if (i == FBTFT_MAX_INIT_SEQUENCE) {
+		dev_err(par->info->device,
+			"missing stop marker at end of init sequence\n");
+		return -EINVAL;
+	}
+
+	par->fbtftops.reset(par);
+	if (par->gpio.cs != -1)
+		gpio_set_value(par->gpio.cs, 0);  /* Activate chip */
+
+	i = 0;
+	while (i < FBTFT_MAX_INIT_SEQUENCE) {
+		if (par->init_sequence[i] == -3) {
+			/* done */
+			return 0;
+		}
+		if (par->init_sequence[i] >= 0) {
+			dev_err(par->info->device,
+				"missing delimiter at position %d\n", i);
+			return -EINVAL;
+		}
+		if (par->init_sequence[i+1] < 0) {
+			dev_err(par->info->device,
+				"missing value after delimiter %d at position %d\n",
+				par->init_sequence[i], i);
+			return -EINVAL;
+		}
+		switch (par->init_sequence[i]) {
+		case -1:
+			i++;
+			/* make debug message */
+			strcpy(msg, "");
+			j = i + 1;
+			while (par->init_sequence[j] >= 0) {
+				sprintf(str, "0x%02X ", par->init_sequence[j]);
+				strcat(msg, str);
+				j++;
+			}
+			fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
+				"init: write(0x%02X) %s\n",
+				par->init_sequence[i], msg);
+
+			/* Write */
+			j = 0;
+			while (par->init_sequence[i] >= 0) {
+				if (j > 63) {
+					dev_err(par->info->device,
+					"%s: Maximum register values exceeded\n",
+					__func__);
+					return -EINVAL;
+				}
+				buf[j++] = par->init_sequence[i++];
+			}
+			par->fbtftops.write_register(par, j,
+				buf[0], buf[1], buf[2], buf[3],
+				buf[4], buf[5], buf[6], buf[7],
+				buf[8], buf[9], buf[10], buf[11],
+				buf[12], buf[13], buf[14], buf[15],
+				buf[16], buf[17], buf[18], buf[19],
+				buf[20], buf[21], buf[22], buf[23],
+				buf[24], buf[25], buf[26], buf[27],
+				buf[28], buf[29], buf[30], buf[31],
+				buf[32], buf[33], buf[34], buf[35],
+				buf[36], buf[37], buf[38], buf[39],
+				buf[40], buf[41], buf[42], buf[43],
+				buf[44], buf[45], buf[46], buf[47],
+				buf[48], buf[49], buf[50], buf[51],
+				buf[52], buf[53], buf[54], buf[55],
+				buf[56], buf[57], buf[58], buf[59],
+				buf[60], buf[61], buf[62], buf[63]);
+			break;
+		case -2:
+			i++;
+			fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
+				"init: mdelay(%d)\n", par->init_sequence[i]);
+			mdelay(par->init_sequence[i++]);
+			break;
+		default:
+			dev_err(par->info->device,
+				"unknown delimiter %d at position %d\n",
+				par->init_sequence[i], i);
+			return -EINVAL;
+		}
+	}
+
+	dev_err(par->info->device,
+		"%s: something is wrong. Shouldn't get here.\n", __func__);
+	return -EINVAL;
+}
+EXPORT_SYMBOL(fbtft_init_display);
+
+/**
+ * fbtft_verify_gpios() - Generic verify_gpios() function
+ * @par: Driver data
+ *
+ * Uses @spi, @pdev and @buswidth to determine which GPIOs is needed
+ *
+ * Return: 0 if successful, negative if error
+ */
+static int fbtft_verify_gpios(struct fbtft_par *par)
+{
+	struct fbtft_platform_data *pdata;
+	int i;
+
+	fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__);
+
+	pdata = par->info->device->platform_data;
+	if (pdata->display.buswidth != 9 && par->startbyte == 0 && \
+							par->gpio.dc < 0) {
+		dev_err(par->info->device,
+			"Missing info about 'dc' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+
+	if (!par->pdev)
+		return 0;
+
+	if (par->gpio.wr < 0) {
+		dev_err(par->info->device, "Missing 'wr' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+	for (i = 0; i < pdata->display.buswidth; i++) {
+		if (par->gpio.db[i] < 0) {
+			dev_err(par->info->device,
+				"Missing 'db%02d' gpio. Aborting.\n", i);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+/* returns 0 if the property is not present */
+static u32 fbtft_of_value(struct device_node *node, const char *propname)
+{
+	int ret;
+	u32 val = 0;
+
+	ret = of_property_read_u32(node, propname, &val);
+	if (ret == 0)
+		pr_info("%s: %s = %u\n", __func__, propname, val);
+
+	return val;
+}
+
+static struct fbtft_platform_data *fbtft_probe_dt(struct device *dev)
+{
+	struct device_node *node = dev->of_node;
+	struct fbtft_platform_data *pdata;
+
+	if (!node) {
+		dev_err(dev, "Missing platform data or DT\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	pdata->display.width = fbtft_of_value(node, "width");
+	pdata->display.height = fbtft_of_value(node, "height");
+	pdata->display.regwidth = fbtft_of_value(node, "regwidth");
+	pdata->display.buswidth = fbtft_of_value(node, "buswidth");
+	pdata->display.backlight = fbtft_of_value(node, "backlight");
+	pdata->display.bpp = fbtft_of_value(node, "bpp");
+	pdata->display.debug = fbtft_of_value(node, "debug");
+	pdata->rotate = fbtft_of_value(node, "rotate");
+	pdata->bgr = of_property_read_bool(node, "bgr");
+	pdata->fps = fbtft_of_value(node, "fps");
+	pdata->txbuflen = fbtft_of_value(node, "txbuflen");
+	pdata->startbyte = fbtft_of_value(node, "startbyte");
+	of_property_read_string(node, "gamma", (const char **)&pdata->gamma);
+
+	if (of_find_property(node, "led-gpios", NULL))
+		pdata->display.backlight = 1;
+	if (of_find_property(node, "init", NULL))
+		pdata->display.fbtftops.init_display = fbtft_init_display_dt;
+	pdata->display.fbtftops.request_gpios = fbtft_request_gpios_dt;
+
+	return pdata;
+}
+#else
+static struct fbtft_platform_data *fbtft_probe_dt(struct device *dev)
+{
+	dev_err(dev, "Missing platform data\n");
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
+/**
+ * fbtft_probe_common() - Generic device probe() helper function
+ * @display: Display properties
+ * @sdev: SPI device
+ * @pdev: Platform device
+ *
+ * Allocates, initializes and registers a framebuffer
+ *
+ * Either @sdev or @pdev should be NULL
+ *
+ * Return: 0 if successful, negative if error
+ */
+int fbtft_probe_common(struct fbtft_display *display,
+			struct spi_device *sdev, struct platform_device *pdev)
+{
+	struct device *dev;
+	struct fb_info *info;
+	struct fbtft_par *par;
+	struct fbtft_platform_data *pdata;
+	int ret;
+
+	if (sdev)
+		dev = &sdev->dev;
+	else
+		dev = &pdev->dev;
+
+	if (unlikely(display->debug & DEBUG_DRIVER_INIT_FUNCTIONS))
+		dev_info(dev, "%s()\n", __func__);
+
+	pdata = dev->platform_data;
+	if (!pdata) {
+		pdata = fbtft_probe_dt(dev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+		dev->platform_data = pdata;
+	}
+
+	info = fbtft_framebuffer_alloc(display, dev);
+	if (!info)
+		return -ENOMEM;
+
+	par = info->par;
+	par->spi = sdev;
+	par->pdev = pdev;
+
+	if (display->buswidth == 0) {
+		dev_err(dev, "buswidth is not set\n");
+		return -EINVAL;
+	}
+
+	/* write register functions */
+	if (display->regwidth == 8 && display->buswidth == 8) {
+		par->fbtftops.write_register = fbtft_write_reg8_bus8;
+	} else
+	if (display->regwidth == 8 && display->buswidth == 9 && par->spi) {
+		par->fbtftops.write_register = fbtft_write_reg8_bus9;
+	} else if (display->regwidth == 16 && display->buswidth == 8) {
+		par->fbtftops.write_register = fbtft_write_reg16_bus8;
+	} else if (display->regwidth == 16 && display->buswidth == 16) {
+		par->fbtftops.write_register = fbtft_write_reg16_bus16;
+	} else {
+		dev_warn(dev,
+			"no default functions for regwidth=%d and buswidth=%d\n",
+			display->regwidth, display->buswidth);
+	}
+
+	/* write_vmem() functions */
+	if (display->buswidth == 8)
+		par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
+	else if (display->buswidth == 9)
+		par->fbtftops.write_vmem = fbtft_write_vmem16_bus9;
+	else if (display->buswidth == 16)
+		par->fbtftops.write_vmem = fbtft_write_vmem16_bus16;
+
+	/* GPIO write() functions */
+	if (par->pdev) {
+		if (display->buswidth == 8)
+			par->fbtftops.write = fbtft_write_gpio8_wr;
+		else if (display->buswidth == 16)
+			par->fbtftops.write = fbtft_write_gpio16_wr;
+	}
+
+	/* 9-bit SPI setup */
+	if (par->spi && display->buswidth == 9) {
+		par->spi->bits_per_word = 9;
+		ret = par->spi->master->setup(par->spi);
+		if (ret) {
+			dev_warn(&par->spi->dev,
+				"9-bit SPI not available, emulating using 8-bit.\n");
+			par->spi->bits_per_word = 8;
+			ret = par->spi->master->setup(par->spi);
+			if (ret)
+				goto out_release;
+			/* allocate buffer with room for dc bits */
+			par->extra = devm_kzalloc(par->info->device,
+				par->txbuf.len + (par->txbuf.len / 8) + 8,
+				GFP_KERNEL);
+			if (!par->extra) {
+				ret = -ENOMEM;
+				goto out_release;
+			}
+			par->fbtftops.write = fbtft_write_spi_emulate_9;
+		}
+	}
+
+	if (!par->fbtftops.verify_gpios)
+		par->fbtftops.verify_gpios = fbtft_verify_gpios;
+
+	/* make sure we still use the driver provided functions */
+	fbtft_merge_fbtftops(&par->fbtftops, &display->fbtftops);
+
+	/* use init_sequence if provided */
+	if (par->init_sequence)
+		par->fbtftops.init_display = fbtft_init_display;
+
+	/* use platform_data provided functions above all */
+	fbtft_merge_fbtftops(&par->fbtftops, &pdata->display.fbtftops);
+
+	ret = fbtft_register_framebuffer(info);
+	if (ret < 0)
+		goto out_release;
+
+	return 0;
+
+out_release:
+	fbtft_framebuffer_release(info);
+
+	return ret;
+}
+EXPORT_SYMBOL(fbtft_probe_common);
+
+/**
+ * fbtft_remove_common() - Generic device remove() helper function
+ * @dev: Device
+ * @info: Framebuffer
+ *
+ * Unregisters and releases the framebuffer
+ *
+ * Return: 0 if successful, negative if error
+ */
+int fbtft_remove_common(struct device *dev, struct fb_info *info)
+{
+	struct fbtft_par *par;
+
+	if (!info)
+		return -EINVAL;
+	par = info->par;
+	if (par)
+		fbtft_par_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, par,
+			"%s()\n", __func__);
+	fbtft_unregister_framebuffer(info);
+	fbtft_framebuffer_release(info);
+
+	return 0;
+}
+EXPORT_SYMBOL(fbtft_remove_common);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/fbtft-io.c b/drivers/staging/fbtft/fbtft-io.c
new file mode 100644
index 000000000000..32155a7b2a62
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft-io.c
@@ -0,0 +1,239 @@
+#include <linux/export.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include "fbtft.h"
+
+int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len)
+{
+	struct spi_transfer t = {
+		.tx_buf = buf,
+		.len = len,
+	};
+	struct spi_message m;
+
+	fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
+		"%s(len=%d): ", __func__, len);
+
+	if (!par->spi) {
+		dev_err(par->info->device,
+			"%s: par->spi is unexpectedly NULL\n", __func__);
+		return -1;
+	}
+
+	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);
+}
+EXPORT_SYMBOL(fbtft_write_spi);
+
+/**
+ * fbtft_write_spi_emulate_9() - write SPI emulating 9-bit
+ * @par: Driver data
+ * @buf: Buffer to write
+ * @len: Length of buffer (must be divisible by 8)
+ *
+ * When 9-bit SPI is not available, this function can be used to emulate that.
+ * par->extra must hold a transformation buffer used for transfer.
+ */
+int fbtft_write_spi_emulate_9(struct fbtft_par *par, void *buf, size_t len)
+{
+	u16 *src = buf;
+	u8 *dst = par->extra;
+	size_t size = len / 2;
+	size_t added = 0;
+	int bits, i, j;
+	u64 val, dc, tmp;
+
+	fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
+		"%s(len=%d): ", __func__, len);
+
+	if (!par->extra) {
+		dev_err(par->info->device, "%s: error: par->extra is NULL\n",
+			__func__);
+		return -EINVAL;
+	}
+	if ((len % 8) != 0) {
+		dev_err(par->info->device,
+			"%s: error: len=%d must be divisible by 8\n",
+			__func__, len);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < size; i += 8) {
+		tmp = 0;
+		bits = 63;
+		for (j = 0; j < 7; j++) {
+			dc = (*src & 0x0100) ? 1 : 0;
+			val = *src & 0x00FF;
+			tmp |= dc << bits;
+			bits -= 8;
+			tmp |= val << bits--;
+			src++;
+		}
+		tmp |= ((*src & 0x0100) ? 1 : 0);
+		*(u64 *)dst = cpu_to_be64(tmp);
+		dst += 8;
+		*dst++ = (u8)(*src++ & 0x00FF);
+		added++;
+	}
+
+	return spi_write(par->spi, par->extra, size + added);
+}
+EXPORT_SYMBOL(fbtft_write_spi_emulate_9);
+
+int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len)
+{
+	int ret;
+	u8 txbuf[32] = { 0, };
+	struct spi_transfer	t = {
+			.speed_hz = 2000000,
+			.rx_buf		= buf,
+			.len		= len,
+		};
+	struct spi_message	m;
+
+	if (!par->spi) {
+		dev_err(par->info->device,
+			"%s: par->spi is unexpectedly NULL\n", __func__);
+		return -ENODEV;
+	}
+
+	if (par->startbyte) {
+		if (len > 32) {
+			dev_err(par->info->device,
+				"%s: len=%d can't be larger than 32 when using 'startbyte'\n",
+				__func__, len);
+			return -EINVAL;
+		}
+		txbuf[0] = par->startbyte | 0x3;
+		t.tx_buf = txbuf;
+		fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8,
+			txbuf, len, "%s(len=%d) txbuf => ", __func__, len);
+	}
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+	ret = spi_sync(par->spi, &m);
+	fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8, buf, len,
+		"%s(len=%d) buf <= ", __func__, len);
+
+	return ret;
+}
+EXPORT_SYMBOL(fbtft_read_spi);
+
+/*
+ * Optimized use of gpiolib is twice as fast as no optimization
+ * only one driver can use the optimized version at a time
+ */
+int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len)
+{
+	u8 data;
+	int i;
+#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+	static u8 prev_data;
+#endif
+
+	fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
+		"%s(len=%d): ", __func__, len);
+
+	while (len--) {
+		data = *(u8 *) buf;
+
+		/* Start writing by pulling down /WR */
+		gpio_set_value(par->gpio.wr, 0);
+
+		/* Set data */
+#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+		if (data == prev_data) {
+			gpio_set_value(par->gpio.wr, 0); /* used as delay */
+		} else {
+			for (i = 0; i < 8; i++) {
+				if ((data & 1) != (prev_data & 1))
+					gpio_set_value(par->gpio.db[i],
+								(data & 1));
+				data >>= 1;
+				prev_data >>= 1;
+			}
+		}
+#else
+		for (i = 0; i < 8; i++) {
+			gpio_set_value(par->gpio.db[i], (data & 1));
+			data >>= 1;
+		}
+#endif
+
+		/* Pullup /WR */
+		gpio_set_value(par->gpio.wr, 1);
+
+#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+		prev_data = *(u8 *) buf;
+#endif
+		buf++;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(fbtft_write_gpio8_wr);
+
+int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len)
+{
+	u16 data;
+	int i;
+#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+	static u16 prev_data;
+#endif
+
+	fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
+		"%s(len=%d): ", __func__, len);
+
+	while (len) {
+		data = *(u16 *) buf;
+
+		/* Start writing by pulling down /WR */
+		gpio_set_value(par->gpio.wr, 0);
+
+		/* Set data */
+#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+		if (data == prev_data) {
+			gpio_set_value(par->gpio.wr, 0); /* used as delay */
+		} else {
+			for (i = 0; i < 16; i++) {
+				if ((data & 1) != (prev_data & 1))
+					gpio_set_value(par->gpio.db[i],
+								(data & 1));
+				data >>= 1;
+				prev_data >>= 1;
+			}
+		}
+#else
+		for (i = 0; i < 16; i++) {
+			gpio_set_value(par->gpio.db[i], (data & 1));
+			data >>= 1;
+		}
+#endif
+
+		/* Pullup /WR */
+		gpio_set_value(par->gpio.wr, 1);
+
+#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+		prev_data = *(u16 *) buf;
+#endif
+		buf += 2;
+		len -= 2;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(fbtft_write_gpio16_wr);
+
+int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len)
+{
+	dev_err(par->info->device, "%s: function not implemented\n", __func__);
+	return -1;
+}
+EXPORT_SYMBOL(fbtft_write_gpio16_wr_latched);
diff --git a/drivers/staging/fbtft/fbtft-sysfs.c b/drivers/staging/fbtft/fbtft-sysfs.c
new file mode 100644
index 000000000000..45f8de3d11ad
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft-sysfs.c
@@ -0,0 +1,222 @@
+#include "fbtft.h"
+
+
+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;
+
+	p_val = strsep(str_p, sep);
+
+	if (!p_val)
+		return -EINVAL;
+
+	ret = kstrtoul(p_val, base, val);
+	if (ret)
+		return -EINVAL;
+
+	return 0;
+}
+
+int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves,
+						const char *str, int size)
+{
+	char *str_p, *curve_p = NULL;
+	char *tmp;
+	unsigned long val = 0;
+	int ret = 0;
+	int curve_counter, value_counter;
+
+	fbtft_par_dbg(DEBUG_SYSFS, par, "%s() str=\n", __func__);
+
+	if (!str || !curves)
+		return -EINVAL;
+
+	fbtft_par_dbg(DEBUG_SYSFS, par, "%s\n", str);
+
+	tmp = kmalloc(size+1, GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+	memcpy(tmp, str, size+1);
+
+	/* replace optional separators */
+	str_p = tmp;
+	while (*str_p) {
+		if (*str_p == ',')
+			*str_p = ' ';
+		if (*str_p == ';')
+			*str_p = '\n';
+		str_p++;
+	}
+
+	str_p = strim(tmp);
+
+	curve_counter = 0;
+	while (str_p) {
+		if (curve_counter == par->gamma.num_curves) {
+			dev_err(par->info->device, "Gamma: Too many curves\n");
+			ret = -EINVAL;
+			goto out;
+		}
+		curve_p = strsep(&str_p, "\n");
+		value_counter = 0;
+		while (curve_p) {
+			if (value_counter == par->gamma.num_values) {
+				dev_err(par->info->device,
+					"Gamma: Too many values\n");
+				ret = -EINVAL;
+				goto out;
+			}
+			ret = get_next_ulong(&curve_p, &val, " ", 16);
+			if (ret)
+				goto out;
+			curves[curve_counter * par->gamma.num_values + value_counter] = val;
+			value_counter++;
+		}
+		if (value_counter != par->gamma.num_values) {
+			dev_err(par->info->device, "Gamma: Too few values\n");
+			ret = -EINVAL;
+			goto out;
+		}
+		curve_counter++;
+	}
+	if (curve_counter != par->gamma.num_curves) {
+		dev_err(par->info->device, "Gamma: Too few curves\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+out:
+	kfree(tmp);
+	return ret;
+}
+
+static ssize_t
+sprintf_gamma(struct fbtft_par *par, unsigned long *curves, char *buf)
+{
+	ssize_t len = 0;
+	unsigned int i, j;
+
+	mutex_lock(&par->gamma.lock);
+	for (i = 0; i < par->gamma.num_curves; i++) {
+		for (j = 0; j < par->gamma.num_values; j++)
+			len += scnprintf(&buf[len], PAGE_SIZE,
+				"%04lx ", curves[i*par->gamma.num_values + j]);
+		buf[len-1] = '\n';
+	}
+	mutex_unlock(&par->gamma.lock);
+
+	return len;
+}
+
+static ssize_t store_gamma_curve(struct device *device,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct fbtft_par *par = fb_info->par;
+	unsigned long tmp_curves[FBTFT_GAMMA_MAX_VALUES_TOTAL];
+	int ret;
+
+	ret = fbtft_gamma_parse_str(par, tmp_curves, buf, count);
+	if (ret)
+		return ret;
+
+	ret = par->fbtftops.set_gamma(par, tmp_curves);
+	if (ret)
+		return ret;
+
+	mutex_lock(&par->gamma.lock);
+	memcpy(par->gamma.curves, tmp_curves,
+		par->gamma.num_curves * par->gamma.num_values * sizeof(tmp_curves[0]));
+	mutex_unlock(&par->gamma.lock);
+
+	return count;
+}
+
+static ssize_t show_gamma_curve(struct device *device,
+				struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct fbtft_par *par = fb_info->par;
+
+	return sprintf_gamma(par, par->gamma.curves, buf);
+}
+
+static struct device_attribute gamma_device_attrs[] = {
+	__ATTR(gamma, 0660, show_gamma_curve, store_gamma_curve),
+};
+
+
+void fbtft_expand_debug_value(unsigned long *debug)
+{
+	switch (*debug & 0b111) {
+	case 1:
+		*debug |= DEBUG_LEVEL_1;
+		break;
+	case 2:
+		*debug |= DEBUG_LEVEL_2;
+		break;
+	case 3:
+		*debug |= DEBUG_LEVEL_3;
+		break;
+	case 4:
+		*debug |= DEBUG_LEVEL_4;
+		break;
+	case 5:
+		*debug |= DEBUG_LEVEL_5;
+		break;
+	case 6:
+		*debug |= DEBUG_LEVEL_6;
+		break;
+	case 7:
+		*debug = 0xFFFFFFFF;
+		break;
+	}
+}
+
+static ssize_t store_debug(struct device *device,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct fbtft_par *par = fb_info->par;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &par->debug);
+	if (ret)
+		return ret;
+	fbtft_expand_debug_value(&par->debug);
+
+	return count;
+}
+
+static ssize_t show_debug(struct device *device,
+				struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fb_info = dev_get_drvdata(device);
+	struct fbtft_par *par = fb_info->par;
+
+	return snprintf(buf, PAGE_SIZE, "%lu\n", par->debug);
+}
+
+static struct device_attribute debug_device_attr = \
+	__ATTR(debug, 0660, show_debug, store_debug);
+
+
+void fbtft_sysfs_init(struct fbtft_par *par)
+{
+	device_create_file(par->info->dev, &debug_device_attr);
+	if (par->gamma.curves && par->fbtftops.set_gamma)
+		device_create_file(par->info->dev, &gamma_device_attrs[0]);
+}
+
+void fbtft_sysfs_exit(struct fbtft_par *par)
+{
+	device_remove_file(par->info->dev, &debug_device_attr);
+	if (par->gamma.curves && par->fbtftops.set_gamma)
+		device_remove_file(par->info->dev, &gamma_device_attrs[0]);
+}
diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h
new file mode 100644
index 000000000000..0dbf3f95fe78
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft.h
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LINUX_FBTFT_H
+#define __LINUX_FBTFT_H
+
+#include <linux/fb.h>
+#include <linux/spinlock.h>
+#include <linux/spi/spi.h>
+#include <linux/platform_device.h>
+
+
+#define FBTFT_NOP		0x00
+#define FBTFT_SWRESET	0x01
+#define FBTFT_RDDID		0x04
+#define FBTFT_RDDST		0x09
+#define FBTFT_CASET		0x2A
+#define FBTFT_RASET		0x2B
+#define FBTFT_RAMWR		0x2C
+
+#define FBTFT_ONBOARD_BACKLIGHT 2
+
+#define FBTFT_GPIO_NO_MATCH		0xFFFF
+#define FBTFT_GPIO_NAME_SIZE	32
+#define FBTFT_MAX_INIT_SEQUENCE      512
+#define FBTFT_GAMMA_MAX_VALUES_TOTAL 128
+
+#define FBTFT_OF_INIT_CMD	BIT(24)
+#define FBTFT_OF_INIT_DELAY	BIT(25)
+
+/**
+ * struct fbtft_gpio - Structure that holds one pinname to gpio mapping
+ * @name: pinname (reset, dc, etc.)
+ * @gpio: GPIO number
+ *
+ */
+struct fbtft_gpio {
+	char name[FBTFT_GPIO_NAME_SIZE];
+	unsigned gpio;
+};
+
+struct fbtft_par;
+
+/**
+ * struct fbtft_ops - FBTFT operations structure
+ * @write: Writes to interface bus
+ * @read: Reads from interface bus
+ * @write_vmem: Writes video memory to display
+ * @write_reg: Writes to controller register
+ * @set_addr_win: Set the GRAM update window
+ * @reset: Reset the LCD controller
+ * @mkdirty: Marks display lines for update
+ * @update_display: Updates the display
+ * @init_display: Initializes the display
+ * @blank: Blank the display (optional)
+ * @request_gpios_match: Do pinname to gpio matching
+ * @request_gpios: Request gpios from the kernel
+ * @free_gpios: Free previously requested gpios
+ * @verify_gpios: Verify that necessary gpios is present (optional)
+ * @register_backlight: Used to register backlight device (optional)
+ * @unregister_backlight: Unregister backlight device (optional)
+ * @set_var: Configure LCD with values from variables like @rotate and @bgr
+ *           (optional)
+ * @set_gamma: Set Gamma curve (optional)
+ *
+ * Most of these operations have default functions assigned to them in
+ *     fbtft_framebuffer_alloc()
+ */
+struct fbtft_ops {
+	int (*write)(struct fbtft_par *par, void *buf, size_t len);
+	int (*read)(struct fbtft_par *par, void *buf, size_t len);
+	int (*write_vmem)(struct fbtft_par *par, size_t offset, size_t len);
+	void (*write_register)(struct fbtft_par *par, int len, ...);
+
+	void (*set_addr_win)(struct fbtft_par *par,
+		int xs, int ys, int xe, int ye);
+	void (*reset)(struct fbtft_par *par);
+	void (*mkdirty)(struct fb_info *info, int from, int to);
+	void (*update_display)(struct fbtft_par *par,
+				unsigned start_line, unsigned end_line);
+	int (*init_display)(struct fbtft_par *par);
+	int (*blank)(struct fbtft_par *par, bool on);
+
+	unsigned long (*request_gpios_match)(struct fbtft_par *par,
+		const struct fbtft_gpio *gpio);
+	int (*request_gpios)(struct fbtft_par *par);
+	int (*verify_gpios)(struct fbtft_par *par);
+
+	void (*register_backlight)(struct fbtft_par *par);
+	void (*unregister_backlight)(struct fbtft_par *par);
+
+	int (*set_var)(struct fbtft_par *par);
+	int (*set_gamma)(struct fbtft_par *par, unsigned long *curves);
+};
+
+/**
+ * struct fbtft_display - Describes the display properties
+ * @width: Width of display in pixels
+ * @height: Height of display in pixels
+ * @regwidth: LCD Controller Register width in bits
+ * @buswidth: Display interface bus width in bits
+ * @backlight: Backlight type.
+ * @fbtftops: FBTFT operations provided by driver or device (platform_data)
+ * @bpp: Bits per pixel
+ * @fps: Frames per second
+ * @txbuflen: Size of transmit buffer
+ * @init_sequence: Pointer to LCD initialization array
+ * @gamma: String representation of Gamma curve(s)
+ * @gamma_num: Number of Gamma curves
+ * @gamma_len: Number of values per Gamma curve
+ * @debug: Initial debug value
+ *
+ * This structure is not stored by FBTFT except for init_sequence.
+ */
+struct fbtft_display {
+	unsigned width;
+	unsigned height;
+	unsigned regwidth;
+	unsigned buswidth;
+	unsigned backlight;
+	struct fbtft_ops fbtftops;
+	unsigned bpp;
+	unsigned fps;
+	int txbuflen;
+	int *init_sequence;
+	char *gamma;
+	int gamma_num;
+	int gamma_len;
+	unsigned long debug;
+};
+
+/**
+ * struct fbtft_platform_data - Passes display specific data to the driver
+ * @display: Display properties
+ * @gpios: Pointer to an array of piname to gpio mappings
+ * @rotate: Display rotation angle
+ * @bgr: LCD Controller BGR bit
+ * @fps: Frames per second (this will go away, use @fps in @fbtft_display)
+ * @txbuflen: Size of transmit buffer
+ * @startbyte: When set, enables use of Startbyte in transfers
+ * @gamma: String representation of Gamma curve(s)
+ * @extra: A way to pass extra info
+ */
+struct fbtft_platform_data {
+	struct fbtft_display display;
+	const struct fbtft_gpio *gpios;
+	unsigned rotate;
+	bool bgr;
+	unsigned fps;
+	int txbuflen;
+	u8 startbyte;
+	char *gamma;
+	void *extra;
+};
+
+/**
+ * struct fbtft_par - Main FBTFT data structure
+ *
+ * This structure holds all relevant data to operate the display
+ *
+ * See sourcefile for documentation since nested structs is not
+ * supported by kernel-doc.
+ *
+ */
+/* @spi: Set if it is a SPI device
+ * @pdev: Set if it is a platform device
+ * @info: Pointer to framebuffer fb_info structure
+ * @pdata: Pointer to platform data
+ * @ssbuf: Not used
+ * @pseudo_palette: Used by fb_set_colreg()
+ * @txbuf.buf: Transmit buffer
+ * @txbuf.len: Transmit buffer length
+ * @buf: Small buffer used when writing init data over SPI
+ * @startbyte: Used by some controllers when in SPI mode.
+ *             Format: 6 bit Device id + RS bit + RW bit
+ * @fbtftops: FBTFT operations provided by driver or device (platform_data)
+ * @dirty_lock: Protects dirty_lines_start and dirty_lines_end
+ * @dirty_lines_start: Where to begin updating display
+ * @dirty_lines_end: Where to end updating display
+ * @gpio.reset: GPIO used to reset display
+ * @gpio.dc: Data/Command signal, also known as RS
+ * @gpio.rd: Read latching signal
+ * @gpio.wr: Write latching signal
+ * @gpio.latch: Bus latch signal, eg. 16->8 bit bus latch
+ * @gpio.cs: LCD Chip Select with parallel interface bus
+ * @gpio.db[16]: Parallel databus
+ * @gpio.led[16]: Led control signals
+ * @gpio.aux[16]: Auxillary signals, not used by core
+ * @init_sequence: Pointer to LCD initialization array
+ * @gamma.lock: Mutex for Gamma curve locking
+ * @gamma.curves: Pointer to Gamma curve array
+ * @gamma.num_values: Number of values per Gamma curve
+ * @gamma.num_curves: Number of Gamma curves
+ * @debug: Pointer to debug value
+ * @current_debug:
+ * @first_update_done: Used to only time the first display update
+ * @update_time: Used to calculate 'fps' in debug output
+ * @bgr: BGR mode/\n
+ * @extra: Extra info needed by driver
+ */
+struct fbtft_par {
+	struct spi_device *spi;
+	struct platform_device *pdev;
+	struct fb_info *info;
+	struct fbtft_platform_data *pdata;
+	u16 *ssbuf;
+	u32 pseudo_palette[16];
+	struct {
+		void *buf;
+		dma_addr_t dma;
+		size_t len;
+	} txbuf;
+	u8 *buf;
+	u8 startbyte;
+	struct fbtft_ops fbtftops;
+	spinlock_t dirty_lock;
+	unsigned dirty_lines_start;
+	unsigned dirty_lines_end;
+	struct {
+		int reset;
+		int dc;
+		int rd;
+		int wr;
+		int latch;
+		int cs;
+		int db[16];
+		int led[16];
+		int aux[16];
+	} gpio;
+	int *init_sequence;
+	struct {
+		struct mutex lock;
+		unsigned long *curves;
+		int num_values;
+		int num_curves;
+	} gamma;
+	unsigned long debug;
+	bool first_update_done;
+	struct timespec update_time;
+	bool bgr;
+	void *extra;
+};
+
+#define NUMARGS(...)  (sizeof((int[]){__VA_ARGS__})/sizeof(int))
+
+#define write_reg(par, ...)                                              \
+do {                                                                     \
+	par->fbtftops.write_register(par, NUMARGS(__VA_ARGS__), __VA_ARGS__); \
+} while (0)
+
+/* fbtft-core.c */
+extern void fbtft_dbg_hex(const struct device *dev,
+	int groupsize, void *buf, size_t len, const char *fmt, ...);
+extern struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
+	struct device *dev);
+extern void fbtft_framebuffer_release(struct fb_info *info);
+extern int fbtft_register_framebuffer(struct fb_info *fb_info);
+extern int fbtft_unregister_framebuffer(struct fb_info *fb_info);
+extern void fbtft_register_backlight(struct fbtft_par *par);
+extern void fbtft_unregister_backlight(struct fbtft_par *par);
+extern int fbtft_init_display(struct fbtft_par *par);
+extern int fbtft_probe_common(struct fbtft_display *display,
+	struct spi_device *sdev, struct platform_device *pdev);
+extern int fbtft_remove_common(struct device *dev, struct fb_info *info);
+
+/* fbtft-io.c */
+extern int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len);
+extern int fbtft_write_spi_emulate_9(struct fbtft_par *par,
+	void *buf, size_t len);
+extern int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len);
+extern int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len);
+extern int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len);
+extern int fbtft_write_gpio16_wr_latched(struct fbtft_par *par,
+	void *buf, size_t len);
+
+/* fbtft-bus.c */
+extern int fbtft_write_vmem8_bus8(struct fbtft_par *par, size_t offset, size_t len);
+extern int fbtft_write_vmem16_bus16(struct fbtft_par *par, size_t offset, size_t len);
+extern int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len);
+extern int fbtft_write_vmem16_bus9(struct fbtft_par *par, size_t offset, size_t len);
+extern void fbtft_write_reg8_bus8(struct fbtft_par *par, int len, ...);
+extern void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...);
+extern void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...);
+extern void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...);
+
+
+#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display)                \
+									   \
+static int fbtft_driver_probe_spi(struct spi_device *spi)                  \
+{                                                                          \
+	return fbtft_probe_common(_display, spi, NULL);                    \
+}                                                                          \
+									   \
+static int fbtft_driver_remove_spi(struct spi_device *spi)                 \
+{                                                                          \
+	struct fb_info *info = spi_get_drvdata(spi);                       \
+									   \
+	return fbtft_remove_common(&spi->dev, info);                       \
+}                                                                          \
+									   \
+static int fbtft_driver_probe_pdev(struct platform_device *pdev)           \
+{                                                                          \
+	return fbtft_probe_common(_display, NULL, pdev);                   \
+}                                                                          \
+									   \
+static int fbtft_driver_remove_pdev(struct platform_device *pdev)          \
+{                                                                          \
+	struct fb_info *info = platform_get_drvdata(pdev);                 \
+									   \
+	return fbtft_remove_common(&pdev->dev, info);                      \
+}                                                                          \
+									   \
+static const struct of_device_id dt_ids[] = {                              \
+        { .compatible = _compatible },                                     \
+        {},                                                                \
+};                                                                         \
+									   \
+MODULE_DEVICE_TABLE(of, dt_ids);                                           \
+									   \
+									   \
+static struct spi_driver fbtft_driver_spi_driver = {                       \
+	.driver = {                                                        \
+		.name   = _name,                                           \
+		.owner  = THIS_MODULE,                                     \
+                .of_match_table = of_match_ptr(dt_ids),                    \
+	},                                                                 \
+	.probe  = fbtft_driver_probe_spi,                                  \
+	.remove = fbtft_driver_remove_spi,                                 \
+};                                                                         \
+									   \
+static struct platform_driver fbtft_driver_platform_driver = {             \
+	.driver = {                                                        \
+		.name   = _name,                                           \
+		.owner  = THIS_MODULE,                                     \
+                .of_match_table = of_match_ptr(dt_ids),                    \
+	},                                                                 \
+	.probe  = fbtft_driver_probe_pdev,                                 \
+	.remove = fbtft_driver_remove_pdev,                                \
+};                                                                         \
+									   \
+static int __init fbtft_driver_module_init(void)                           \
+{                                                                          \
+	int ret;                                                           \
+									   \
+	ret = spi_register_driver(&fbtft_driver_spi_driver);               \
+	if (ret < 0)                                                       \
+		return ret;                                                \
+	return platform_driver_register(&fbtft_driver_platform_driver);    \
+}                                                                          \
+									   \
+static void __exit fbtft_driver_module_exit(void)                          \
+{                                                                          \
+	spi_unregister_driver(&fbtft_driver_spi_driver);                   \
+	platform_driver_unregister(&fbtft_driver_platform_driver);         \
+}                                                                          \
+									   \
+module_init(fbtft_driver_module_init);                                     \
+module_exit(fbtft_driver_module_exit);
+
+
+/* Debug macros */
+
+/* shorthand debug levels */
+#define DEBUG_LEVEL_1	DEBUG_REQUEST_GPIOS
+#define DEBUG_LEVEL_2	(DEBUG_LEVEL_1 | DEBUG_DRIVER_INIT_FUNCTIONS | DEBUG_TIME_FIRST_UPDATE)
+#define DEBUG_LEVEL_3	(DEBUG_LEVEL_2 | DEBUG_RESET | DEBUG_INIT_DISPLAY | DEBUG_BLANK | DEBUG_REQUEST_GPIOS | DEBUG_FREE_GPIOS | DEBUG_VERIFY_GPIOS | DEBUG_BACKLIGHT | DEBUG_SYSFS)
+#define DEBUG_LEVEL_4	(DEBUG_LEVEL_2 | DEBUG_FB_READ | DEBUG_FB_WRITE | DEBUG_FB_FILLRECT | DEBUG_FB_COPYAREA | DEBUG_FB_IMAGEBLIT | DEBUG_FB_BLANK)
+#define DEBUG_LEVEL_5	(DEBUG_LEVEL_3 | DEBUG_UPDATE_DISPLAY)
+#define DEBUG_LEVEL_6	(DEBUG_LEVEL_4 | DEBUG_LEVEL_5)
+#define DEBUG_LEVEL_7	0xFFFFFFFF
+
+#define DEBUG_DRIVER_INIT_FUNCTIONS (1<<3)
+#define DEBUG_TIME_FIRST_UPDATE     (1<<4)
+#define DEBUG_TIME_EACH_UPDATE      (1<<5)
+#define DEBUG_DEFERRED_IO           (1<<6)
+#define DEBUG_FBTFT_INIT_FUNCTIONS  (1<<7)
+
+/* fbops */
+#define DEBUG_FB_READ               (1<<8)
+#define DEBUG_FB_WRITE              (1<<9)
+#define DEBUG_FB_FILLRECT           (1<<10)
+#define DEBUG_FB_COPYAREA           (1<<11)
+#define DEBUG_FB_IMAGEBLIT          (1<<12)
+#define DEBUG_FB_SETCOLREG          (1<<13)
+#define DEBUG_FB_BLANK              (1<<14)
+
+#define DEBUG_SYSFS                 (1<<16)
+
+/* fbtftops */
+#define DEBUG_BACKLIGHT             (1<<17)
+#define DEBUG_READ                  (1<<18)
+#define DEBUG_WRITE                 (1<<19)
+#define DEBUG_WRITE_VMEM            (1<<20)
+#define DEBUG_WRITE_REGISTER        (1<<21)
+#define DEBUG_SET_ADDR_WIN          (1<<22)
+#define DEBUG_RESET                 (1<<23)
+#define DEBUG_MKDIRTY               (1<<24)
+#define DEBUG_UPDATE_DISPLAY        (1<<25)
+#define DEBUG_INIT_DISPLAY          (1<<26)
+#define DEBUG_BLANK                 (1<<27)
+#define DEBUG_REQUEST_GPIOS         (1<<28)
+#define DEBUG_FREE_GPIOS            (1<<29)
+#define DEBUG_REQUEST_GPIOS_MATCH   (1<<30)
+#define DEBUG_VERIFY_GPIOS          (1<<31)
+
+
+#define fbtft_init_dbg(dev, format, arg...)                  \
+do {                                                         \
+	if (unlikely((dev)->platform_data &&                 \
+	    (((struct fbtft_platform_data *)(dev)->platform_data)->display.debug & DEBUG_DRIVER_INIT_FUNCTIONS))) \
+		dev_info(dev, format, ##arg);                \
+} while (0)
+
+#define fbtft_par_dbg(level, par, format, arg...)            \
+do {                                                         \
+	if (unlikely(par->debug & level))                    \
+		dev_info(par->info->device, format, ##arg);  \
+} while (0)
+
+#define fbtft_dev_dbg(level, par, dev, format, arg...)       \
+do {                                                         \
+	if (unlikely(par->debug & level))                    \
+		dev_info(dev, format, ##arg);                \
+} while (0)
+
+#define fbtft_par_dbg_hex(level, par, dev, type, buf, num, format, arg...) \
+do {                                                                       \
+	if (unlikely(par->debug & level))                                  \
+		fbtft_dbg_hex(dev, sizeof(type), buf, num * sizeof(type), format, ##arg); \
+} while (0)
+
+#endif /* __LINUX_FBTFT_H */
diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c
new file mode 100644
index 000000000000..b9f4c30e39c6
--- /dev/null
+++ b/drivers/staging/fbtft/fbtft_device.c
@@ -0,0 +1,1444 @@
+/*
+ *
+ * Copyright (C) 2013, Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+
+#include "fbtft.h"
+
+#define DRVNAME "fbtft_device"
+
+#define MAX_GPIOS 32
+
+struct spi_device *spi_device;
+struct platform_device *p_device;
+
+static char *name;
+module_param(name, charp, 0);
+MODULE_PARM_DESC(name, "Devicename (required). " \
+"name=list => list all supported devices.");
+
+static unsigned rotate;
+module_param(rotate, uint, 0);
+MODULE_PARM_DESC(rotate,
+"Angle to rotate display counter clockwise: 0, 90, 180, 270");
+
+static unsigned busnum;
+module_param(busnum, uint, 0);
+MODULE_PARM_DESC(busnum, "SPI bus number (default=0)");
+
+static unsigned cs;
+module_param(cs, uint, 0);
+MODULE_PARM_DESC(cs, "SPI chip select (default=0)");
+
+static unsigned speed;
+module_param(speed, uint, 0);
+MODULE_PARM_DESC(speed, "SPI speed (override device default)");
+
+static int mode = -1;
+module_param(mode, int, 0);
+MODULE_PARM_DESC(mode, "SPI mode (override device default)");
+
+static char *gpios;
+module_param(gpios, charp, 0);
+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 fps;
+module_param(fps, uint, 0);
+MODULE_PARM_DESC(fps, "Frames per second (override driver default)");
+
+static char *gamma;
+module_param(gamma, charp, 0);
+MODULE_PARM_DESC(gamma,
+"String representation of Gamma Curve(s). Driver specific.");
+
+static int txbuflen;
+module_param(txbuflen, int, 0);
+MODULE_PARM_DESC(txbuflen, "txbuflen (override driver default)");
+
+static int bgr = -1;
+module_param(bgr, int, 0);
+MODULE_PARM_DESC(bgr,
+"BGR bit (supported by some drivers).");
+
+static unsigned startbyte;
+module_param(startbyte, uint, 0);
+MODULE_PARM_DESC(startbyte, "Sets the Start byte used by some SPI displays.");
+
+static bool custom;
+module_param(custom, bool, 0);
+MODULE_PARM_DESC(custom, "Add a custom display device. " \
+"Use speed= argument to make it a SPI device, else platform_device");
+
+static unsigned width;
+module_param(width, uint, 0);
+MODULE_PARM_DESC(width, "Display width, used with the custom argument");
+
+static unsigned height;
+module_param(height, uint, 0);
+MODULE_PARM_DESC(height, "Display height, used with the custom argument");
+
+static unsigned buswidth = 8;
+module_param(buswidth, uint, 0);
+MODULE_PARM_DESC(buswidth, "Display bus width, used with the custom argument");
+
+static int init[FBTFT_MAX_INIT_SEQUENCE];
+static int init_num;
+module_param_array(init, int, &init_num, 0);
+MODULE_PARM_DESC(init, "Init sequence, used with the custom argument");
+
+static unsigned long debug;
+module_param(debug, ulong , 0);
+MODULE_PARM_DESC(debug,
+"level: 0-7 (the remaining 29 bits is for advanced usage)");
+
+static unsigned verbose = 3;
+module_param(verbose, uint, 0);
+MODULE_PARM_DESC(verbose,
+"0 silent, >0 show gpios, >1 show devices, >2 show devices before (default=3)");
+
+
+struct fbtft_device_display {
+	char *name;
+	struct spi_board_info *spi;
+	struct platform_device *pdev;
+};
+
+static void fbtft_device_pdev_release(struct device *dev);
+
+static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len);
+static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
+	int xs, int ys, int xe, int ye);
+
+#define ADAFRUIT18_GAMMA \
+		"02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
+		"03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
+
+static int hy28b_init_sequence[] = {
+	-1,0x00e7,0x0010,-1,0x0000,0x0001,-1,0x0001,0x0100,-1,0x0002,0x0700,
+	-1,0x0003,0x1030,-1,0x0004,0x0000,-1,0x0008,0x0207,-1,0x0009,0x0000,
+	-1,0x000a,0x0000,-1,0x000c,0x0001,-1,0x000d,0x0000,-1,0x000f,0x0000,
+	-1,0x0010,0x0000,-1,0x0011,0x0007,-1,0x0012,0x0000,-1,0x0013,0x0000,
+	-2,50,-1,0x0010,0x1590,-1,0x0011,0x0227,-2,50,-1,0x0012,0x009c,-2,50,
+	-1,0x0013,0x1900,-1,0x0029,0x0023,-1,0x002b,0x000e,-2,50,
+	-1,0x0020,0x0000,-1,0x0021,0x0000,-2,50,-1,0x0050,0x0000,
+	-1,0x0051,0x00ef,-1,0x0052,0x0000,-1,0x0053,0x013f,-1,0x0060,0xa700,
+	-1,0x0061,0x0001,-1,0x006a,0x0000,-1,0x0080,0x0000,-1,0x0081,0x0000,
+	-1,0x0082,0x0000,-1,0x0083,0x0000,-1,0x0084,0x0000,-1,0x0085,0x0000,
+	-1,0x0090,0x0010,-1,0x0092,0x0000,-1,0x0093,0x0003,-1,0x0095,0x0110,
+	-1,0x0097,0x0000,-1,0x0098,0x0000,-1,0x0007,0x0133,-1,0x0020,0x0000,
+	-1,0x0021,0x0000,-2,100,-3 };
+
+#define HY28B_GAMMA \
+	"04 1F 4 7 7 0 7 7 6 0\n" \
+	"0F 00 1 7 4 0 0 0 6 7"
+
+static int pitft_init_sequence[] = {
+	-1,0x01,-2,5,-1,0x28,-1,0xEF,0x03,0x80,0x02,-1,0xCF,0x00,0xC1,0x30,
+	-1,0xED,0x64,0x03,0x12,0x81,-1,0xE8,0x85,0x00,0x78,
+	-1,0xCB,0x39,0x2C,0x00,0x34,0x02,-1,0xF7,0x20,-1,0xEA,0x00,0x00,
+	-1,0xC0,0x23,-1,0xC1,0x10,-1,0xC5,0x3e,0x28,-1,0xC7,0x86,-1,0x3A,0x55,
+	-1,0xB1,0x00,0x18,-1,0xB6,0x08,0x82,0x27,-1,0xF2,0x00,-1,0x26,0x01,
+	-1,0xE0,0x0F,0x31,0x2B,0x0C,0x0E,0x08,0x4E,0xF1,0x37,0x07,0x10,0x03,
+	0x0E,0x09,0x00,-1,0xE1,0x00,0x0E,0x14,0x03,0x11,0x07,0x31,0xC1,0x48,
+	0x08,0x0F,0x0C,0x31,0x36,0x0F,-1,0x11,-2,100,-1,0x29,-2,20,-3 };
+
+static int waveshare32b_init_sequence[] = {
+	-1,0xCB,0x39,0x2C,0x00,0x34,0x02,-1,0xCF,0x00,0xC1,0x30,
+	-1,0xE8,0x85,0x00,0x78,-1,0xEA,0x00,0x00,-1,0xED,0x64,0x03,0x12,0x81,
+	-1,0xF7,0x20,-1,0xC0,0x23,-1,0xC1,0x10,-1,0xC5,0x3e,0x28,-1,0xC7,0x86,
+	-1,0x36,0x28,-1,0x3A,0x55,-1,0xB1,0x00,0x18,-1,0xB6,0x08,0x82,0x27,
+	-1,0xF2,0x00,-1,0x26,0x01,
+	-1,0xE0,0x0F,0x31,0x2B,0x0C,0x0E,0x08,0x4E,0xF1,0x37,0x07,0x10,0x03,0x0E,0x09,0x00,
+	-1,0xE1,0x00,0x0E,0x14,0x03,0x11,0x07,0x31,0xC1,0x48,0x08,0x0F,0x0C,0x31,0x36,0x0F,
+	-1,0x11,-2,120,-1,0x29,-1,0x2c,-3 };
+
+/* Supported displays in alphabetical order */
+static struct fbtft_device_display displays[] = {
+	{
+		.name = "adafruit18",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_st7735r",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 18 },
+					{},
+				},
+				.gamma = ADAFRUIT18_GAMMA,
+			}
+		}
+	}, {
+		.name = "adafruit18_green",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_st7735r",
+			.max_speed_hz = 4000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+					.fbtftops.set_addr_win = \
+					    adafruit18_green_tab_set_addr_win,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 18 },
+					{},
+				},
+				.gamma = ADAFRUIT18_GAMMA,
+			}
+		}
+	}, {
+		.name = "adafruit22",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_hx8340bn",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 9,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "led", 23 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "adafruit22a",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9340",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "adafruit28",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9341",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "adafruit13m",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ssd1306",
+			.max_speed_hz = 16000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "agm1264k-fl",
+		.pdev = &(struct platform_device) {
+			.name = "fb_agm1264k-fl",
+			.id = 0,
+			.dev = {
+			.release = fbtft_device_pdev_release,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = FBTFT_ONBOARD_BACKLIGHT,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{},
+				},
+			},
+			}
+		}
+	}, {
+		.name = "dogs102",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_uc1701",
+			.max_speed_hz = 8000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 13 },
+					{ "dc", 6 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "er_tftm050_2",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ra8875",
+			.max_speed_hz = 5000000,
+			.mode = SPI_MODE_3,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+					.width = 480,
+					.height = 272,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "er_tftm070_5",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ra8875",
+			.max_speed_hz = 5000000,
+			.mode = SPI_MODE_3,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+					.width = 800,
+					.height = 480,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "flexfb",
+		.spi = &(struct spi_board_info) {
+			.modalias = "flexfb",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "flexpfb",
+		.pdev = &(struct platform_device) {
+			.name = "flexpfb",
+			.id = 0,
+			.dev = {
+			.release = fbtft_device_pdev_release,
+			.platform_data = &(struct fbtft_platform_data) {
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 17 },
+					{ "dc", 1 },
+					{ "wr", 0 },
+					{ "cs", 21 },
+					{ "db00", 9 },
+					{ "db01", 11 },
+					{ "db02", 18 },
+					{ "db03", 23 },
+					{ "db04", 24 },
+					{ "db05", 25 },
+					{ "db06", 8 },
+					{ "db07", 7 },
+					{ "led", 4 },
+					{},
+				},
+			},
+			}
+		}
+	}, {
+		.name = "freetronicsoled128",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ssd1351",
+			.max_speed_hz = 20000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = FBTFT_ONBOARD_BACKLIGHT,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 24 },
+					{ "dc", 25 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "hx8353d",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_hx8353d",
+			.max_speed_hz = 16000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 23 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "hy28a",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9320",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_3,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.startbyte = 0b01110000,
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "led", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "hy28b",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9325",
+			.max_speed_hz = 48000000,
+			.mode = SPI_MODE_3,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+					.init_sequence = hy28b_init_sequence,
+				},
+				.startbyte = 0b01110000,
+				.bgr = true,
+				.fps= 50,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "led", 18 },
+					{},
+				},
+				.gamma = HY28B_GAMMA,
+			}
+		}
+	}, {
+		.name = "ili9481",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9481",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.regwidth = 16,
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 22 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "itdb24",
+		.pdev = &(struct platform_device) {
+			.name = "fb_s6d1121",
+			.id = 0,
+			.dev = {
+			.release = fbtft_device_pdev_release,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = false,
+				.gpios = (const struct fbtft_gpio []) {
+					/* Wiring for LCD adapter kit */
+					{ "reset", 7 },
+					{ "dc", 0 }, 	/* rev 2: 2 */
+					{ "wr", 1 }, 	/* rev 2: 3 */
+					{ "cs", 8 },
+					{ "db00", 17 },
+					{ "db01", 18 },
+					{ "db02", 21 }, /* rev 2: 27 */
+					{ "db03", 22 },
+					{ "db04", 23 },
+					{ "db05", 24 },
+					{ "db06", 25 },
+					{ "db07", 4 },
+					{}
+				},
+			},
+			}
+		}
+	}, {
+		.name = "itdb28",
+		.pdev = &(struct platform_device) {
+			.name = "fb_ili9325",
+			.id = 0,
+			.dev = {
+			.release = fbtft_device_pdev_release,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{},
+				},
+			},
+			}
+		}
+	}, {
+		.name = "itdb28_spi",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9325",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "mi0283qt-2",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_hx8347d",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.startbyte = 0b01110000,
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "mi0283qt-9a",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9341",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 9,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "led", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "mi0283qt-v2",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_watterott",
+			.max_speed_hz = 4000000,
+			.mode = SPI_MODE_3,
+			.platform_data = &(struct fbtft_platform_data) {
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "nokia3310",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_pcd8544",
+			.max_speed_hz = 400000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 23 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "nokia3310a",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_tls8204",
+			.max_speed_hz = 1000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 23 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "piscreen",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9486",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.regwidth = 16,
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 22 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "pitft",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9340",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.chip_select = 0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+					.init_sequence = pitft_init_sequence,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "dc", 25 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "pioled",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ssd1351",
+			.max_speed_hz = 20000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 24 },
+					{ "dc", 25 },
+					{},
+				},
+				.gamma =	"0 2 2 2 2 2 2 2 " \
+						"2 2 2 2 2 2 2 2 " \
+						"2 2 2 2 2 2 2 2 " \
+						"2 2 2 2 2 2 2 3 " \
+						"3 3 3 3 3 3 3 3 " \
+						"3 3 3 3 3 3 3 3 " \
+						"3 3 3 4 4 4 4 4 " \
+						"4 4 4 4 4 4 4"
+			}
+		}
+	}, {
+		.name = "rpi-display",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9341",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 23 },
+					{ "dc", 24 },
+					{ "led", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "s6d02a1",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_s6d02a1",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 23 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "sainsmart18",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_st7735r",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "sainsmart32",
+		.pdev = &(struct platform_device) {
+			.name = "fb_ssd1289",
+			.id = 0,
+			.dev = {
+			.release = fbtft_device_pdev_release,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 16,
+					.txbuflen = -2, /* disable buffer */
+					.backlight = 1,
+					.fbtftops.write = write_gpio16_wr_slow,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{},
+				},
+			},
+		},
+		}
+	}, {
+		.name = "sainsmart32_fast",
+		.pdev = &(struct platform_device) {
+			.name = "fb_ssd1289",
+			.id = 0,
+			.dev = {
+			.release = fbtft_device_pdev_release,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 16,
+					.txbuflen = -2, /* disable buffer */
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{},
+				},
+			},
+		},
+		}
+	}, {
+		.name = "sainsmart32_latched",
+		.pdev = &(struct platform_device) {
+			.name = "fb_ssd1289",
+			.id = 0,
+			.dev = {
+			.release = fbtft_device_pdev_release,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 16,
+					.txbuflen = -2, /* disable buffer */
+					.backlight = 1,
+					.fbtftops.write = \
+						fbtft_write_gpio16_wr_latched,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{},
+				},
+			},
+		},
+		}
+	}, {
+		.name = "sainsmart32_spi",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ssd1289",
+			.max_speed_hz = 16000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "spidev",
+		.spi = &(struct spi_board_info) {
+			.modalias = "spidev",
+			.max_speed_hz = 500000,
+			.bus_num = 0,
+			.chip_select = 0,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.gpios = (const struct fbtft_gpio []) {
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "ssd1331",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ssd1331",
+			.max_speed_hz = 20000000,
+			.mode = SPI_MODE_3,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 24 },
+					{ "dc", 25 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "tinylcd35",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_tinylcd",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "tm022hdh26",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9341",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 25 },
+					{ "dc", 24 },
+					{ "led", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "tontec35_9481", /* boards before 02 July 2014 */
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9481",
+			.max_speed_hz = 128000000,
+			.mode = SPI_MODE_3,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 15 },
+					{ "dc", 25 },
+					{ "led_", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "tontec35_9486", /* boards after 02 July 2014 */
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9486",
+			.max_speed_hz = 128000000,
+			.mode = SPI_MODE_3,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 15 },
+					{ "dc", 25 },
+					{ "led_", 18 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "upd161704",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_upd161704",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 24 },
+					{ "dc", 25 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "waveshare32b",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_ili9340",
+			.max_speed_hz = 48000000,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+					.backlight = 1,
+					.init_sequence = waveshare32b_init_sequence,
+				},
+				.bgr = true,
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 27 },
+					{ "dc", 22 },
+					{},
+				},
+			}
+		}
+	}, {
+		.name = "waveshare22",
+		.spi = &(struct spi_board_info) {
+			.modalias = "fb_bd663474",
+			.max_speed_hz = 32000000,
+			.mode = SPI_MODE_3,
+			.platform_data = &(struct fbtft_platform_data) {
+				.display = {
+					.buswidth = 8,
+				},
+				.gpios = (const struct fbtft_gpio []) {
+					{ "reset", 24 },
+					{ "dc", 25 },
+					{},
+				},
+			}
+		}
+	}, {
+		/* This should be the last item.
+		   Used with the custom argument */
+		.name = "",
+		.spi = &(struct spi_board_info) {
+			.modalias = "",
+			.max_speed_hz = 0,
+			.mode = SPI_MODE_0,
+			.platform_data = &(struct fbtft_platform_data) {
+				.gpios = (const struct fbtft_gpio []) {
+					{},
+				},
+			}
+		},
+		.pdev = &(struct platform_device) {
+			.name = "",
+			.id = 0,
+			.dev = {
+			.release = fbtft_device_pdev_release,
+			.platform_data = &(struct fbtft_platform_data) {
+				.gpios = (const struct fbtft_gpio []) {
+					{},
+				},
+			},
+		},
+		},
+	}
+};
+
+static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len)
+{
+	u16 data;
+	int i;
+#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+	static u16 prev_data;
+#endif
+
+	fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
+		"%s(len=%d): ", __func__, len);
+
+	while (len) {
+		data = *(u16 *) buf;
+
+		/* Start writing by pulling down /WR */
+		gpio_set_value(par->gpio.wr, 0);
+
+		/* Set data */
+#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+		if (data == prev_data) {
+			gpio_set_value(par->gpio.wr, 0); /* used as delay */
+		} else {
+			for (i = 0; i < 16; i++) {
+				if ((data & 1) != (prev_data & 1))
+					gpio_set_value(par->gpio.db[i],
+								(data & 1));
+				data >>= 1;
+				prev_data >>= 1;
+			}
+		}
+#else
+		for (i = 0; i < 16; i++) {
+			gpio_set_value(par->gpio.db[i], (data & 1));
+			data >>= 1;
+		}
+#endif
+
+		/* Pullup /WR */
+		gpio_set_value(par->gpio.wr, 1);
+
+#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
+		prev_data = *(u16 *) buf;
+#endif
+		buf += 2;
+		len -= 2;
+	}
+
+	return 0;
+}
+
+static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
+						int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par,
+		"%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+	write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
+	write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
+	write_reg(par, 0x2C);
+}
+
+/* used if gpios parameter is present */
+static struct fbtft_gpio fbtft_device_param_gpios[MAX_GPIOS+1] = { };
+
+static void fbtft_device_pdev_release(struct device *dev)
+{
+/* Needed to silence this message:
+Device 'xxx' does not have a release() function, it is broken and must be fixed
+*/
+}
+
+static int spi_device_found(struct device *dev, void *data)
+{
+	struct spi_device *spi = container_of(dev, struct spi_device, dev);
+
+	pr_info(DRVNAME":      %s %s %dkHz %d bits mode=0x%02X\n",
+		spi->modalias, dev_name(dev), spi->max_speed_hz/1000,
+		spi->bits_per_word, spi->mode);
+
+	return 0;
+}
+
+static void pr_spi_devices(void)
+{
+	pr_info(DRVNAME":  SPI devices registered:\n");
+	bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found);
+}
+
+static int p_device_found(struct device *dev, void *data)
+{
+	struct platform_device
+	*pdev = container_of(dev, struct platform_device, dev);
+
+	if (strstr(pdev->name, "fb"))
+		pr_info(DRVNAME":      %s id=%d pdata? %s\n",
+				pdev->name, pdev->id,
+				pdev->dev.platform_data ? "yes" : "no");
+
+	return 0;
+}
+
+static void pr_p_devices(void)
+{
+	pr_info(DRVNAME":  'fb' Platform devices registered:\n");
+	bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found);
+}
+
+#ifdef MODULE
+static void fbtft_device_spi_delete(struct spi_master *master, unsigned cs)
+{
+	struct device *dev;
+	char str[32];
+
+	snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), cs);
+
+	dev = bus_find_device_by_name(&spi_bus_type, NULL, str);
+	if (dev) {
+		if (verbose)
+			pr_info(DRVNAME": Deleting %s\n", str);
+		device_del(dev);
+	}
+}
+
+static int fbtft_device_spi_device_register(struct spi_board_info *spi)
+{
+	struct spi_master *master;
+
+	master = spi_busnum_to_master(spi->bus_num);
+	if (!master) {
+		pr_err(DRVNAME ":  spi_busnum_to_master(%d) returned NULL\n",
+								spi->bus_num);
+		return -EINVAL;
+	}
+	/* make sure it's available */
+	fbtft_device_spi_delete(master, spi->chip_select);
+	spi_device = spi_new_device(master, spi);
+	put_device(&master->dev);
+	if (!spi_device) {
+		pr_err(DRVNAME ":    spi_new_device() returned NULL\n");
+		return -EPERM;
+	}
+	return 0;
+}
+#else
+static int fbtft_device_spi_device_register(struct spi_board_info *spi)
+{
+	return spi_register_board_info(spi, 1);
+}
+#endif
+
+static int __init fbtft_device_init(void)
+{
+	struct spi_board_info *spi = NULL;
+	struct fbtft_platform_data *pdata;
+	const struct fbtft_gpio *gpio = NULL;
+	char *p_gpio, *p_name, *p_num;
+	bool found = false;
+	int i = 0;
+	long val;
+	int ret = 0;
+
+	pr_debug("\n\n"DRVNAME": init\n");
+
+	if (name == NULL) {
+#ifdef MODULE
+		pr_err(DRVNAME":  missing module parameter: 'name'\n");
+		return -EINVAL;
+#else
+		return 0;
+#endif
+	}
+
+	if (init_num > FBTFT_MAX_INIT_SEQUENCE) {
+		pr_err(DRVNAME \
+			":  init parameter: exceeded max array size: %d\n",
+			FBTFT_MAX_INIT_SEQUENCE);
+		return -EINVAL;
+	}
+
+	/* parse module parameter: gpios */
+	while ((p_gpio = strsep(&gpios, ","))) {
+		if (strchr(p_gpio, ':') == NULL) {
+			pr_err(DRVNAME \
+				":  error: missing ':' in gpios parameter: %s\n",
+				p_gpio);
+			return -EINVAL;
+		}
+		p_num = p_gpio;
+		p_name = strsep(&p_num, ":");
+		if (p_name == NULL || p_num == NULL) {
+			pr_err(DRVNAME \
+				":  something bad happened parsing gpios parameter: %s\n",
+				p_gpio);
+			return -EINVAL;
+		}
+		ret = kstrtol(p_num, 10, &val);
+		if (ret) {
+			pr_err(DRVNAME \
+				":  could not parse number in gpios parameter: %s:%s\n",
+				p_name, p_num);
+			return -EINVAL;
+		}
+		strcpy(fbtft_device_param_gpios[i].name, p_name);
+		fbtft_device_param_gpios[i++].gpio = (int) val;
+		if (i == MAX_GPIOS) {
+			pr_err(DRVNAME \
+				":  gpios parameter: exceeded max array size: %d\n",
+				MAX_GPIOS);
+			return -EINVAL;
+		}
+	}
+	if (fbtft_device_param_gpios[0].name[0])
+		gpio = fbtft_device_param_gpios;
+
+	if (verbose > 2)
+		pr_spi_devices(); /* print list of registered SPI devices */
+
+	if (verbose > 2)
+		pr_p_devices(); /* print list of 'fb' platform devices */
+
+	pr_debug(DRVNAME":  name='%s', busnum=%d, cs=%d\n", name, busnum, cs);
+
+	if (rotate > 0 && rotate < 4) {
+		rotate = (4 - rotate) * 90;
+		pr_warn("argument 'rotate' should be an angle. Values 1-3 is deprecated. Setting it to %d.\n",
+			rotate);
+	}
+	if (rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
+		pr_warn("argument 'rotate' illegal value: %d. Setting it to 0.\n",
+			rotate);
+		rotate = 0;
+	}
+
+	/* name=list lists all supported displays */
+	if (strncmp(name, "list", 32) == 0) {
+		pr_info(DRVNAME":  Supported displays:\n");
+
+		for (i = 0; i < ARRAY_SIZE(displays); i++)
+			pr_info(DRVNAME":      %s\n", displays[i].name);
+		return -ECANCELED;
+	}
+
+	if (custom) {
+		i = ARRAY_SIZE(displays) - 1;
+		displays[i].name = name;
+		if (speed == 0) {
+			displays[i].pdev->name = name;
+			displays[i].spi = NULL;
+		} else {
+			strncpy(displays[i].spi->modalias, name, SPI_NAME_SIZE);
+			displays[i].pdev = NULL;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(displays); i++) {
+		if (strncmp(name, displays[i].name, 32) == 0) {
+			if (displays[i].spi) {
+				spi = displays[i].spi;
+				spi->chip_select = cs;
+				spi->bus_num = busnum;
+				if (speed)
+					spi->max_speed_hz = speed;
+				if (mode != -1)
+					spi->mode = mode;
+				pdata = (void *)spi->platform_data;
+			} else if (displays[i].pdev) {
+				p_device = displays[i].pdev;
+				pdata = p_device->dev.platform_data;
+			} else {
+				pr_err(DRVNAME": broken displays array\n");
+				return -EINVAL;
+			}
+
+			pdata->rotate = rotate;
+			if (bgr == 0)
+				pdata->bgr = false;
+			else if (bgr == 1)
+				pdata->bgr = true;
+			if (startbyte)
+				pdata->startbyte = startbyte;
+			if (gamma)
+				pdata->gamma = gamma;
+			pdata->display.debug = debug;
+			if (fps)
+				pdata->fps = fps;
+			if (txbuflen)
+				pdata->txbuflen = txbuflen;
+			if (init_num)
+				pdata->display.init_sequence = init;
+			if (gpio)
+				pdata->gpios = gpio;
+			if (custom) {
+				pdata->display.width = width;
+				pdata->display.height = height;
+				pdata->display.buswidth = buswidth;
+				pdata->display.backlight = 1;
+			}
+
+			if (displays[i].spi) {
+				ret = fbtft_device_spi_device_register(spi);
+				if (ret) {
+					pr_err(DRVNAME \
+						": failed to register SPI device\n");
+					return ret;
+				}
+				found = true;
+				break;
+			} else {
+				ret = platform_device_register(p_device);
+				if (ret < 0) {
+					pr_err(DRVNAME \
+						":    platform_device_register() returned %d\n",
+						ret);
+					return ret;
+				}
+				found = true;
+				break;
+			}
+		}
+	}
+
+	if (!found) {
+		pr_err(DRVNAME":  display not supported: '%s'\n", name);
+		return -EINVAL;
+	}
+
+	if (verbose && pdata && pdata->gpios) {
+		gpio = pdata->gpios;
+		pr_info(DRVNAME":  GPIOS used by '%s':\n", name);
+		found = false;
+		while (verbose && gpio->name[0]) {
+			pr_info(DRVNAME":    '%s' = GPIO%d\n",
+				gpio->name, gpio->gpio);
+			gpio++;
+			found = true;
+		}
+		if (!found)
+			pr_info(DRVNAME":    (none)\n");
+	}
+
+	if (spi_device && (verbose > 1))
+		pr_spi_devices();
+	if (p_device && (verbose > 1))
+		pr_p_devices();
+
+	return 0;
+}
+
+static void __exit fbtft_device_exit(void)
+{
+	pr_debug(DRVNAME" - exit\n");
+
+	if (spi_device) {
+		device_del(&spi_device->dev);
+		kfree(spi_device);
+	}
+
+	if (p_device)
+		platform_device_unregister(p_device);
+
+}
+
+arch_initcall(fbtft_device_init);
+module_exit(fbtft_device_exit);
+
+MODULE_DESCRIPTION("Add a FBTFT device.");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c
new file mode 100644
index 000000000000..90832c36e557
--- /dev/null
+++ b/drivers/staging/fbtft/flexfb.c
@@ -0,0 +1,592 @@
+/*
+ * Generic FB driver for TFT LCD displays
+ *
+ * Copyright (C) 2013 Noralf Tronnes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+
+#include "fbtft.h"
+
+#define DRVNAME	    "flexfb"
+
+
+static char *chip;
+module_param(chip, charp, 0);
+MODULE_PARM_DESC(chip, "LCD controller");
+
+static unsigned int width;
+module_param(width, uint, 0);
+MODULE_PARM_DESC(width, "Display width");
+
+static unsigned int height;
+module_param(height, uint, 0);
+MODULE_PARM_DESC(height, "Display height");
+
+static int init[512];
+static int init_num;
+module_param_array(init, int, &init_num, 0);
+MODULE_PARM_DESC(init, "Init sequence");
+
+static unsigned int setaddrwin;
+module_param(setaddrwin, uint, 0);
+MODULE_PARM_DESC(setaddrwin, "Which set_addr_win() implementation to use");
+
+static unsigned int buswidth = 8;
+module_param(buswidth, uint, 0);
+MODULE_PARM_DESC(buswidth, "Width of databus (default: 8)");
+
+static unsigned int regwidth = 8;
+module_param(regwidth, uint, 0);
+MODULE_PARM_DESC(regwidth, "Width of controller register (default: 8)");
+
+static bool nobacklight;
+module_param(nobacklight, bool, 0);
+MODULE_PARM_DESC(nobacklight, "Turn off backlight functionality.");
+
+static bool latched;
+module_param(latched, bool, 0);
+MODULE_PARM_DESC(latched, "Use with latched 16-bit databus");
+
+
+static int *initp;
+static int initp_num;
+
+/* default init sequences */
+static int st7735r_init[] = { \
+-1,0x01,-2,150,-1,0x11,-2,500,-1,0xB1,0x01,0x2C,0x2D,-1,0xB2,0x01,0x2C,0x2D,-1,0xB3,0x01,0x2C,0x2D,0x01,0x2C,0x2D, \
+-1,0xB4,0x07,-1,0xC0,0xA2,0x02,0x84,-1,0xC1,0xC5,-1,0xC2,0x0A,0x00,-1,0xC3,0x8A,0x2A,-1,0xC4,0x8A,0xEE,-1,0xC5,0x0E, \
+-1,0x20,-1,0x36,0xC0,-1,0x3A,0x05,-1,0xE0,0x0f,0x1a,0x0f,0x18,0x2f,0x28,0x20,0x22,0x1f,0x1b,0x23,0x37,0x00,0x07,0x02,0x10, \
+-1,0xE1,0x0f,0x1b,0x0f,0x17,0x33,0x2c,0x29,0x2e,0x30,0x30,0x39,0x3f,0x00,0x07,0x03,0x10,-1,0x29,-2,100,-1,0x13,-2,10,-3 };
+
+static int ssd1289_init[] = { \
+-1,0x00,0x0001,-1,0x03,0xA8A4,-1,0x0C,0x0000,-1,0x0D,0x080C,-1,0x0E,0x2B00,-1,0x1E,0x00B7,-1,0x01,0x2B3F,-1,0x02,0x0600, \
+-1,0x10,0x0000,-1,0x11,0x6070,-1,0x05,0x0000,-1,0x06,0x0000,-1,0x16,0xEF1C,-1,0x17,0x0003,-1,0x07,0x0233,-1,0x0B,0x0000, \
+-1,0x0F,0x0000,-1,0x41,0x0000,-1,0x42,0x0000,-1,0x48,0x0000,-1,0x49,0x013F,-1,0x4A,0x0000,-1,0x4B,0x0000,-1,0x44,0xEF00, \
+-1,0x45,0x0000,-1,0x46,0x013F,-1,0x30,0x0707,-1,0x31,0x0204,-1,0x32,0x0204,-1,0x33,0x0502,-1,0x34,0x0507,-1,0x35,0x0204, \
+-1,0x36,0x0204,-1,0x37,0x0502,-1,0x3A,0x0302,-1,0x3B,0x0302,-1,0x23,0x0000,-1,0x24,0x0000,-1,0x25,0x8000,-1,0x4f,0x0000, \
+-1,0x4e,0x0000,-1,0x22,-3 };
+
+static int hx8340bn_init[] = { \
+-1,0xC1,0xFF,0x83,0x40,-1,0x11,-2,150,-1,0xCA,0x70,0x00,0xD9,-1,0xB0,0x01,0x11, \
+-1,0xC9,0x90,0x49,0x10,0x28,0x28,0x10,0x00,0x06,-2,20,-1,0xC2,0x60,0x71,0x01,0x0E,0x05,0x02,0x09,0x31,0x0A, \
+-1,0xC3,0x67,0x30,0x61,0x17,0x48,0x07,0x05,0x33,-2,10,-1,0xB5,0x35,0x20,0x45,-1,0xB4,0x33,0x25,0x4C,-2,10, \
+-1,0x3A,0x05,-1,0x29,-2,10,-3 };
+
+static int ili9225_init[] = { \
+-1,0x0001,0x011C,-1,0x0002,0x0100,-1,0x0003,0x1030,-1,0x0008,0x0808,-1,0x000C,0x0000,-1,0x000F,0x0A01,-1,0x0020,0x0000, \
+-1,0x0021,0x0000,-2,50,-1,0x0010,0x0A00,-1,0x0011,0x1038,-2,50,-1,0x0012,0x1121,-1,0x0013,0x004E,-1,0x0014,0x676F, \
+-1,0x0030,0x0000,-1,0x0031,0x00DB,-1,0x0032,0x0000,-1,0x0033,0x0000,-1,0x0034,0x00DB,-1,0x0035,0x0000,-1,0x0036,0x00AF, \
+-1,0x0037,0x0000,-1,0x0038,0x00DB,-1,0x0039,0x0000,-1,0x0050,0x0000,-1,0x0051,0x060A,-1,0x0052,0x0D0A,-1,0x0053,0x0303, \
+-1,0x0054,0x0A0D,-1,0x0055,0x0A06,-1,0x0056,0x0000,-1,0x0057,0x0303,-1,0x0058,0x0000,-1,0x0059,0x0000,-2,50, \
+-1,0x0007,0x1017,-2,50,-3 };
+
+static int ili9320_init[] = { \
+-1,0x00E5,0x8000,-1,0x0000,0x0001,-1,0x0001,0x0100,-1,0x0002,0x0700,-1,0x0003,0x1030,-1,0x0004,0x0000,-1,0x0008,0x0202, \
+-1,0x0009,0x0000,-1,0x000A,0x0000,-1,0x000C,0x0000,-1,0x000D,0x0000,-1,0x000F,0x0000,-1,0x0010,0x0000,-1,0x0011,0x0007, \
+-1,0x0012,0x0000,-1,0x0013,0x0000,-2,200,-1,0x0010,0x17B0,-1,0x0011,0x0031,-2,50,-1,0x0012,0x0138,-2,50,-1,0x0013,0x1800, \
+-1,0x0029,0x0008,-2,50,-1,0x0020,0x0000,-1,0x0021,0x0000,-1,0x0030,0x0000,-1,0x0031,0x0505,-1,0x0032,0x0004, \
+-1,0x0035,0x0006,-1,0x0036,0x0707,-1,0x0037,0x0105,-1,0x0038,0x0002,-1,0x0039,0x0707,-1,0x003C,0x0704,-1,0x003D,0x0807, \
+-1,0x0050,0x0000,-1,0x0051,0x00EF,-1,0x0052,0x0000,-1,0x0053,0x013F,-1,0x0060,0x2700,-1,0x0061,0x0001,-1,0x006A,0x0000, \
+-1,0x0080,0x0000,-1,0x0081,0x0000,-1,0x0082,0x0000,-1,0x0083,0x0000,-1,0x0084,0x0000,-1,0x0085,0x0000,-1,0x0090,0x0010, \
+-1,0x0092,0x0000,-1,0x0093,0x0003,-1,0x0095,0x0110,-1,0x0097,0x0000,-1,0x0098,0x0000,-1,0x0007,0x0173,-3 };
+
+static int ili9325_init[] = { \
+-1,0x00E3,0x3008,-1,0x00E7,0x0012,-1,0x00EF,0x1231,-1,0x0001,0x0100,-1,0x0002,0x0700,-1,0x0003,0x1030,-1,0x0004,0x0000, \
+-1,0x0008,0x0207,-1,0x0009,0x0000,-1,0x000A,0x0000,-1,0x000C,0x0000,-1,0x000D,0x0000,-1,0x000F,0x0000,-1,0x0010,0x0000, \
+-1,0x0011,0x0007,-1,0x0012,0x0000,-1,0x0013,0x0000,-2,200,-1,0x0010,0x1690,-1,0x0011,0x0223,-2,50,-1,0x0012,0x000D,-2,50, \
+-1,0x0013,0x1200,-1,0x0029,0x000A,-1,0x002B,0x000C,-2,50,-1,0x0020,0x0000,-1,0x0021,0x0000,-1,0x0030,0x0000, \
+-1,0x0031,0x0506,-1,0x0032,0x0104,-1,0x0035,0x0207,-1,0x0036,0x000F,-1,0x0037,0x0306,-1,0x0038,0x0102,-1,0x0039,0x0707, \
+-1,0x003C,0x0702,-1,0x003D,0x1604,-1,0x0050,0x0000,-1,0x0051,0x00EF,-1,0x0052,0x0000,-1,0x0053,0x013F,-1,0x0060,0xA700, \
+-1,0x0061,0x0001,-1,0x006A,0x0000,-1,0x0080,0x0000,-1,0x0081,0x0000,-1,0x0082,0x0000,-1,0x0083,0x0000,-1,0x0084,0x0000, \
+-1,0x0085,0x0000,-1,0x0090,0x0010,-1,0x0092,0x0600,-1,0x0007,0x0133,-3 };
+
+static int ili9341_init[] = { \
+-1,0x28,-2,20,-1,0xCF,0x00,0x83,0x30,-1,0xED,0x64,0x03,0x12,0x81,-1,0xE8,0x85,0x01,0x79, \
+-1,0xCB,0x39,0x2c,0x00,0x34,0x02,-1,0xF7,0x20,-1,0xEA,0x00,0x00,-1,0xC0,0x26,-1,0xC1,0x11, \
+-1,0xC5,0x35,0x3E,-1,0xC7,0xBE,-1,0xB1,0x00,0x1B,-1,0xB6,0x0a,0x82,0x27,0x00,-1,0xB7,0x07, \
+-1,0x3A,0x55,-1,0x36,0x48,-1,0x11,-2,120,-1,0x29,-2,20,-3 };
+
+static int ssd1351_init[] = { -1,0xfd,0x12,-1,0xfd,0xb1,-1,0xae,-1,0xb3,0xf1,-1,0xca,0x7f,-1,0xa0,0x74, \
+                              -1,0x15,0x00,0x7f,-1,0x75,0x00,0x7f,-1,0xa1,0x00,-1,0xa2,0x00,-1,0xb5,0x00, \
+                              -1,0xab,0x01,-1,0xb1,0x32,-1,0xb4,0xa0,0xb5,0x55,-1,0xbb,0x17,-1,0xbe,0x05, \
+                              -1,0xc1,0xc8,0x80,0xc8,-1,0xc7,0x0f,-1,0xb6,0x01,-1,0xa6,-1,0xaf,-3 };
+
+
+/* ili9320, ili9325 */
+static void flexfb_set_addr_win_1(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+	switch (par->info->var.rotate) {
+	/* R20h = Horizontal GRAM Start Address */
+	/* R21h = Vertical GRAM Start Address */
+	case 0:
+		write_reg(par, 0x0020, xs);
+		write_reg(par, 0x0021, ys);
+		break;
+	case 180:
+		write_reg(par, 0x0020, width - 1 - xs);
+		write_reg(par, 0x0021, height - 1 - ys);
+		break;
+	case 270:
+		write_reg(par, 0x0020, width - 1 - ys);
+		write_reg(par, 0x0021, xs);
+		break;
+	case 90:
+		write_reg(par, 0x0020, ys);
+		write_reg(par, 0x0021, height - 1 - xs);
+		break;
+	}
+	write_reg(par, 0x0022); /* Write Data to GRAM */
+}
+
+/* ssd1289 */
+static void flexfb_set_addr_win_2(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	switch (par->info->var.rotate) {
+	/* R4Eh - Set GDDRAM X address counter */
+	/* R4Fh - Set GDDRAM Y address counter */
+	case 0:
+		write_reg(par, 0x4e, xs);
+		write_reg(par, 0x4f, ys);
+		break;
+	case 180:
+		write_reg(par, 0x4e, par->info->var.xres - 1 - xs);
+		write_reg(par, 0x4f, par->info->var.yres - 1 - ys);
+		break;
+	case 270:
+		write_reg(par, 0x4e, par->info->var.yres - 1 - ys);
+		write_reg(par, 0x4f, xs);
+		break;
+	case 90:
+		write_reg(par, 0x4e, ys);
+		write_reg(par, 0x4f, par->info->var.xres - 1 - xs);
+		break;
+	}
+
+	/* R22h - RAM data write */
+	write_reg(par, 0x22, 0);
+}
+
+/* ssd1351 */
+static void set_addr_win_3(struct fbtft_par *par, int xs, int ys, int xe, int ye)
+{
+	fbtft_par_dbg(DEBUG_SET_ADDR_WIN, par, "%s(xs=%d, ys=%d, xe=%d, ye=%d)\n", __func__, xs, ys, xe, ye);
+
+	write_reg(par, 0x15, xs, xe);
+	write_reg(par, 0x75, ys, ye);
+	write_reg(par, 0x5C);
+}
+
+static int flexfb_verify_gpios_dc(struct fbtft_par *par)
+{
+	fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__);
+
+	if (par->gpio.dc < 0) {
+		dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int flexfb_verify_gpios_db(struct fbtft_par *par)
+{
+	int i;
+	int num_db = buswidth;
+
+	fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__);
+
+	if (par->gpio.dc < 0) {
+		dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+	if (par->gpio.wr < 0) {
+		dev_err(par->info->device, "Missing info about 'wr' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+	if (latched && (par->gpio.latch < 0)) {
+		dev_err(par->info->device, "Missing info about 'latch' gpio. Aborting.\n");
+		return -EINVAL;
+	}
+	if (latched)
+		num_db=buswidth/2;
+	for (i=0;i < num_db;i++) {
+		if (par->gpio.db[i] < 0) {
+			dev_err(par->info->device, "Missing info about 'db%02d' gpio. Aborting.\n", i);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static struct fbtft_display flex_display = { };
+
+static int flexfb_probe_common(struct spi_device *sdev, struct platform_device *pdev)
+{
+	struct device *dev;
+	struct fb_info *info;
+	struct fbtft_par *par;
+	int ret;
+
+	initp = init;
+	initp_num = init_num;
+
+	if (sdev)
+		dev = &sdev->dev;
+	else
+		dev = &pdev->dev;
+
+	fbtft_init_dbg(dev, "%s(%s)\n", __func__, sdev ? "'SPI device'" : "'Platform device'");
+
+	if (chip) {
+
+		if (!strcmp(chip, "st7735r")) {
+			if (!width)
+				width = 128;
+			if (!height)
+				height = 160;
+			if (init_num == 0) {
+				initp = st7735r_init;
+				initp_num = ARRAY_SIZE(st7735r_init);
+			}
+
+
+		} else if (!strcmp(chip, "hx8340bn")) {
+			if (!width)
+				width = 176;
+			if (!height)
+				height = 220;
+			setaddrwin = 0;
+			if (init_num == 0) {
+				initp = hx8340bn_init;
+				initp_num = ARRAY_SIZE(hx8340bn_init);
+			}
+
+
+		} else if (!strcmp(chip, "ili9225")) {
+			if (!width)
+				width = 176;
+			if (!height)
+				height = 220;
+			setaddrwin = 0;
+			regwidth = 16;
+			if (init_num == 0) {
+				initp = ili9225_init;
+				initp_num = ARRAY_SIZE(ili9225_init);
+			}
+
+
+
+		} else if (!strcmp(chip, "ili9320")) {
+			if (!width)
+				width = 240;
+			if (!height)
+				height = 320;
+			setaddrwin = 1;
+			regwidth = 16;
+			if (init_num == 0) {
+				initp = ili9320_init;
+				initp_num = ARRAY_SIZE(ili9320_init);
+			}
+
+
+		} else if (!strcmp(chip, "ili9325")) {
+			if (!width)
+				width = 240;
+			if (!height)
+				height = 320;
+			setaddrwin = 1;
+			regwidth = 16;
+			if (init_num == 0) {
+				initp = ili9325_init;
+				initp_num = ARRAY_SIZE(ili9325_init);
+			}
+
+		} else if (!strcmp(chip, "ili9341")) {
+			if (!width)
+				width = 240;
+			if (!height)
+				height = 320;
+			setaddrwin = 0;
+			regwidth = 8;
+			if (init_num == 0) {
+				initp = ili9341_init;
+				initp_num = ARRAY_SIZE(ili9341_init);
+			}
+
+
+		} else if (!strcmp(chip, "ssd1289")) {
+			if (!width)
+				width = 240;
+			if (!height)
+				height = 320;
+			setaddrwin = 2;
+			regwidth = 16;
+			if (init_num == 0) {
+				initp = ssd1289_init;
+				initp_num = ARRAY_SIZE(ssd1289_init);
+			}
+
+
+
+		} else if (!strcmp(chip, "ssd1351")) {
+			if (!width)
+				width = 128;
+			if (!height)
+				height = 128;
+			setaddrwin = 3;
+			if (init_num == 0) {
+				initp = ssd1351_init;
+				initp_num = ARRAY_SIZE(ssd1351_init);
+			}
+		} else {
+			dev_err(dev, "chip=%s is not supported\n", chip);
+			return -EINVAL;
+		}
+	}
+
+	if (width == 0 || height == 0) {
+		dev_err(dev, "argument(s) missing: width and height has to be set.\n");
+		return -EINVAL;
+	}
+	flex_display.width = width;
+	flex_display.height = height;
+	fbtft_init_dbg(dev, "Display resolution: %dx%d\n", width, height);
+	fbtft_init_dbg(dev, "chip = %s\n", chip ? chip : "not set");
+	fbtft_init_dbg(dev, "setaddrwin = %d\n", setaddrwin);
+	fbtft_init_dbg(dev, "regwidth = %d\n", regwidth);
+	fbtft_init_dbg(dev, "buswidth = %d\n", buswidth);
+
+	info = fbtft_framebuffer_alloc(&flex_display, dev);
+	if (!info)
+		return -ENOMEM;
+
+	par = info->par;
+	if (sdev)
+		par->spi = sdev;
+	else
+		par->pdev = pdev;
+	if (!par->init_sequence)
+		par->init_sequence = initp;
+	par->fbtftops.init_display = fbtft_init_display;
+
+	/* registerwrite functions */
+	switch (regwidth) {
+	case 8:
+		par->fbtftops.write_register = fbtft_write_reg8_bus8;
+		break;
+	case 16:
+		par->fbtftops.write_register = fbtft_write_reg16_bus8;
+		break;
+	default:
+		dev_err(dev, "argument 'regwidth': %d is not supported.\n", regwidth);
+		return -EINVAL;
+	}
+
+	/* bus functions */
+	if (sdev) {
+		par->fbtftops.write = fbtft_write_spi;
+		switch (buswidth) {
+		case 8:
+			par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
+			if (!par->startbyte)
+				par->fbtftops.verify_gpios = flexfb_verify_gpios_dc;
+			break;
+		case 9:
+			if (regwidth == 16) {
+				dev_err(dev, "argument 'regwidth': %d is not supported with buswidth=%d and SPI.\n", regwidth, buswidth);
+				return -EINVAL;
+			}
+			par->fbtftops.write_register = fbtft_write_reg8_bus9;
+			par->fbtftops.write_vmem = fbtft_write_vmem16_bus9;
+			sdev->bits_per_word=9;
+			ret = sdev->master->setup(sdev);
+			if (ret) {
+				dev_warn(dev,
+					"9-bit SPI not available, emulating using 8-bit.\n");
+				sdev->bits_per_word = 8;
+				ret = sdev->master->setup(sdev);
+				if (ret)
+					goto out_release;
+				/* allocate buffer with room for dc bits */
+				par->extra = devm_kzalloc(par->info->device,
+						par->txbuf.len + (par->txbuf.len / 8) + 8,
+						GFP_KERNEL);
+				if (!par->extra) {
+					ret = -ENOMEM;
+					goto out_release;
+				}
+				par->fbtftops.write = fbtft_write_spi_emulate_9;
+			}
+			break;
+		default:
+			dev_err(dev, "argument 'buswidth': %d is not supported with SPI.\n", buswidth);
+			return -EINVAL;
+		}
+	} else {
+		par->fbtftops.verify_gpios = flexfb_verify_gpios_db;
+		switch (buswidth) {
+		case 8:
+			par->fbtftops.write = fbtft_write_gpio8_wr;
+			par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
+			break;
+		case 16:
+			par->fbtftops.write_register = fbtft_write_reg16_bus16;
+			if (latched)
+				par->fbtftops.write = fbtft_write_gpio16_wr_latched;
+			else
+				par->fbtftops.write = fbtft_write_gpio16_wr;
+			par->fbtftops.write_vmem = fbtft_write_vmem16_bus16;
+			break;
+		default:
+			dev_err(dev, "argument 'buswidth': %d is not supported with parallel.\n", buswidth);
+			return -EINVAL;
+		}
+	}
+
+	/* set_addr_win function */
+	switch (setaddrwin) {
+	case 0:
+		/* use default */
+		break;
+	case 1:
+		par->fbtftops.set_addr_win = flexfb_set_addr_win_1;
+		break;
+	case 2:
+		par->fbtftops.set_addr_win = flexfb_set_addr_win_2;
+		break;
+	case 3:
+		par->fbtftops.set_addr_win = set_addr_win_3;
+		break;
+	default:
+		dev_err(dev, "argument 'setaddrwin': unknown value %d.\n", setaddrwin);
+		return -EINVAL;
+	}
+
+	if (!nobacklight)
+		par->fbtftops.register_backlight = fbtft_register_backlight;
+
+	ret = fbtft_register_framebuffer(info);
+	if (ret < 0)
+		goto out_release;
+
+	return 0;
+
+out_release:
+	fbtft_framebuffer_release(info);
+
+	return ret;
+}
+
+static int flexfb_remove_common(struct device *dev, struct fb_info *info)
+{
+	struct fbtft_par *par;
+
+	if (!info)
+		return -EINVAL;
+	par = info->par;
+	if (par)
+		fbtft_par_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, par,
+			"%s()\n", __func__);
+	fbtft_unregister_framebuffer(info);
+	fbtft_framebuffer_release(info);
+
+	return 0;
+}
+
+static int flexfb_probe_spi(struct spi_device *spi)
+{
+	return flexfb_probe_common(spi, NULL);
+}
+
+static int flexfb_remove_spi(struct spi_device *spi)
+{
+	struct fb_info *info = spi_get_drvdata(spi);
+
+	return flexfb_remove_common(&spi->dev, info);
+}
+
+static int flexfb_probe_pdev(struct platform_device *pdev)
+{
+	return flexfb_probe_common(NULL, pdev);
+}
+
+static int flexfb_remove_pdev(struct platform_device *pdev)
+{
+	struct fb_info *info = platform_get_drvdata(pdev);
+
+	return flexfb_remove_common(&pdev->dev, info);
+}
+
+static struct spi_driver flexfb_spi_driver = {
+	.driver = {
+		.name   = DRVNAME,
+		.owner  = THIS_MODULE,
+	},
+	.probe  = flexfb_probe_spi,
+	.remove = flexfb_remove_spi,
+};
+
+static const struct platform_device_id flexfb_platform_ids[] = {
+	{ "flexpfb", 0 },
+	{ },
+};
+
+static struct platform_driver flexfb_platform_driver = {
+	.driver = {
+		.name   = DRVNAME,
+	},
+	.id_table = flexfb_platform_ids,
+	.probe  = flexfb_probe_pdev,
+	.remove = flexfb_remove_pdev,
+};
+
+static int __init flexfb_init(void)
+{
+	int ret, ret2;
+
+	ret = spi_register_driver(&flexfb_spi_driver);
+	ret2 = platform_driver_register(&flexfb_platform_driver);
+	if (ret < 0)
+		return ret;
+	return ret2;
+}
+
+static void __exit flexfb_exit(void)
+{
+	spi_unregister_driver(&flexfb_spi_driver);
+	platform_driver_unregister(&flexfb_platform_driver);
+}
+
+/* ------------------------------------------------------------------------- */
+
+module_init(flexfb_init);
+module_exit(flexfb_exit);
+
+MODULE_DESCRIPTION("Generic FB driver for TFT LCD displays");
+MODULE_AUTHOR("Noralf Tronnes");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
index d5475b7270a8..017c3b92f51b 100644
--- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c
@@ -172,11 +172,11 @@ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index)
 	spin_lock_irqsave(&info->dpram_lock, flags);
 	ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
 	/* check if we want to read upper or lower 32-bit word */
-	if (Index) {
+	if (Index)
 		data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL);
-	} else {
+	else
 		data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAH);
-	}
+
 	spin_unlock_irqrestore(&info->dpram_lock, flags);
 
 	return data;
@@ -204,11 +204,11 @@ static inline void ft1000_write_dpram_mag_16(struct net_device *dev,
 	/* Provide mutual exclusive access while reading ASIC registers. */
 	spin_lock_irqsave(&info->dpram_lock, flags);
 	ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset);
-	if (Index) {
+	if (Index)
 		ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAL, value);
-	} else {
+	else
 		ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, value);
-	}
+
 	spin_unlock_irqrestore(&info->dpram_lock, flags);
 }
 
@@ -440,9 +440,8 @@ static int ft1000_reset_card(struct net_device *dev)
 			tempword =
 				ft1000_read_dpram_mag_16(dev, FT1000_MAG_DPRAM_FEFE,
 							 FT1000_MAG_DPRAM_FEFE_INDX);
-			if (tempword == 0xfefe) {
+			if (tempword == 0xfefe)
 				break;
-			}
 			mdelay(20);
 		}
 
@@ -570,12 +569,12 @@ static void ft1000_hbchk(u_long data)
 		pr_debug("hi_ho value = 0x%x\n", tempword);
 		/* Let's perform another check if ho is not detected */
 		if (tempword != ho) {
-			if (info->AsicID == ELECTRABUZZ_ID) {
+			if (info->AsicID == ELECTRABUZZ_ID)
 				tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
-			}
-			else {
-				tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
-			}
+			else
+				tempword = ntohs(ft1000_read_dpram_mag_16(dev,
+							FT1000_MAG_HI_HO,
+							FT1000_MAG_HI_HO_INDX));
 		}
 		if (tempword != ho) {
 			pr_info("heartbeat failed - no ho detected\n");
@@ -621,9 +620,9 @@ static void ft1000_hbchk(u_long data)
 
 		tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
 		/* Let's check doorbell again if fail */
-		if (tempword & FT1000_DB_HB) {
+		if (tempword & FT1000_DB_HB)
 			tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-		}
+
 		if (tempword & FT1000_DB_HB) {
 			pr_info("heartbeat doorbell not clear by firmware\n");
 			if (info->AsicID == ELECTRABUZZ_ID) {
@@ -686,19 +685,15 @@ static void ft1000_hbchk(u_long data)
 		}
 		/* Let's write hi again if fail */
 		if (tempword != hi) {
-			if (info->AsicID == ELECTRABUZZ_ID) {
+			if (info->AsicID == ELECTRABUZZ_ID)
 				ft1000_write_dpram(dev, FT1000_HI_HO, hi);
-			}
-			else {
+			else
 				ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, hi_mag, FT1000_MAG_HI_HO_INDX);
-			}
 
-			if (info->AsicID == ELECTRABUZZ_ID) {
+			if (info->AsicID == ELECTRABUZZ_ID)
 				tempword = ft1000_read_dpram(dev, FT1000_HI_HO);
-			}
-			else {
+			else
 				tempword = ntohs(ft1000_read_dpram_mag_16(dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX));
-			}
 
 		}
 
@@ -770,9 +765,8 @@ static void ft1000_send_cmd(struct net_device *dev, u16 *ptempbuffer, int size,
 
 	size += sizeof(struct pseudo_hdr);
 	/* check for odd byte and increment to 16-bit word align value */
-	if ((size & 0x0001)) {
+	if ((size & 0x0001))
 		size++;
-	}
 	pr_debug("total length = %d\n", size);
 	pr_debug("length = %d\n", ntohs(*ptempbuffer));
 	/*
@@ -915,9 +909,8 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer,
 		 * Calculate pseudo header checksum
 		 */
 		tempword = *ppseudohdr++;
-		for (i = 1; i < 7; i++) {
+		for (i = 1; i < 7; i++)
 			tempword ^= *ppseudohdr++;
-		}
 		if ((tempword != *ppseudohdr)) {
 			pr_debug("Pseudo header checksum mismatch\n");
 			/* Drop this message */
@@ -957,12 +950,11 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
 		u16 wrd;
 	} convert;
 
-	if (info->AsicID == ELECTRABUZZ_ID) {
+	if (info->AsicID == ELECTRABUZZ_ID)
 		tempword = FT1000_DPRAM_RX_BASE+2;
-	}
-	else {
+	else
 		tempword = FT1000_DPRAM_MAG_RX_BASE;
-	}
+
 	if (ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword)) {
 
 		/* Get the message type which is total_len + PSEUDO header + msgtype + message body */
@@ -982,9 +974,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
 				while (tempword & FT1000_DB_DPRAM_TX) {
 					mdelay(5);
 					i++;
-					if (i == 10) {
+					if (i == 10)
 						break;
-					}
 				}
 				ptr =
 					list_entry(info->prov_list.next,
@@ -1039,8 +1030,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
 						info->ConTm = 0;
 					}
 				}
-			}
-			else {
+			} else {
 				pr_debug("Media is down\n");
 				if (info->mediastate == 1) {
 					info->mediastate = 0;
@@ -1105,9 +1095,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
 				mdelay(10);
 				tempword =
 					ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-				if (tempword & FT1000_DB_DPRAM_TX) {
+				if (tempword & FT1000_DB_DPRAM_TX)
 					mdelay(10);
-				}
 			}
 
 			if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
@@ -1134,9 +1123,9 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
 				ppseudo_hdr->portsrc = 0;
 				/* Calculate new checksum */
 				ppseudo_hdr->checksum = *pmsg++;
-				for (i = 1; i < 7; i++) {
+				for (i = 1; i < 7; i++)
 					ppseudo_hdr->checksum ^= *pmsg++;
-				}
+
 				info->DSPInfoBlk[8] = 0x7200;
 				info->DSPInfoBlk[9] =
 					htons(info->DSPInfoBlklen);
@@ -1156,9 +1145,8 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
 				mdelay(10);
 				tempword =
 					ft1000_read_reg(dev, FT1000_REG_DOORBELL);
-				if (tempword & FT1000_DB_DPRAM_TX) {
+				if (tempword & FT1000_DB_DPRAM_TX)
 					mdelay(10);
-				}
 			}
 
 			if ((tempword & FT1000_DB_DPRAM_TX) == 0) {
@@ -1184,9 +1172,9 @@ static void ft1000_proc_drvmsg(struct net_device *dev)
 				ppseudo_hdr->portsrc = 0;
 				/* Calculate new checksum */
 				ppseudo_hdr->checksum = *pmsg++;
-				for (i = 1; i < 7; i++) {
+				for (i = 1; i < 7; i++)
 					ppseudo_hdr->checksum ^= *pmsg++;
-				}
+
 				pmsg = (u16 *)&tempbuffer[16];
 				*pmsg++ = htons(RSP_DRV_ERR_RPT_MSG);
 				*pmsg++ = htons(0x000e);
@@ -1508,9 +1496,8 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum)
 			tempword = inw(dev->base_addr + FT1000_REG_MAG_DFSR);
 			pr_debug("FT1000_REG_MAG_DFSR = 0x%x\n", tempword);
 		}
-		if (DrvErrNum) {
+		if (DrvErrNum)
 			pcmcia->PktIntfErr++;
-		}
 	}
 }
 
@@ -1567,9 +1554,9 @@ static int ft1000_copy_up_pkt(struct net_device *dev)
 	if (skb == NULL) {
 		pr_debug("No Network buffers available\n");
 		/* Read High word to complete 32 bit access */
-		if (info->AsicID == MAGNEMITE_ID) {
+		if (info->AsicID == MAGNEMITE_ID)
 			tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH);
-		}
+
 		ft1000_flush_fifo(dev, 0);
 		info->stats.rx_errors++;
 		return FAILURE;
@@ -1673,9 +1660,8 @@ static int ft1000_copy_up_pkt(struct net_device *dev)
 	}
 
 	pr_debug("Data passed to Protocol layer:\n");
-	for (i = 0; i < len + 12; i++) {
+	for (i = 0; i < len + 12; i++)
 		pr_debug("Protocol Data: 0x%x\n", *ptemp++);
-	}
 
 	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, dev);
@@ -1729,21 +1715,16 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
 	/* Check if there is room on the FIFO */
 	if (len > ft1000_read_fifo_len(dev)) {
 		udelay(10);
-		if (len > ft1000_read_fifo_len(dev)) {
+		if (len > ft1000_read_fifo_len(dev))
 			udelay(20);
-		}
-		if (len > ft1000_read_fifo_len(dev)) {
+		if (len > ft1000_read_fifo_len(dev))
 			udelay(20);
-		}
-		if (len > ft1000_read_fifo_len(dev)) {
+		if (len > ft1000_read_fifo_len(dev))
 			udelay(20);
-		}
-		if (len > ft1000_read_fifo_len(dev)) {
+		if (len > ft1000_read_fifo_len(dev))
 			udelay(20);
-		}
-		if (len > ft1000_read_fifo_len(dev)) {
+		if (len > ft1000_read_fifo_len(dev))
 			udelay(20);
-		}
 		if (len > ft1000_read_fifo_len(dev)) {
 			pr_debug("Transmit FIFO is full - pkt drop\n");
 			info->stats.tx_errors++;
@@ -1751,11 +1732,11 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
 		}
 	}
 	/* Create pseudo header and send pseudo/ip to hardware */
-	if (info->AsicID == ELECTRABUZZ_ID) {
+	if (info->AsicID == ELECTRABUZZ_ID)
 		pseudo.blk.length = len;
-	} else {
+	else
 		pseudo.blk.length = ntohs(len);
-	}
+
 	pseudo.blk.source = DSPID;	/* Need to swap to get in correct order */
 	pseudo.blk.destination = HOSTID;
 	pseudo.blk.portdest = NETWORKID;	/* Need to swap to get in correct order */
@@ -1768,9 +1749,8 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
 	pseudo.blk.qos_class = 0;
 	/* Calculate pseudo header checksum */
 	pseudo.blk.checksum = pseudo.buff[0];
-	for (i = 1; i < 7; i++) {
+	for (i = 1; i < 7; i++)
 		pseudo.blk.checksum ^= pseudo.buff[i];
-	}
 
 	/* Production Mode */
 	if (info->AsicID == ELECTRABUZZ_ID) {
@@ -1835,9 +1815,8 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 *packet, u16 len)
 
 		plong = (u32 *)packet;
 		/* Write PPP type + IP Packet into Downlink FIFO */
-		for (i = 0; i < (len >> 2); i++) {
+		for (i = 0; i < (len >> 2); i++)
 			outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR);
-		}
 
 		/* Check for odd alignment */
 		if (len & 0x0003) {
diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
index d12cfc9aa32a..f0ac43838461 100644
--- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
+++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
@@ -332,15 +332,15 @@ int card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer,
 
 	pr_debug("enter card_send_command... size=%d\n", size);
 
+	ret = ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
+	if (ret)
+		return ret;
+
 	commandbuf = kmalloc(size + 2, GFP_KERNEL);
 	if (!commandbuf)
 		return -ENOMEM;
 	memcpy((void *)commandbuf + 2, (void *)ptempbuffer, size);
 
-	ret = ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
-	if (ret)
-		return ret;
-
 	if (temp & 0x0100)
 		usleep_range(900, 1100);
 
diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c
index 73eede163820..7c4a77bb94aa 100644
--- a/drivers/staging/gdm724x/gdm_lte.c
+++ b/drivers/staging/gdm724x/gdm_lte.c
@@ -281,7 +281,8 @@ static int gdm_lte_emulate_ndp(struct sk_buff *skb_in, u32 nic_type)
 		icmp6_out.icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT;
 		icmp6_out.icmp6_code = 0;
 		icmp6_out.icmp6_cksum = 0;
-		icmp6_out.icmp6_dataun.un_data32[0] = htonl(0x60000000); /* R=0, S=1, O=1 */
+		/* R=0, S=1, O=1 */
+		icmp6_out.icmp6_dataun.un_data32[0] = htonl(0x60000000);
 
 		ns = (struct neighbour_solicitation *)
 			(skb_in->data + mac_header_len +
diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c
index b5b063a738f8..d1ab996b3305 100644
--- a/drivers/staging/gdm724x/gdm_mux.c
+++ b/drivers/staging/gdm724x/gdm_mux.c
@@ -220,7 +220,7 @@ static int up_to_host(struct mux_rx *r)
 static void do_rx(struct work_struct *work)
 {
 	struct mux_dev *mux_dev =
-		container_of(work, struct mux_dev , work_rx.work);
+		container_of(work, struct mux_dev, work_rx.work);
 	struct mux_rx *r;
 	struct rx_cxt *rx = (struct rx_cxt *)&mux_dev->rx;
 	unsigned long flags;
diff --git a/drivers/staging/gs_fpgaboot/io.c b/drivers/staging/gs_fpgaboot/io.c
index b260e45c6698..819db53da64d 100644
--- a/drivers/staging/gs_fpgaboot/io.c
+++ b/drivers/staging/gs_fpgaboot/io.c
@@ -79,15 +79,6 @@ void xl_shift_bytes_out(enum wbus bus_byte, unsigned char *pdata)
 /*
  * generic bit swap for xilinx SYSTEMMAP FPGA programming
  */
-static inline unsigned char bitswap(unsigned char s)
-{
-	unsigned char d;
-
-	d = (((s&0x80)>>7) | ((s&0x40)>>5) | ((s&0x20)>>3) | ((s&0x10)>>1) |
-		((s&0x08)<<1) | ((s&0x04)<<3) | ((s&0x02)<<5) | ((s&0x01)<<7));
-	return d;
-}
-
 void xl_program_b(int32_t i)
 {
 }
diff --git a/drivers/message/i2o/Kconfig b/drivers/staging/i2o/Kconfig
index 5afa0e393ecf..286c53f4b13d 100644
--- a/drivers/message/i2o/Kconfig
+++ b/drivers/staging/i2o/Kconfig
@@ -1,4 +1,3 @@
-
 menuconfig I2O
 	tristate "I2O device support"
 	depends on PCI
diff --git a/drivers/message/i2o/Makefile b/drivers/staging/i2o/Makefile
index b0982dacfd0a..b0982dacfd0a 100644
--- a/drivers/message/i2o/Makefile
+++ b/drivers/staging/i2o/Makefile
diff --git a/drivers/message/i2o/README b/drivers/staging/i2o/README
index f072a8eb3041..f072a8eb3041 100644
--- a/drivers/message/i2o/README
+++ b/drivers/staging/i2o/README
diff --git a/drivers/message/i2o/README.ioctl b/drivers/staging/i2o/README.ioctl
index 4a7d2ebdfc97..4a7d2ebdfc97 100644
--- a/drivers/message/i2o/README.ioctl
+++ b/drivers/staging/i2o/README.ioctl
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/staging/i2o/bus-osm.c
index c463dc2efc09..7aa0339aea05 100644
--- a/drivers/message/i2o/bus-osm.c
+++ b/drivers/staging/i2o/bus-osm.c
@@ -14,7 +14,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 
 #define OSM_NAME	"bus-osm"
 #define OSM_VERSION	"1.317"
diff --git a/drivers/message/i2o/config-osm.c b/drivers/staging/i2o/config-osm.c
index 3bba7aa82e58..519f52f9f688 100644
--- a/drivers/message/i2o/config-osm.c
+++ b/drivers/staging/i2o/config-osm.c
@@ -14,7 +14,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/dcache.h>
 #include <linux/namei.h>
 #include <linux/fs.h>
diff --git a/drivers/message/i2o/core.h b/drivers/staging/i2o/core.h
index 91614f11f89a..91614f11f89a 100644
--- a/drivers/message/i2o/core.h
+++ b/drivers/staging/i2o/core.h
diff --git a/drivers/message/i2o/debug.c b/drivers/staging/i2o/debug.c
index ce62d8bfe1c8..7a16114ed8ea 100644
--- a/drivers/message/i2o/debug.c
+++ b/drivers/staging/i2o/debug.c
@@ -1,7 +1,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 
 static void i2o_report_util_cmd(u8 cmd);
 static void i2o_report_exec_cmd(u8 cmd);
diff --git a/drivers/message/i2o/device.c b/drivers/staging/i2o/device.c
index 98348f420b52..2af22553dd4e 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/staging/i2o/device.c
@@ -14,7 +14,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/slab.h>
diff --git a/drivers/message/i2o/driver.c b/drivers/staging/i2o/driver.c
index 1b18a0d1d05b..111c3edde035 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/staging/i2o/driver.c
@@ -16,7 +16,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/rwsem.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/workqueue.h>
 #include <linux/string.h>
 #include <linux/slab.h>
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/staging/i2o/exec-osm.c
index a3970e56ae53..16d857d5e655 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/staging/i2o/exec-osm.c
@@ -28,7 +28,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/delay.h>
 #include <linux/workqueue.h>
 #include <linux/string.h>
diff --git a/include/linux/i2o.h b/drivers/staging/i2o/i2o.h
index d23c3c20b201..d23c3c20b201 100644
--- a/include/linux/i2o.h
+++ b/drivers/staging/i2o/i2o.h
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/staging/i2o/i2o_block.c
index 6fc3866965df..0a13c64ce000 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/staging/i2o/i2o_block.c
@@ -52,7 +52,7 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/mutex.h>
 
 #include <linux/mempool.h>
diff --git a/drivers/message/i2o/i2o_block.h b/drivers/staging/i2o/i2o_block.h
index cf8873cbca3f..cf8873cbca3f 100644
--- a/drivers/message/i2o/i2o_block.h
+++ b/drivers/staging/i2o/i2o_block.h
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/staging/i2o/i2o_config.c
index 04bd3b6de401..04bd3b6de401 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/staging/i2o/i2o_config.c
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/staging/i2o/i2o_proc.c
index b7d87cd227a9..ad84f3304f3c 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/staging/i2o/i2o_proc.c
@@ -39,7 +39,7 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/staging/i2o/i2o_scsi.c
index 8152e9fa9d95..1b11dcb3faea 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/staging/i2o/i2o_scsi.c
@@ -53,7 +53,7 @@
 #include <linux/prefetch.h>
 #include <linux/pci.h>
 #include <linux/blkdev.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/scatterlist.h>
 
 #include <asm/dma.h>
diff --git a/drivers/message/i2o/iop.c b/drivers/staging/i2o/iop.c
index 92752fb5b2d3..52334fc8b547 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/staging/i2o/iop.c
@@ -26,7 +26,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
diff --git a/drivers/message/i2o/memory.c b/drivers/staging/i2o/memory.c
index 292b41e49fbd..8f9509d275a4 100644
--- a/drivers/message/i2o/memory.c
+++ b/drivers/staging/i2o/memory.c
@@ -11,7 +11,7 @@
  */
 
 #include <linux/module.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/slab.h>
diff --git a/drivers/message/i2o/pci.c b/drivers/staging/i2o/pci.c
index 0f9f3e1a2b6b..b3b8a61dd4a6 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/staging/i2o/pci.c
@@ -30,7 +30,7 @@
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
-#include <linux/i2o.h>
+#include "i2o.h"
 #include <linux/module.h>
 #include "core.h"
 
diff --git a/drivers/staging/iio/Documentation/iio_event_monitor.c b/drivers/staging/iio/Documentation/iio_event_monitor.c
index 940ed2399e73..72c96aa6e992 100644
--- a/drivers/staging/iio/Documentation/iio_event_monitor.c
+++ b/drivers/staging/iio/Documentation/iio_event_monitor.c
@@ -49,6 +49,8 @@ static const char * const iio_chan_type_name_spec[] = {
 	[IIO_CCT] = "cct",
 	[IIO_PRESSURE] = "pressure",
 	[IIO_HUMIDITYRELATIVE] = "humidityrelative",
+	[IIO_ACTIVITY] = "activity",
+	[IIO_STEPS] = "steps",
 };
 
 static const char * const iio_ev_type_text[] = {
@@ -57,6 +59,7 @@ static const char * const iio_ev_type_text[] = {
 	[IIO_EV_TYPE_ROC] = "roc",
 	[IIO_EV_TYPE_THRESH_ADAPTIVE] = "thresh_adaptive",
 	[IIO_EV_TYPE_MAG_ADAPTIVE] = "mag_adaptive",
+	[IIO_EV_TYPE_CHANGE] = "change",
 };
 
 static const char * const iio_ev_dir_text[] = {
@@ -92,6 +95,10 @@ static const char * const iio_modifier_names[] = {
 	[IIO_MOD_NORTH_TRUE] = "from_north_true",
 	[IIO_MOD_NORTH_MAGN_TILT_COMP] = "from_north_magnetic_tilt_comp",
 	[IIO_MOD_NORTH_TRUE_TILT_COMP] = "from_north_true_tilt_comp",
+	[IIO_MOD_RUNNING] = "running",
+	[IIO_MOD_JOGGING] = "jogging",
+	[IIO_MOD_WALKING] = "walking",
+	[IIO_MOD_STILL] = "still",
 };
 
 static bool event_is_known(struct iio_event_data *event)
@@ -121,6 +128,8 @@ static bool event_is_known(struct iio_event_data *event)
 	case IIO_CCT:
 	case IIO_PRESSURE:
 	case IIO_HUMIDITYRELATIVE:
+	case IIO_ACTIVITY:
+	case IIO_STEPS:
 		break;
 	default:
 		return false;
@@ -154,6 +163,10 @@ static bool event_is_known(struct iio_event_data *event)
 	case IIO_MOD_NORTH_TRUE:
 	case IIO_MOD_NORTH_MAGN_TILT_COMP:
 	case IIO_MOD_NORTH_TRUE_TILT_COMP:
+	case IIO_MOD_RUNNING:
+	case IIO_MOD_JOGGING:
+	case IIO_MOD_WALKING:
+	case IIO_MOD_STILL:
 		break;
 	default:
 		return false;
@@ -165,6 +178,7 @@ static bool event_is_known(struct iio_event_data *event)
 	case IIO_EV_TYPE_ROC:
 	case IIO_EV_TYPE_THRESH_ADAPTIVE:
 	case IIO_EV_TYPE_MAG_ADAPTIVE:
+	case IIO_EV_TYPE_CHANGE:
 		break;
 	default:
 		return false;
@@ -174,6 +188,7 @@ static bool event_is_known(struct iio_event_data *event)
 	case IIO_EV_DIR_EITHER:
 	case IIO_EV_DIR_RISING:
 	case IIO_EV_DIR_FALLING:
+	case IIO_EV_DIR_NONE:
 		break;
 	default:
 		return false;
@@ -214,9 +229,11 @@ static void print_event(struct iio_event_data *event)
 	else if (chan >= 0)
 		printf("channel: %d, ", chan);
 
-	printf("evtype: %s, direction: %s\n",
-		iio_ev_type_text[ev_type],
-		iio_ev_dir_text[dir]);
+	printf("evtype: %s", iio_ev_type_text[ev_type]);
+
+	if (dir != IIO_EV_DIR_NONE)
+		printf(", direction: %s", iio_ev_dir_text[dir]);
+	printf("\n");
 }
 
 int main(int argc, char **argv)
diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt
index e1da43381d0e..18718fcaf259 100644
--- a/drivers/staging/iio/Documentation/ring.txt
+++ b/drivers/staging/iio/Documentation/ring.txt
@@ -39,9 +39,9 @@ request_update
   If parameters have changed that require reinitialization or configuration of
   the buffer this will trigger it.
 
-get_bytes_per_datum, set_bytes_per_datum
-  Get/set the number of bytes for a complete scan. (All samples + timestamp)
+set_bytes_per_datum
+  Set the number of bytes for a complete scan. (All samples + timestamp)
 
-get_length / set_length
-  Get/set the number of complete scans that may be held by the buffer.
+set_length
+  Set the number of complete scans that may be held by the buffer.
 
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index f5e145caffa9..b78c9c5d5588 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -716,14 +716,6 @@ static int lis3l02dq_probe(struct spi_device *spi)
 	if (ret)
 		return ret;
 
-	ret = iio_buffer_register(indio_dev,
-				  lis3l02dq_channels,
-				  ARRAY_SIZE(lis3l02dq_channels));
-	if (ret) {
-		dev_err(&spi->dev, "failed to initialize the buffer\n");
-		goto error_unreg_buffer_funcs;
-	}
-
 	if (spi->irq) {
 		ret = request_threaded_irq(st->us->irq,
 					   &lis3l02dq_th,
@@ -732,7 +724,7 @@ static int lis3l02dq_probe(struct spi_device *spi)
 					   "lis3l02dq",
 					   indio_dev);
 		if (ret)
-			goto error_uninitialize_buffer;
+			goto error_unreg_buffer_funcs;
 
 		ret = lis3l02dq_probe_trigger(indio_dev);
 		if (ret)
@@ -756,8 +748,6 @@ error_remove_trigger:
 error_free_interrupt:
 	if (spi->irq)
 		free_irq(st->us->irq, indio_dev);
-error_uninitialize_buffer:
-	iio_buffer_unregister(indio_dev);
 error_unreg_buffer_funcs:
 	lis3l02dq_unconfigure_buffer(indio_dev);
 	return ret;
@@ -804,7 +794,6 @@ static int lis3l02dq_remove(struct spi_device *spi)
 		free_irq(st->us->irq, indio_dev);
 
 	lis3l02dq_remove_trigger(indio_dev);
-	iio_buffer_unregister(indio_dev);
 	lis3l02dq_unconfigure_buffer(indio_dev);
 
 	return 0;
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
index 9efc77b0ebdd..1fd90090a633 100644
--- a/drivers/staging/iio/accel/lis3l02dq_ring.c
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -393,7 +393,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
 	int ret;
 	struct iio_buffer *buffer;
 
-	buffer = iio_kfifo_allocate(indio_dev);
+	buffer = iio_kfifo_allocate();
 	if (!buffer)
 		return -ENOMEM;
 
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
index e4e56391487a..31fb2182c198 100644
--- a/drivers/staging/iio/accel/sca3000_core.c
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -223,33 +223,6 @@ error_ret:
 	return ret;
 }
 
-#ifdef SCA3000_DEBUG
-/**
- * sca3000_check_status() check the status register
- *
- * Only used for debugging purposes
- **/
-static int sca3000_check_status(struct device *dev)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-	struct sca3000_state *st = iio_priv(indio_dev);
-
-	mutex_lock(&st->lock);
-	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1);
-	if (ret < 0)
-		goto error_ret;
-	if (st->rx[0] & SCA3000_EEPROM_CS_ERROR)
-		dev_err(dev, "eeprom error\n");
-	if (st->rx[0] & SCA3000_SPI_FRAME_ERROR)
-		dev_err(dev, "Previous SPI Frame was corrupt\n");
-
-error_ret:
-	mutex_unlock(&st->lock);
-	return ret;
-}
-#endif /* SCA3000_DEBUG */
-
 /**
  * sca3000_show_rev() - sysfs interface to read the chip revision number
  **/
@@ -459,6 +432,8 @@ static const struct iio_chan_spec sca3000_channels_with_temp[] = {
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
 			BIT(IIO_CHAN_INFO_OFFSET),
+		/* No buffer support */
+		.scan_index = -1,
 	},
 };
 
@@ -1154,17 +1129,6 @@ static int sca3000_probe(struct spi_device *spi)
 	if (ret < 0)
 		return ret;
 
-	ret = iio_buffer_register(indio_dev,
-				  sca3000_channels,
-				  ARRAY_SIZE(sca3000_channels));
-	if (ret < 0)
-		goto error_unregister_dev;
-	if (indio_dev->buffer) {
-		iio_scan_mask_set(indio_dev, indio_dev->buffer, 0);
-		iio_scan_mask_set(indio_dev, indio_dev->buffer, 1);
-		iio_scan_mask_set(indio_dev, indio_dev->buffer, 2);
-	}
-
 	if (spi->irq) {
 		ret = request_threaded_irq(spi->irq,
 					   NULL,
@@ -1173,7 +1137,7 @@ static int sca3000_probe(struct spi_device *spi)
 					   "sca3000",
 					   indio_dev);
 		if (ret)
-			goto error_unregister_ring;
+			goto error_unregister_dev;
 	}
 	sca3000_register_ring_funcs(indio_dev);
 	ret = sca3000_clean_setup(st);
@@ -1184,8 +1148,6 @@ static int sca3000_probe(struct spi_device *spi)
 error_free_irq:
 	if (spi->irq)
 		free_irq(spi->irq, indio_dev);
-error_unregister_ring:
-	iio_buffer_unregister(indio_dev);
 error_unregister_dev:
 	iio_device_unregister(indio_dev);
 	return ret;
@@ -1219,7 +1181,6 @@ static int sca3000_remove(struct spi_device *spi)
 	if (spi->irq)
 		free_irq(spi->irq, indio_dev);
 	iio_device_unregister(indio_dev);
-	iio_buffer_unregister(indio_dev);
 	sca3000_unconfigure_ring(indio_dev);
 
 	return 0;
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
index 157827651bfa..f76a26885808 100644
--- a/drivers/staging/iio/accel/sca3000_ring.c
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -129,26 +129,11 @@ error_ret:
 	return ret ? ret : num_read;
 }
 
-/* This is only valid with all 3 elements enabled */
-static int sca3000_ring_get_length(struct iio_buffer *r)
-{
-	return 64;
-}
-
-/* only valid if resolution is kept at 11bits */
-static int sca3000_ring_get_bytes_per_datum(struct iio_buffer *r)
-{
-	return 6;
-}
-
 static bool sca3000_ring_buf_data_available(struct iio_buffer *r)
 {
 	return r->stufftoread;
 }
 
-static IIO_BUFFER_ENABLE_ATTR;
-static IIO_BUFFER_LENGTH_ATTR;
-
 /**
  * sca3000_query_ring_int() is the hardware ring status interrupt enabled
  **/
@@ -238,20 +223,13 @@ static IIO_DEVICE_ATTR(in_accel_scale,
  * only apply to the ring buffer.  At all times full rate and accuracy
  * is available via direct reading from registers.
  */
-static struct attribute *sca3000_ring_attributes[] = {
-	&dev_attr_length.attr,
-	&dev_attr_enable.attr,
+static const struct attribute *sca3000_ring_attributes[] = {
 	&iio_dev_attr_50_percent.dev_attr.attr,
 	&iio_dev_attr_75_percent.dev_attr.attr,
 	&iio_dev_attr_in_accel_scale.dev_attr.attr,
 	NULL,
 };
 
-static struct attribute_group sca3000_ring_attr = {
-	.attrs = sca3000_ring_attributes,
-	.name = "buffer",
-};
-
 static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
 {
 	struct iio_buffer *buf;
@@ -264,7 +242,8 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
 	ring->private = indio_dev;
 	buf = &ring->buf;
 	buf->stufftoread = 0;
-	buf->attrs = &sca3000_ring_attr;
+	buf->length = 64;
+	buf->attrs = sca3000_ring_attributes;
 	iio_buffer_init(buf);
 
 	return buf;
@@ -277,8 +256,6 @@ static void sca3000_ring_release(struct iio_buffer *r)
 
 static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = {
 	.read_first_n = &sca3000_read_first_n_hw_rb,
-	.get_length = &sca3000_ring_get_length,
-	.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum,
 	.data_available = sca3000_ring_buf_data_available,
 	.release = sca3000_ring_release,
 };
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c
index f6526aa22e8a..6f8ce6c6574b 100644
--- a/drivers/staging/iio/adc/ad7192.c
+++ b/drivers/staging/iio/adc/ad7192.c
@@ -612,7 +612,7 @@ static int ad7192_probe(struct spi_device *spi)
 	const struct ad7192_platform_data *pdata = spi->dev.platform_data;
 	struct ad7192_state *st;
 	struct iio_dev *indio_dev;
-	int ret , voltage_uv = 0;
+	int ret, voltage_uv = 0;
 
 	if (!pdata) {
 		dev_err(&spi->dev, "no platform data?\n");
diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c
index f053535385bf..d9d6fad7cb00 100644
--- a/drivers/staging/iio/adc/mxs-lradc.c
+++ b/drivers/staging/iio/adc/mxs-lradc.c
@@ -436,7 +436,14 @@ static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
 	 */
 	mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch));
 
-	/* prepare the delay/loop unit according to the oversampling count */
+	/*
+	 * prepare the delay/loop unit according to the oversampling count
+	 *
+	 * from the datasheet:
+	 * "The DELAY fields in HW_LRADC_DELAY0, HW_LRADC_DELAY1,
+	 * HW_LRADC_DELAY2, and HW_LRADC_DELAY3 must be non-zero; otherwise,
+	 * the LRADC will not trigger the delay group."
+	 */
 	mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch) |
 		LRADC_DELAY_TRIGGER_DELAYS(0) |
 		LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
@@ -1495,20 +1502,38 @@ static int mxs_lradc_probe_touchscreen(struct mxs_lradc *lradc,
 		return -EINVAL;
 	}
 
-	lradc->over_sample_cnt = 4;
-	ret = of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt);
-	if (ret == 0)
+	if (of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt)) {
+		lradc->over_sample_cnt = 4;
+	} else {
+		if (adapt < 1 || adapt > 32) {
+			dev_err(lradc->dev, "Invalid sample count (%u)\n",
+				adapt);
+			return -EINVAL;
+		}
 		lradc->over_sample_cnt = adapt;
+	}
 
-	lradc->over_sample_delay = 2;
-	ret = of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt);
-	if (ret == 0)
+	if (of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt)) {
+		lradc->over_sample_delay = 2;
+	} else {
+		if (adapt < 2 || adapt > LRADC_DELAY_DELAY_MASK + 1) {
+			dev_err(lradc->dev, "Invalid sample delay (%u)\n",
+				adapt);
+			return -EINVAL;
+		}
 		lradc->over_sample_delay = adapt;
+	}
 
-	lradc->settling_delay = 10;
-	ret = of_property_read_u32(lradc_node, "fsl,settling", &adapt);
-	if (ret == 0)
+	if (of_property_read_u32(lradc_node, "fsl,settling", &adapt)) {
+		lradc->settling_delay = 10;
+	} else {
+		if (adapt < 1 || adapt > LRADC_DELAY_DELAY_MASK) {
+			dev_err(lradc->dev, "Invalid settling delay (%u)\n",
+				adapt);
+			return -EINVAL;
+		}
 		lradc->settling_delay = adapt;
+	}
 
 	return 0;
 }
diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c
index 5a804f16ec2f..59ad5a3efe9c 100644
--- a/drivers/staging/iio/iio_dummy_evgen.c
+++ b/drivers/staging/iio/iio_dummy_evgen.c
@@ -33,6 +33,7 @@
  * @base: base of irq range
  * @enabled: mask of which irqs are enabled
  * @inuse: mask of which irqs are connected
+ * @regs: irq regs we are faking
  * @lock: protect the evgen state
  */
 struct iio_dummy_eventgen {
@@ -40,6 +41,7 @@ struct iio_dummy_eventgen {
 	int base;
 	bool enabled[IIO_EVENTGEN_NO];
 	bool inuse[IIO_EVENTGEN_NO];
+	struct iio_dummy_regs regs[IIO_EVENTGEN_NO];
 	struct mutex lock;
 };
 
@@ -136,6 +138,12 @@ int iio_dummy_evgen_release_irq(int irq)
 }
 EXPORT_SYMBOL_GPL(iio_dummy_evgen_release_irq);
 
+struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq)
+{
+	return &iio_evgen->regs[irq - iio_evgen->base];
+}
+EXPORT_SYMBOL_GPL(iio_dummy_evgen_get_regs);
+
 static void iio_dummy_evgen_free(void)
 {
 	irq_free_descs(iio_evgen->base, IIO_EVENTGEN_NO);
@@ -153,6 +161,15 @@ static ssize_t iio_evgen_poke(struct device *dev,
 			      size_t len)
 {
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	unsigned long event;
+	int ret;
+
+	ret = kstrtoul(buf, 10, &event);
+	if (ret)
+		return ret;
+
+	iio_evgen->regs[this_attr->address].reg_id   = this_attr->address;
+	iio_evgen->regs[this_attr->address].reg_data = event;
 
 	if (iio_evgen->enabled[this_attr->address])
 		handle_nested_irq(iio_evgen->base + this_attr->address);
diff --git a/drivers/staging/iio/iio_dummy_evgen.h b/drivers/staging/iio/iio_dummy_evgen.h
index 3a180811b315..2ac293ab7c8f 100644
--- a/drivers/staging/iio/iio_dummy_evgen.h
+++ b/drivers/staging/iio/iio_dummy_evgen.h
@@ -1,6 +1,12 @@
 #ifndef _IIO_DUMMY_EVGEN_H_
 #define _IIO_DUMMY_EVGEN_H_
 
+struct iio_dummy_regs {
+	u32 reg_id;
+	u32 reg_data;
+};
+
+struct iio_dummy_regs *iio_dummy_evgen_get_regs(int irq);
 int iio_dummy_evgen_get_irq(void);
 int iio_dummy_evgen_release_irq(int irq);
 
diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c
index bf78e6f0311f..e4520213f627 100644
--- a/drivers/staging/iio/iio_simple_dummy.c
+++ b/drivers/staging/iio/iio_simple_dummy.c
@@ -69,6 +69,34 @@ static const struct iio_event_spec iio_dummy_event = {
 	.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
 };
 
+/*
+ * simple step detect event - triggered when a step is detected
+ */
+static const struct iio_event_spec step_detect_event = {
+	.type = IIO_EV_TYPE_CHANGE,
+	.dir = IIO_EV_DIR_NONE,
+	.mask_separate = BIT(IIO_EV_INFO_ENABLE),
+};
+
+/*
+ * simple transition event - triggered when the reported running confidence
+ * value rises above a threshold value
+ */
+static const struct iio_event_spec iio_running_event = {
+	.type = IIO_EV_TYPE_THRESH,
+	.dir = IIO_EV_DIR_RISING,
+	.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
+
+/*
+ * simple transition event - triggered when the reported walking confidence
+ * value falls under a threshold value
+ */
+static const struct iio_event_spec iio_walking_event = {
+	.type = IIO_EV_TYPE_THRESH,
+	.dir = IIO_EV_DIR_FALLING,
+	.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
 #endif
 
 /*
@@ -211,10 +239,44 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
 	{
 		.type = IIO_VOLTAGE,
 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.scan_index = -1, /* No buffer support */
 		.output = 1,
 		.indexed = 1,
 		.channel = 0,
 	},
+	{
+		.type = IIO_STEPS,
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_ENABLE) |
+			BIT(IIO_CHAN_INFO_CALIBHEIGHT),
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+		.scan_index = -1, /* No buffer support */
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+		.event_spec = &step_detect_event,
+		.num_event_specs = 1,
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.modified = 1,
+		.channel2 = IIO_MOD_RUNNING,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+		.scan_index = -1, /* No buffer support */
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+		.event_spec = &iio_running_event,
+		.num_event_specs = 1,
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
+	},
+	{
+		.type = IIO_ACTIVITY,
+		.modified = 1,
+		.channel2 = IIO_MOD_WALKING,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+		.scan_index = -1, /* No buffer support */
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+		.event_spec = &iio_walking_event,
+		.num_event_specs = 1,
+#endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
+	},
 };
 
 /**
@@ -263,24 +325,55 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
 			break;
 		}
 		break;
+	case IIO_CHAN_INFO_PROCESSED:
+		switch (chan->type) {
+		case IIO_STEPS:
+			*val = st->steps;
+			ret = IIO_VAL_INT;
+			break;
+		case IIO_ACTIVITY:
+			switch (chan->channel2) {
+			case IIO_MOD_RUNNING:
+				*val = st->activity_running;
+				ret = IIO_VAL_INT;
+				break;
+			case IIO_MOD_WALKING:
+				*val = st->activity_walking;
+				ret = IIO_VAL_INT;
+				break;
+			default:
+				break;
+			}
+			break;
+		default:
+			break;
+		}
+		break;
 	case IIO_CHAN_INFO_OFFSET:
 		/* only single ended adc -> 7 */
 		*val = 7;
 		ret = IIO_VAL_INT;
 		break;
 	case IIO_CHAN_INFO_SCALE:
-		switch (chan->differential) {
-		case 0:
-			/* only single ended adc -> 0.001333 */
-			*val = 0;
-			*val2 = 1333;
-			ret = IIO_VAL_INT_PLUS_MICRO;
+		switch (chan->type) {
+		case IIO_VOLTAGE:
+			switch (chan->differential) {
+			case 0:
+				/* only single ended adc -> 0.001333 */
+				*val = 0;
+				*val2 = 1333;
+				ret = IIO_VAL_INT_PLUS_MICRO;
+				break;
+			case 1:
+				/* all differential adc channels ->
+				 * 0.000001344 */
+				*val = 0;
+				*val2 = 1344;
+				ret = IIO_VAL_INT_PLUS_NANO;
+			}
+			break;
+		default:
 			break;
-		case 1:
-			/* all differential adc channels -> 0.000001344 */
-			*val = 0;
-			*val2 = 1344;
-			ret = IIO_VAL_INT_PLUS_NANO;
 		}
 		break;
 	case IIO_CHAN_INFO_CALIBBIAS:
@@ -298,6 +391,27 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
 		*val2 = 33;
 		ret = IIO_VAL_INT_PLUS_NANO;
 		break;
+	case IIO_CHAN_INFO_ENABLE:
+		switch (chan->type) {
+		case IIO_STEPS:
+			*val = st->steps_enabled;
+			ret = IIO_VAL_INT;
+			break;
+		default:
+			break;
+		}
+		break;
+	case IIO_CHAN_INFO_CALIBHEIGHT:
+		switch (chan->type) {
+		case IIO_STEPS:
+			*val = st->height;
+			ret = IIO_VAL_INT;
+			break;
+		default:
+			break;
+		}
+		break;
+
 	default:
 		break;
 	}
@@ -330,14 +444,45 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev,
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
-		if (chan->output == 0)
+		switch (chan->type) {
+		case IIO_VOLTAGE:
+			if (chan->output == 0)
+				return -EINVAL;
+
+			/* Locking not required as writing single value */
+			mutex_lock(&st->lock);
+			st->dac_val = val;
+			mutex_unlock(&st->lock);
+			return 0;
+		default:
 			return -EINVAL;
-
-		/* Locking not required as writing single value */
-		mutex_lock(&st->lock);
-		st->dac_val = val;
-		mutex_unlock(&st->lock);
-		return 0;
+		}
+	case IIO_CHAN_INFO_PROCESSED:
+		switch (chan->type) {
+		case IIO_STEPS:
+			mutex_lock(&st->lock);
+			st->steps = val;
+			mutex_unlock(&st->lock);
+			return 0;
+		case IIO_ACTIVITY:
+			if (val < 0)
+				val = 0;
+			if (val > 100)
+				val = 100;
+			switch (chan->channel2) {
+			case IIO_MOD_RUNNING:
+				st->activity_running = val;
+				return 0;
+			case IIO_MOD_WALKING:
+				st->activity_walking = val;
+				return 0;
+			default:
+				return -EINVAL;
+			}
+			break;
+		default:
+			return -EINVAL;
+		}
 	case IIO_CHAN_INFO_CALIBSCALE:
 		mutex_lock(&st->lock);
 		/* Compare against table - hard matching here */
@@ -356,6 +501,24 @@ static int iio_dummy_write_raw(struct iio_dev *indio_dev,
 		st->accel_calibbias = val;
 		mutex_unlock(&st->lock);
 		return 0;
+	case IIO_CHAN_INFO_ENABLE:
+		switch (chan->type) {
+		case IIO_STEPS:
+			mutex_lock(&st->lock);
+			st->steps_enabled = val;
+			mutex_unlock(&st->lock);
+			return 0;
+		default:
+			return -EINVAL;
+		}
+	case IIO_CHAN_INFO_CALIBHEIGHT:
+		switch (chan->type) {
+		case IIO_STEPS:
+			st->height = val;
+			return 0;
+		default:
+			return -EINVAL;
+		}
 
 	default:
 		return -EINVAL;
@@ -395,6 +558,9 @@ static int iio_dummy_init_device(struct iio_dev *indio_dev)
 	st->accel_val = 34;
 	st->accel_calibbias = -7;
 	st->accel_calibscale = &dummy_scales[0];
+	st->steps = 47;
+	st->activity_running = 98;
+	st->activity_walking = 4;
 
 	return 0;
 }
@@ -475,13 +641,7 @@ static int iio_dummy_probe(int index)
 	if (ret < 0)
 		goto error_free_device;
 
-	/*
-	 * Configure buffered capture support and register the channels with the
-	 * buffer, but avoid the output channel being registered by reducing the
-	 * number of channels by 1.
-	 */
-	ret = iio_simple_dummy_configure_buffer(indio_dev,
-						iio_dummy_channels, 5);
+	ret = iio_simple_dummy_configure_buffer(indio_dev);
 	if (ret < 0)
 		goto error_unregister_events;
 
diff --git a/drivers/staging/iio/iio_simple_dummy.h b/drivers/staging/iio/iio_simple_dummy.h
index 3027aed79093..34989bf248a7 100644
--- a/drivers/staging/iio/iio_simple_dummy.h
+++ b/drivers/staging/iio/iio_simple_dummy.h
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 
 struct iio_dummy_accel_calibscale;
+struct iio_dummy_regs;
 
 /**
  * struct iio_dummy_state - device instance specific state.
@@ -33,8 +34,14 @@ struct iio_dummy_state {
 	int differential_adc_val[2];
 	int accel_val;
 	int accel_calibbias;
+	int activity_running;
+	int activity_walking;
 	const struct iio_dummy_accel_calibscale *accel_calibscale;
 	struct mutex lock;
+	struct iio_dummy_regs *regs;
+	int steps_enabled;
+	int steps;
+	int height;
 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
 	int event_irq;
 	int event_val;
@@ -107,12 +114,10 @@ enum iio_simple_dummy_scan_elements {
 };
 
 #ifdef CONFIG_IIO_SIMPLE_DUMMY_BUFFER
-int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *channels, unsigned int num_channels);
+int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev);
 void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev);
 #else
-static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *channels, unsigned int num_channels)
+static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
 {
 	return 0;
 };
diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c
index fd74f9166a5f..360a4c980722 100644
--- a/drivers/staging/iio/iio_simple_dummy_buffer.c
+++ b/drivers/staging/iio/iio_simple_dummy_buffer.c
@@ -115,14 +115,13 @@ static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
 	.predisable = &iio_triggered_buffer_predisable,
 };
 
-int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
-	const struct iio_chan_spec *channels, unsigned int num_channels)
+int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
 {
 	int ret;
 	struct iio_buffer *buffer;
 
 	/* Allocate a buffer to use - here a kfifo */
-	buffer = iio_kfifo_allocate(indio_dev);
+	buffer = iio_kfifo_allocate();
 	if (buffer == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
@@ -173,14 +172,8 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
 	 */
 	indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
 
-	ret = iio_buffer_register(indio_dev, channels, num_channels);
-	if (ret)
-		goto error_dealloc_pollfunc;
-
 	return 0;
 
-error_dealloc_pollfunc:
-	iio_dealloc_pollfunc(indio_dev->pollfunc);
 error_free_buffer:
 	iio_kfifo_free(indio_dev->buffer);
 error_ret:
@@ -194,7 +187,6 @@ error_ret:
  */
 void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
 {
-	iio_buffer_unregister(indio_dev);
 	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_kfifo_free(indio_dev->buffer);
 }
diff --git a/drivers/staging/iio/iio_simple_dummy_events.c b/drivers/staging/iio/iio_simple_dummy_events.c
index 64b45b077549..a5cd3bb219fe 100644
--- a/drivers/staging/iio/iio_simple_dummy_events.c
+++ b/drivers/staging/iio/iio_simple_dummy_events.c
@@ -72,6 +72,22 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
 				st->event_en = state;
 			else
 				return -EINVAL;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case IIO_ACTIVITY:
+		switch (type) {
+		case IIO_EV_TYPE_THRESH:
+			st->event_en = state;
+			break;
+		default:
+			return -EINVAL;
+		}
+	case IIO_STEPS:
+		switch (type) {
+		case IIO_EV_TYPE_CHANGE:
+			st->event_en = state;
 			break;
 		default:
 			return -EINVAL;
@@ -148,12 +164,50 @@ int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
 static irqreturn_t iio_simple_dummy_event_handler(int irq, void *private)
 {
 	struct iio_dev *indio_dev = private;
+	struct iio_dummy_state *st = iio_priv(indio_dev);
+
+	dev_dbg(&indio_dev->dev, "id %x event %x\n",
+		st->regs->reg_id, st->regs->reg_data);
+
+	switch (st->regs->reg_data) {
+	case 0:
+		iio_push_event(indio_dev,
+			       IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
+					      IIO_EV_DIR_RISING,
+					      IIO_EV_TYPE_THRESH, 0, 0, 0),
+			       iio_get_time_ns());
+		break;
+	case 1:
+		if (st->activity_running > st->event_val)
+			iio_push_event(indio_dev,
+				       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
+						      IIO_MOD_RUNNING,
+						      IIO_EV_DIR_RISING,
+						      IIO_EV_TYPE_THRESH,
+						      0, 0, 0),
+				       iio_get_time_ns());
+		break;
+	case 2:
+		if (st->activity_walking < st->event_val)
+			iio_push_event(indio_dev,
+				       IIO_EVENT_CODE(IIO_ACTIVITY, 0,
+						      IIO_MOD_WALKING,
+						      IIO_EV_DIR_FALLING,
+						      IIO_EV_TYPE_THRESH,
+						      0, 0, 0),
+				       iio_get_time_ns());
+		break;
+	case 3:
+		iio_push_event(indio_dev,
+			       IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,
+					      IIO_EV_DIR_NONE,
+					      IIO_EV_TYPE_CHANGE, 0, 0, 0),
+			       iio_get_time_ns());
+		break;
+	default:
+		break;
+	}
 
-	iio_push_event(indio_dev,
-		       IIO_EVENT_CODE(IIO_VOLTAGE, 0, 0,
-				      IIO_EV_DIR_RISING,
-				      IIO_EV_TYPE_THRESH, 0, 0, 0),
-		       iio_get_time_ns());
 	return IRQ_HANDLED;
 }
 
@@ -179,6 +233,8 @@ int iio_simple_dummy_events_register(struct iio_dev *indio_dev)
 		ret = st->event_irq;
 		goto error_ret;
 	}
+	st->regs = iio_dummy_evgen_get_regs(st->event_irq);
+
 	ret = request_threaded_irq(st->event_irq,
 				   NULL,
 				   &iio_simple_dummy_event_handler,
diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
index b6bd609c3655..79194399e040 100644
--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -89,7 +89,6 @@
 struct ad5933_state {
 	struct i2c_client		*client;
 	struct regulator		*reg;
-	struct ad5933_platform_data	*pdata;
 	struct delayed_work		work;
 	unsigned long			mclk_hz;
 	unsigned char			ctrl_hb;
@@ -113,7 +112,8 @@ static const struct iio_chan_spec ad5933_channels[] = {
 		.type = IIO_TEMP,
 		.indexed = 1,
 		.channel = 0,
-		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+			BIT(IIO_CHAN_INFO_SCALE),
 		.address = AD5933_REG_TEMP_DATA,
 		.scan_index = -1,
 		.scan_type = {
@@ -360,11 +360,11 @@ static ssize_t ad5933_show(struct device *dev,
 	mutex_lock(&indio_dev->mlock);
 	switch ((u32) this_attr->address) {
 	case AD5933_OUT_RANGE:
-		len = sprintf(buf, "%d\n",
+		len = sprintf(buf, "%u\n",
 			      st->range_avail[(st->ctrl_hb >> 1) & 0x3]);
 		break;
 	case AD5933_OUT_RANGE_AVAIL:
-		len = sprintf(buf, "%d %d %d %d\n", st->range_avail[0],
+		len = sprintf(buf, "%u %u %u %u\n", st->range_avail[0],
 			      st->range_avail[3], st->range_avail[2],
 			      st->range_avail[1]);
 		break;
@@ -520,12 +520,11 @@ static int ad5933_read_raw(struct iio_dev *indio_dev,
 {
 	struct ad5933_state *st = iio_priv(indio_dev);
 	__be16 dat;
-	int ret = -EINVAL;
+	int ret;
 
-	mutex_lock(&indio_dev->mlock);
 	switch (m) {
 	case IIO_CHAN_INFO_RAW:
-	case IIO_CHAN_INFO_PROCESSED:
+		mutex_lock(&indio_dev->mlock);
 		if (iio_buffer_enabled(indio_dev)) {
 			ret = -EBUSY;
 			goto out;
@@ -543,16 +542,16 @@ static int ad5933_read_raw(struct iio_dev *indio_dev,
 		if (ret < 0)
 			goto out;
 		mutex_unlock(&indio_dev->mlock);
-		ret = be16_to_cpu(dat);
-		/* Temp in Milli degrees Celsius */
-		if (ret < 8192)
-			*val = ret * 1000 / 32;
-		else
-			*val = (ret - 16384) * 1000 / 32;
+		*val = sign_extend32(be16_to_cpu(dat), 13);
 
 		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_SCALE:
+		*val = 1000;
+		*val2 = 5;
+		return IIO_VAL_FRACTIONAL_LOG2;
 	}
 
+	return -EINVAL;
 out:
 	mutex_unlock(&indio_dev->mlock);
 	return ret;
@@ -626,7 +625,7 @@ static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
 	struct iio_buffer *buffer;
 
-	buffer = iio_kfifo_allocate(indio_dev);
+	buffer = iio_kfifo_allocate();
 	if (!buffer)
 		return -ENOMEM;
 
@@ -712,9 +711,7 @@ static int ad5933_probe(struct i2c_client *client,
 	st->client = client;
 
 	if (!pdata)
-		st->pdata = &ad5933_default_pdata;
-	else
-		st->pdata = pdata;
+		pdata = &ad5933_default_pdata;
 
 	st->reg = devm_regulator_get(&client->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
@@ -727,10 +724,10 @@ static int ad5933_probe(struct i2c_client *client,
 	if (voltage_uv)
 		st->vref_mv = voltage_uv / 1000;
 	else
-		st->vref_mv = st->pdata->vref_mv;
+		st->vref_mv = pdata->vref_mv;
 
-	if (st->pdata->ext_clk_Hz) {
-		st->mclk_hz = st->pdata->ext_clk_Hz;
+	if (pdata->ext_clk_Hz) {
+		st->mclk_hz = pdata->ext_clk_Hz;
 		st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK;
 	} else {
 		st->mclk_hz = AD5933_INT_OSC_FREQ_Hz;
@@ -752,27 +749,16 @@ static int ad5933_probe(struct i2c_client *client,
 	if (ret)
 		goto error_disable_reg;
 
-	ret = iio_buffer_register(indio_dev, ad5933_channels,
-		ARRAY_SIZE(ad5933_channels));
-	if (ret)
-		goto error_unreg_ring;
-
-	/* enable both REAL and IMAG channels by default */
-	iio_scan_mask_set(indio_dev, indio_dev->buffer, 0);
-	iio_scan_mask_set(indio_dev, indio_dev->buffer, 1);
-
 	ret = ad5933_setup(st);
 	if (ret)
-		goto error_uninitialize_ring;
+		goto error_unreg_ring;
 
 	ret = iio_device_register(indio_dev);
 	if (ret)
-		goto error_uninitialize_ring;
+		goto error_unreg_ring;
 
 	return 0;
 
-error_uninitialize_ring:
-	iio_buffer_unregister(indio_dev);
 error_unreg_ring:
 	iio_kfifo_free(indio_dev->buffer);
 error_disable_reg:
@@ -788,7 +774,6 @@ static int ad5933_remove(struct i2c_client *client)
 	struct ad5933_state *st = iio_priv(indio_dev);
 
 	iio_device_unregister(indio_dev);
-	iio_buffer_unregister(indio_dev);
 	iio_kfifo_free(indio_dev->buffer);
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index cc4ddcce4ff9..8afae8e33d56 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -692,7 +692,7 @@ static ssize_t taos_luxtable_show(struct device *dev,
 	int offset = 0;
 
 	for (i = 0; i < ARRAY_SIZE(taos_device_lux); i++) {
-		offset += sprintf(buf + offset, "%d,%d,%d,",
+		offset += sprintf(buf + offset, "%u,%u,%u,",
 				  taos_device_lux[i].ratio,
 				  taos_device_lux[i].ch0,
 				  taos_device_lux[i].ch1);
diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c
index 423f96bdf595..4a5dc26fed4c 100644
--- a/drivers/staging/iio/light/tsl2x7x_core.c
+++ b/drivers/staging/iio/light/tsl2x7x_core.c
@@ -1147,7 +1147,7 @@ static ssize_t tsl2x7x_luxtable_show(struct device *dev,
 	int offset = 0;
 
 	while (i < (TSL2X7X_MAX_LUX_TABLE_SIZE * 3)) {
-		offset += snprintf(buf + offset, PAGE_SIZE, "%d,%d,%d,",
+		offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,%u,",
 			chip->tsl2x7x_device_lux[i].ratio,
 			chip->tsl2x7x_device_lux[i].ch0,
 			chip->tsl2x7x_device_lux[i].ch1);
diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h
index e8c98cf57070..f6739e2c24b1 100644
--- a/drivers/staging/iio/meter/ade7758.h
+++ b/drivers/staging/iio/meter/ade7758.h
@@ -145,7 +145,6 @@ ssize_t ade7758_read_data_from_ring(struct device *dev,
 int ade7758_configure_ring(struct iio_dev *indio_dev);
 void ade7758_unconfigure_ring(struct iio_dev *indio_dev);
 
-void ade7758_uninitialize_ring(struct iio_dev *indio_dev);
 int ade7758_set_irq(struct device *dev, bool enable);
 
 int ade7758_spi_write_reg_8(struct device *dev,
diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c
index fb373b89dcc2..70e96b20c2eb 100644
--- a/drivers/staging/iio/meter/ade7758_core.c
+++ b/drivers/staging/iio/meter/ade7758_core.c
@@ -850,23 +850,15 @@ static int ade7758_probe(struct spi_device *spi)
 	if (ret)
 		goto error_free_tx;
 
-	ret = iio_buffer_register(indio_dev,
-				  &ade7758_channels[0],
-				  ARRAY_SIZE(ade7758_channels));
-	if (ret) {
-		dev_err(&spi->dev, "failed to initialize the ring\n");
-		goto error_unreg_ring_funcs;
-	}
-
 	/* Get the device into a sane initial state */
 	ret = ade7758_initial_setup(indio_dev);
 	if (ret)
-		goto error_uninitialize_ring;
+		goto error_unreg_ring_funcs;
 
 	if (spi->irq) {
 		ret = ade7758_probe_trigger(indio_dev);
 		if (ret)
-			goto error_uninitialize_ring;
+			goto error_unreg_ring_funcs;
 	}
 
 	ret = iio_device_register(indio_dev);
@@ -878,8 +870,6 @@ static int ade7758_probe(struct spi_device *spi)
 error_remove_trigger:
 	if (spi->irq)
 		ade7758_remove_trigger(indio_dev);
-error_uninitialize_ring:
-	ade7758_uninitialize_ring(indio_dev);
 error_unreg_ring_funcs:
 	ade7758_unconfigure_ring(indio_dev);
 error_free_tx:
@@ -897,7 +887,6 @@ static int ade7758_remove(struct spi_device *spi)
 	iio_device_unregister(indio_dev);
 	ade7758_stop_device(&indio_dev->dev);
 	ade7758_remove_trigger(indio_dev);
-	ade7758_uninitialize_ring(indio_dev);
 	ade7758_unconfigure_ring(indio_dev);
 	kfree(st->tx);
 	kfree(st->rx);
diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c
index 6e9006490742..3792b5761645 100644
--- a/drivers/staging/iio/meter/ade7758_ring.c
+++ b/drivers/staging/iio/meter/ade7758_ring.c
@@ -118,7 +118,7 @@ int ade7758_configure_ring(struct iio_dev *indio_dev)
 	struct iio_buffer *buffer;
 	int ret = 0;
 
-	buffer = iio_kfifo_allocate(indio_dev);
+	buffer = iio_kfifo_allocate();
 	if (!buffer) {
 		ret = -ENOMEM;
 		return ret;
@@ -180,8 +180,3 @@ error_iio_kfifo_free:
 	iio_kfifo_free(indio_dev->buffer);
 	return ret;
 }
-
-void ade7758_uninitialize_ring(struct iio_dev *indio_dev)
-{
-	iio_buffer_unregister(indio_dev);
-}
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c
index 7d217430616a..b0c7dbc8a428 100644
--- a/drivers/staging/iio/meter/ade7759.c
+++ b/drivers/staging/iio/meter/ade7759.c
@@ -116,7 +116,7 @@ static int ade7759_spi_read_reg_40(struct device *dev,
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = ADE7759_READ_REG(reg_address);
-	memset(&st->tx[1], 0 , 5);
+	memset(&st->tx[1], 0, 5);
 
 	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
 	if (ret) {
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
index a6b2f906bb1a..4410d7fdc1b4 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h
@@ -85,6 +85,9 @@ static inline int __is_po2(unsigned long long val)
 
 #include <linux/list.h>
 
+int libcfs_arch_init(void);
+void libcfs_arch_cleanup(void);
+
 /* libcfs tcpip */
 int libcfs_ipif_query(char *name, int *up, __u32 *ip, __u32 *mask);
 int libcfs_ipif_enumerate(char ***names);
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
index 375586bf7312..808e49411a30 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
@@ -454,25 +454,23 @@ cfs_hash_bkt_size(struct cfs_hash *hs)
 	       hs->hs_extra_bytes;
 }
 
-#define CFS_HOP(hs, op)	   (hs)->hs_ops->hs_ ## op
-
 static inline unsigned
 cfs_hash_id(struct cfs_hash *hs, const void *key, unsigned mask)
 {
-	return CFS_HOP(hs, hash)(hs, key, mask);
+	return hs->hs_ops->hs_hash(hs, key, mask);
 }
 
 static inline void *
 cfs_hash_key(struct cfs_hash *hs, struct hlist_node *hnode)
 {
-	return CFS_HOP(hs, key)(hnode);
+	return hs->hs_ops->hs_key(hnode);
 }
 
 static inline void
 cfs_hash_keycpy(struct cfs_hash *hs, struct hlist_node *hnode, void *key)
 {
-	if (CFS_HOP(hs, keycpy) != NULL)
-		CFS_HOP(hs, keycpy)(hnode, key);
+        if (hs->hs_ops->hs_keycpy)
+		hs->hs_ops->hs_keycpy(hnode, key);
 }
 
 /**
@@ -481,42 +479,38 @@ cfs_hash_keycpy(struct cfs_hash *hs, struct hlist_node *hnode, void *key)
 static inline int
 cfs_hash_keycmp(struct cfs_hash *hs, const void *key, struct hlist_node *hnode)
 {
-	return CFS_HOP(hs, keycmp)(key, hnode);
+	return hs->hs_ops->hs_keycmp(key, hnode);
 }
 
 static inline void *
 cfs_hash_object(struct cfs_hash *hs, struct hlist_node *hnode)
 {
-	return CFS_HOP(hs, object)(hnode);
+	return hs->hs_ops->hs_object(hnode);
 }
 
 static inline void
 cfs_hash_get(struct cfs_hash *hs, struct hlist_node *hnode)
 {
-	return CFS_HOP(hs, get)(hs, hnode);
+	return hs->hs_ops->hs_get(hs, hnode);
 }
 
 static inline void
 cfs_hash_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 {
-	LASSERT(CFS_HOP(hs, put_locked) != NULL);
-
-	return CFS_HOP(hs, put_locked)(hs, hnode);
+	return hs->hs_ops->hs_put_locked(hs, hnode);
 }
 
 static inline void
 cfs_hash_put(struct cfs_hash *hs, struct hlist_node *hnode)
 {
-	LASSERT(CFS_HOP(hs, put) != NULL);
-
-	return CFS_HOP(hs, put)(hs, hnode);
+	return hs->hs_ops->hs_put(hs, hnode);
 }
 
 static inline void
 cfs_hash_exit(struct cfs_hash *hs, struct hlist_node *hnode)
 {
-	if (CFS_HOP(hs, exit))
-		CFS_HOP(hs, exit)(hs, hnode);
+	if (hs->hs_ops->hs_exit)
+		hs->hs_ops->hs_exit(hs, hnode);
 }
 
 static inline void cfs_hash_lock(struct cfs_hash *hs, int excl)
diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
index 2817112c0633..3d86fb5b5481 100644
--- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
+++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h
@@ -458,14 +458,6 @@ struct libcfs_device_userstate {
 	struct page   *ldu_memhog_root_page;
 };
 
-/* what used to be in portals_lib.h */
-#ifndef MIN
-# define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef MAX
-# define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#endif
-
 #define MKSTR(ptr) ((ptr)) ? (ptr) : ""
 
 static inline int cfs_size_round4(int val)
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
index 7e89b3be1a74..0038d29a37fe 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
@@ -636,6 +636,7 @@ lnet_net2rnethash(__u32 net)
 }
 
 extern lnd_t the_lolnd;
+extern int avoid_asym_router_failure;
 
 int lnet_cpt_of_nid_locked(lnet_nid_t nid);
 int lnet_cpt_of_nid(lnet_nid_t nid);
@@ -752,9 +753,9 @@ int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold);
 void lnet_counters_get(lnet_counters_t *counters);
 void lnet_counters_reset(void);
 
-unsigned int lnet_iov_nob(unsigned int niov, struct iovec *iov);
-int lnet_extract_iov(int dst_niov, struct iovec *dst,
-		     int src_niov, struct iovec *src,
+unsigned int lnet_iov_nob(unsigned int niov, struct kvec *iov);
+int lnet_extract_iov(int dst_niov, struct kvec *dst,
+		     int src_niov, struct kvec *src,
 		      unsigned int offset, unsigned int len);
 
 unsigned int lnet_kiov_nob(unsigned int niov, lnet_kiov_t *iov);
@@ -762,17 +763,17 @@ int lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
 		      int src_niov, lnet_kiov_t *src,
 		      unsigned int offset, unsigned int len);
 
-void lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov,
+void lnet_copy_iov2iov(unsigned int ndiov, struct kvec *diov,
 		       unsigned int doffset,
-			unsigned int nsiov, struct iovec *siov,
+			unsigned int nsiov, struct kvec *siov,
 			unsigned int soffset, unsigned int nob);
-void lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov,
+void lnet_copy_kiov2iov(unsigned int niov, struct kvec *iov,
 			unsigned int iovoffset,
 			 unsigned int nkiov, lnet_kiov_t *kiov,
 			 unsigned int kiovoffset, unsigned int nob);
 void lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
 			unsigned int kiovoffset,
-			 unsigned int niov, struct iovec *iov,
+			 unsigned int niov, struct kvec *iov,
 			 unsigned int iovoffset, unsigned int nob);
 void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t *dkiov,
 			 unsigned int doffset,
@@ -781,10 +782,10 @@ void lnet_copy_kiov2kiov(unsigned int ndkiov, lnet_kiov_t *dkiov,
 
 static inline void
 lnet_copy_iov2flat(int dlen, void *dest, unsigned int doffset,
-		   unsigned int nsiov, struct iovec *siov, unsigned int soffset,
+		   unsigned int nsiov, struct kvec *siov, unsigned int soffset,
 		   unsigned int nob)
 {
-	struct iovec diov = {/*.iov_base = */ dest, /*.iov_len = */ dlen};
+	struct kvec diov = {/*.iov_base = */ dest, /*.iov_len = */ dlen};
 
 	lnet_copy_iov2iov(1, &diov, doffset,
 			  nsiov, siov, soffset, nob);
@@ -795,17 +796,17 @@ lnet_copy_kiov2flat(int dlen, void *dest, unsigned int doffset,
 		    unsigned int nsiov, lnet_kiov_t *skiov,
 		    unsigned int soffset, unsigned int nob)
 {
-	struct iovec diov = {/* .iov_base = */ dest, /* .iov_len = */ dlen};
+	struct kvec diov = {/* .iov_base = */ dest, /* .iov_len = */ dlen};
 
 	lnet_copy_kiov2iov(1, &diov, doffset,
 			   nsiov, skiov, soffset, nob);
 }
 
 static inline void
-lnet_copy_flat2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
+lnet_copy_flat2iov(unsigned int ndiov, struct kvec *diov, unsigned int doffset,
 		   int slen, void *src, unsigned int soffset, unsigned int nob)
 {
-	struct iovec siov = {/*.iov_base = */ src, /*.iov_len = */slen};
+	struct kvec siov = {/*.iov_base = */ src, /*.iov_len = */slen};
 
 	lnet_copy_iov2iov(ndiov, diov, doffset,
 			  1, &siov, soffset, nob);
@@ -816,7 +817,7 @@ lnet_copy_flat2kiov(unsigned int ndiov, lnet_kiov_t *dkiov,
 		    unsigned int doffset, int slen, void *src,
 		    unsigned int soffset, unsigned int nob)
 {
-	struct iovec siov = {/* .iov_base = */ src, /* .iov_len = */ slen};
+	struct kvec siov = {/* .iov_base = */ src, /* .iov_len = */ slen};
 
 	lnet_copy_iov2kiov(ndiov, dkiov, doffset,
 			   1, &siov, soffset, nob);
@@ -851,6 +852,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);
 
 int lnet_ping_target_init(void);
@@ -870,4 +872,12 @@ void lnet_peer_tables_destroy(void);
 int lnet_peer_tables_create(void);
 void lnet_debug_peer(lnet_nid_t nid);
 
+static inline void lnet_peer_set_alive(lnet_peer_t *lp)
+{
+	lp->lp_last_alive = lp->lp_last_query = get_seconds();
+	if (!lp->lp_alive)
+		lnet_notify_locked(lp, 0, 1, lp->lp_last_alive);
+}
+
+
 #endif
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h
index f16213f1771a..50537668f59d 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-types.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h
@@ -217,7 +217,7 @@ typedef struct lnet_msg {
 	unsigned int	  msg_wanted;
 	unsigned int	  msg_offset;
 	unsigned int	  msg_niov;
-	struct iovec	 *msg_iov;
+	struct kvec	 *msg_iov;
 	lnet_kiov_t	  *msg_kiov;
 
 	lnet_event_t	  msg_ev;
@@ -271,7 +271,7 @@ typedef struct lnet_libmd {
 	lnet_eq_t	    *md_eq;
 	unsigned int	  md_niov;		/* # frags */
 	union {
-		struct iovec  iov[LNET_MAX_IOV];
+		struct kvec   iov[LNET_MAX_IOV];
 		lnet_kiov_t   kiov[LNET_MAX_IOV];
 	} md_iov;
 } lnet_libmd_t;
@@ -346,7 +346,7 @@ typedef struct lnet_lnd {
 	 * credit if the LND does flow control. */
 	int (*lnd_recv)(struct lnet_ni *ni, void *private, lnet_msg_t *msg,
 			int delayed, unsigned int niov,
-			struct iovec *iov, lnet_kiov_t *kiov,
+			struct kvec *iov, lnet_kiov_t *kiov,
 			unsigned int offset, unsigned int mlen, unsigned int rlen);
 
 	/* lnet_parse() has had to delay processing of this message
@@ -622,7 +622,7 @@ typedef struct lnet_portal {
 	/* Match table for each CPT */
 	struct lnet_match_table	**ptl_mtables;
 	/* spread rotor of incoming "PUT" */
-	int			ptl_rotor;
+	unsigned int		ptl_rotor;
 	/* # active entries for this portal */
 	int		     ptl_mt_nmaps;
 	/* array of active entries' cpu-partition-id */
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
index 62b575deac3a..651016919669 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c
@@ -1538,7 +1538,7 @@ kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status)
 	fmr->fmr_pfmr = NULL;
 
 	spin_lock(&fps->fps_lock);
-	fpo->fpo_map_count --;  /* decref the pool */
+	fpo->fpo_map_count--;  /* decref the pool */
 
 	list_for_each_entry_safe(fpo, tmp, &fps->fps_pool_list, fpo_list) {
 		/* the first pool is persistent */
@@ -1547,7 +1547,7 @@ kiblnd_fmr_pool_unmap(kib_fmr_t *fmr, int status)
 
 		if (kiblnd_fmr_pool_is_idle(fpo, now)) {
 			list_move(&fpo->fpo_list, &zombies);
-			fps->fps_version ++;
+			fps->fps_version++;
 		}
 	}
 	spin_unlock(&fps->fps_lock);
@@ -1752,7 +1752,7 @@ kiblnd_pool_free_node(kib_pool_t *pool, struct list_head *node)
 
 	LASSERT (pool->po_allocated > 0);
 	list_add(node, &pool->po_free_list);
-	pool->po_allocated --;
+	pool->po_allocated--;
 
 	list_for_each_entry_safe(pool, tmp, &ps->ps_pool_list, po_list) {
 		/* the first pool is persistent */
@@ -1781,7 +1781,7 @@ kiblnd_pool_alloc_node(kib_poolset_t *ps)
 		if (list_empty(&pool->po_free_list))
 			continue;
 
-		pool->po_allocated ++;
+		pool->po_allocated++;
 		pool->po_deadline = cfs_time_shift(IBLND_POOL_DEADLINE);
 		node = pool->po_free_list.next;
 		list_del(node);
@@ -1864,7 +1864,7 @@ kiblnd_pmr_pool_map(kib_pmr_poolset_t *pps, kib_hca_dev_t *hdev,
 		return -EAGAIN;
 	}
 
-	for (i = 0; i < rd->rd_nfrags; i ++) {
+	for (i = 0; i < rd->rd_nfrags; i++) {
 		pmr->pmr_ipb[i].addr = rd->rd_frags[i].rf_addr;
 		pmr->pmr_ipb[i].size = rd->rd_frags[i].rf_nob;
 	}
@@ -2117,7 +2117,7 @@ kiblnd_tx_init(kib_pool_t *pool, struct list_head *node)
 					     tps_poolset);
 	kib_tx_t	 *tx  = list_entry(node, kib_tx_t, tx_list);
 
-	tx->tx_cookie = tps->tps_next_tx_cookie ++;
+	tx->tx_cookie = tps->tps_next_tx_cookie++;
 }
 
 static void
@@ -2326,7 +2326,7 @@ kiblnd_hdev_get_attr(kib_hca_dev_t *hdev)
 	}
 
 	for (hdev->ibh_mr_shift = 0;
-	     hdev->ibh_mr_shift < 64; hdev->ibh_mr_shift ++) {
+	     hdev->ibh_mr_shift < 64; hdev->ibh_mr_shift++) {
 		if (hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) ||
 		    hdev->ibh_mr_size == (1ULL << hdev->ibh_mr_shift) - 1)
 			return 0;
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
index b02b4ec1e29d..ab128dee9483 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h
@@ -1026,5 +1026,5 @@ int  kiblnd_post_rx (kib_rx_t *rx, int credit);
 
 int  kiblnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
 int  kiblnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
-		 unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov,
+		 unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
 		 unsigned int offset, unsigned int mlen, unsigned int rlen);
diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
index b48d7edf5669..48d885dc51d9 100644
--- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c
@@ -697,7 +697,7 @@ kiblnd_map_tx(lnet_ni_t *ni, kib_tx_t *tx,
 
 static int
 kiblnd_setup_rd_iov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
-		    unsigned int niov, struct iovec *iov, int offset, int nob)
+		    unsigned int niov, struct kvec *iov, int offset, int nob)
 {
 	kib_net_t	  *net = ni->ni_data;
 	struct page	*page;
@@ -1125,8 +1125,9 @@ kiblnd_init_rdma (kib_conn_t *conn, kib_tx_t *tx, int type,
 			break;
 		}
 
-		wrknob = MIN(MIN(kiblnd_rd_frag_size(srcrd, srcidx),
-				 kiblnd_rd_frag_size(dstrd, dstidx)), resid);
+		wrknob = min(min(kiblnd_rd_frag_size(srcrd, srcidx),
+				 kiblnd_rd_frag_size(dstrd, dstidx)),
+			     (__u32) resid);
 
 		sge = &tx->tx_sge[tx->tx_nwrq];
 		sge->addr   = kiblnd_rd_frag_addr(srcrd, srcidx);
@@ -1461,7 +1462,7 @@ kiblnd_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
 	int	       target_is_router = lntmsg->msg_target_is_router;
 	int	       routing = lntmsg->msg_routing;
 	unsigned int      payload_niov = lntmsg->msg_niov;
-	struct iovec     *payload_iov = lntmsg->msg_iov;
+	struct kvec      *payload_iov = lntmsg->msg_iov;
 	lnet_kiov_t      *payload_kiov = lntmsg->msg_kiov;
 	unsigned int      payload_offset = lntmsg->msg_offset;
 	unsigned int      payload_nob = lntmsg->msg_len;
@@ -1628,7 +1629,7 @@ kiblnd_reply (lnet_ni_t *ni, kib_rx_t *rx, lnet_msg_t *lntmsg)
 {
 	lnet_process_id_t target = lntmsg->msg_target;
 	unsigned int      niov = lntmsg->msg_niov;
-	struct iovec     *iov = lntmsg->msg_iov;
+	struct kvec      *iov = lntmsg->msg_iov;
 	lnet_kiov_t      *kiov = lntmsg->msg_kiov;
 	unsigned int      offset = lntmsg->msg_offset;
 	unsigned int      nob = lntmsg->msg_len;
@@ -1687,7 +1688,7 @@ kiblnd_reply (lnet_ni_t *ni, kib_rx_t *rx, lnet_msg_t *lntmsg)
 
 int
 kiblnd_recv (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg, int delayed,
-	     unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov,
+	     unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
 	     unsigned int offset, unsigned int mlen, unsigned int rlen)
 {
 	kib_rx_t    *rx = private;
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
index 9188b34e6948..5956dbac5d04 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c
@@ -773,7 +773,7 @@ ksocknal_select_ips(ksock_peer_t *peer, __u32 *peerips, int n_peerips)
 	/* Only match interfaces for additional connections
 	 * if I have > 1 interface */
 	n_ips = (net->ksnn_ninterfaces < 2) ? 0 :
-		MIN(n_peerips, net->ksnn_ninterfaces);
+		min(n_peerips, net->ksnn_ninterfaces);
 
 	for (i = 0; peer->ksnp_n_passive_ips < n_ips; i++) {
 		/*	      ^ yes really... */
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
index a29d4da6e343..03488d289c74 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.h
@@ -69,7 +69,7 @@ typedef struct				  /* per scheduler state */
 	int			kss_nconns;
 	struct ksock_sched_info	*kss_info;	/* owner of it */
 	struct page		*kss_rx_scratch_pgs[LNET_MAX_IOV];
-	struct iovec		kss_scratch_iov[LNET_MAX_IOV];
+	struct kvec		kss_scratch_iov[LNET_MAX_IOV];
 } ksock_sched_t;
 
 struct ksock_sched_info {
@@ -213,7 +213,7 @@ typedef struct				  /* transmit packet */
 	int	    tx_nob;	 /* # packet bytes */
 	int	    tx_resid;       /* residual bytes */
 	int	    tx_niov;	/* # packet iovec frags */
-	struct iovec  *tx_iov;	 /* packet iovec frags */
+	struct kvec  *tx_iov;	 /* packet iovec frags */
 	int	    tx_nkiov;       /* # packet page frags */
 	unsigned short tx_zc_aborted;  /* aborted ZC request */
 	unsigned short tx_zc_capable:1; /* payload is large enough for ZC */
@@ -227,11 +227,11 @@ typedef struct				  /* transmit packet */
 	int	    tx_desc_size;   /* size of this descriptor */
 	union {
 		struct {
-			struct iovec iov;       /* virt hdr */
+			struct kvec iov;       /* virt hdr */
 			lnet_kiov_t  kiov[0];   /* paged payload */
 		}		  paged;
 		struct {
-			struct iovec iov[1];    /* virt hdr + payload */
+			struct kvec iov[1];    /* virt hdr + payload */
 		}		  virt;
 	}		       tx_frags;
 } ksock_tx_t;
@@ -243,7 +243,7 @@ typedef struct				  /* transmit packet */
 /* space for the rx frag descriptors; we either read a single contiguous
  * header, or up to LNET_MAX_IOV frags of payload of either type. */
 typedef union {
-	struct iovec     iov[LNET_MAX_IOV];
+	struct kvec      iov[LNET_MAX_IOV];
 	lnet_kiov_t      kiov[LNET_MAX_IOV];
 } ksock_rxiovspace_t;
 
@@ -284,7 +284,7 @@ typedef struct ksock_conn {
 	int		   ksnc_rx_nob_left; /* # bytes to next hdr/body */
 	int		   ksnc_rx_nob_wanted; /* bytes actually wanted */
 	int		   ksnc_rx_niov;     /* # iovec frags */
-	struct iovec	 *ksnc_rx_iov;      /* the iovec frags */
+	struct kvec 	 *ksnc_rx_iov;      /* the iovec frags */
 	int		   ksnc_rx_nkiov;    /* # page frags */
 	lnet_kiov_t	  *ksnc_rx_kiov;     /* the page frags */
 	ksock_rxiovspace_t    ksnc_rx_iov_space;/* space for frag descriptors */
@@ -517,7 +517,7 @@ int ksocknal_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg);
 int ksocknal_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg);
 int ksocknal_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
 		  int delayed, unsigned int niov,
-		  struct iovec *iov, lnet_kiov_t *kiov,
+		  struct kvec *iov, lnet_kiov_t *kiov,
 		  unsigned int offset, unsigned int mlen, unsigned int rlen);
 int ksocknal_accept(lnet_ni_t *ni, struct socket *sock);
 
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
index e6c1d3647952..92760fe94184 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c
@@ -110,7 +110,7 @@ ksocknal_free_tx (ksock_tx_t *tx)
 static int
 ksocknal_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
 {
-	struct iovec  *iov = tx->tx_iov;
+	struct kvec  *iov = tx->tx_iov;
 	int    nob;
 	int    rc;
 
@@ -251,7 +251,7 @@ ksocknal_transmit (ksock_conn_t *conn, ksock_tx_t *tx)
 static int
 ksocknal_recv_iov (ksock_conn_t *conn)
 {
-	struct iovec *iov = conn->ksnc_rx_iov;
+	struct kvec *iov = conn->ksnc_rx_iov;
 	int     nob;
 	int     rc;
 
@@ -926,7 +926,7 @@ ksocknal_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
 	int	       type = lntmsg->msg_type;
 	lnet_process_id_t target = lntmsg->msg_target;
 	unsigned int      payload_niov = lntmsg->msg_niov;
-	struct iovec     *payload_iov = lntmsg->msg_iov;
+	struct kvec      *payload_iov = lntmsg->msg_iov;
 	lnet_kiov_t      *payload_kiov = lntmsg->msg_kiov;
 	unsigned int      payload_offset = lntmsg->msg_offset;
 	unsigned int      payload_nob = lntmsg->msg_len;
@@ -1047,8 +1047,8 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
 		case  KSOCK_PROTO_V2:
 		case  KSOCK_PROTO_V3:
 			conn->ksnc_rx_state = SOCKNAL_RX_KSM_HEADER;
-			conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space;
-			conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg;
+			conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
+			conn->ksnc_rx_iov[0].iov_base = &conn->ksnc_msg;
 
 			conn->ksnc_rx_nob_wanted = offsetof(ksock_msg_t, ksm_u);
 			conn->ksnc_rx_nob_left = offsetof(ksock_msg_t, ksm_u);
@@ -1061,8 +1061,8 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
 			conn->ksnc_rx_nob_wanted = sizeof(lnet_hdr_t);
 			conn->ksnc_rx_nob_left = sizeof(lnet_hdr_t);
 
-			conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space;
-			conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg.ksm_u.lnetmsg;
+			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);
 			break;
 
@@ -1082,12 +1082,12 @@ ksocknal_new_packet (ksock_conn_t *conn, int nob_to_skip)
 
 	conn->ksnc_rx_state = SOCKNAL_RX_SLOP;
 	conn->ksnc_rx_nob_left = nob_to_skip;
-	conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space;
+	conn->ksnc_rx_iov = (struct kvec *)&conn->ksnc_rx_iov_space;
 	skipped = 0;
 	niov = 0;
 
 	do {
-		nob = MIN (nob_to_skip, sizeof (ksocknal_slop_buffer));
+		nob = min_t(int, nob_to_skip, sizeof(ksocknal_slop_buffer));
 
 		conn->ksnc_rx_iov[niov].iov_base = ksocknal_slop_buffer;
 		conn->ksnc_rx_iov[niov].iov_len  = nob;
@@ -1212,8 +1212,8 @@ ksocknal_process_receive (ksock_conn_t *conn)
 		conn->ksnc_rx_nob_wanted = sizeof(ksock_lnet_msg_t);
 		conn->ksnc_rx_nob_left = sizeof(ksock_lnet_msg_t);
 
-		conn->ksnc_rx_iov = (struct iovec *)&conn->ksnc_rx_iov_space;
-		conn->ksnc_rx_iov[0].iov_base = (char *)&conn->ksnc_msg.ksm_u.lnetmsg;
+		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(ksock_lnet_msg_t);
 
 		conn->ksnc_rx_niov = 1;
@@ -1311,7 +1311,7 @@ ksocknal_process_receive (ksock_conn_t *conn)
 
 int
 ksocknal_recv (lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
-	       unsigned int niov, struct iovec *iov, lnet_kiov_t *kiov,
+	       unsigned int niov, struct kvec *iov, lnet_kiov_t *kiov,
 	       unsigned int offset, unsigned int mlen, unsigned int rlen)
 {
 	ksock_conn_t  *conn = (ksock_conn_t *)private;
@@ -1950,10 +1950,10 @@ ksocknal_connect (ksock_route_t *route)
 	/* This is a retry rather than a new connection */
 	route->ksnr_retry_interval *= 2;
 	route->ksnr_retry_interval =
-		MAX(route->ksnr_retry_interval,
+		max(route->ksnr_retry_interval,
 		    cfs_time_seconds(*ksocknal_tunables.ksnd_min_reconnectms)/1000);
 	route->ksnr_retry_interval =
-		MIN(route->ksnr_retry_interval,
+		min(route->ksnr_retry_interval,
 		    cfs_time_seconds(*ksocknal_tunables.ksnd_max_reconnectms)/1000);
 
 	LASSERT (route->ksnr_retry_interval != 0);
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
index 245c9d7560af..66cc509295e5 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_lib-linux.c
@@ -92,11 +92,11 @@ ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
 
 	{
 #if SOCKNAL_SINGLE_FRAG_TX
-		struct iovec    scratch;
-		struct iovec   *scratchiov = &scratch;
+		struct kvec    scratch;
+		struct kvec   *scratchiov = &scratch;
 		unsigned int    niov = 1;
 #else
-		struct iovec   *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
+		struct kvec   *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
 		unsigned int    niov = tx->tx_niov;
 #endif
 		struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
@@ -111,7 +111,7 @@ ksocknal_lib_send_iov (ksock_conn_t *conn, ksock_tx_t *tx)
 		    nob < tx->tx_resid)
 			msg.msg_flags |= MSG_MORE;
 
-		rc = kernel_sendmsg(sock, &msg, (struct kvec *)scratchiov, niov, nob);
+		rc = kernel_sendmsg(sock, &msg, scratchiov, niov, nob);
 	}
 	return rc;
 }
@@ -153,14 +153,14 @@ ksocknal_lib_send_kiov (ksock_conn_t *conn, ksock_tx_t *tx)
 		}
 	} else {
 #if SOCKNAL_SINGLE_FRAG_TX || !SOCKNAL_RISK_KMAP_DEADLOCK
-		struct iovec  scratch;
-		struct iovec *scratchiov = &scratch;
+		struct kvec  scratch;
+		struct kvec *scratchiov = &scratch;
 		unsigned int  niov = 1;
 #else
 #ifdef CONFIG_HIGHMEM
 #warning "XXX risk of kmap deadlock on multiple frags..."
 #endif
-		struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
+		struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
 		unsigned int  niov = tx->tx_nkiov;
 #endif
 		struct msghdr msg = {.msg_flags = MSG_DONTWAIT};
@@ -203,14 +203,14 @@ int
 ksocknal_lib_recv_iov (ksock_conn_t *conn)
 {
 #if SOCKNAL_SINGLE_FRAG_RX
-	struct iovec  scratch;
-	struct iovec *scratchiov = &scratch;
+	struct kvec  scratch;
+	struct kvec *scratchiov = &scratch;
 	unsigned int  niov = 1;
 #else
-	struct iovec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
+	struct kvec *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
 	unsigned int  niov = conn->ksnc_rx_niov;
 #endif
-	struct iovec *iov = conn->ksnc_rx_iov;
+	struct kvec *iov = conn->ksnc_rx_iov;
 	struct msghdr msg = {
 		.msg_flags      = 0
 	};
@@ -232,7 +232,7 @@ ksocknal_lib_recv_iov (ksock_conn_t *conn)
 	LASSERT (nob <= conn->ksnc_rx_nob_wanted);
 
 	rc = kernel_recvmsg(conn->ksnc_sock, &msg,
-		(struct kvec *)scratchiov, niov, nob, MSG_DONTWAIT);
+		scratchiov, niov, nob, MSG_DONTWAIT);
 
 	saved_csum = 0;
 	if (conn->ksnc_proto == &ksocknal_protocol_v2x) {
@@ -269,7 +269,7 @@ ksocknal_lib_kiov_vunmap(void *addr)
 
 static void *
 ksocknal_lib_kiov_vmap(lnet_kiov_t *kiov, int niov,
-		       struct iovec *iov, struct page **pages)
+		       struct kvec *iov, struct page **pages)
 {
 	void	     *addr;
 	int	       nob;
@@ -307,15 +307,15 @@ int
 ksocknal_lib_recv_kiov (ksock_conn_t *conn)
 {
 #if SOCKNAL_SINGLE_FRAG_RX || !SOCKNAL_RISK_KMAP_DEADLOCK
-	struct iovec   scratch;
-	struct iovec  *scratchiov = &scratch;
+	struct kvec   scratch;
+	struct kvec  *scratchiov = &scratch;
 	struct page  **pages      = NULL;
 	unsigned int   niov       = 1;
 #else
 #ifdef CONFIG_HIGHMEM
 #warning "XXX risk of kmap deadlock on multiple frags..."
 #endif
-	struct iovec  *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
+	struct kvec  *scratchiov = conn->ksnc_scheduler->kss_scratch_iov;
 	struct page  **pages      = conn->ksnc_scheduler->kss_rx_scratch_pgs;
 	unsigned int   niov       = conn->ksnc_rx_nkiov;
 #endif
@@ -390,13 +390,13 @@ ksocknal_lib_csum_tx(ksock_tx_t *tx)
 	__u32	csum;
 	void	*base;
 
-	LASSERT(tx->tx_iov[0].iov_base == (void *)&tx->tx_msg);
+	LASSERT(tx->tx_iov[0].iov_base == &tx->tx_msg);
 	LASSERT(tx->tx_conn != NULL);
 	LASSERT(tx->tx_conn->ksnc_proto == &ksocknal_protocol_v2x);
 
 	tx->tx_msg.ksm_csum = 0;
 
-	csum = ksocknal_csum(~0, (void *)tx->tx_iov[0].iov_base,
+	csum = ksocknal_csum(~0, tx->tx_iov[0].iov_base,
 			     tx->tx_iov[0].iov_len);
 
 	if (tx->tx_kiov != NULL) {
diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
index ea9d80f40cab..b2f88eb47bba 100644
--- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
+++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c
@@ -717,7 +717,7 @@ ksocknal_pack_msg_v1(ksock_tx_t *tx)
 	LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
 	LASSERT(tx->tx_lnetmsg != NULL);
 
-	tx->tx_iov[0].iov_base = (void *)&tx->tx_lnetmsg->msg_hdr;
+	tx->tx_iov[0].iov_base = &tx->tx_lnetmsg->msg_hdr;
 	tx->tx_iov[0].iov_len  = sizeof(lnet_hdr_t);
 
 	tx->tx_resid = tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t);
@@ -726,7 +726,7 @@ ksocknal_pack_msg_v1(ksock_tx_t *tx)
 static void
 ksocknal_pack_msg_v2(ksock_tx_t *tx)
 {
-	tx->tx_iov[0].iov_base = (void *)&tx->tx_msg;
+	tx->tx_iov[0].iov_base = &tx->tx_msg;
 
 	if (tx->tx_lnetmsg != NULL) {
 		LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c
index c8c1ed84fe5c..0f53c761f1a9 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-move.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-move.c
@@ -158,7 +158,7 @@ fail_peer(lnet_nid_t nid, int outgoing)
 }
 
 unsigned int
-lnet_iov_nob(unsigned int niov, struct iovec *iov)
+lnet_iov_nob(unsigned int niov, struct kvec *iov)
 {
 	unsigned int nob = 0;
 
@@ -170,8 +170,8 @@ lnet_iov_nob(unsigned int niov, struct iovec *iov)
 EXPORT_SYMBOL(lnet_iov_nob);
 
 void
-lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
-		   unsigned int nsiov, struct iovec *siov, unsigned int soffset,
+lnet_copy_iov2iov(unsigned int ndiov, struct kvec *diov, unsigned int doffset,
+		   unsigned int nsiov, struct kvec *siov, unsigned int soffset,
 		   unsigned int nob)
 {
 	/* NB diov, siov are READ-ONLY */
@@ -201,9 +201,9 @@ lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
 	do {
 		LASSERT(ndiov > 0);
 		LASSERT(nsiov > 0);
-		this_nob = MIN(diov->iov_len - doffset,
+		this_nob = min(diov->iov_len - doffset,
 			       siov->iov_len - soffset);
-		this_nob = MIN(this_nob, nob);
+		this_nob = min(this_nob, nob);
 
 		memcpy((char *)diov->iov_base + doffset,
 			(char *)siov->iov_base + soffset, this_nob);
@@ -229,8 +229,8 @@ lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
 EXPORT_SYMBOL(lnet_copy_iov2iov);
 
 int
-lnet_extract_iov(int dst_niov, struct iovec *dst,
-		  int src_niov, struct iovec *src,
+lnet_extract_iov(int dst_niov, struct kvec *dst,
+		  int src_niov, struct kvec *src,
 		  unsigned int offset, unsigned int len)
 {
 	/* Initialise 'dst' to the subset of 'src' starting at 'offset',
@@ -322,9 +322,9 @@ lnet_copy_kiov2kiov(unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
 	do {
 		LASSERT(ndiov > 0);
 		LASSERT(nsiov > 0);
-		this_nob = MIN(diov->kiov_len - doffset,
+		this_nob = min(diov->kiov_len - doffset,
 			       siov->kiov_len - soffset);
-		this_nob = MIN(this_nob, nob);
+		this_nob = min(this_nob, nob);
 
 		if (daddr == NULL)
 			daddr = ((char *)kmap(diov->kiov_page)) +
@@ -371,7 +371,7 @@ lnet_copy_kiov2kiov(unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
 EXPORT_SYMBOL(lnet_copy_kiov2kiov);
 
 void
-lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov, unsigned int iovoffset,
+lnet_copy_kiov2iov(unsigned int niov, struct kvec *iov, unsigned int iovoffset,
 		   unsigned int nkiov, lnet_kiov_t *kiov,
 		   unsigned int kiovoffset, unsigned int nob)
 {
@@ -403,9 +403,9 @@ lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov, unsigned int iovoffset,
 	do {
 		LASSERT(niov > 0);
 		LASSERT(nkiov > 0);
-		this_nob = MIN(iov->iov_len - iovoffset,
-			       kiov->kiov_len - kiovoffset);
-		this_nob = MIN(this_nob, nob);
+		this_nob = min(iov->iov_len - iovoffset,
+			       (__kernel_size_t) kiov->kiov_len - kiovoffset);
+		this_nob = min(this_nob, nob);
 
 		if (addr == NULL)
 			addr = ((char *)kmap(kiov->kiov_page)) +
@@ -443,7 +443,7 @@ EXPORT_SYMBOL(lnet_copy_kiov2iov);
 void
 lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
 		   unsigned int kiovoffset, unsigned int niov,
-		   struct iovec *iov, unsigned int iovoffset,
+		   struct kvec *iov, unsigned int iovoffset,
 		   unsigned int nob)
 {
 	/* NB kiov, iov are READ-ONLY */
@@ -474,9 +474,9 @@ lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
 	do {
 		LASSERT(nkiov > 0);
 		LASSERT(niov > 0);
-		this_nob = MIN(kiov->kiov_len - kiovoffset,
+		this_nob = min((__kernel_size_t) kiov->kiov_len - kiovoffset,
 			       iov->iov_len - iovoffset);
-		this_nob = MIN(this_nob, nob);
+		this_nob = min(this_nob, nob);
 
 		if (addr == NULL)
 			addr = ((char *)kmap(kiov->kiov_page)) +
@@ -566,7 +566,7 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
 	     unsigned int offset, unsigned int mlen, unsigned int rlen)
 {
 	unsigned int  niov = 0;
-	struct iovec *iov = NULL;
+	struct kvec *iov = NULL;
 	lnet_kiov_t  *kiov = NULL;
 	int	   rc;
 
@@ -1530,7 +1530,7 @@ lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
 	LASSERT(md->md_offset == 0);
 
 	rlength = hdr->payload_length;
-	mlength = MIN(rlength, (int)md->md_length);
+	mlength = min_t(int, rlength, md->md_length);
 
 	if (mlength < rlength &&
 	    (md->md_options & LNET_MD_TRUNCATE) == 0) {
@@ -1877,6 +1877,19 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
 		goto drop;
 	}
 
+	if (lnet_isrouter(msg->msg_rxpeer)) {
+		lnet_peer_set_alive(msg->msg_rxpeer);
+		if (avoid_asym_router_failure &&
+		    LNET_NIDNET(src_nid) != LNET_NIDNET(from_nid)) {
+			/* received a remote message from router, update
+			 * remote NI status on this router.
+			 * NB: multi-hop routed message will be ignored.
+			 */
+			lnet_router_ni_update_locked(msg->msg_rxpeer,
+						     LNET_NIDNET(src_nid));
+		}
+	}
+
 	lnet_msg_commit(msg, cpt);
 
 	if (!for_me) {
diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
index 19ed696344fe..3ba0da919b41 100644
--- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c
+++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c
@@ -262,10 +262,10 @@ lnet_mt_of_match(struct lnet_match_info *info, struct lnet_msg *msg)
 {
 	struct lnet_match_table	*mtable;
 	struct lnet_portal	*ptl;
-	int			nmaps;
-	int			rotor;
-	int			routed;
-	int			cpt;
+	unsigned int		nmaps;
+	unsigned int		rotor;
+	unsigned int		cpt;
+	bool			routed;
 
 	/* NB: called w/o lock */
 	LASSERT(info->mi_portal < the_lnet.ln_nportals);
diff --git a/drivers/staging/lustre/lnet/lnet/lo.c b/drivers/staging/lustre/lnet/lnet/lo.c
index 17e1643fd675..f708c2e649d7 100644
--- a/drivers/staging/lustre/lnet/lnet/lo.c
+++ b/drivers/staging/lustre/lnet/lnet/lo.c
@@ -47,7 +47,7 @@ lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
 static int
 lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
 	    int delayed, unsigned int niov,
-	    struct iovec *iov, lnet_kiov_t *kiov,
+	    struct kvec *iov, lnet_kiov_t *kiov,
 	    unsigned int offset, unsigned int mlen, unsigned int rlen)
 {
 	lnet_msg_t *sendmsg = private;
diff --git a/drivers/staging/lustre/lnet/lnet/module.c b/drivers/staging/lustre/lnet/lnet/module.c
index 3c23677bc280..72b7fbc83718 100644
--- a/drivers/staging/lustre/lnet/lnet/module.c
+++ b/drivers/staging/lustre/lnet/lnet/module.c
@@ -108,7 +108,7 @@ lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data)
 	}
 }
 
-DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl);
+static DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl);
 
 static int __init
 init_lnet(void)
diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c
index c667b5b76761..52ec0ab7e3c3 100644
--- a/drivers/staging/lustre/lnet/lnet/router.c
+++ b/drivers/staging/lustre/lnet/lnet/router.c
@@ -46,7 +46,7 @@ MODULE_PARM_DESC(small_router_buffers, "# of small (1 page) messages to buffer i
 static int large_router_buffers;
 module_param(large_router_buffers, int, 0444);
 MODULE_PARM_DESC(large_router_buffers, "# of large messages to buffer in the router");
-static int peer_buffer_credits = 0;
+static int peer_buffer_credits;
 module_param(peer_buffer_credits, int, 0444);
 MODULE_PARM_DESC(peer_buffer_credits, "# router buffer credits per peer");
 
@@ -80,11 +80,11 @@ lnet_peer_buffer_credits(lnet_ni_t *ni)
 
 #endif
 
-static int check_routers_before_use = 0;
+static int check_routers_before_use;
 module_param(check_routers_before_use, int, 0444);
 MODULE_PARM_DESC(check_routers_before_use, "Assume routers are down and ping them before use");
 
-static int avoid_asym_router_failure = 1;
+int avoid_asym_router_failure = 1;
 module_param(avoid_asym_router_failure, int, 0644);
 MODULE_PARM_DESC(avoid_asym_router_failure, "Avoid asymmetrical router failures (0 to disable)");
 
@@ -245,7 +245,7 @@ lnet_find_net_locked (__u32 net)
 
 static void lnet_shuffle_seed(void)
 {
-	static int seeded = 0;
+	static int seeded;
 	int lnd_type, seed[2];
 	struct timeval tv;
 	lnet_ni_t *ni;
@@ -783,6 +783,21 @@ lnet_wait_known_routerstate(void)
 	}
 }
 
+void
+lnet_router_ni_update_locked(lnet_peer_t *gw, __u32 net)
+{
+	lnet_route_t *rte;
+
+	if ((gw->lp_ping_feats & LNET_PING_FEAT_NI_STATUS) != 0) {
+		list_for_each_entry(rte, &gw->lp_routes, lr_gwlist) {
+			if (rte->lr_net == net) {
+				rte->lr_downis = 0;
+				break;
+			}
+		}
+	}
+}
+
 static void
 lnet_update_ni_status_locked(void)
 {
@@ -793,7 +808,7 @@ lnet_update_ni_status_locked(void)
 	LASSERT(the_lnet.ln_routing);
 
 	timeout = router_ping_timeout +
-		  MAX(live_router_check_interval, dead_router_check_interval);
+		  max(live_router_check_interval, dead_router_check_interval);
 
 	now = get_seconds();
 	list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) {
@@ -1578,8 +1593,8 @@ lnet_notify (lnet_ni_t *ni, lnet_nid_t nid, int alive, unsigned long when)
 void
 lnet_router_checker (void)
 {
-	static time_t last = 0;
-	static int    running = 0;
+	static time_t last;
+	static int    running;
 
 	time_t	    now = get_seconds();
 	int	       interval = now - last;
@@ -1593,7 +1608,7 @@ lnet_router_checker (void)
 		return;
 
 	if (last != 0 &&
-	    interval > MAX(live_router_check_interval,
+	    interval > max(live_router_check_interval,
 			   dead_router_check_interval))
 		CNETERR("Checker(%d/%d) not called for %d seconds\n",
 			live_router_check_interval, dead_router_check_interval,
@@ -1664,13 +1679,16 @@ lnet_get_tunables (void)
 	char *s;
 
 	s = getenv("LNET_ROUTER_PING_TIMEOUT");
-	if (s != NULL) router_ping_timeout = atoi(s);
+	if (s != NULL)
+		router_ping_timeout = atoi(s);
 
 	s = getenv("LNET_LIVE_ROUTER_CHECK_INTERVAL");
-	if (s != NULL) live_router_check_interval = atoi(s);
+	if (s != NULL)
+		live_router_check_interval = atoi(s);
 
 	s = getenv("LNET_DEAD_ROUTER_CHECK_INTERVAL");
-	if (s != NULL) dead_router_check_interval = atoi(s);
+	if (s != NULL)
+		dead_router_check_interval = atoi(s);
 
 	/* This replaces old lnd_notify mechanism */
 	check_routers_before_use = 1;
diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c
index 46cde7036f1d..c055afc86eb4 100644
--- a/drivers/staging/lustre/lnet/lnet/router_proc.c
+++ b/drivers/staging/lustre/lnet/lnet/router_proc.c
@@ -49,7 +49,7 @@ enum {
  */
 #define LNET_PROC_CPT_BITS	(LNET_CPT_BITS + 1)
 /* change version, 16 bits or 8 bits */
-#define LNET_PROC_VER_BITS	MAX(((MIN(LNET_LOFFT_BITS, 64)) / 4), 8)
+#define LNET_PROC_VER_BITS	max_t(size_t, min_t(size_t, LNET_LOFFT_BITS, 64) / 4, 8)
 
 #define LNET_PROC_HASH_BITS	LNET_PEER_HASH_BITS
 /*
diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c
index 5bc615309e72..fbff84cea52f 100644
--- a/drivers/staging/lustre/lnet/selftest/conctl.c
+++ b/drivers/staging/lustre/lnet/selftest/conctl.c
@@ -721,7 +721,7 @@ lst_stat_query_ioctl(lstio_stat_args_t *args)
 	return rc;
 }
 
-int lst_test_add_ioctl(lstio_test_args_t *args)
+static int lst_test_add_ioctl(lstio_test_args_t *args)
 {
 	char		*batch_name;
 	char		*src_name = NULL;
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c
index 9999b0dc03e4..77f02b76128e 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.c
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.c
@@ -703,7 +703,7 @@ lstcon_statrpc_prep(lstcon_node_t *nd, unsigned feats, lstcon_rpc_t **crpc)
 	return 0;
 }
 
-lnet_process_id_packed_t *
+static lnet_process_id_packed_t *
 lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov)
 {
 	lnet_process_id_packed_t *pid;
diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.h b/drivers/staging/lustre/lnet/selftest/conrpc.h
index fc1cb56cbab2..2353889c6eac 100644
--- a/drivers/staging/lustre/lnet/selftest/conrpc.h
+++ b/drivers/staging/lustre/lnet/selftest/conrpc.h
@@ -54,7 +54,7 @@
 #define LST_TRANS_TIMEOUT       30
 #define LST_TRANS_MIN_TIMEOUT   3
 
-#define LST_VALIDATE_TIMEOUT(t) MIN(MAX(t, LST_TRANS_MIN_TIMEOUT), LST_TRANS_TIMEOUT)
+#define LST_VALIDATE_TIMEOUT(t) min(max(t, LST_TRANS_MIN_TIMEOUT), LST_TRANS_TIMEOUT)
 
 #define LST_PING_INTERVAL       8
 
diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c
index 49cb6543d538..1e0afc286847 100644
--- a/drivers/staging/lustre/lnet/selftest/console.c
+++ b/drivers/staging/lustre/lnet/selftest/console.c
@@ -46,17 +46,17 @@
 #include "console.h"
 #include "conrpc.h"
 
-#define LST_NODE_STATE_COUNTER(nd, p)		   \
-do {						    \
-	if ((nd)->nd_state == LST_NODE_ACTIVE)	  \
-		(p)->nle_nactive ++;		    \
+#define LST_NODE_STATE_COUNTER(nd, p)			\
+do {							\
+	if ((nd)->nd_state == LST_NODE_ACTIVE)		\
+		(p)->nle_nactive++;			\
 	else if ((nd)->nd_state == LST_NODE_BUSY)       \
-		(p)->nle_nbusy ++;		      \
+		(p)->nle_nbusy++;			\
 	else if ((nd)->nd_state == LST_NODE_DOWN)       \
-		(p)->nle_ndown ++;		      \
-	else					    \
-		(p)->nle_nunknown ++;		   \
-	(p)->nle_nnode ++;			      \
+		(p)->nle_ndown++;			\
+	else						\
+		(p)->nle_nunknown++;			\
+	(p)->nle_nnode++;				\
 } while (0)
 
 lstcon_session_t	console_session;
@@ -223,7 +223,7 @@ lstcon_group_alloc(char *name, lstcon_group_t **grpp)
 static void
 lstcon_group_addref(lstcon_group_t *grp)
 {
-	grp->grp_ref ++;
+	grp->grp_ref++;
 }
 
 static void lstcon_group_ndlink_release(lstcon_group_t *, lstcon_ndlink_t *);
@@ -298,7 +298,7 @@ lstcon_group_ndlink_find(lstcon_group_t *grp, lnet_process_id_t id,
 		return 0;
 
 	list_add_tail(&(*ndlpp)->ndl_link, &grp->grp_ndl_list);
-	grp->grp_nnode ++;
+	grp->grp_nnode++;
 
 	return 0;
 }
@@ -324,7 +324,7 @@ lstcon_group_ndlink_move(lstcon_group_t *old,
 
 	list_add_tail(&ndl->ndl_hlink, &new->grp_ndl_hash[idx]);
 	list_add_tail(&ndl->ndl_link, &new->grp_ndl_list);
-	new->grp_nnode ++;
+	new->grp_nnode++;
 
 	return;
 }
@@ -767,7 +767,7 @@ lstcon_nodes_getent(struct list_head *head, int *index_p,
 				     &nd->nd_state, sizeof(nd->nd_state)))
 			return -EFAULT;
 
-		count ++;
+		count++;
 	}
 
 	if (index <= *index_p)
@@ -1343,7 +1343,7 @@ lstcon_test_add(char *batch_name, int type, int loop,
 	/* add to test list anyway, so user can check what's going on */
 	list_add_tail(&test->tes_link, &batch->bat_test_list);
 
-	batch->bat_ntest ++;
+	batch->bat_ntest++;
 	test->tes_hdr.tsb_index = batch->bat_ntest;
 
 	/*  hold groups so nobody can change them */
@@ -1986,7 +1986,7 @@ static void lstcon_init_acceptor_service(void)
 
 extern int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_data *data);
 
-DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry);
+static DECLARE_IOCTL_HANDLER(lstcon_ioctl_handler, lstcon_ioctl_entry);
 
 /* initialize console */
 int
diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c
index cc9d1826ae66..570914828b8c 100644
--- a/drivers/staging/lustre/lnet/selftest/framework.c
+++ b/drivers/staging/lustre/lnet/selftest/framework.c
@@ -103,7 +103,7 @@ do {				    \
 #define sfw_test_active(t)      (atomic_read(&(t)->tsi_nactive) != 0)
 #define sfw_batch_active(b)     (atomic_read(&(b)->bat_nactive) != 0)
 
-struct smoketest_framework {
+static struct smoketest_framework {
 	struct list_head	 fw_zombie_rpcs;     /* RPCs to be recycled */
 	struct list_head	 fw_zombie_sessions; /* stopping sessions */
 	struct list_head	 fw_tests;	   /* registered test cases */
@@ -194,9 +194,9 @@ sfw_del_session_timer (void)
 	return EBUSY; /* racing with sfw_session_expired() */
 }
 
-/* called with sfw_data.fw_lock held */
 static void
 sfw_deactivate_session (void)
+	__must_hold(&sfw_data.fw_lock)
 {
 	sfw_session_t *sn = sfw_data.fw_session;
 	int	    nactive = 0;
diff --git a/drivers/staging/lustre/lnet/selftest/module.c b/drivers/staging/lustre/lnet/selftest/module.c
index c6ef5b0d8de1..faf409802372 100644
--- a/drivers/staging/lustre/lnet/selftest/module.c
+++ b/drivers/staging/lustre/lnet/selftest/module.c
@@ -61,31 +61,31 @@ lnet_selftest_fini(void)
 	int	i;
 
 	switch (lst_init_step) {
-		case LST_INIT_CONSOLE:
-			lstcon_console_fini();
-		case LST_INIT_FW:
-			sfw_shutdown();
-		case LST_INIT_RPC:
-			srpc_shutdown();
-		case LST_INIT_WI_TEST:
-			for (i = 0;
-			     i < cfs_cpt_number(lnet_cpt_table()); i++) {
-				if (lst_sched_test[i] == NULL)
-					continue;
-				cfs_wi_sched_destroy(lst_sched_test[i]);
-			}
-			LIBCFS_FREE(lst_sched_test,
-				    sizeof(lst_sched_test[0]) *
-				    cfs_cpt_number(lnet_cpt_table()));
-			lst_sched_test = NULL;
-
-		case LST_INIT_WI_SERIAL:
-			cfs_wi_sched_destroy(lst_sched_serial);
-			lst_sched_serial = NULL;
-		case LST_INIT_NONE:
-			break;
-		default:
-			LBUG();
+	case LST_INIT_CONSOLE:
+		lstcon_console_fini();
+	case LST_INIT_FW:
+		sfw_shutdown();
+	case LST_INIT_RPC:
+		srpc_shutdown();
+	case LST_INIT_WI_TEST:
+		for (i = 0;
+		     i < cfs_cpt_number(lnet_cpt_table()); i++) {
+			if (lst_sched_test[i] == NULL)
+				continue;
+			cfs_wi_sched_destroy(lst_sched_test[i]);
+		}
+		LIBCFS_FREE(lst_sched_test,
+			    sizeof(lst_sched_test[0]) *
+			    cfs_cpt_number(lnet_cpt_table()));
+		lst_sched_test = NULL;
+
+	case LST_INIT_WI_SERIAL:
+		cfs_wi_sched_destroy(lst_sched_serial);
+		lst_sched_serial = NULL;
+	case LST_INIT_NONE:
+		break;
+	default:
+		LBUG();
 	}
 	return;
 }
diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c
index f753add7bfb3..1f7d9a6248db 100644
--- a/drivers/staging/lustre/lnet/selftest/rpc.c
+++ b/drivers/staging/lustre/lnet/selftest/rpc.c
@@ -54,7 +54,7 @@ typedef enum {
 	SRPC_STATE_STOPPING,
 } srpc_state_t;
 
-struct smoketest_rpc {
+static struct smoketest_rpc {
 	spinlock_t	 rpc_glock;	/* global lock */
 	srpc_service_t	*rpc_services[SRPC_SERVICE_MAX_ID + 1];
 	lnet_handle_eq_t rpc_lnet_eq;	/* _the_ LNet event queue */
@@ -468,6 +468,7 @@ srpc_post_passive_rqtbuf(int service, int local, void *buf, int len,
 
 static int
 srpc_service_post_buffer(struct srpc_service_cd *scd, struct srpc_buffer *buf)
+	__must_hold(&scd->scd_lock)
 {
 	struct srpc_service	*sv = scd->scd_svc;
 	struct srpc_msg		*msg = &buf->buf_msg;
@@ -559,7 +560,7 @@ srpc_add_buffer(struct swi_workitem *wi)
 		LASSERT(scd->scd_buf_posting > 0);
 		scd->scd_buf_posting--;
 		scd->scd_buf_total++;
-		scd->scd_buf_low = MAX(2, scd->scd_buf_total / 4);
+		scd->scd_buf_low = max(2, scd->scd_buf_total / 4);
 	}
 
 	if (rc != 0) {
@@ -697,6 +698,7 @@ srpc_finish_service(struct srpc_service *sv)
 /* called with sv->sv_lock held */
 static void
 srpc_service_recycle_buffer(struct srpc_service_cd *scd, srpc_buffer_t *buf)
+	__must_hold(&scd->scd_lock)
 {
 	if (!scd->scd_svc->sv_shuttingdown && scd->scd_buf_adjust >= 0) {
 		if (srpc_service_post_buffer(scd, buf) != 0) {
@@ -1486,7 +1488,7 @@ srpc_lnet_ev_handler(lnet_event_t *ev)
 		if (scd->scd_buf_err == 0 && /* adding buffer is enabled */
 		    scd->scd_buf_adjust == 0 &&
 		    scd->scd_buf_nposted < scd->scd_buf_low) {
-			scd->scd_buf_adjust = MAX(scd->scd_buf_total / 2,
+			scd->scd_buf_adjust = max(scd->scd_buf_total / 2,
 						  SFW_TEST_WI_MIN);
 			swi_schedule_workitem(&scd->scd_buf_wi);
 		}
diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h
index 9b5c5df6eb2c..d48701834b18 100644
--- a/drivers/staging/lustre/lnet/selftest/selftest.h
+++ b/drivers/staging/lustre/lnet/selftest/selftest.h
@@ -609,4 +609,16 @@ srpc_wait_service_shutdown(srpc_service_t *sv)
 	}
 }
 
+extern sfw_test_client_ops_t brw_test_client;
+void brw_init_test_client(void);
+
+extern srpc_service_t brw_test_service;
+void brw_init_test_service(void);
+
+extern sfw_test_client_ops_t ping_test_client;
+void ping_init_test_client(void);
+
+extern srpc_service_t ping_test_service;
+void ping_init_test_service(void);
+
 #endif /* __SELFTEST_SELFTEST_H__ */
diff --git a/drivers/staging/lustre/lnet/selftest/timer.c b/drivers/staging/lustre/lnet/selftest/timer.c
index f8352c2a7d37..441f9472a834 100644
--- a/drivers/staging/lustre/lnet/selftest/timer.c
+++ b/drivers/staging/lustre/lnet/selftest/timer.c
@@ -57,7 +57,7 @@
 #define STTIMER_SLOT(t)	       (&stt_data.stt_hash[(((t) >> STTIMER_MINPOLL) & \
 						    (STTIMER_NSLOTS - 1))])
 
-struct st_timer_data {
+static struct st_timer_data {
 	spinlock_t	 stt_lock;
 	/* start time of the slot processed previously */
 	unsigned long       stt_prev_slot;
diff --git a/drivers/staging/lustre/lustre/fid/fid_internal.h b/drivers/staging/lustre/lustre/fid/fid_internal.h
index eb607c52ef3b..b5e8da8956f2 100644
--- a/drivers/staging/lustre/lustre/fid/fid_internal.h
+++ b/drivers/staging/lustre/lustre/fid/fid_internal.h
@@ -47,7 +47,7 @@
 int seq_client_alloc_super(struct lu_client_seq *seq,
 			   const struct lu_env *env);
 
-#if defined (CONFIG_PROC_FS)
+#if defined(CONFIG_PROC_FS)
 extern struct lprocfs_vars seq_client_proc_list[];
 #endif
 
diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c
index 64b1d80c64b0..063441abfcfc 100644
--- a/drivers/staging/lustre/lustre/fid/fid_request.c
+++ b/drivers/staging/lustre/lustre/fid/fid_request.c
@@ -402,7 +402,7 @@ EXPORT_SYMBOL(seq_client_flush);
 
 static void seq_client_proc_fini(struct lu_client_seq *seq)
 {
-#if defined (CONFIG_PROC_FS)
+#if defined(CONFIG_PROC_FS)
 	if (seq->lcs_proc_dir) {
 		if (!IS_ERR(seq->lcs_proc_dir))
 			lprocfs_remove(&seq->lcs_proc_dir);
@@ -413,7 +413,7 @@ static void seq_client_proc_fini(struct lu_client_seq *seq)
 
 static int seq_client_proc_init(struct lu_client_seq *seq)
 {
-#if defined (CONFIG_PROC_FS)
+#if defined(CONFIG_PROC_FS)
 	int rc;
 
 	seq->lcs_proc_dir = lprocfs_register(seq->lcs_name,
diff --git a/drivers/staging/lustre/lustre/fld/fld_cache.c b/drivers/staging/lustre/lustre/fld/fld_cache.c
index 5d95d0b358b8..0d0a73745065 100644
--- a/drivers/staging/lustre/lustre/fld/fld_cache.c
+++ b/drivers/staging/lustre/lustre/fld/fld_cache.c
@@ -257,9 +257,9 @@ void fld_cache_flush(struct fld_cache *cache)
  * entry accordingly.
  */
 
-void fld_cache_punch_hole(struct fld_cache *cache,
-			  struct fld_cache_entry *f_curr,
-			  struct fld_cache_entry *f_new)
+static void fld_cache_punch_hole(struct fld_cache *cache,
+				 struct fld_cache_entry *f_curr,
+				 struct fld_cache_entry *f_new)
 {
 	const struct lu_seq_range *range = &f_new->fce_range;
 	const u64 new_start  = range->lsr_start;
diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h
index 8806b6096953..6125bbe822b5 100644
--- a/drivers/staging/lustre/lustre/fld/fld_internal.h
+++ b/drivers/staging/lustre/lustre/fld/fld_internal.h
@@ -111,7 +111,7 @@ struct fld_cache {
 
 	/**
 	 * Cache name used for debug and messages. */
-	char		     fci_name[80];
+	char		     fci_name[LUSTRE_MDT_MAXNAMELEN];
 	unsigned int		 fci_no_shrink:1;
 };
 
diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c
index 0d361ff43212..b8d17e109a96 100644
--- a/drivers/staging/lustre/lustre/fld/fld_request.c
+++ b/drivers/staging/lustre/lustre/fld/fld_request.c
@@ -131,11 +131,20 @@ fld_rrb_scan(struct lu_client_fld *fld, u64 seq)
 	else
 		hash = 0;
 
+again:
 	list_for_each_entry(target, &fld->lcf_targets, ft_chain) {
 		if (target->ft_idx == hash)
 			return target;
 	}
 
+	if (hash != 0) {
+		/* It is possible the remote target(MDT) are not connected to
+		 * with client yet, so we will refer this to MDT0, which should
+		 * be connected during mount */
+		hash = 0;
+		goto again;
+	}
+
 	CERROR("%s: Can't find target by hash %d (seq %#llx). Targets (%d):\n",
 		fld->lcf_name, hash, seq, fld->lcf_count);
 
@@ -269,7 +278,7 @@ int fld_client_del_target(struct lu_client_fld *fld, __u64 idx)
 }
 EXPORT_SYMBOL(fld_client_del_target);
 
-struct proc_dir_entry *fld_type_proc_dir = NULL;
+static struct proc_dir_entry *fld_type_proc_dir;
 
 #if defined (CONFIG_PROC_FS)
 static int fld_client_proc_init(struct lu_client_fld *fld)
diff --git a/drivers/staging/lustre/lustre/fld/lproc_fld.c b/drivers/staging/lustre/lustre/fld/lproc_fld.c
index 95e7de18d2f1..8c5a65704a37 100644
--- a/drivers/staging/lustre/lustre/fld/lproc_fld.c
+++ b/drivers/staging/lustre/lustre/fld/lproc_fld.c
@@ -87,13 +87,21 @@ fld_proc_hash_seq_show(struct seq_file *m, void *unused)
 }
 
 static ssize_t
-fld_proc_hash_seq_write(struct file *file, const char *buffer,
-			size_t count, loff_t *off)
+fld_proc_hash_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct lu_client_fld *fld;
 	struct lu_fld_hash *hash = NULL;
+	char fh_name[8];
 	int i;
 
+	if (count > sizeof(fh_name))
+		return -ENAMETOOLONG;
+
+	if (copy_from_user(fh_name, buffer, count) != 0)
+		return -EFAULT;
+
 	fld = ((struct seq_file *)file->private_data)->private;
 	LASSERT(fld != NULL);
 
@@ -101,7 +109,7 @@ fld_proc_hash_seq_write(struct file *file, const char *buffer,
 		if (count != strlen(fld_hash[i].fh_name))
 			continue;
 
-		if (!strncmp(fld_hash[i].fh_name, buffer, count)) {
+		if (!strncmp(fld_hash[i].fh_name, fh_name, count)) {
 			hash = &fld_hash[i];
 			break;
 		}
@@ -146,7 +154,7 @@ static int fld_proc_cache_flush_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
-struct file_operations fld_proc_cache_flush_fops = {
+static struct file_operations fld_proc_cache_flush_fops = {
 	.owner		= THIS_MODULE,
 	.open		= fld_proc_cache_flush_open,
 	.write		= fld_proc_cache_flush_write,
diff --git a/drivers/staging/lustre/lustre/include/lclient.h b/drivers/staging/lustre/lustre/include/lclient.h
index b3b841f4d6e6..c5c3a8d9eaa4 100644
--- a/drivers/staging/lustre/lustre/include/lclient.h
+++ b/drivers/staging/lustre/lustre/include/lclient.h
@@ -135,6 +135,7 @@ static inline struct ccc_thread_info *ccc_env_info(const struct lu_env *env)
 static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env)
 {
 	struct cl_attr *attr = &ccc_env_info(env)->cti_attr;
+
 	memset(attr, 0, sizeof(*attr));
 	return attr;
 }
@@ -142,6 +143,7 @@ static inline struct cl_attr *ccc_env_thread_attr(const struct lu_env *env)
 static inline struct cl_io *ccc_env_thread_io(const struct lu_env *env)
 {
 	struct cl_io *io = &ccc_env_info(env)->cti_io;
+
 	memset(io, 0, sizeof(*io));
 	return io;
 }
@@ -323,6 +325,7 @@ void ccc_lock_fini(const struct lu_env *env, struct cl_lock_slice *slice);
 int ccc_lock_enqueue(const struct lu_env *env,
 		     const struct cl_lock_slice *slice,
 		     struct cl_io *io, __u32 enqflags);
+int ccc_lock_use(const struct lu_env *env, const struct cl_lock_slice *slice);
 int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice);
 int ccc_lock_wait(const struct lu_env *env, const struct cl_lock_slice *slice);
 int ccc_lock_fits_into(const struct lu_env *env,
diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h
index cfe503b7df62..8a25cf6f6825 100644
--- a/drivers/staging/lustre/lustre/include/lprocfs_status.h
+++ b/drivers/staging/lustre/lustre/include/lprocfs_status.h
@@ -627,16 +627,16 @@ struct adaptive_timeout;
 extern int lprocfs_at_hist_helper(struct seq_file *m,
 				  struct adaptive_timeout *at);
 extern int lprocfs_rd_timeouts(struct seq_file *m, void *data);
-extern int lprocfs_wr_timeouts(struct file *file, const char *buffer,
+extern int lprocfs_wr_timeouts(struct file *file, const char __user *buffer,
 			       unsigned long count, void *data);
-extern int lprocfs_wr_evict_client(struct file *file, const char *buffer,
+extern int lprocfs_wr_evict_client(struct file *file, const char __user *buffer,
 			    size_t count, loff_t *off);
-extern int lprocfs_wr_ping(struct file *file, const char *buffer,
+extern int lprocfs_wr_ping(struct file *file, const char __user *buffer,
 			   size_t count, loff_t *off);
-extern int lprocfs_wr_import(struct file *file, const char *buffer,
+extern int lprocfs_wr_import(struct file *file, const char __user *buffer,
 		      size_t count, loff_t *off);
 extern int lprocfs_rd_pinger_recov(struct seq_file *m, void *n);
-extern int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
+extern int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer,
 				   size_t count, loff_t *off);
 
 /* Statfs helpers */
@@ -650,8 +650,8 @@ extern int lprocfs_rd_filesfree(struct seq_file *m, void *data);
 extern int lprocfs_write_helper(const char __user *buffer, unsigned long count,
 				int *val);
 extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult);
-extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count,
-				    __u64 *val);
+extern int lprocfs_write_u64_helper(const char __user *buffer,
+				unsigned long count, __u64 *val);
 extern int lprocfs_write_frac_u64_helper(const char *buffer,
 					 unsigned long count,
 					 __u64 *val, int mult);
@@ -716,7 +716,8 @@ static struct file_operations name##_fops = {				\
 		return lprocfs_rd_##type(m, m->private);		\
 	}								\
 	static ssize_t name##_##type##_seq_write(struct file *file,	\
-			const char *buffer, size_t count, loff_t *off)	\
+			const char __user *buffer, size_t count,	\
+						loff_t *off)		\
 	{								\
 		struct seq_file *seq = file->private_data;		\
 		return lprocfs_wr_##type(file, buffer,			\
@@ -726,7 +727,8 @@ static struct file_operations name##_fops = {				\
 
 #define LPROC_SEQ_FOPS_WR_ONLY(name, type)				\
 	static ssize_t name##_##type##_write(struct file *file,		\
-			const char *buffer, size_t count, loff_t *off)	\
+			const char __user *buffer, size_t count,	\
+						loff_t *off)		\
 	{								\
 		return lprocfs_wr_##type(file, buffer, count, off);	\
 	}								\
@@ -939,20 +941,24 @@ static inline int lprocfs_at_hist_helper(struct seq_file *m,
 static inline int lprocfs_rd_timeouts(struct seq_file *m, void *data)
 { return 0; }
 static inline int lprocfs_wr_timeouts(struct file *file,
-				      const char *buffer,
-				      unsigned long count, void *data)
+				const char __user *buffer,
+				unsigned long count, void *data)
 { return 0; }
-static inline int lprocfs_wr_evict_client(struct file *file, const char *buffer,
-				    size_t count, loff_t *off)
+static inline int lprocfs_wr_evict_client(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 { return 0; }
-static inline int lprocfs_wr_ping(struct file *file, const char *buffer,
-			   size_t count, loff_t *off)
+static inline int lprocfs_wr_ping(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 { return 0; }
-static inline int lprocfs_wr_import(struct file *file, const char *buffer,
-			      size_t count, loff_t *off)
+static inline int lprocfs_wr_import(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 { return 0; }
-static inline int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
-					size_t count, loff_t *off)
+static inline int lprocfs_wr_pinger_recov(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 { return 0; }
 
 /* Statfs helpers */
diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
index 7b7457cf70e3..305ecbee9b78 100644
--- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
+++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
@@ -105,6 +105,11 @@
  * FOO_BULK_PORTAL    is for incoming bulk on the FOO
  */
 
+/* Lustre service names are following the format
+ * service name + MDT + seq name
+ */
+#define LUSTRE_MDT_MAXNAMELEN	80
+
 #define CONNMGR_REQUEST_PORTAL	  1
 #define CONNMGR_REPLY_PORTAL	    2
 //#define OSC_REQUEST_PORTAL	    3
diff --git a/drivers/staging/lustre/lustre/include/lustre_fid.h b/drivers/staging/lustre/lustre/include/lustre_fid.h
index 2d6fbb4b1b39..0a0929fd9023 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fid.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fid.h
@@ -358,7 +358,7 @@ struct lu_client_seq {
 	 * Service uuid, passed from MDT + seq name to form unique seq name to
 	 * use it with procfs.
 	 */
-	char		    lcs_name[80];
+	char		    lcs_name[LUSTRE_MDT_MAXNAMELEN];
 
 	/*
 	 * Sequence width, that is how many objects may be allocated in one
@@ -408,7 +408,7 @@ struct lu_server_seq {
 	 * Service uuid, passed from MDT + seq name to form unique seq name to
 	 * use it with procfs.
 	 */
-	char		    lss_name[80];
+	char		    lss_name[LUSTRE_MDT_MAXNAMELEN];
 
 	/*
 	 * Allocation chunks for super and meta sequences. Default values are
diff --git a/drivers/staging/lustre/lustre/include/lustre_fld.h b/drivers/staging/lustre/lustre/include/lustre_fld.h
index 64c504849a22..5ee4b1ed0995 100644
--- a/drivers/staging/lustre/lustre/include/lustre_fld.h
+++ b/drivers/staging/lustre/lustre/include/lustre_fld.h
@@ -93,7 +93,7 @@ struct lu_server_fld {
 
 	/**
 	 * Fld service name in form "fld-srv-lustre-MDTXXX" */
-	char		     lsf_name[80];
+	char		     lsf_name[LUSTRE_MDT_MAXNAMELEN];
 
 };
 
@@ -124,7 +124,7 @@ struct lu_client_fld {
 
 	/**
 	 * Client fld proc entry name. */
-	char		     lcf_name[80];
+	char		     lcf_name[LUSTRE_MDT_MAXNAMELEN];
 
 	int		      lcf_flags;
 };
diff --git a/drivers/staging/lustre/lustre/include/lustre_update.h b/drivers/staging/lustre/lustre/include/lustre_update.h
deleted file mode 100644
index 84defce0f623..000000000000
--- a/drivers/staging/lustre/lustre/include/lustre_update.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.htm
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2013, Intel Corporation.
- */
-/*
- * lustre/include/lustre_update.h
- *
- * Author: Di Wang <di.wang@intel.com>
- */
-
-#ifndef _LUSTRE_UPDATE_H
-#define _LUSTRE_UPDATE_H
-
-#define UPDATE_BUFFER_SIZE	8192
-struct update_request {
-	struct dt_device	*ur_dt;
-	struct list_head		ur_list;    /* attached itself to thandle */
-	int			ur_flags;
-	int			ur_rc;	    /* request result */
-	int			ur_batchid; /* Current batch(trans) id */
-	struct update_buf	*ur_buf;   /* Holding the update req */
-};
-
-static inline unsigned long update_size(struct update *update)
-{
-	unsigned long size;
-	int	   i;
-
-	size = cfs_size_round(offsetof(struct update, u_bufs[0]));
-	for (i = 0; i < UPDATE_BUF_COUNT; i++)
-		size += cfs_size_round(update->u_lens[i]);
-
-	return size;
-}
-
-static inline void *update_param_buf(struct update *update, int index,
-				     int *size)
-{
-	int	i;
-	void	*ptr;
-
-	if (index >= UPDATE_BUF_COUNT)
-		return NULL;
-
-	ptr = (char *)update + cfs_size_round(offsetof(struct update,
-						       u_bufs[0]));
-	for (i = 0; i < index; i++) {
-		LASSERT(update->u_lens[i] > 0);
-		ptr += cfs_size_round(update->u_lens[i]);
-	}
-
-	if (size != NULL)
-		*size = update->u_lens[index];
-
-	return ptr;
-}
-
-static inline unsigned long update_buf_size(struct update_buf *buf)
-{
-	unsigned long size;
-	int	   i = 0;
-
-	size = cfs_size_round(offsetof(struct update_buf, ub_bufs[0]));
-	for (i = 0; i < buf->ub_count; i++) {
-		struct update *update;
-
-		update = (struct update *)((char *)buf + size);
-		size += update_size(update);
-	}
-	LASSERT(size <= UPDATE_BUFFER_SIZE);
-	return size;
-}
-
-static inline void *update_buf_get(struct update_buf *buf, int index, int *size)
-{
-	int	count = buf->ub_count;
-	void	*ptr;
-	int	i = 0;
-
-	if (index >= count)
-		return NULL;
-
-	ptr = (char *)buf + cfs_size_round(offsetof(struct update_buf,
-						    ub_bufs[0]));
-	for (i = 0; i < index; i++)
-		ptr += update_size((struct update *)ptr);
-
-	if (size != NULL)
-		*size = update_size((struct update *)ptr);
-
-	return ptr;
-}
-
-static inline void update_init_reply_buf(struct update_reply *reply, int count)
-{
-	reply->ur_version = UPDATE_REPLY_V1;
-	reply->ur_count = count;
-}
-
-static inline void *update_get_buf_internal(struct update_reply *reply,
-					    int index, int *size)
-{
-	char *ptr;
-	int count = reply->ur_count;
-	int i;
-
-	if (index >= count)
-		return NULL;
-
-	ptr = (char *)reply + cfs_size_round(offsetof(struct update_reply,
-					     ur_lens[count]));
-	for (i = 0; i < index; i++) {
-		LASSERT(reply->ur_lens[i] > 0);
-		ptr += cfs_size_round(reply->ur_lens[i]);
-	}
-
-	if (size != NULL)
-		*size = reply->ur_lens[index];
-
-	return ptr;
-}
-
-static inline void update_insert_reply(struct update_reply *reply, void *data,
-				       int data_len, int index, int rc)
-{
-	char *ptr;
-
-	ptr = update_get_buf_internal(reply, index, NULL);
-	LASSERT(ptr != NULL);
-
-	*(int *)ptr = cpu_to_le32(rc);
-	ptr += sizeof(int);
-	if (data_len > 0) {
-		LASSERT(data != NULL);
-		memcpy(ptr, data, data_len);
-	}
-	reply->ur_lens[index] = data_len + sizeof(int);
-}
-
-static inline int update_get_reply_buf(struct update_reply *reply, void **buf,
-				       int index)
-{
-	char *ptr;
-	int  size = 0;
-	int  result;
-
-	ptr = update_get_buf_internal(reply, index, &size);
-	result = *(int *)ptr;
-
-	if (result < 0)
-		return result;
-
-	LASSERT((ptr != NULL && size >= sizeof(int)));
-	*buf = ptr + sizeof(int);
-	return size - sizeof(int);
-}
-
-static inline int update_get_reply_result(struct update_reply *reply,
-					  void **buf, int index)
-{
-	void *ptr;
-	int  size;
-
-	ptr = update_get_buf_internal(reply, index, &size);
-	LASSERT(ptr != NULL && size > sizeof(int));
-	return *(int *)ptr;
-}
-
-#endif
diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
index 24d26ab35346..23095bb75226 100644
--- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
@@ -586,6 +586,12 @@ int ccc_lock_enqueue(const struct lu_env *env,
 	return 0;
 }
 
+int ccc_lock_use(const struct lu_env *env, const struct cl_lock_slice *slice)
+{
+	CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj));
+	return 0;
+}
+
 int ccc_lock_unuse(const struct lu_env *env, const struct cl_lock_slice *slice)
 {
 	CLOBINVRNT(env, slice->cls_obj, ccc_object_invariant(slice->cls_obj));
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
index 6c6c57ca91de..20e64cddb1f4 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_internal.h
@@ -249,8 +249,9 @@ typedef enum ldlm_policy_res ldlm_policy_res_t;
 	struct __##var##__dummy_read {; } /* semicolon catcher */
 
 #define LDLM_POOL_PROC_WRITER(var, type)				    \
-	static int lprocfs_wr_##var(struct file *file, const char *buffer,  \
-			     unsigned long count, void *data)		    \
+	static int lprocfs_wr_##var(struct file *file,			    \
+				const char __user *buffer,		    \
+				unsigned long count, void *data)	    \
 	{								    \
 		struct ldlm_pool *pl = data;				    \
 		type tmp;						    \
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
index 4c838f615a64..d20d277dc2f7 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c
@@ -470,6 +470,7 @@ static void ldlm_cli_pool_pop_slv(struct ldlm_pool *pl)
 static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
 {
 	time_t recalc_interval_sec;
+	int ret;
 
 	recalc_interval_sec = get_seconds() - pl->pl_recalc_time;
 	if (recalc_interval_sec < pl->pl_recalc_period)
@@ -490,16 +491,15 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
 	 */
 	ldlm_cli_pool_pop_slv(pl);
 
-	pl->pl_recalc_time = get_seconds();
-	lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
-			    recalc_interval_sec);
 	spin_unlock(&pl->pl_lock);
 
 	/*
 	 * Do not cancel locks in case lru resize is disabled for this ns.
 	 */
-	if (!ns_connect_lru_resize(ldlm_pl2ns(pl)))
-		return 0;
+	if (!ns_connect_lru_resize(ldlm_pl2ns(pl))) {
+		ret = 0;
+		goto out;
+	}
 
 	/*
 	 * In the time of canceling locks on client we do not need to maintain
@@ -507,7 +507,19 @@ static int ldlm_cli_pool_recalc(struct ldlm_pool *pl)
 	 * It may be called when SLV has changed much, this is why we do not
 	 * take into account pl->pl_recalc_time here.
 	 */
-	return ldlm_cancel_lru(ldlm_pl2ns(pl), 0, LCF_ASYNC, LDLM_CANCEL_LRUR);
+	ret = ldlm_cancel_lru(ldlm_pl2ns(pl), 0, LCF_ASYNC, LDLM_CANCEL_LRUR);
+
+out:
+	spin_lock(&pl->pl_lock);
+	/*
+	 * Time of LRU resizing might be longer than period,
+	 * so update after LRU resizing rather than before it.
+	 */
+	pl->pl_recalc_time = get_seconds();
+	lprocfs_counter_add(pl->pl_stats, LDLM_POOL_TIMING_STAT,
+			    recalc_interval_sec);
+	spin_unlock(&pl->pl_lock);
+	return ret;
 }
 
 /**
@@ -591,6 +603,14 @@ int ldlm_pool_recalc(struct ldlm_pool *pl)
 	}
 	recalc_interval_sec = pl->pl_recalc_time - get_seconds() +
 			      pl->pl_recalc_period;
+	if (recalc_interval_sec <= 0) {
+		/* Prevent too frequent recalculation. */
+		CDEBUG(D_DLMTRACE, "Negative interval(%ld), "
+		       "too short period(%ld)",
+		       recalc_interval_sec,
+		       pl->pl_recalc_period);
+		recalc_interval_sec = 1;
+	}
 
 	return recalc_interval_sec;
 }
@@ -697,8 +717,8 @@ LPROC_SEQ_FOPS_RO(lprocfs_grant_plan);
 LDLM_POOL_PROC_READER_SEQ_SHOW(recalc_period, int);
 LDLM_POOL_PROC_WRITER(recalc_period, int);
 static ssize_t lprocfs_recalc_period_seq_write(struct file *file,
-					       const char *buf, size_t len,
-					       loff_t *off)
+					       const char __user *buf,
+					       size_t len, loff_t *off)
 {
 	struct seq_file *seq = file->private_data;
 
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
index 1f150e46f50e..c6f62a91b233 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
@@ -72,7 +72,7 @@ extern unsigned int ldlm_cancel_unused_locks_before_replay;
 unsigned int ldlm_dump_granted_max = 256;
 
 #if defined(CONFIG_PROC_FS)
-static ssize_t lprocfs_wr_dump_ns(struct file *file, const char *buffer,
+static ssize_t lprocfs_wr_dump_ns(struct file *file, const char __user *buffer,
 				  size_t count, loff_t *off)
 {
 	ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE);
@@ -287,8 +287,9 @@ static int lprocfs_elc_seq_show(struct seq_file *m, void *v)
 	return lprocfs_rd_uint(m, &supp);
 }
 
-static ssize_t lprocfs_elc_seq_write(struct file *file, const char *buffer,
-				 size_t count, loff_t *off)
+static ssize_t lprocfs_elc_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private;
 	unsigned int supp = -1;
diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c
index a7a7ac626aaf..76c62e87a415 100644
--- a/drivers/staging/lustre/lustre/libcfs/debug.c
+++ b/drivers/staging/lustre/lustre/libcfs/debug.c
@@ -57,7 +57,7 @@ module_param(libcfs_debug, int, 0644);
 MODULE_PARM_DESC(libcfs_debug, "Lustre kernel debug mask");
 EXPORT_SYMBOL(libcfs_debug);
 
-unsigned int libcfs_debug_mb = 0;
+static unsigned int libcfs_debug_mb;
 module_param(libcfs_debug_mb, uint, 0644);
 MODULE_PARM_DESC(libcfs_debug_mb, "Total debug buffer size.");
 EXPORT_SYMBOL(libcfs_debug_mb);
@@ -93,7 +93,7 @@ EXPORT_SYMBOL(libcfs_debug_binary);
 unsigned int libcfs_stack = 3 * THREAD_SIZE / 4;
 EXPORT_SYMBOL(libcfs_stack);
 
-unsigned int portal_enter_debugger;
+static unsigned int portal_enter_debugger;
 EXPORT_SYMBOL(portal_enter_debugger);
 
 unsigned int libcfs_catastrophe;
@@ -115,7 +115,7 @@ static wait_queue_head_t debug_ctlwq;
 char libcfs_debug_file_path_arr[PATH_MAX] = LIBCFS_DEBUG_FILE_PATH_DEFAULT;
 
 /* We need to pass a pointer here, but elsewhere this must be a const */
-char *libcfs_debug_file_path;
+static char *libcfs_debug_file_path;
 module_param(libcfs_debug_file_path, charp, 0644);
 MODULE_PARM_DESC(libcfs_debug_file_path,
 		 "Path for dumping debug logs, set 'NONE' to prevent log dumping");
@@ -124,7 +124,7 @@ int libcfs_panic_in_progress;
 
 /* libcfs_debug_token2mask() expects the returned
  * string in lower-case */
-const char *
+static const char *
 libcfs_debug_subsys2str(int subsys)
 {
 	switch (1 << subsys) {
@@ -185,7 +185,7 @@ libcfs_debug_subsys2str(int subsys)
 
 /* libcfs_debug_token2mask() expects the returned
  * string in lower-case */
-const char *
+static const char *
 libcfs_debug_dbg2str(int debug)
 {
 	switch (1 << debug) {
@@ -350,7 +350,7 @@ void libcfs_debug_dumplog_internal(void *arg)
 	current->journal_info = journal_info;
 }
 
-int libcfs_debug_dumplog_thread(void *arg)
+static int libcfs_debug_dumplog_thread(void *arg)
 {
 	libcfs_debug_dumplog_internal(arg);
 	wake_up(&debug_ctlwq);
diff --git a/drivers/staging/lustre/lustre/libcfs/hash.c b/drivers/staging/lustre/lustre/libcfs/hash.c
index 2d1e6729e996..ec3a2a8b8b2c 100644
--- a/drivers/staging/lustre/lustre/libcfs/hash.c
+++ b/drivers/staging/lustre/lustre/libcfs/hash.c
@@ -126,18 +126,21 @@ cfs_hash_nl_unlock(union cfs_hash_lock *lock, int exclusive) {}
 
 static inline void
 cfs_hash_spin_lock(union cfs_hash_lock *lock, int exclusive)
+	__acquires(&lock->spin)
 {
 	spin_lock(&lock->spin);
 }
 
 static inline void
 cfs_hash_spin_unlock(union cfs_hash_lock *lock, int exclusive)
+	__releases(&lock->spin)
 {
 	spin_unlock(&lock->spin);
 }
 
 static inline void
 cfs_hash_rw_lock(union cfs_hash_lock *lock, int exclusive)
+	__acquires(&lock->rw)
 {
 	if (!exclusive)
 		read_lock(&lock->rw);
@@ -147,6 +150,7 @@ cfs_hash_rw_lock(union cfs_hash_lock *lock, int exclusive)
 
 static inline void
 cfs_hash_rw_unlock(union cfs_hash_lock *lock, int exclusive)
+	__releases(&lock->rw)
 {
 	if (!exclusive)
 		read_unlock(&lock->rw);
@@ -1580,7 +1584,7 @@ cfs_hash_for_each_relax(struct cfs_hash *hs, cfs_hash_for_each_cb_t func,
 
 	stop_on_change = cfs_hash_with_rehash_key(hs) ||
 			 !cfs_hash_with_no_itemref(hs) ||
-			 CFS_HOP(hs, put_locked) == NULL;
+			 hs->hs_ops->hs_put_locked == NULL;
 	cfs_hash_lock(hs, 0);
 	LASSERT(!cfs_hash_is_rehashing(hs));
 
@@ -1635,9 +1639,9 @@ cfs_hash_for_each_nolock(struct cfs_hash *hs,
 	    !cfs_hash_with_no_itemref(hs))
 		return -EOPNOTSUPP;
 
-	if (CFS_HOP(hs, get) == NULL ||
-	    (CFS_HOP(hs, put) == NULL &&
-	     CFS_HOP(hs, put_locked) == NULL))
+	if (hs->hs_ops->hs_get == NULL ||
+	    (hs->hs_ops->hs_put == NULL &&
+	     hs->hs_ops->hs_put_locked == NULL))
 		return -EOPNOTSUPP;
 
 	cfs_hash_for_each_enter(hs);
@@ -1667,9 +1671,9 @@ cfs_hash_for_each_empty(struct cfs_hash *hs,
 	if (cfs_hash_with_no_lock(hs))
 		return -EOPNOTSUPP;
 
-	if (CFS_HOP(hs, get) == NULL ||
-	    (CFS_HOP(hs, put) == NULL &&
-	     CFS_HOP(hs, put_locked) == NULL))
+	if (hs->hs_ops->hs_get == NULL ||
+	    (hs->hs_ops->hs_put == NULL &&
+	     hs->hs_ops->hs_put_locked == NULL))
 		return -EOPNOTSUPP;
 
 	cfs_hash_for_each_enter(hs);
diff --git a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
index e2aa637abcf9..d9b7c6b69db4 100644
--- a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
+++ b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
@@ -228,12 +228,12 @@ int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func,
 	if (kkuc_groups[group].next == NULL)
 		return 0;
 
-	down_read(&kg_sem);
+	down_write(&kg_sem);
 	list_for_each_entry(reg, &kkuc_groups[group], kr_chain) {
 		if (reg->kr_fp != NULL)
 			rc = cb_func(reg->kr_data, cb_arg);
 	}
-	up_read(&kg_sem);
+	up_write(&kg_sem);
 
 	return rc;
 }
diff --git a/drivers/staging/lustre/lustre/libcfs/libcfs_string.c b/drivers/staging/lustre/lustre/libcfs/libcfs_string.c
index fb88733607a9..76d4392bd282 100644
--- a/drivers/staging/lustre/lustre/libcfs/libcfs_string.c
+++ b/drivers/staging/lustre/lustre/libcfs/libcfs_string.c
@@ -47,7 +47,7 @@ int cfs_str2mask(const char *str, const char *(*bit2str)(int bit),
 		 int *oldmask, int minmask, int allmask)
 {
 	const char *debugstr;
-	char op = 0;
+	char op = '\0';
 	int newmask = minmask, i, len, found = 0;
 
 	/* <str> must be a list of tokens separated by whitespace
@@ -55,10 +55,10 @@ int cfs_str2mask(const char *str, const char *(*bit2str)(int bit),
 	 * appears first in <str>, '*oldmask' is used as the starting point
 	 * (relative), otherwise minmask is used (absolute).  An operator
 	 * applies to all following tokens up to the next operator. */
-	while (*str != 0) {
+	while (*str != '\0') {
 		while (isspace(*str))
 			str++;
-		if (*str == 0)
+		if (*str == '\0')
 			break;
 		if (*str == '+' || *str == '-') {
 			op = *str++;
@@ -67,13 +67,15 @@ int cfs_str2mask(const char *str, const char *(*bit2str)(int bit),
 				newmask = *oldmask;
 			while (isspace(*str))
 				str++;
-			if (*str == 0)	  /* trailing op */
+			if (*str == '\0')  /* trailing op */
 				return -EINVAL;
 		}
 
 		/* find token length */
-		for (len = 0; str[len] != 0 && !isspace(str[len]) &&
-		      str[len] != '+' && str[len] != '-'; len++);
+		len = 0;
+		while (str[len] != '\0' && !isspace(str[len]) &&
+		       str[len] != '+' && str[len] != '-')
+			len++;
 
 		/* match token */
 		found = 0;
@@ -132,7 +134,7 @@ char *cfs_firststr(char *str, size_t size)
 		++end;
 	}
 
-	*end= '\0';
+	*end = '\0';
 out:
 	return str;
 }
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
index d71ad5ed1f6d..277f6b890e09 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
@@ -82,17 +82,12 @@ int cfs_cap_raised(cfs_cap_t cap)
 	return cap_raised(current_cap(), cap);
 }
 
-void cfs_kernel_cap_pack(kernel_cap_t kcap, cfs_cap_t *cap)
+static void cfs_kernel_cap_pack(kernel_cap_t kcap, cfs_cap_t *cap)
 {
 	/* XXX lost high byte */
 	*cap = kcap.cap[0];
 }
 
-void cfs_kernel_cap_unpack(kernel_cap_t *kcap, cfs_cap_t cap)
-{
-	kcap->cap[0] = cap;
-}
-
 cfs_cap_t cfs_curproc_cap_pack(void)
 {
 	cfs_cap_t cap;
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
index 83d3f08a37b2..c539e3741583 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-proc.c
@@ -232,8 +232,9 @@ static int proc_debug_mb(struct ctl_table *table, int write,
 				 __proc_debug_mb);
 }
 
-int proc_console_max_delay_cs(struct ctl_table *table, int write,
-			      void __user *buffer, size_t *lenp, loff_t *ppos)
+static int proc_console_max_delay_cs(struct ctl_table *table, int write,
+				     void __user *buffer, size_t *lenp,
+				     loff_t *ppos)
 {
 	int rc, max_delay_cs;
 	struct ctl_table dummy = *table;
@@ -264,8 +265,9 @@ int proc_console_max_delay_cs(struct ctl_table *table, int write,
 	return rc;
 }
 
-int proc_console_min_delay_cs(struct ctl_table *table, int write,
-			      void __user *buffer, size_t *lenp, loff_t *ppos)
+static int proc_console_min_delay_cs(struct ctl_table *table, int write,
+				     void __user *buffer, size_t *lenp,
+				     loff_t *ppos)
 {
 	int rc, min_delay_cs;
 	struct ctl_table dummy = *table;
@@ -296,8 +298,8 @@ int proc_console_min_delay_cs(struct ctl_table *table, int write,
 	return rc;
 }
 
-int proc_console_backoff(struct ctl_table *table, int write,
-			 void __user *buffer, size_t *lenp, loff_t *ppos)
+static int proc_console_backoff(struct ctl_table *table, int write,
+				void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	int rc, backoff;
 	struct ctl_table dummy = *table;
@@ -324,16 +326,18 @@ int proc_console_backoff(struct ctl_table *table, int write,
 	return rc;
 }
 
-int libcfs_force_lbug(struct ctl_table *table, int write, void __user *buffer,
-		      size_t *lenp, loff_t *ppos)
+static int libcfs_force_lbug(struct ctl_table *table, int write,
+			     void __user *buffer,
+			     size_t *lenp, loff_t *ppos)
 {
 	if (write)
 		LBUG();
 	return 0;
 }
 
-int proc_fail_loc(struct ctl_table *table, int write, void __user *buffer,
-		  size_t *lenp, loff_t *ppos)
+static int proc_fail_loc(struct ctl_table *table, int write,
+			 void __user *buffer,
+			 size_t *lenp, loff_t *ppos)
 {
 	int rc;
 	long old_fail_loc = cfs_fail_loc;
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c
index b91a1f95bbd0..cd2fc01dea4c 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-tcpip.c
@@ -43,7 +43,7 @@
 /* For sys_open & sys_close */
 #include <linux/syscalls.h>
 
-int
+static int
 libcfs_sock_ioctl(int cmd, unsigned long arg)
 {
 	mm_segment_t	oldmm = get_fs();
diff --git a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c
index 976c61ed49f4..c8e293002e07 100644
--- a/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c
+++ b/drivers/staging/lustre/lustre/libcfs/linux/linux-tracefile.c
@@ -151,6 +151,7 @@ cfs_trace_buf_type_t cfs_trace_buf_idx_get(void)
  * for details.
  */
 int cfs_trace_lock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
+	__acquires(&tcd->tc_lock)
 {
 	__LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX);
 	if (tcd->tcd_type == CFS_TCD_TYPE_IRQ)
@@ -165,6 +166,7 @@ int cfs_trace_lock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
 }
 
 void cfs_trace_unlock_tcd(struct cfs_trace_cpu_data *tcd, int walking)
+	__releases(&tcd->tcd_lock)
 {
 	__LASSERT(tcd->tcd_type < CFS_TCD_TYPE_MAX);
 	if (tcd->tcd_type == CFS_TCD_TYPE_IRQ)
@@ -269,5 +271,5 @@ int cfs_trace_max_debug_mb(void)
 {
 	int  total_mb = (totalram_pages >> (20 - PAGE_SHIFT));
 
-	return MAX(512, (total_mb * 80)/100);
+	return max(512, (total_mb * 80)/100);
 }
diff --git a/drivers/staging/lustre/lustre/libcfs/module.c b/drivers/staging/lustre/lustre/libcfs/module.c
index 2c4fc74505bc..7dc77dd402b8 100644
--- a/drivers/staging/lustre/lustre/libcfs/module.c
+++ b/drivers/staging/lustre/lustre/libcfs/module.c
@@ -42,8 +42,7 @@
 #include "../../include/linux/lnet/lnet.h"
 #include "tracefile.h"
 
-void
-kportal_memhog_free (struct libcfs_device_userstate *ldu)
+static void kportal_memhog_free (struct libcfs_device_userstate *ldu)
 {
 	struct page **level0p = &ldu->ldu_memhog_root_page;
 	struct page **level1p;
@@ -86,8 +85,7 @@ kportal_memhog_free (struct libcfs_device_userstate *ldu)
 	LASSERT (ldu->ldu_memhog_pages == 0);
 }
 
-int
-kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages,
+static int kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages,
 		     gfp_t flags)
 {
 	struct page **level0p;
@@ -334,8 +332,6 @@ extern struct mutex cfs_trace_thread_mutex;
 extern struct cfs_wi_sched *cfs_sched_rehash;
 
 extern void libcfs_init_nidstrings(void);
-extern int libcfs_arch_init(void);
-extern void libcfs_arch_cleanup(void);
 
 static int init_libcfs_module(void)
 {
diff --git a/drivers/staging/lustre/lustre/libcfs/nidstrings.c b/drivers/staging/lustre/lustre/libcfs/nidstrings.c
index 47c239f22ba8..087449f4e6c1 100644
--- a/drivers/staging/lustre/lustre/libcfs/nidstrings.c
+++ b/drivers/staging/lustre/lustre/libcfs/nidstrings.c
@@ -81,14 +81,105 @@ libcfs_next_nidstring(void)
 	return str;
 }
 
-static int  libcfs_lo_str2addr(const char *str, int nob, __u32 *addr);
-static void libcfs_ip_addr2str(__u32 addr, char *str);
-static int  libcfs_ip_str2addr(const char *str, int nob, __u32 *addr);
-static void libcfs_decnum_addr2str(__u32 addr, char *str);
-static void libcfs_hexnum_addr2str(__u32 addr, char *str);
-static int  libcfs_num_str2addr(const char *str, int nob, __u32 *addr);
-static int  libcfs_num_parse(char *str, int len, struct list_head *list);
-static int  libcfs_num_match(__u32 addr, struct list_head *list);
+static int libcfs_lo_str2addr(const char *str, int nob, __u32 *addr)
+{
+	*addr = 0;
+	return 1;
+}
+
+static void libcfs_ip_addr2str(__u32 addr, char *str)
+{
+	snprintf(str, LNET_NIDSTR_SIZE, "%u.%u.%u.%u",
+		 (addr >> 24) & 0xff, (addr >> 16) & 0xff,
+		 (addr >> 8) & 0xff, addr & 0xff);
+}
+
+static int libcfs_ip_str2addr(const char *str, int nob, __u32 *addr)
+{
+	unsigned int	a;
+	unsigned int	b;
+	unsigned int	c;
+	unsigned int	d;
+	int		n = nob; /* XscanfX */
+
+	/* numeric IP? */
+	if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 &&
+	    n == nob &&
+	    (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
+	    (c & ~0xff) == 0 && (d & ~0xff) == 0) {
+		*addr = ((a<<24)|(b<<16)|(c<<8)|d);
+		return 1;
+	}
+
+	return 0;
+}
+
+static void libcfs_decnum_addr2str(__u32 addr, char *str)
+{
+	snprintf(str, LNET_NIDSTR_SIZE, "%u", addr);
+}
+
+static void libcfs_hexnum_addr2str(__u32 addr, char *str)
+{
+	snprintf(str, LNET_NIDSTR_SIZE, "0x%x", addr);
+}
+
+static int libcfs_num_str2addr(const char *str, int nob, __u32 *addr)
+{
+	int     n;
+
+	n = nob;
+	if (sscanf(str, "0x%x%n", addr, &n) >= 1 && n == nob)
+		return 1;
+
+	n = nob;
+	if (sscanf(str, "0X%x%n", addr, &n) >= 1 && n == nob)
+		return 1;
+
+	n = nob;
+	if (sscanf(str, "%u%n", addr, &n) >= 1 && n == nob)
+		return 1;
+
+	return 0;
+}
+
+/**
+ * Nf_parse_addrlist method for networks using numeric addresses.
+ *
+ * Examples of such networks are gm and elan.
+ *
+ * \retval 0 if \a str parsed to numeric address
+ * \retval errno otherwise
+ */
+static int
+libcfs_num_parse(char *str, int len, struct list_head *list)
+{
+	struct cfs_expr_list *el;
+	int	rc;
+
+	rc = cfs_expr_list_parse(str, len, 0, MAX_NUMERIC_VALUE, &el);
+	if (rc == 0)
+		list_add_tail(&el->el_link, list);
+
+	return rc;
+}
+
+/*
+ * Nf_match_addr method for networks using numeric addresses
+ *
+ * \retval 1 on match
+ * \retval 0 otherwise
+ */
+static int
+libcfs_num_match(__u32 addr, struct list_head *numaddr)
+{
+	struct cfs_expr_list *el;
+
+	LASSERT(!list_empty(numaddr));
+	el = list_entry(numaddr->next, struct cfs_expr_list, el_link);
+
+	return cfs_expr_list_match(addr, el);
+}
 
 struct netstrfns {
 	int	  nf_type;
@@ -197,24 +288,7 @@ static struct netstrfns  libcfs_netstrfns[] = {
 	{/* .nf_type      */  -1},
 };
 
-const int libcfs_nnetstrfns = ARRAY_SIZE(libcfs_netstrfns);
-
-int
-libcfs_lo_str2addr(const char *str, int nob, __u32 *addr)
-{
-	*addr = 0;
-	return 1;
-}
-
-void
-libcfs_ip_addr2str(__u32 addr, char *str)
-{
-#if 0   /* never lookup */
-#endif
-	snprintf(str, LNET_NIDSTR_SIZE, "%u.%u.%u.%u",
-		 (addr >> 24) & 0xff, (addr >> 16) & 0xff,
-		 (addr >> 8) & 0xff, addr & 0xff);
-}
+static const int libcfs_nnetstrfns = ARRAY_SIZE(libcfs_netstrfns);
 
 /* CAVEAT EMPTOR XscanfX
  * I use "%n" at the end of a sscanf format to detect trailing junk.  However
@@ -223,60 +297,7 @@ libcfs_ip_addr2str(__u32 addr, char *str)
  * fine, if it doesn't, then the scan ended at the end of the string, which is
  * fine too :) */
 
-int
-libcfs_ip_str2addr(const char *str, int nob, __u32 *addr)
-{
-	unsigned int	a;
-	unsigned int	b;
-	unsigned int	c;
-	unsigned int	d;
-	int		n = nob; /* XscanfX */
-
-	/* numeric IP? */
-	if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 &&
-	    n == nob &&
-	    (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
-	    (c & ~0xff) == 0 && (d & ~0xff) == 0) {
-		*addr = ((a<<24)|(b<<16)|(c<<8)|d);
-		return 1;
-	}
-
-	return 0;
-}
-
-void
-libcfs_decnum_addr2str(__u32 addr, char *str)
-{
-	snprintf(str, LNET_NIDSTR_SIZE, "%u", addr);
-}
-
-void
-libcfs_hexnum_addr2str(__u32 addr, char *str)
-{
-	snprintf(str, LNET_NIDSTR_SIZE, "0x%x", addr);
-}
-
-int
-libcfs_num_str2addr(const char *str, int nob, __u32 *addr)
-{
-	int     n;
-
-	n = nob;
-	if (sscanf(str, "0x%x%n", addr, &n) >= 1 && n == nob)
-		return 1;
-
-	n = nob;
-	if (sscanf(str, "0X%x%n", addr, &n) >= 1 && n == nob)
-		return 1;
-
-	n = nob;
-	if (sscanf(str, "%u%n", addr, &n) >= 1 && n == nob)
-		return 1;
-
-	return 0;
-}
-
-struct netstrfns *
+static struct netstrfns *
 libcfs_lnd2netstrfns(int lnd)
 {
 	int    i;
@@ -289,7 +310,7 @@ libcfs_lnd2netstrfns(int lnd)
 	return NULL;
 }
 
-struct netstrfns *
+static struct netstrfns *
 libcfs_namenum2netstrfns(const char *name)
 {
 	struct netstrfns *nf;
@@ -304,7 +325,7 @@ libcfs_namenum2netstrfns(const char *name)
 	return NULL;
 }
 
-struct netstrfns *
+static struct netstrfns *
 libcfs_name2netstrfns(const char *name)
 {
 	int    i;
@@ -343,7 +364,7 @@ libcfs_lnd2str(int lnd)
 		return nf->nf_name;
 
 	str = libcfs_next_nidstring();
-	snprintf(str, LNET_NIDSTR_SIZE, "?%u?", lnd);
+	snprintf(str, LNET_NIDSTR_SIZE, "?%d?", lnd);
 	return str;
 }
 EXPORT_SYMBOL(libcfs_lnd2str);
@@ -369,11 +390,11 @@ libcfs_net2str(__u32 net)
 	char	     *str = libcfs_next_nidstring();
 
 	if (nf == NULL)
-		snprintf(str, LNET_NIDSTR_SIZE, "<%u:%u>", lnd, num);
+		snprintf(str, LNET_NIDSTR_SIZE, "<%d:%d>", lnd, num);
 	else if (num == 0)
 		snprintf(str, LNET_NIDSTR_SIZE, "%s", nf->nf_name);
 	else
-		snprintf(str, LNET_NIDSTR_SIZE, "%s%u", nf->nf_name, num);
+		snprintf(str, LNET_NIDSTR_SIZE, "%s%d", nf->nf_name, num);
 
 	return str;
 }
@@ -397,7 +418,7 @@ libcfs_nid2str(lnet_nid_t nid)
 	str = libcfs_next_nidstring();
 
 	if (nf == NULL)
-		snprintf(str, LNET_NIDSTR_SIZE, "%x@<%u:%u>", addr, lnd, nnum);
+		snprintf(str, LNET_NIDSTR_SIZE, "%x@<%d:%d>", addr, lnd, nnum);
 	else {
 		nf->nf_addr2str(addr, str);
 		nob = strlen(str);
@@ -405,7 +426,7 @@ libcfs_nid2str(lnet_nid_t nid)
 			snprintf(str + nob, LNET_NIDSTR_SIZE - nob, "@%s",
 				 nf->nf_name);
 		else
-			snprintf(str + nob, LNET_NIDSTR_SIZE - nob, "@%s%u",
+			snprintf(str + nob, LNET_NIDSTR_SIZE - nob, "@%s%d",
 				 nf->nf_name, nnum);
 	}
 
@@ -586,27 +607,6 @@ struct addrrange {
 };
 
 /**
- * Nf_parse_addrlist method for networks using numeric addresses.
- *
- * Examples of such networks are gm and elan.
- *
- * \retval 0 if \a str parsed to numeric address
- * \retval errno otherwise
- */
-static int
-libcfs_num_parse(char *str, int len, struct list_head *list)
-{
-	struct cfs_expr_list *el;
-	int	rc;
-
-	rc = cfs_expr_list_parse(str, len, 0, MAX_NUMERIC_VALUE, &el);
-	if (rc == 0)
-		list_add_tail(&el->el_link, list);
-
-	return rc;
-}
-
-/**
  * Parses \<addrrange\> token on the syntax.
  *
  * Allocates struct addrrange and links to \a nidrange via
@@ -812,23 +812,6 @@ cfs_parse_nidlist(char *str, int len, struct list_head *nidlist)
 }
 EXPORT_SYMBOL(cfs_parse_nidlist);
 
-/*
- * Nf_match_addr method for networks using numeric addresses
- *
- * \retval 1 on match
- * \retval 0 otherwise
- */
-static int
-libcfs_num_match(__u32 addr, struct list_head *numaddr)
-{
-	struct cfs_expr_list *el;
-
-	LASSERT(!list_empty(numaddr));
-	el = list_entry(numaddr->next, struct cfs_expr_list, el_link);
-
-	return cfs_expr_list_match(addr, el);
-}
-
 /**
  * Matches a nid (\a nid) against the compiled list of nidranges (\a nidlist).
  *
diff --git a/drivers/staging/lustre/lustre/libcfs/tracefile.c b/drivers/staging/lustre/lustre/libcfs/tracefile.c
index 5917c31c7ed6..eb65b50f832d 100644
--- a/drivers/staging/lustre/lustre/libcfs/tracefile.c
+++ b/drivers/staging/lustre/lustre/libcfs/tracefile.c
@@ -55,7 +55,7 @@ static struct tracefiled_ctl trace_tctl;
 struct mutex cfs_trace_thread_mutex;
 static int thread_running = 0;
 
-atomic_t cfs_tage_allocated = ATOMIC_INIT(0);
+static atomic_t cfs_tage_allocated = ATOMIC_INIT(0);
 
 static void put_pages_on_tcd_daemon_list(struct page_collection *pc,
 					 struct cfs_trace_cpu_data *tcd);
@@ -1037,6 +1037,7 @@ static int tracefiled(void *arg)
 				       tage->used, rc);
 				put_pages_back(&pc);
 				__LASSERT(list_empty(&pc.pc_pages));
+				break;
 			}
 		}
 		MMSPACE_CLOSE;
diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c
index 1ac7a702ce26..a18201913273 100644
--- a/drivers/staging/lustre/lustre/llite/dir.c
+++ b/drivers/staging/lustre/lustre/llite/dir.c
@@ -183,7 +183,10 @@ static int ll_dir_filler(void *_hash, struct page *page0)
 	op_data->op_offset = hash;
 	rc = md_readpage(exp, op_data, page_pool, &request);
 	ll_finish_md_op_data(op_data);
-	if (rc == 0) {
+	if (rc < 0) {
+		/* page0 is special, which was added into page cache early */
+		delete_from_page_cache(page0);
+	} else if (rc == 0) {
 		body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
 		/* Checked by mdc_readpage() */
 		LASSERT(body != NULL);
@@ -278,7 +281,7 @@ static struct page *ll_dir_page_locate(struct inode *dir, __u64 *hash,
 	spin_lock_irq(&mapping->tree_lock);
 	found = radix_tree_gang_lookup(&mapping->page_tree,
 				       (void **)&page, offset, 1);
-	if (found > 0) {
+	if (found > 0 && !radix_tree_exceptional_entry(page)) {
 		struct lu_dirpage *dp;
 
 		page_cache_get(page);
@@ -652,8 +655,8 @@ static int ll_send_mgc_param(struct obd_export *mgc, char *string)
 	return rc;
 }
 
-int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump,
-			char *filename)
+static int ll_dir_setdirstripe(struct inode *dir, struct lmv_user_md *lump,
+			       char *filename)
 {
 	struct ptlrpc_request *request = NULL;
 	struct md_op_data *op_data;
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index 35a2df01528c..7c7ef7ec908e 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -1553,6 +1553,11 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
 	struct ccc_grouplock    grouplock;
 	int		     rc;
 
+	if (arg == 0) {
+		CWARN("group id for group lock must not be 0\n");
+		return -EINVAL;
+	}
+
 	if (ll_file_nolock(file))
 		return -EOPNOTSUPP;
 
@@ -1587,7 +1592,8 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
 	return 0;
 }
 
-int ll_put_grouplock(struct inode *inode, struct file *file, unsigned long arg)
+static int ll_put_grouplock(struct inode *inode, struct file *file,
+			    unsigned long arg)
 {
 	struct ll_inode_info   *lli = ll_i2info(inode);
 	struct ll_file_data    *fd = LUSTRE_FPRIVATE(file);
diff --git a/drivers/staging/lustre/lustre/llite/lproc_llite.c b/drivers/staging/lustre/lustre/llite/lproc_llite.c
index e6a909e6faf0..aaa13bd3e8de 100644
--- a/drivers/staging/lustre/lustre/llite/lproc_llite.c
+++ b/drivers/staging/lustre/lustre/llite/lproc_llite.c
@@ -399,9 +399,6 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
 		return -ERANGE;
 	}
 
-	if (sbi->ll_dt_exp == NULL)
-		return -ENODEV;
-
 	spin_lock(&sbi->ll_lock);
 	diff = pages_number - cache->ccc_lru_max;
 	spin_unlock(&sbi->ll_lock);
@@ -437,6 +434,11 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file,
 		if (diff <= 0)
 			break;
 
+		if (sbi->ll_dt_exp == NULL) { /* being initialized */
+			rc = -ENODEV;
+			break;
+		}
+
 		/* difficult - have to ask OSCs to drop LRU slots. */
 		tmp = diff << 1;
 		rc = obd_set_info_async(NULL, sbi->ll_dt_exp,
diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c
index 6aff155651cc..7c1e02a031ba 100644
--- a/drivers/staging/lustre/lustre/llite/super25.c
+++ b/drivers/staging/lustre/lustre/llite/super25.c
@@ -72,21 +72,6 @@ static void ll_destroy_inode(struct inode *inode)
 	call_rcu(&inode->i_rcu, ll_inode_destroy_callback);
 }
 
-static int ll_init_inodecache(void)
-{
-	ll_inode_cachep = kmem_cache_create("lustre_inode_cache",
-					       sizeof(struct ll_inode_info),
-					       0, SLAB_HWCACHE_ALIGN, NULL);
-	if (ll_inode_cachep == NULL)
-		return -ENOMEM;
-	return 0;
-}
-
-static void ll_destroy_inodecache(void)
-{
-	kmem_cache_destroy(ll_inode_cachep);
-}
-
 /* exported operations */
 struct super_operations lustre_super_operations = {
 	.alloc_inode   = ll_alloc_inode,
@@ -104,9 +89,10 @@ void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg));
 
 static int __init init_lustre_lite(void)
 {
-	int i, rc, seed[2];
-	struct timeval tv;
+	struct proc_dir_entry *entry;
 	lnet_process_id_t lnet_id;
+	struct timeval tv;
+	int i, rc, seed[2];
 
 	CLASSERT(sizeof(LUSTRE_VOLATILE_HDR) == LUSTRE_VOLATILE_HDR_LEN + 1);
 
@@ -116,59 +102,52 @@ static int __init init_lustre_lite(void)
 	CDEBUG(D_INFO, "Lustre client module (%p).\n",
 	       &lustre_super_operations);
 
-	rc = ll_init_inodecache();
-	if (rc)
-		return -ENOMEM;
+	rc = -ENOMEM;
+	ll_inode_cachep = kmem_cache_create("lustre_inode_cache",
+					    sizeof(struct ll_inode_info),
+					    0, SLAB_HWCACHE_ALIGN, NULL);
+	if (ll_inode_cachep == NULL)
+		goto out_cache;
+
 	ll_file_data_slab = kmem_cache_create("ll_file_data",
 						 sizeof(struct ll_file_data), 0,
 						 SLAB_HWCACHE_ALIGN, NULL);
-	if (ll_file_data_slab == NULL) {
-		ll_destroy_inodecache();
-		return -ENOMEM;
-	}
+	if (ll_file_data_slab == NULL)
+		goto out_cache;
 
 	ll_remote_perm_cachep = kmem_cache_create("ll_remote_perm_cache",
 						  sizeof(struct ll_remote_perm),
 						      0, 0, NULL);
-	if (ll_remote_perm_cachep == NULL) {
-		kmem_cache_destroy(ll_file_data_slab);
-		ll_file_data_slab = NULL;
-		ll_destroy_inodecache();
-		return -ENOMEM;
-	}
+	if (ll_remote_perm_cachep == NULL)
+		goto out_cache;
 
 	ll_rmtperm_hash_cachep = kmem_cache_create("ll_rmtperm_hash_cache",
 						   REMOTE_PERM_HASHSIZE *
 						   sizeof(struct list_head),
 						   0, 0, NULL);
-	if (ll_rmtperm_hash_cachep == NULL) {
-		kmem_cache_destroy(ll_remote_perm_cachep);
-		ll_remote_perm_cachep = NULL;
-		kmem_cache_destroy(ll_file_data_slab);
-		ll_file_data_slab = NULL;
-		ll_destroy_inodecache();
-		return -ENOMEM;
+	if (ll_rmtperm_hash_cachep == NULL)
+		goto out_cache;
+
+	entry = lprocfs_register("llite", proc_lustre_root, NULL, NULL);
+	if (IS_ERR(entry)) {
+		rc = PTR_ERR(entry);
+		CERROR("cannot register '/proc/fs/lustre/llite': rc = %d\n",
+		       rc);
+		goto out_cache;
 	}
 
-	proc_lustre_fs_root = proc_lustre_root ?
-			      lprocfs_register("llite", proc_lustre_root, NULL, NULL) : NULL;
-
-	lustre_register_client_fill_super(ll_fill_super);
-	lustre_register_kill_super_cb(ll_kill_super);
-
-	lustre_register_client_process_config(ll_process_config);
+	proc_lustre_fs_root = entry;
 
 	cfs_get_random_bytes(seed, sizeof(seed));
 
-	/* Nodes with small feet have little entropy
-	 * the NID for this node gives the most entropy in the low bits */
-	for (i = 0; ; i++) {
-		if (LNetGetId(i, &lnet_id) == -ENOENT) {
+	/* Nodes with small feet have little entropy. The NID for this
+	 * node gives the most entropy in the low bits */
+	for (i = 0;; i++) {
+		if (LNetGetId(i, &lnet_id) == -ENOENT)
 			break;
-		}
-		if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND) {
+
+		if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND)
 			seed[0] ^= LNET_NIDADDR(lnet_id.nid);
-		}
 	}
 
 	do_gettimeofday(&tv);
@@ -177,20 +156,54 @@ static int __init init_lustre_lite(void)
 	init_timer(&ll_capa_timer);
 	ll_capa_timer.function = ll_capa_timer_callback;
 	rc = ll_capa_thread_start();
-	/*
-	 * XXX normal cleanup is needed here.
-	 */
-	if (rc == 0)
-		rc = vvp_global_init();
+	if (rc != 0)
+		goto out_proc;
 
-	if (rc == 0)
-		rc = ll_xattr_init();
+	rc = vvp_global_init();
+	if (rc != 0)
+		goto out_capa;
+
+	rc = ll_xattr_init();
+	if (rc != 0)
+		goto out_vvp;
+
+	lustre_register_client_fill_super(ll_fill_super);
+	lustre_register_kill_super_cb(ll_kill_super);
+	lustre_register_client_process_config(ll_process_config);
+
+	return 0;
+
+out_vvp:
+	vvp_global_fini();
+out_capa:
+	del_timer(&ll_capa_timer);
+	ll_capa_thread_stop();
+out_proc:
+	lprocfs_remove(&proc_lustre_fs_root);
+out_cache:
+	if (ll_inode_cachep != NULL)
+		kmem_cache_destroy(ll_inode_cachep);
+
+	if (ll_file_data_slab != NULL)
+		kmem_cache_destroy(ll_file_data_slab);
+
+	if (ll_remote_perm_cachep != NULL)
+		kmem_cache_destroy(ll_remote_perm_cachep);
+
+	if (ll_rmtperm_hash_cachep != NULL)
+		kmem_cache_destroy(ll_rmtperm_hash_cachep);
 
 	return rc;
 }
 
 static void __exit exit_lustre_lite(void)
 {
+	lustre_register_client_fill_super(NULL);
+	lustre_register_kill_super_cb(NULL);
+	lustre_register_client_process_config(NULL);
+
+	lprocfs_remove(&proc_lustre_fs_root);
+
 	ll_xattr_fini();
 	vvp_global_fini();
 	del_timer(&ll_capa_timer);
@@ -199,22 +212,12 @@ static void __exit exit_lustre_lite(void)
 		 "client remaining capa count %d\n",
 		 capa_count[CAPA_SITE_CLIENT]);
 
-	lustre_register_client_fill_super(NULL);
-	lustre_register_kill_super_cb(NULL);
-
-	lustre_register_client_process_config(NULL);
-
-	ll_destroy_inodecache();
-
+	kmem_cache_destroy(ll_inode_cachep);
 	kmem_cache_destroy(ll_rmtperm_hash_cachep);
-	ll_rmtperm_hash_cachep = NULL;
 
 	kmem_cache_destroy(ll_remote_perm_cachep);
-	ll_remote_perm_cachep = NULL;
 
 	kmem_cache_destroy(ll_file_data_slab);
-	if (proc_lustre_fs_root && !IS_ERR(proc_lustre_fs_root))
-		lprocfs_remove(&proc_lustre_fs_root);
 }
 
 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c
index 65d610abe06e..91bba79678cf 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -307,18 +307,13 @@ static int vvp_io_rw_lock(const struct lu_env *env, struct cl_io *io,
 static int vvp_io_read_lock(const struct lu_env *env,
 			    const struct cl_io_slice *ios)
 {
-	struct cl_io	 *io  = ios->cis_io;
-	struct ll_inode_info *lli = ll_i2info(ccc_object_inode(io->ci_obj));
+	struct cl_io	 *io = ios->cis_io;
+	struct cl_io_rw_common *rd = &io->u.ci_rd.rd;
 	int result;
 
-	/* XXX: Layer violation, we shouldn't see lsm at llite level. */
-	if (lli->lli_has_smd) /* lsm-less file doesn't need to lock */
-		result = vvp_io_rw_lock(env, io, CLM_READ,
-					io->u.ci_rd.rd.crw_pos,
-					io->u.ci_rd.rd.crw_pos +
-					io->u.ci_rd.rd.crw_count - 1);
-	else
-		result = 0;
+	result = vvp_io_rw_lock(env, io, CLM_READ, rd->crw_pos,
+				rd->crw_pos + rd->crw_count - 1);
+
 	return result;
 }
 
diff --git a/drivers/staging/lustre/lustre/llite/vvp_lock.c b/drivers/staging/lustre/lustre/llite/vvp_lock.c
index 372633e164b9..f354e82d4ae7 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_lock.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_lock.c
@@ -71,6 +71,7 @@ static const struct cl_lock_operations vvp_lock_ops = {
 	.clo_fini      = ccc_lock_fini,
 	.clo_enqueue   = ccc_lock_enqueue,
 	.clo_wait      = ccc_lock_wait,
+	.clo_use       = ccc_lock_use,
 	.clo_unuse     = ccc_lock_unuse,
 	.clo_fits_into = ccc_lock_fits_into,
 	.clo_state     = ccc_lock_state,
diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
index 9f3837412cdf..b779f47384c5 100644
--- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c
+++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c
@@ -128,7 +128,7 @@ static int lmv_set_mdc_active(struct lmv_obd *lmv, struct obd_uuid *uuid,
 	return rc;
 }
 
-struct obd_uuid *lmv_get_uuid(struct obd_export *exp)
+static struct obd_uuid *lmv_get_uuid(struct obd_export *exp)
 {
 	struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
 
@@ -335,7 +335,7 @@ static int lmv_init_ea_size(struct obd_export *exp, int easize,
 
 #define MAX_STRING_SIZE 128
 
-int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
+static int lmv_connect_mdc(struct obd_device *obd, struct lmv_tgt_desc *tgt)
 {
 	struct proc_dir_entry   *lmv_proc_dir;
 	struct lmv_obd	  *lmv = &obd->u.lmv;
@@ -1663,10 +1663,10 @@ struct lmv_tgt_desc
 	return tgt;
 }
 
-int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
-	       const void *data, int datalen, int mode, __u32 uid,
-	       __u32 gid, cfs_cap_t cap_effective, __u64 rdev,
-	       struct ptlrpc_request **request)
+static int lmv_create(struct obd_export *exp, struct md_op_data *op_data,
+		      const void *data, int datalen, int mode, __u32 uid,
+		      __u32 gid, cfs_cap_t cap_effective, __u64 rdev,
+		      struct ptlrpc_request **request)
 {
 	struct obd_device       *obd = exp->exp_obd;
 	struct lmv_obd	  *lmv = &obd->u.lmv;
@@ -2387,9 +2387,9 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp,
 	return -EINVAL;
 }
 
-int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
-		       u32 keylen, void *key, u32 vallen,
-		       void *val, struct ptlrpc_request_set *set)
+static int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
+			      u32 keylen, void *key, u32 vallen,
+			      void *val, struct ptlrpc_request_set *set)
 {
 	struct lmv_tgt_desc    *tgt;
 	struct obd_device      *obd;
@@ -2425,8 +2425,8 @@ int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp,
 	return -EINVAL;
 }
 
-int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
-	       struct lov_stripe_md *lsm)
+static int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
+		      struct lov_stripe_md *lsm)
 {
 	struct obd_device	 *obd = class_exp2obd(exp);
 	struct lmv_obd	    *lmv = &obd->u.lmv;
@@ -2473,8 +2473,8 @@ int lmv_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
 	return mea_size;
 }
 
-int lmv_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
-		 struct lov_mds_md *lmm, int lmm_size)
+static int lmv_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
+			struct lov_mds_md *lmm, int lmm_size)
 {
 	struct obd_device	  *obd = class_exp2obd(exp);
 	struct lmv_stripe_md      **tmea = (struct lmv_stripe_md **)lsmp;
@@ -2551,8 +2551,8 @@ static int lmv_cancel_unused(struct obd_export *exp, const struct lu_fid *fid,
 	return rc;
 }
 
-int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
-		      __u64 *bits)
+static int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
+			     __u64 *bits)
 {
 	struct lmv_obd	  *lmv = &exp->exp_obd->u.lmv;
 	int		      rc;
@@ -2561,10 +2561,10 @@ int lmv_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data,
 	return rc;
 }
 
-ldlm_mode_t lmv_lock_match(struct obd_export *exp, __u64 flags,
-			   const struct lu_fid *fid, ldlm_type_t type,
-			   ldlm_policy_data_t *policy, ldlm_mode_t mode,
-			   struct lustre_handle *lockh)
+static ldlm_mode_t lmv_lock_match(struct obd_export *exp, __u64 flags,
+				  const struct lu_fid *fid, ldlm_type_t type,
+				  ldlm_policy_data_t *policy, ldlm_mode_t mode,
+				  struct lustre_handle *lockh)
 {
 	struct obd_device       *obd = exp->exp_obd;
 	struct lmv_obd	  *lmv = &obd->u.lmv;
@@ -2594,16 +2594,18 @@ ldlm_mode_t lmv_lock_match(struct obd_export *exp, __u64 flags,
 	return 0;
 }
 
-int lmv_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req,
-		      struct obd_export *dt_exp, struct obd_export *md_exp,
-		      struct lustre_md *md)
+static int lmv_get_lustre_md(struct obd_export *exp,
+			     struct ptlrpc_request *req,
+			     struct obd_export *dt_exp,
+			     struct obd_export *md_exp,
+			     struct lustre_md *md)
 {
 	struct lmv_obd	  *lmv = &exp->exp_obd->u.lmv;
 
 	return md_get_lustre_md(lmv->tgts[0]->ltd_exp, req, dt_exp, md_exp, md);
 }
 
-int lmv_free_lustre_md(struct obd_export *exp, struct lustre_md *md)
+static int lmv_free_lustre_md(struct obd_export *exp, struct lustre_md *md)
 {
 	struct obd_device       *obd = exp->exp_obd;
 	struct lmv_obd	  *lmv = &obd->u.lmv;
@@ -2613,9 +2615,9 @@ int lmv_free_lustre_md(struct obd_export *exp, struct lustre_md *md)
 	return md_free_lustre_md(lmv->tgts[0]->ltd_exp, md);
 }
 
-int lmv_set_open_replay_data(struct obd_export *exp,
-			     struct obd_client_handle *och,
-			     struct lookup_intent *it)
+static int lmv_set_open_replay_data(struct obd_export *exp,
+				    struct obd_client_handle *och,
+				    struct lookup_intent *it)
 {
 	struct obd_device       *obd = exp->exp_obd;
 	struct lmv_obd	  *lmv = &obd->u.lmv;
@@ -2628,8 +2630,8 @@ int lmv_set_open_replay_data(struct obd_export *exp,
 	return md_set_open_replay_data(tgt->ltd_exp, och, it);
 }
 
-int lmv_clear_open_replay_data(struct obd_export *exp,
-			       struct obd_client_handle *och)
+static int lmv_clear_open_replay_data(struct obd_export *exp,
+				      struct obd_client_handle *och)
 {
 	struct obd_device       *obd = exp->exp_obd;
 	struct lmv_obd	  *lmv = &obd->u.lmv;
@@ -2684,17 +2686,18 @@ static int lmv_renew_capa(struct obd_export *exp, struct obd_capa *oc,
 	return rc;
 }
 
-int lmv_unpack_capa(struct obd_export *exp, struct ptlrpc_request *req,
-		    const struct req_msg_field *field, struct obd_capa **oc)
+static int lmv_unpack_capa(struct obd_export *exp, struct ptlrpc_request *req,
+			   const struct req_msg_field *field,
+			   struct obd_capa **oc)
 {
 	struct lmv_obd *lmv = &exp->exp_obd->u.lmv;
 
 	return md_unpack_capa(lmv->tgts[0]->ltd_exp, req, field, oc);
 }
 
-int lmv_intent_getattr_async(struct obd_export *exp,
-			     struct md_enqueue_info *minfo,
-			     struct ldlm_enqueue_info *einfo)
+static int lmv_intent_getattr_async(struct obd_export *exp,
+				    struct md_enqueue_info *minfo,
+				    struct ldlm_enqueue_info *einfo)
 {
 	struct md_op_data       *op_data = &minfo->mi_data;
 	struct obd_device       *obd = exp->exp_obd;
@@ -2714,8 +2717,8 @@ int lmv_intent_getattr_async(struct obd_export *exp,
 	return rc;
 }
 
-int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
-			struct lu_fid *fid, __u64 *bits)
+static int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
+			       struct lu_fid *fid, __u64 *bits)
 {
 	struct obd_device       *obd = exp->exp_obd;
 	struct lmv_obd	  *lmv = &obd->u.lmv;
@@ -2739,8 +2742,8 @@ int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it,
  * process with other slave MDTs. The only exception is Q_GETOQUOTA for which
  * we directly fetch data from the slave MDTs.
  */
-int lmv_quotactl(struct obd_device *unused, struct obd_export *exp,
-		 struct obd_quotactl *oqctl)
+static int lmv_quotactl(struct obd_device *unused, struct obd_export *exp,
+			struct obd_quotactl *oqctl)
 {
 	struct obd_device   *obd = class_exp2obd(exp);
 	struct lmv_obd      *lmv = &obd->u.lmv;
@@ -2786,8 +2789,8 @@ int lmv_quotactl(struct obd_device *unused, struct obd_export *exp,
 	return rc;
 }
 
-int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp,
-		   struct obd_quotactl *oqctl)
+static int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp,
+			  struct obd_quotactl *oqctl)
 {
 	struct obd_device   *obd = class_exp2obd(exp);
 	struct lmv_obd      *lmv = &obd->u.lmv;
@@ -2810,7 +2813,7 @@ int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp,
 	return rc;
 }
 
-struct obd_ops lmv_obd_ops = {
+static struct obd_ops lmv_obd_ops = {
 	.o_owner		= THIS_MODULE,
 	.o_setup		= lmv_setup,
 	.o_cleanup	      = lmv_cleanup,
@@ -2830,7 +2833,7 @@ struct obd_ops lmv_obd_ops = {
 	.o_quotactl	     = lmv_quotactl
 };
 
-struct md_ops lmv_md_ops = {
+static struct md_ops lmv_md_ops = {
 	.m_getstatus	    = lmv_getstatus,
 	.m_null_inode		= lmv_null_inode,
 	.m_find_cbdata	  = lmv_find_cbdata,
@@ -2864,7 +2867,7 @@ struct md_ops lmv_md_ops = {
 	.m_revalidate_lock      = lmv_revalidate_lock
 };
 
-int __init lmv_init(void)
+static int __init lmv_init(void)
 {
 	struct lprocfs_static_vars lvars;
 	int			rc;
diff --git a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
index 117002097b28..5be4176829d3 100644
--- a/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
+++ b/drivers/staging/lustre/lustre/lmv/lproc_lmv.c
@@ -175,7 +175,7 @@ static int lmv_tgt_seq_show(struct seq_file *p, void *v)
 			  tgt->ltd_uuid.uuid, tgt->ltd_active ? "" : "IN");
 }
 
-struct seq_operations lmv_tgt_sops = {
+static struct seq_operations lmv_tgt_sops = {
 	.start		 = lmv_tgt_seq_start,
 	.stop		  = lmv_tgt_seq_stop,
 	.next		  = lmv_tgt_seq_next,
@@ -199,7 +199,7 @@ static int lmv_target_seq_open(struct inode *inode, struct file *file)
 
 LPROC_SEQ_FOPS_RO_TYPE(lmv, uuid);
 
-struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
+static struct lprocfs_vars lprocfs_lmv_obd_vars[] = {
 	{ "numobd",	  &lmv_numobd_fops,	  NULL, 0 },
 	{ "placement",	  &lmv_placement_fops,    NULL, 0 },
 	{ "activeobd",	  &lmv_activeobd_fops,    NULL, 0 },
diff --git a/drivers/staging/lustre/lustre/lov/lproc_lov.c b/drivers/staging/lustre/lustre/lov/lproc_lov.c
index c993f25fb303..c99f2f44ec62 100644
--- a/drivers/staging/lustre/lustre/lov/lproc_lov.c
+++ b/drivers/staging/lustre/lustre/lov/lproc_lov.c
@@ -51,8 +51,9 @@ static int lov_stripesize_seq_show(struct seq_file *m, void *v)
 	return seq_printf(m, "%llu\n", desc->ld_default_stripe_size);
 }
 
-static ssize_t lov_stripesize_seq_write(struct file *file, const char *buffer,
-				    size_t count, loff_t *off)
+static ssize_t lov_stripesize_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
 	struct lov_desc *desc;
@@ -81,8 +82,9 @@ static int lov_stripeoffset_seq_show(struct seq_file *m, void *v)
 	return seq_printf(m, "%llu\n", desc->ld_default_stripe_offset);
 }
 
-static ssize_t lov_stripeoffset_seq_write(struct file *file, const char *buffer,
-				      size_t count, loff_t *off)
+static ssize_t lov_stripeoffset_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
 	struct lov_desc *desc;
@@ -110,8 +112,9 @@ static int lov_stripetype_seq_show(struct seq_file *m, void *v)
 	return seq_printf(m, "%u\n", desc->ld_pattern);
 }
 
-static ssize_t lov_stripetype_seq_write(struct file *file, const char *buffer,
-				    size_t count, loff_t *off)
+static ssize_t lov_stripetype_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
 	struct lov_desc *desc;
@@ -140,8 +143,9 @@ static int lov_stripecount_seq_show(struct seq_file *m, void *v)
 			(__s16)(desc->ld_default_stripe_count + 1) - 1);
 }
 
-static ssize_t lov_stripecount_seq_write(struct file *file, const char *buffer,
-				     size_t count, loff_t *off)
+static ssize_t lov_stripecount_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
 	struct lov_desc *desc;
diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
index 16341c818358..c791941bd810 100644
--- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
+++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c
@@ -52,7 +52,7 @@ static int mdc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v)
 }
 
 static ssize_t mdc_max_rpcs_in_flight_seq_write(struct file *file,
-						const char *buffer,
+						const char __user *buffer,
 						size_t count,
 						loff_t *off)
 {
@@ -82,8 +82,9 @@ static int mdc_kuc_open(struct inode *inode, struct file *file)
 }
 
 /* temporary for testing */
-static ssize_t mdc_kuc_write(struct file *file, const char *buffer,
-			     size_t count, loff_t *off)
+static ssize_t mdc_kuc_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *obd =
 			((struct seq_file *)file->private_data)->private;
@@ -105,6 +106,8 @@ static ssize_t mdc_kuc_write(struct file *file, const char *buffer,
 		/* for mockup below */ 2 * cfs_size_round(sizeof(*hai));
 
 	OBD_ALLOC(lh, len);
+	if (!lh)
+		return -ENOMEM;
 
 	lh->kuc_magic = KUC_MAGIC;
 	lh->kuc_transport = KUC_TRANSPORT_HSM;
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c
index 4e59995e0042..d3234cb1ea22 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c
@@ -222,10 +222,9 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data,
 	rec->cr_fsuid    = from_kuid(&init_user_ns, current_fsuid());
 	rec->cr_fsgid    = from_kgid(&init_user_ns, current_fsgid());
 	rec->cr_cap      = cfs_curproc_cap_pack();
-	if (op_data != NULL) {
-		rec->cr_fid1 = op_data->op_fid1;
-		rec->cr_fid2 = op_data->op_fid2;
-	}
+	rec->cr_fid1 = op_data->op_fid1;
+	rec->cr_fid2 = op_data->op_fid2;
+
 	rec->cr_mode     = mode;
 	cr_flags = mds_pack_open_flags(flags, mode);
 	rec->cr_rdev     = rdev;
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
index 8c9b4f5494e9..d1c224ecd2b7 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c
@@ -828,6 +828,7 @@ resend:
 			 einfo->ei_type);
 		policy = (ldlm_policy_data_t *)lmm;
 		res_id.name[3] = LDLM_FLOCK;
+		req = NULL;
 	} else if (it->it_op & IT_OPEN) {
 		req = mdc_intent_open_pack(exp, it, op_data, lmm, lmmsize,
 					   einfo->ei_cbdata);
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index 3b0f245a8780..ef2744700d8b 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -855,8 +855,8 @@ static void mdc_close_handle_reply(struct ptlrpc_request *req,
 	}
 }
 
-int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
-	      struct md_open_data *mod, struct ptlrpc_request **request)
+static int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
+		     struct md_open_data *mod, struct ptlrpc_request **request)
 {
 	struct obd_device     *obd = class_exp2obd(exp);
 	struct ptlrpc_request *req;
@@ -974,8 +974,8 @@ int mdc_close(struct obd_export *exp, struct md_op_data *op_data,
 	return rc < 0 ? rc : saved_rc;
 }
 
-int mdc_done_writing(struct obd_export *exp, struct md_op_data *op_data,
-		     struct md_open_data *mod)
+static int mdc_done_writing(struct obd_export *exp, struct md_op_data *op_data,
+			    struct md_open_data *mod)
 {
 	struct obd_device     *obd = class_exp2obd(exp);
 	struct ptlrpc_request *req;
@@ -1044,8 +1044,8 @@ int mdc_done_writing(struct obd_export *exp, struct md_op_data *op_data,
 }
 
 
-int mdc_readpage(struct obd_export *exp, struct md_op_data *op_data,
-		 struct page **pages, struct ptlrpc_request **request)
+static int mdc_readpage(struct obd_export *exp, struct md_op_data *op_data,
+			struct page **pages, struct ptlrpc_request **request)
 {
 	struct ptlrpc_request   *req;
 	struct ptlrpc_bulk_desc *desc;
@@ -1908,8 +1908,8 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 
 		/* copy UUID */
 		if (copy_to_user(data->ioc_pbuf2, obd2cli_tgt(obd),
-				     min((int) data->ioc_plen2,
-					 (int) sizeof(struct obd_uuid)))) {
+				 min_t(size_t, data->ioc_plen2,
+					       sizeof(struct obd_uuid)))) {
 			rc = -EFAULT;
 			goto out;
 		}
@@ -1921,8 +1921,8 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 			goto out;
 
 		if (copy_to_user(data->ioc_pbuf1, &stat_buf,
-				     min((int) data->ioc_plen1,
-					 (int) sizeof(stat_buf)))) {
+				 min_t(size_t, data->ioc_plen1,
+					       sizeof(stat_buf)))) {
 			rc = -EFAULT;
 			goto out;
 		}
@@ -1974,9 +1974,9 @@ out:
 	return rc;
 }
 
-int mdc_get_info_rpc(struct obd_export *exp,
-		     u32 keylen, void *key,
-		     int vallen, void *val)
+static int mdc_get_info_rpc(struct obd_export *exp,
+			    u32 keylen, void *key,
+			    int vallen, void *val)
 {
 	struct obd_import      *imp = class_exp2cliimp(exp);
 	struct ptlrpc_request  *req;
@@ -2148,11 +2148,11 @@ static int mdc_kuc_reregister(struct obd_import *imp)
 					 (void *)imp);
 }
 
-int mdc_set_info_async(const struct lu_env *env,
-		       struct obd_export *exp,
-		       u32 keylen, void *key,
-		       u32 vallen, void *val,
-		       struct ptlrpc_request_set *set)
+static int mdc_set_info_async(const struct lu_env *env,
+			      struct obd_export *exp,
+			      u32 keylen, void *key,
+			      u32 vallen, void *val,
+			      struct ptlrpc_request_set *set)
 {
 	struct obd_import	*imp = class_exp2cliimp(exp);
 	int			 rc;
@@ -2199,9 +2199,9 @@ int mdc_set_info_async(const struct lu_env *env,
 	return -EINVAL;
 }
 
-int mdc_get_info(const struct lu_env *env, struct obd_export *exp,
-		 __u32 keylen, void *key, __u32 *vallen, void *val,
-		 struct lov_stripe_md *lsm)
+static int mdc_get_info(const struct lu_env *env, struct obd_export *exp,
+			__u32 keylen, void *key, __u32 *vallen, void *val,
+			struct lov_stripe_md *lsm)
 {
 	int rc = -EINVAL;
 
@@ -2263,8 +2263,8 @@ int mdc_get_info(const struct lu_env *env, struct obd_export *exp,
 	return rc;
 }
 
-int mdc_sync(struct obd_export *exp, const struct lu_fid *fid,
-	     struct obd_capa *oc, struct ptlrpc_request **request)
+static int mdc_sync(struct obd_export *exp, const struct lu_fid *fid,
+		    struct obd_capa *oc, struct ptlrpc_request **request)
 {
 	struct ptlrpc_request *req;
 	int		    rc;
@@ -2356,7 +2356,7 @@ int mdc_fid_alloc(struct obd_export *exp, struct lu_fid *fid,
 	return seq_client_alloc_fid(NULL, seq, fid);
 }
 
-struct obd_uuid *mdc_get_uuid(struct obd_export *exp)
+static struct obd_uuid *mdc_get_uuid(struct obd_export *exp)
 {
 	struct client_obd *cli = &exp->exp_obd->u.cli;
 
@@ -2390,7 +2390,7 @@ static int mdc_resource_inode_free(struct ldlm_resource *res)
 	return 0;
 }
 
-struct ldlm_valblock_ops inode_lvbo = {
+static struct ldlm_valblock_ops inode_lvbo = {
 	.lvbo_free = mdc_resource_inode_free,
 };
 
@@ -2550,9 +2550,9 @@ static int mdc_process_config(struct obd_device *obd, u32 len, void *buf)
 
 
 /* get remote permission for current user on fid */
-int mdc_get_remote_perm(struct obd_export *exp, const struct lu_fid *fid,
-			struct obd_capa *oc, __u32 suppgid,
-			struct ptlrpc_request **request)
+static int mdc_get_remote_perm(struct obd_export *exp, const struct lu_fid *fid,
+			       struct obd_capa *oc, __u32 suppgid,
+			       struct ptlrpc_request **request)
 {
 	struct ptlrpc_request  *req;
 	int		    rc;
@@ -2647,7 +2647,7 @@ static int mdc_renew_capa(struct obd_export *exp, struct obd_capa *oc,
 	return 0;
 }
 
-struct obd_ops mdc_obd_ops = {
+static struct obd_ops mdc_obd_ops = {
 	.o_owner	    = THIS_MODULE,
 	.o_setup	    = mdc_setup,
 	.o_precleanup       = mdc_precleanup,
@@ -2670,7 +2670,7 @@ struct obd_ops mdc_obd_ops = {
 	.o_quotacheck       = mdc_quotacheck
 };
 
-struct md_ops mdc_md_ops = {
+static struct md_ops mdc_md_ops = {
 	.m_getstatus	= mdc_getstatus,
 	.m_null_inode	    = mdc_null_inode,
 	.m_find_cbdata      = mdc_find_cbdata,
@@ -2705,7 +2705,7 @@ struct md_ops mdc_md_ops = {
 	.m_revalidate_lock      = mdc_revalidate_lock
 };
 
-int __init mdc_init(void)
+static int __init mdc_init(void)
 {
 	int rc;
 	struct lprocfs_static_vars lvars = { NULL };
diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c
index ce96bd279111..f13d1fbffd9d 100644
--- a/drivers/staging/lustre/lustre/obdclass/cl_object.c
+++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c
@@ -193,6 +193,7 @@ static spinlock_t *cl_object_attr_guard(struct cl_object *o)
  * cl_object_attr_get(), cl_object_attr_set().
  */
 void cl_object_attr_lock(struct cl_object *o)
+	__acquires(cl_object_attr_guard(o))
 {
 	spin_lock(cl_object_attr_guard(o));
 }
@@ -202,6 +203,7 @@ EXPORT_SYMBOL(cl_object_attr_lock);
  * Releases data-attributes lock, acquired by cl_object_attr_lock().
  */
 void cl_object_attr_unlock(struct cl_object *o)
+	__releases(cl_object_attr_guard(o))
 {
 	spin_unlock(cl_object_attr_guard(o));
 }
@@ -662,7 +664,8 @@ static int cl_env_store_init(void) {
 	return cl_env_hash != NULL ? 0 :-ENOMEM;
 }
 
-static void cl_env_store_fini(void) {
+static void cl_env_store_fini(void)
+{
 	cfs_hash_putref(cl_env_hash);
 }
 
diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index 89a3fb2e56b2..29456e1ad225 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -61,7 +61,7 @@ __u64 obd_alloc;
 EXPORT_SYMBOL(obd_alloc);
 __u64 obd_pages;
 EXPORT_SYMBOL(obd_pages);
-DEFINE_SPINLOCK(obd_updatemax_lock);
+static DEFINE_SPINLOCK(obd_updatemax_lock);
 
 /* The following are visible and mutable through /proc/sys/lustre/. */
 unsigned int obd_alloc_fail_rate = 0;
diff --git a/drivers/staging/lustre/lustre/obdclass/genops.c b/drivers/staging/lustre/lustre/obdclass/genops.c
index 736ca410aca3..82508210465e 100644
--- a/drivers/staging/lustre/lustre/obdclass/genops.c
+++ b/drivers/staging/lustre/lustre/obdclass/genops.c
@@ -1151,22 +1151,24 @@ void class_export_recovery_cleanup(struct obd_export *exp)
 			exp->exp_obd->obd_stale_clients++;
 	}
 	spin_unlock(&obd->obd_recovery_task_lock);
+
+	spin_lock(&exp->exp_lock);
 	/** Cleanup req replay fields */
 	if (exp->exp_req_replay_needed) {
-		spin_lock(&exp->exp_lock);
 		exp->exp_req_replay_needed = 0;
-		spin_unlock(&exp->exp_lock);
+
 		LASSERT(atomic_read(&obd->obd_req_replay_clients));
 		atomic_dec(&obd->obd_req_replay_clients);
 	}
+
 	/** Cleanup lock replay data */
 	if (exp->exp_lock_replay_needed) {
-		spin_lock(&exp->exp_lock);
 		exp->exp_lock_replay_needed = 0;
-		spin_unlock(&exp->exp_lock);
+
 		LASSERT(atomic_read(&obd->obd_lock_replay_clients));
 		atomic_dec(&obd->obd_lock_replay_clients);
 	}
+	spin_unlock(&exp->exp_lock);
 }
 
 /* This function removes 1-3 references from the export:
diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
index 66ceab20c743..b94aeac18a37 100644
--- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
+++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c
@@ -83,9 +83,8 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
 	int err;
 	int offset = 0;
 
-	err = copy_from_user(&hdr, (void *)arg, sizeof(hdr));
-	if (err)
-		return err;
+	if (copy_from_user(&hdr, (void *)arg, sizeof(hdr)))
+		return -EFAULT;
 
 	if (hdr.ioc_version != OBD_IOCTL_VERSION) {
 		CERROR("Version mismatch kernel (%x) vs application (%x)\n",
@@ -117,18 +116,19 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
 	*len = hdr.ioc_len;
 	data = (struct obd_ioctl_data *)*buf;
 
-	err = copy_from_user(*buf, (void *)arg, hdr.ioc_len);
-	if (err) {
-		OBD_FREE_LARGE(*buf, hdr.ioc_len);
-		return err;
+	if (copy_from_user(*buf, (void *)arg, hdr.ioc_len)) {
+		err = -EFAULT;
+		goto free_buf;
+	}
+	if (hdr.ioc_len != data->ioc_len) {
+		err = -EINVAL;
+		goto free_buf;
 	}
-	if (hdr.ioc_len != data->ioc_len)
-		return -EINVAL;
 
 	if (obd_ioctl_is_invalid(data)) {
 		CERROR("ioctl not correctly formatted\n");
-		OBD_FREE_LARGE(*buf, hdr.ioc_len);
-		return -EINVAL;
+		err = -EINVAL;
+		goto free_buf;
 	}
 
 	if (data->ioc_inllen1) {
@@ -151,6 +151,10 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
 	}
 
 	return 0;
+
+free_buf:
+	OBD_FREE_LARGE(*buf, hdr.ioc_len);
+	return err;
 }
 EXPORT_SYMBOL(obd_ioctl_getdata);
 
@@ -272,8 +276,9 @@ static int obd_proc_jobid_var_seq_show(struct seq_file *m, void *v)
 	return seq_printf(m, "%s\n", obd_jobid_var);
 }
 
-static ssize_t obd_proc_jobid_var_seq_write(struct file *file, const char *buffer,
-					size_t count, loff_t *off)
+static ssize_t obd_proc_jobid_var_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	if (!count || count > JOBSTATS_JOBID_VAR_MAX_LEN)
 		return -EINVAL;
diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
index d3ec90e85eb9..a2d5aa105d6b 100644
--- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c
+++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c
@@ -168,7 +168,8 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec)
 	}
 	case CHANGELOG_REC:
 	{
-		struct llog_changelog_rec *cr = (struct llog_changelog_rec *)rec;
+		struct llog_changelog_rec *cr =
+			(struct llog_changelog_rec *)rec;
 
 		__swab16s(&cr->cr.cr_namelen);
 		__swab16s(&cr->cr.cr_flags);
@@ -188,6 +189,8 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec)
 		} else {
 			tail = &cr->cr_tail;
 		}
+		tail = (struct llog_rec_tail *)((char *)tail +
+						cr->cr.cr_namelen);
 		break;
 	}
 	case CHANGELOG_USER_REC:
diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
index 3b7dfc367722..ddab94d7ee82 100644
--- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
+++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c
@@ -45,6 +45,7 @@
 #include "../include/lprocfs_status.h"
 #include "../include/lustre/lustre_idl.h"
 #include <linux/seq_file.h>
+#include <linux/ctype.h>
 
 static const char * const obd_connect_names[] = {
 	"read_only",
@@ -1849,7 +1850,7 @@ int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult)
 }
 EXPORT_SYMBOL(lprocfs_seq_read_frac_helper);
 
-int lprocfs_write_u64_helper(const char *buffer, unsigned long count,
+int lprocfs_write_u64_helper(const char __user *buffer, unsigned long count,
 			     __u64 *val)
 {
 	return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
@@ -1862,6 +1863,7 @@ int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
 	char kernbuf[22], *end, *pbuf;
 	__u64 whole, frac = 0, units;
 	unsigned frac_d = 1;
+	int sign = 1;
 
 	if (count > (sizeof(kernbuf) - 1))
 		return -EINVAL;
@@ -1872,7 +1874,7 @@ int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
 	kernbuf[count] = '\0';
 	pbuf = kernbuf;
 	if (*pbuf == '-') {
-		mult = -mult;
+		sign = -1;
 		pbuf++;
 	}
 
@@ -1880,7 +1882,7 @@ int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
 	if (pbuf == end)
 		return -EINVAL;
 
-	if (end != NULL && *end == '.') {
+	if (*end == '.') {
 		int i;
 		pbuf = end + 1;
 
@@ -1895,25 +1897,25 @@ int lprocfs_write_frac_u64_helper(const char *buffer, unsigned long count,
 	}
 
 	units = 1;
-	switch (*end) {
-	case 'p': case 'P':
+	switch (tolower(*end)) {
+	case 'p':
 		units <<= 10;
-	case 't': case 'T':
+	case 't':
 		units <<= 10;
-	case 'g': case 'G':
+	case 'g':
 		units <<= 10;
-	case 'm': case 'M':
+	case 'm':
 		units <<= 10;
-	case 'k': case 'K':
+	case 'k':
 		units <<= 10;
 	}
 	/* Specified units override the multiplier */
-	if (units)
-		mult = mult < 0 ? -units : units;
+	if (units > 1)
+		mult = units;
 
 	frac *= mult;
 	do_div(frac, frac_d);
-	*val = whole * mult + frac;
+	*val = sign * (whole * mult + frac);
 	return 0;
 }
 EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
index 4f39cdee1b5c..3c0c9109cefd 100644
--- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c
+++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c
@@ -376,6 +376,11 @@ int lustre_start_mgc(struct super_block *sb)
 
 	/* Random uuid for MGC allows easier reconnects */
 	OBD_ALLOC_PTR(uuid);
+	if (!uuid) {
+		rc = -ENOMEM;
+		goto out_free;
+	}
+
 	ll_generate_random_uuid(uuidc);
 	class_uuid_unparse(uuidc, uuid);
 
diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c
index 9f719bcecab3..1795d3a7a029 100644
--- a/drivers/staging/lustre/lustre/osc/lproc_osc.c
+++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c
@@ -53,8 +53,9 @@ static int osc_active_seq_show(struct seq_file *m, void *v)
 	return rc;
 }
 
-static ssize_t osc_active_seq_write(struct file *file, const char *buffer,
-				    size_t count, loff_t *off)
+static ssize_t osc_active_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
 	int val, rc;
@@ -88,7 +89,8 @@ static int osc_max_rpcs_in_flight_seq_show(struct seq_file *m, void *v)
 }
 
 static ssize_t osc_max_rpcs_in_flight_seq_write(struct file *file,
-			const char *buffer, size_t count, loff_t *off)
+			const char __user *buffer,
+			size_t count, loff_t *off)
 {
 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
 	struct client_obd *cli = &dev->u.cli;
@@ -130,8 +132,9 @@ static int osc_max_dirty_mb_seq_show(struct seq_file *m, void *v)
 	return lprocfs_seq_read_frac_helper(m, val, mult);
 }
 
-static ssize_t osc_max_dirty_mb_seq_write(struct file *file, const char *buffer,
-				      size_t count, loff_t *off)
+static ssize_t osc_max_dirty_mb_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
 	struct client_obd *cli = &dev->u.cli;
@@ -233,8 +236,9 @@ static int osc_cur_grant_bytes_seq_show(struct seq_file *m, void *v)
 	return rc;
 }
 
-static ssize_t osc_cur_grant_bytes_seq_write(struct file *file, const char *buffer,
-				  size_t count, loff_t *off)
+static ssize_t osc_cur_grant_bytes_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	struct client_obd *cli = &obd->u.cli;
@@ -290,7 +294,8 @@ static int osc_grant_shrink_interval_seq_show(struct seq_file *m, void *v)
 }
 
 static ssize_t osc_grant_shrink_interval_seq_write(struct file *file,
-				const char *buffer, size_t count, loff_t *off)
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	int val, rc;
@@ -322,8 +327,9 @@ static int osc_checksum_seq_show(struct seq_file *m, void *v)
 			obd->u.cli.cl_checksum ? 1 : 0);
 }
 
-static ssize_t osc_checksum_seq_write(struct file *file, const char *buffer,
-			   size_t count, loff_t *off)
+static ssize_t osc_checksum_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	int val, rc;
@@ -358,11 +364,12 @@ static int osc_checksum_type_seq_show(struct seq_file *m, void *v)
 		else
 			seq_printf(m, "%s ", cksum_name[i]);
 	}
-	seq_printf(m, "\n");
+	seq_putc(m, '\n');
 	return 0;
 }
 
-static ssize_t osc_checksum_type_seq_write(struct file *file, const char *buffer,
+static ssize_t osc_checksum_type_seq_write(struct file *file,
+				const char __user *buffer,
 				size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -401,8 +408,9 @@ static int osc_resend_count_seq_show(struct seq_file *m, void *v)
 	return seq_printf(m, "%u\n", atomic_read(&obd->u.cli.cl_resends));
 }
 
-static ssize_t osc_resend_count_seq_write(struct file *file, const char *buffer,
-			       size_t count, loff_t *off)
+static ssize_t osc_resend_count_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	int val, rc;
@@ -428,8 +436,9 @@ static int osc_contention_seconds_seq_show(struct seq_file *m, void *v)
 	return seq_printf(m, "%u\n", od->od_contention_time);
 }
 
-static ssize_t osc_contention_seconds_seq_write(struct file *file, const char *buffer,
-				     size_t count, loff_t *off)
+static ssize_t osc_contention_seconds_seq_write(struct file *file,
+					const char __user *buffer,
+					size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	struct osc_device *od  = obd2osc_dev(obd);
@@ -447,8 +456,9 @@ static int osc_lockless_truncate_seq_show(struct seq_file *m, void *v)
 	return seq_printf(m, "%u\n", od->od_lockless_truncate);
 }
 
-static ssize_t osc_lockless_truncate_seq_write(struct file *file, const char *buffer,
-				    size_t count, loff_t *off)
+static ssize_t osc_lockless_truncate_seq_write(struct file *file,
+					const char __user *buffer,
+					size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
 	struct osc_device *od  = obd2osc_dev(obd);
@@ -472,7 +482,8 @@ static int osc_obd_max_pages_per_rpc_seq_show(struct seq_file *m, void *v)
 }
 
 static ssize_t osc_obd_max_pages_per_rpc_seq_write(struct file *file,
-				const char *buffer, size_t count, loff_t *off)
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
 	struct client_obd *cli = &dev->u.cli;
@@ -590,9 +601,9 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
 	seq_printf(seq, "pending read pages:   %d\n",
 		   atomic_read(&cli->cl_pending_r_pages));
 
-	seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
-	seq_printf(seq, "pages per rpc	 rpcs   %% cum %% |");
-	seq_printf(seq, "       rpcs   %% cum %%\n");
+	seq_puts(seq, "\n\t\t\tread\t\t\twrite\n");
+	seq_puts(seq, "pages per rpc	 rpcs   % cum % |");
+	seq_puts(seq, "       rpcs   % cum %\n");
 
 	read_tot = lprocfs_oh_sum(&cli->cl_read_page_hist);
 	write_tot = lprocfs_oh_sum(&cli->cl_write_page_hist);
@@ -613,9 +624,9 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
 			break;
 	}
 
-	seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
-	seq_printf(seq, "rpcs in flight	rpcs   %% cum %% |");
-	seq_printf(seq, "       rpcs   %% cum %%\n");
+	seq_puts(seq, "\n\t\t\tread\t\t\twrite\n");
+	seq_puts(seq, "rpcs in flight	rpcs   % cum % |");
+	seq_puts(seq, "       rpcs   % cum %\n");
 
 	read_tot = lprocfs_oh_sum(&cli->cl_read_rpc_hist);
 	write_tot = lprocfs_oh_sum(&cli->cl_write_rpc_hist);
@@ -636,9 +647,9 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
 			break;
 	}
 
-	seq_printf(seq, "\n\t\t\tread\t\t\twrite\n");
-	seq_printf(seq, "offset		rpcs   %% cum %% |");
-	seq_printf(seq, "       rpcs   %% cum %%\n");
+	seq_puts(seq, "\n\t\t\tread\t\t\twrite\n");
+	seq_puts(seq, "offset		rpcs   % cum % |");
+	seq_puts(seq, "       rpcs   % cum %\n");
 
 	read_tot = lprocfs_oh_sum(&cli->cl_read_offset_hist);
 	write_tot = lprocfs_oh_sum(&cli->cl_write_offset_hist);
@@ -664,8 +675,9 @@ static int osc_rpc_stats_seq_show(struct seq_file *seq, void *v)
 }
 #undef pct
 
-static ssize_t osc_rpc_stats_seq_write(struct file *file, const char *buf,
-				       size_t len, loff_t *off)
+static ssize_t osc_rpc_stats_seq_write(struct file *file,
+				const char __user *buf,
+				size_t len, loff_t *off)
 {
 	struct seq_file *seq = file->private_data;
 	struct obd_device *dev = seq->private;
@@ -702,8 +714,9 @@ static int osc_stats_seq_show(struct seq_file *seq, void *v)
 	return 0;
 }
 
-static ssize_t osc_stats_seq_write(struct file *file, const char *buf,
-				   size_t len, loff_t *off)
+static ssize_t osc_stats_seq_write(struct file *file,
+				const char __user *buf,
+				size_t len, loff_t *off)
 {
 	struct seq_file *seq = file->private_data;
 	struct obd_device *dev = seq->private;
diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c
index 370e6d4896c6..7022ed42d2d1 100644
--- a/drivers/staging/lustre/lustre/osc/osc_cache.c
+++ b/drivers/staging/lustre/lustre/osc/osc_cache.c
@@ -1820,6 +1820,9 @@ static int try_to_add_extent_for_io(struct client_obd *cli,
 				    int *pc, unsigned int *max_pages)
 {
 	struct osc_extent *tmp;
+	struct osc_async_page *oap = list_first_entry(&ext->oe_pages,
+						      struct osc_async_page,
+						      oap_pending_item);
 
 	EASSERT((ext->oe_state == OES_CACHE || ext->oe_state == OES_LOCK_DONE),
 		ext);
@@ -1829,6 +1832,10 @@ static int try_to_add_extent_for_io(struct client_obd *cli,
 		return 0;
 
 	list_for_each_entry(tmp, rpclist, oe_link) {
+		struct osc_async_page *oap2;
+
+		oap2 = list_first_entry(&tmp->oe_pages, struct osc_async_page,
+					oap_pending_item);
 		EASSERT(tmp->oe_owner == current, tmp);
 #if 0
 		if (overlapped(tmp, ext)) {
@@ -1836,6 +1843,11 @@ static int try_to_add_extent_for_io(struct client_obd *cli,
 			EASSERT(0, ext);
 		}
 #endif
+		if (oap2cl_page(oap)->cp_type != oap2cl_page(oap2)->cp_type) {
+			CDEBUG(D_CACHE, "Do not permit different type of IO"
+					" for a same RPC\n");
+			return 0;
+		}
 
 		if (tmp->oe_srvlock != ext->oe_srvlock ||
 		    !tmp->oe_grants != !ext->oe_grants)
diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h
index d788dac93cd0..af96c7bc7764 100644
--- a/drivers/staging/lustre/lustre/osc/osc_internal.h
+++ b/drivers/staging/lustre/lustre/osc/osc_internal.h
@@ -160,11 +160,6 @@ static inline unsigned long rpcs_in_flight(struct client_obd *cli)
 	return cli->cl_r_in_flight + cli->cl_w_in_flight;
 }
 
-#ifndef min_t
-#define min_t(type, x, y) \
-	({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
-#endif
-
 struct osc_device {
 	struct cl_device    od_cl;
 	struct obd_export  *od_exp;
diff --git a/drivers/staging/lustre/lustre/osc/osc_lock.c b/drivers/staging/lustre/lustre/osc/osc_lock.c
index a7f08bc48166..445655724904 100644
--- a/drivers/staging/lustre/lustre/osc/osc_lock.c
+++ b/drivers/staging/lustre/lustre/osc/osc_lock.c
@@ -100,14 +100,14 @@ static int osc_lock_invariant(struct osc_lock *ols)
 	/*
 	 * If all the following "ergo"s are true, return 1, otherwise 0
 	 */
-	if (! ergo(olock != NULL, handle_used))
+	if (!ergo(olock != NULL, handle_used))
 		return 0;
 
-	if (! ergo(olock != NULL,
+	if (!ergo(olock != NULL,
 		   olock->l_handle.h_cookie == ols->ols_handle.cookie))
 		return 0;
 
-	if (! ergo(handle_used,
+	if (!ergo(handle_used,
 		   ergo(lock != NULL && olock != NULL, lock == olock) &&
 		   ergo(lock == NULL, olock == NULL)))
 		return 0;
@@ -115,18 +115,18 @@ static int osc_lock_invariant(struct osc_lock *ols)
 	 * Check that ->ols_handle and ->ols_lock are consistent, but
 	 * take into account that they are set at the different time.
 	 */
-	if (! ergo(ols->ols_state == OLS_CANCELLED,
+	if (!ergo(ols->ols_state == OLS_CANCELLED,
 		   olock == NULL && !handle_used))
 		return 0;
 	/*
 	 * DLM lock is destroyed only after we have seen cancellation
 	 * ast.
 	 */
-	if (! ergo(olock != NULL && ols->ols_state < OLS_CANCELLED,
+	if (!ergo(olock != NULL && ols->ols_state < OLS_CANCELLED,
 		   ((olock->l_flags & LDLM_FL_DESTROYED) == 0)))
 		return 0;
 
-	if (! ergo(ols->ols_state == OLS_GRANTED,
+	if (!ergo(ols->ols_state == OLS_GRANTED,
 		   olock != NULL &&
 		   olock->l_req_mode == olock->l_granted_mode &&
 		   ols->ols_hold))
diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c
index b9450b95f1c5..0adfa707a763 100644
--- a/drivers/staging/lustre/lustre/osc/osc_request.c
+++ b/drivers/staging/lustre/lustre/osc/osc_request.c
@@ -3332,7 +3332,7 @@ extern struct lu_kmem_descr osc_caches[];
 extern spinlock_t osc_ast_guard;
 extern struct lock_class_key osc_ast_guard_class;
 
-int __init osc_init(void)
+static int __init osc_init(void)
 {
 	struct lprocfs_static_vars lvars = { NULL };
 	int rc;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c
index dc9e406f3212..4882dd0a4483 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/client.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/client.c
@@ -1247,7 +1247,9 @@ static int after_reply(struct ptlrpc_request *req)
 		time_t	now = get_seconds();
 
 		DEBUG_REQ(D_RPCTRACE, req, "Resending request on EINPROGRESS");
+		spin_lock(&req->rq_lock);
 		req->rq_resend = 1;
+		spin_unlock(&req->rq_lock);
 		req->rq_nr_resend++;
 
 		/* allocate new xid to avoid reply reconstruction */
@@ -1497,11 +1499,13 @@ static inline int ptlrpc_set_producer(struct ptlrpc_request_set *set)
 int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
 {
 	struct list_head *tmp, *next;
+	struct list_head comp_reqs;
 	int force_timer_recalc = 0;
 
 	if (atomic_read(&set->set_remaining) == 0)
 		return 1;
 
+	INIT_LIST_HEAD(&comp_reqs);
 	list_for_each_safe(tmp, next, &set->set_requests) {
 		struct ptlrpc_request *req =
 			list_entry(tmp, struct ptlrpc_request,
@@ -1576,8 +1580,10 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set)
 			ptlrpc_rqphase_move(req, req->rq_next_phase);
 		}
 
-		if (req->rq_phase == RQ_PHASE_COMPLETE)
+		if (req->rq_phase == RQ_PHASE_COMPLETE) {
+			list_move_tail(&req->rq_set_chain, &comp_reqs);
 			continue;
+		}
 
 		if (req->rq_phase == RQ_PHASE_INTERPRET)
 			goto interpret;
@@ -1860,9 +1866,15 @@ interpret:
 			if (req->rq_status != 0)
 				set->set_rc = req->rq_status;
 			ptlrpc_req_finished(req);
+		} else {
+			list_move_tail(&req->rq_set_chain, &comp_reqs);
 		}
 	}
 
+	/* move completed request at the head of list so it's easier for
+	 * caller to find them */
+	list_splice(&comp_reqs, &set->set_requests);
+
 	/* If we hit an error, we want to recover promptly. */
 	return atomic_read(&set->set_remaining) == 0 || force_timer_recalc;
 }
diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c
index dc5ceb55d001..bbef666b1d16 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/layout.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c
@@ -65,7 +65,6 @@
 #endif
 /* struct ptlrpc_request, lustre_msg* */
 #include "../include/lustre_req_layout.h"
-#include "../include/lustre_update.h"
 #include "../include/lustre_acl.h"
 #include "../include/lustre_debug.h"
 
diff --git a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
index 4011e0050fcb..0e2071b8a36e 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/lproc_ptlrpc.c
@@ -45,7 +45,7 @@
 #include "ptlrpc_internal.h"
 
 
-struct ll_rpc_opcode {
+static struct ll_rpc_opcode {
 	__u32       opcode;
 	const char *opname;
 } ll_rpc_opcode_table[LUSTRE_MAX_OPCODES] = {
@@ -136,7 +136,7 @@ struct ll_rpc_opcode {
 	{ UPDATE_OBJ,	    "update_obj" },
 };
 
-struct ll_eopcode {
+static struct ll_eopcode {
 	__u32       opcode;
 	const char *opname;
 } ll_eopcode_table[EXTRA_LAST_OPC] = {
@@ -175,15 +175,17 @@ const char *ll_opcode2str(__u32 opcode)
 	return ll_rpc_opcode_table[offset].opname;
 }
 
-const char *ll_eopcode2str(__u32 opcode)
+static const char *ll_eopcode2str(__u32 opcode)
 {
 	LASSERT(ll_eopcode_table[opcode].opcode == opcode);
 	return ll_eopcode_table[opcode].opname;
 }
+
 #if defined (CONFIG_PROC_FS)
-void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir,
-			     char *name, struct proc_dir_entry **procroot_ret,
-			     struct lprocfs_stats **stats_ret)
+static void ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir,
+				    char *name,
+				    struct proc_dir_entry **procroot_ret,
+				    struct lprocfs_stats **stats_ret)
 {
 	struct proc_dir_entry *svc_procroot;
 	struct lprocfs_stats *svc_stats;
@@ -284,8 +286,9 @@ ptlrpc_lprocfs_req_history_max_seq_show(struct seq_file *m, void *n)
 }
 
 static ssize_t
-ptlrpc_lprocfs_req_history_max_seq_write(struct file *file, const char *buffer,
-					 size_t count, loff_t *off)
+ptlrpc_lprocfs_req_history_max_seq_write(struct file *file,
+					const char __user *buffer,
+					size_t count, loff_t *off)
 {
 	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
 	int			    bufpages;
@@ -329,8 +332,9 @@ ptlrpc_lprocfs_threads_min_seq_show(struct seq_file *m, void *n)
 }
 
 static ssize_t
-ptlrpc_lprocfs_threads_min_seq_write(struct file *file, const char *buffer,
-				     size_t count, loff_t *off)
+ptlrpc_lprocfs_threads_min_seq_write(struct file *file,
+					const char __user *buffer,
+					size_t count, loff_t *off)
 {
 	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
 	int	val;
@@ -381,8 +385,9 @@ ptlrpc_lprocfs_threads_max_seq_show(struct seq_file *m, void *n)
 }
 
 static ssize_t
-ptlrpc_lprocfs_threads_max_seq_write(struct file *file, const char *buffer,
-				     size_t count, loff_t *off)
+ptlrpc_lprocfs_threads_max_seq_write(struct file *file,
+				const char __user *buffer,
+				size_t count, loff_t *off)
 {
 	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
 	int	val;
@@ -723,7 +728,7 @@ struct ptlrpc_srh_iterator {
 	struct ptlrpc_request	*srhi_req;
 };
 
-int
+static int
 ptlrpc_lprocfs_svc_req_history_seek(struct ptlrpc_service_part *svcpt,
 				    struct ptlrpc_srh_iterator *srhi,
 				    __u64 seq)
@@ -1025,7 +1030,7 @@ static int ptlrpc_lprocfs_hp_ratio_seq_show(struct seq_file *m, void *v)
 }
 
 static ssize_t ptlrpc_lprocfs_hp_ratio_seq_write(struct file *file,
-					     const char *buffer,
+					     const char __user *buffer,
 					     size_t count,
 					     loff_t *off)
 {
@@ -1175,7 +1180,7 @@ EXPORT_SYMBOL(ptlrpc_lprocfs_unregister_obd);
 
 #define BUFLEN (UUID_MAX + 5)
 
-int lprocfs_wr_evict_client(struct file *file, const char *buffer,
+int lprocfs_wr_evict_client(struct file *file, const char __user *buffer,
 			    size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -1223,7 +1228,7 @@ EXPORT_SYMBOL(lprocfs_wr_evict_client);
 
 #undef BUFLEN
 
-int lprocfs_wr_ping(struct file *file, const char *buffer,
+int lprocfs_wr_ping(struct file *file, const char __user *buffer,
 		    size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -1251,7 +1256,7 @@ EXPORT_SYMBOL(lprocfs_wr_ping);
  * The connection UUID is a node's primary NID. For example,
  * "echo connection=192.168.0.1@tcp0::instance > .../import".
  */
-int lprocfs_wr_import(struct file *file, const char *buffer,
+int lprocfs_wr_import(struct file *file, const char __user *buffer,
 		      size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
@@ -1329,7 +1334,7 @@ int lprocfs_rd_pinger_recov(struct seq_file *m, void *n)
 }
 EXPORT_SYMBOL(lprocfs_rd_pinger_recov);
 
-int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
+int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer,
 		      size_t count, loff_t *off)
 {
 	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
diff --git a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
index cbcc541cac43..4621b71fe0b6 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/ptlrpcd.c
@@ -306,21 +306,16 @@ static int ptlrpcd_check(struct lu_env *env, struct ptlrpcd_ctl *pc)
 	if (atomic_read(&set->set_remaining))
 		rc |= ptlrpc_check_set(env, set);
 
-	if (!list_empty(&set->set_requests)) {
-		/*
-		 * XXX: our set never completes, so we prune the completed
-		 * reqs after each iteration. boy could this be smarter.
-		 */
-		list_for_each_safe(pos, tmp, &set->set_requests) {
-			req = list_entry(pos, struct ptlrpc_request,
-					     rq_set_chain);
-			if (req->rq_phase != RQ_PHASE_COMPLETE)
-				continue;
+	/* NB: ptlrpc_check_set has already moved completed request at the
+	 * head of seq::set_requests */
+	list_for_each_safe(pos, tmp, &set->set_requests) {
+		req = list_entry(pos, struct ptlrpc_request, rq_set_chain);
+		if (req->rq_phase != RQ_PHASE_COMPLETE)
+			break;
 
-			list_del_init(&req->rq_set_chain);
-			req->rq_set = NULL;
-			ptlrpc_req_finished(req);
-		}
+		list_del_init(&req->rq_set_chain);
+		req->rq_set = NULL;
+		ptlrpc_req_finished(req);
 	}
 
 	if (rc == 0) {
diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
index c500aff66193..81de68edb04e 100644
--- a/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
+++ b/drivers/staging/lustre/lustre/ptlrpc/sec_gc.c
@@ -47,6 +47,8 @@
 #include "../include/lustre_net.h"
 #include "../include/lustre_sec.h"
 
+#include "ptlrpc_internal.h"
+
 #define SEC_GC_INTERVAL (30 * 60)
 
 
diff --git a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
index 704fa202ee18..a425f71dfb97 100644
--- a/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
+++ b/drivers/staging/media/davinci_vpfe/dm365_ipipe.c
@@ -901,7 +901,7 @@ static int ipipe_set_gbce_params(struct vpfe_ipipe_device *ipipe, void *param)
 	struct device *dev = ipipe->subdev.v4l2_dev->dev;
 
 	if (!gbce_param) {
-		memset(gbce, 0 , sizeof(struct vpfe_ipipe_gbce));
+		memset(gbce, 0, sizeof(struct vpfe_ipipe_gbce));
 	} else {
 		memcpy(gbce, gbce_param, sizeof(struct vpfe_ipipe_gbce));
 		if (ipipe_validate_gbce_params(gbce) < 0) {
@@ -1086,7 +1086,7 @@ static int ipipe_set_car_params(struct vpfe_ipipe_device *ipipe, void *param)
 	struct vpfe_ipipe_car *car = &ipipe->config.car;
 
 	if (!car_param) {
-		memset(car , 0, sizeof(struct vpfe_ipipe_car));
+		memset(car, 0, sizeof(struct vpfe_ipipe_car));
 	} else {
 		memcpy(car, car_param, sizeof(struct vpfe_ipipe_car));
 		if (ipipe_validate_car_params(car) < 0) {
diff --git a/drivers/staging/mt29f_spinand/Kconfig b/drivers/staging/mt29f_spinand/Kconfig
index 403174817be7..f3f9cb3b5c35 100644
--- a/drivers/staging/mt29f_spinand/Kconfig
+++ b/drivers/staging/mt29f_spinand/Kconfig
@@ -12,5 +12,5 @@ config MTD_SPINAND_ONDIEECC
 	bool "Use SPINAND internal ECC"
 	depends on MTD_SPINAND_MT29F
 	help
-	  Internel ECC.
+	  Internal ECC.
 	  Enables Hardware ECC support for Micron SPI NAND.
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
index 3628bcb840c3..3b191fce45ec 100644
--- a/drivers/staging/mt29f_spinand/mt29f_spinand.c
+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c
@@ -626,7 +626,8 @@ static int spinand_write_page_hwecc(struct mtd_info *mtd,
 static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 		uint8_t *buf, int oob_required, int page)
 {
-	u8 retval, status;
+	int retval;
+	u8 status;
 	uint8_t *p = buf;
 	int eccsize = chip->ecc.size;
 	int eccsteps = chip->ecc.steps;
@@ -640,6 +641,13 @@ static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 
 	while (1) {
 		retval = spinand_read_status(info->spi, &status);
+		if (retval < 0) {
+			dev_err(&mtd->dev,
+					"error %d reading status register\n",
+					retval);
+			return retval;
+		}
+
 		if ((status & STATUS_OIP_MASK) == STATUS_READY) {
 			if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
 				pr_info("spinand: ECC error\n");
@@ -685,6 +693,13 @@ static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip)
 
 	while (time_before(jiffies, timeo)) {
 		retval = spinand_read_status(info->spi, &status);
+		if (retval < 0) {
+			dev_err(&mtd->dev,
+					"error %d reading status register\n",
+					retval);
+			return retval;
+		}
+
 		if ((status & STATUS_OIP_MASK) == STATUS_READY)
 			return 0;
 
diff --git a/drivers/staging/netlogic/xlr_net.c b/drivers/staging/netlogic/xlr_net.c
index 5ecb3e6a5bb3..e8aae09d1624 100644
--- a/drivers/staging/netlogic/xlr_net.c
+++ b/drivers/staging/netlogic/xlr_net.c
@@ -788,7 +788,7 @@ void xlr_set_gmac_speed(struct xlr_net_priv *priv)
 			xlr_nae_wreg(priv->base_addr, R_MAC_CONFIG_2, 0x7117);
 			priv->phy_speed = speed;
 		}
-		/* Set SGMII speed in Interface controll reg */
+		/* Set SGMII speed in Interface control reg */
 		if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
 			if (speed == SPEED_10)
 				xlr_nae_wreg(priv->base_addr,
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c
index 120b70d72d79..5868ebb8389e 100644
--- a/drivers/staging/nvec/nvec.c
+++ b/drivers/staging/nvec/nvec.c
@@ -256,7 +256,7 @@ static void nvec_gpio_set_value(struct nvec_chip *nvec, int value)
  * and return immediately.
  *
  * Returns: 0 on success, a negative error code on failure. If a failure
- * occured, the nvec driver may print an error.
+ * occurred, the nvec driver may print an error.
  */
 int nvec_write_async(struct nvec_chip *nvec, const unsigned char *data,
 			short size)
diff --git a/drivers/staging/octeon-usb/octeon-hcd.c b/drivers/staging/octeon-usb/octeon-hcd.c
index 6b8b108c4e6d..1daeb3125a1f 100644
--- a/drivers/staging/octeon-usb/octeon-hcd.c
+++ b/drivers/staging/octeon-usb/octeon-hcd.c
@@ -2687,7 +2687,7 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
 
 	/*
 	 * Read the channel config info so we can figure out how much data
-	 * transfered
+	 * transferred
 	 */
 	usbc_hcchar.u32 = __cvmx_usb_read_csr32(usb,
 			CVMX_USBCX_HCCHARX(channel, usb->index));
diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
index fcbe836aa997..22667dbb10d8 100644
--- a/drivers/staging/octeon/ethernet-rx.c
+++ b/drivers/staging/octeon/ethernet-rx.c
@@ -109,6 +109,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
 		int interface = cvmx_helper_get_interface_num(work->ipprt);
 		int index = cvmx_helper_get_interface_index_num(work->ipprt);
 		union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
+
 		gmxx_rxx_frm_ctl.u64 =
 		    cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
 		if (gmxx_rxx_frm_ctl.s.pre_chk == 0) {
@@ -214,6 +215,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
 		did_work_request = 0;
 		if (work == NULL) {
 			union cvmx_pow_wq_int wq_int;
+
 			wq_int.u64 = 0;
 			wq_int.s.iq_dis = 1 << pow_receive_group;
 			wq_int.s.wq_int = 1 << pow_receive_group;
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index ee321496dcdd..460e8545904f 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -798,7 +798,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
 	cvm_oct_rx_initialize();
 
 	/*
-	 * 150 uS: about 10 1500-byte packtes at 1GE.
+	 * 150 uS: about 10 1500-byte packets at 1GE.
 	 */
 	cvm_oct_tx_poll_interval = 150 * (octeon_get_clock_rate() / 1000000);
 
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c
index 6a9a8815477c..bc7e664cc8a7 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon.c
@@ -780,7 +780,7 @@ static const struct i2c_device_id dcon_idtable[] = {
 };
 MODULE_DEVICE_TABLE(i2c, dcon_idtable);
 
-struct i2c_driver dcon_driver = {
+static struct i2c_driver dcon_driver = {
 	.driver = {
 		.name	= "olpc_dcon",
 		.pm = &dcon_pm_ops,
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
index 77e8eb5a5abd..0c5a10c69401 100644
--- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
+++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
@@ -52,7 +52,7 @@ static int dcon_init_xo_1(struct dcon_priv *dcon)
 	 * Determine the current state by reading the GPIO bit; earlier
 	 * stages of the boot process have established the state.
 	 *
-	 * Note that we read GPIO_OUPUT_VAL rather than GPIO_READ_BACK here;
+	 * Note that we read GPIO_OUTPUT_VAL rather than GPIO_READ_BACK here;
 	 * this is because OFW will disable input for the pin and set a value..
 	 * READ_BACK will only contain a valid value if input is enabled and
 	 * then a value is set.  So, future readings of the pin can use
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 98325b7b4462..6ed35b6ecf0d 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -130,6 +130,30 @@
 #define LCD_FLAG_N		0x0040	/* 2-rows mode */
 #define LCD_FLAG_L		0x0080	/* backlight enabled */
 
+/* LCD commands */
+#define LCD_CMD_DISPLAY_CLEAR	0x01	/* Clear entire display */
+
+#define LCD_CMD_ENTRY_MODE	0x04	/* Set entry mode */
+#define LCD_CMD_CURSOR_INC	0x02	/* Increment cursor */
+
+#define LCD_CMD_DISPLAY_CTRL	0x08	/* Display control */
+#define LCD_CMD_DISPLAY_ON	0x04	/* Set display on */
+#define LCD_CMD_CURSOR_ON	0x02	/* Set cursor on */
+#define LCD_CMD_BLINK_ON	0x01	/* Set blink on */
+
+#define LCD_CMD_SHIFT		0x10	/* Shift cursor/display */
+#define LCD_CMD_DISPLAY_SHIFT	0x08	/* Shift display instead of cursor */
+#define LCD_CMD_SHIFT_RIGHT	0x04	/* Shift display/cursor to the right */
+
+#define LCD_CMD_FUNCTION_SET	0x20	/* Set function */
+#define LCD_CMD_DATA_LEN_8BITS	0x10	/* Set data length to 8 bits */
+#define LCD_CMD_TWO_LINES	0x08	/* Set to two display lines */
+#define LCD_CMD_FONT_5X10_DOTS	0x04	/* Set char font to 5x10 dots */
+
+#define LCD_CMD_SET_CGRAM_ADDR	0x40	/* Set char generator RAM address */
+
+#define LCD_CMD_SET_DDRAM_ADDR	0x80	/* Set display data RAM address */
+
 #define LCD_ESCAPE_LEN		24	/* max chars for LCD escape command */
 #define LCD_ESCAPE_CHAR	27	/* use char 27 for escape command */
 
@@ -228,9 +252,6 @@ static struct {
 	bool initialized;
 	bool must_clear;
 
-	/* TODO: use bool here? */
-	char left_shift;
-
 	int height;
 	int width;
 	int bwidth;
@@ -759,7 +780,7 @@ static void long_sleep(int ms)
 	if (in_interrupt()) {
 		mdelay(ms);
 	} else {
-		current->state = TASK_INTERRUPTIBLE;
+		__set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout((ms * HZ + 999) / 1000);
 	}
 }
@@ -886,7 +907,7 @@ static void lcd_write_data_tilcd(int data)
 
 static void lcd_gotoxy(void)
 {
-	lcd_write_cmd(0x80	/* set DDRAM address */
+	lcd_write_cmd(LCD_CMD_SET_DDRAM_ADDR
 		      | (lcd.addr.y ? lcd.hwidth : 0)
 		      /* we force the cursor to stay at the end of the
 			 line if it wants to go farther */
@@ -994,7 +1015,7 @@ static void lcd_clear_fast_tilcd(void)
 /* clears the display and resets X/Y */
 static void lcd_clear_display(void)
 {
-	lcd_write_cmd(0x01);	/* clear display */
+	lcd_write_cmd(LCD_CMD_DISPLAY_CLEAR);
 	lcd.addr.x = 0;
 	lcd.addr.y = 0;
 	/* we must wait a few milliseconds (15) */
@@ -1008,26 +1029,29 @@ static void lcd_init_display(void)
 
 	long_sleep(20);		/* wait 20 ms after power-up for the paranoid */
 
-	lcd_write_cmd(0x30);	/* 8bits, 1 line, small fonts */
+	/* 8bits, 1 line, small fonts; let's do it 3 times */
+	lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
 	long_sleep(10);
-	lcd_write_cmd(0x30);	/* 8bits, 1 line, small fonts */
+	lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
 	long_sleep(10);
-	lcd_write_cmd(0x30);	/* 8bits, 1 line, small fonts */
+	lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS);
 	long_sleep(10);
 
-	lcd_write_cmd(0x30	/* set font height and lines number */
-		      | ((lcd.flags & LCD_FLAG_F) ? 4 : 0)
-		      | ((lcd.flags & LCD_FLAG_N) ? 8 : 0)
+	/* set font height and lines number */
+	lcd_write_cmd(LCD_CMD_FUNCTION_SET | LCD_CMD_DATA_LEN_8BITS
+		      | ((lcd.flags & LCD_FLAG_F) ? LCD_CMD_FONT_5X10_DOTS : 0)
+		      | ((lcd.flags & LCD_FLAG_N) ? LCD_CMD_TWO_LINES : 0)
 	    );
 	long_sleep(10);
 
-	lcd_write_cmd(0x08);	/* display off, cursor off, blink off */
+	/* display off, cursor off, blink off */
+	lcd_write_cmd(LCD_CMD_DISPLAY_CTRL);
 	long_sleep(10);
 
-	lcd_write_cmd(0x08	/* set display mode */
-		      | ((lcd.flags & LCD_FLAG_D) ? 4 : 0)
-		      | ((lcd.flags & LCD_FLAG_C) ? 2 : 0)
-		      | ((lcd.flags & LCD_FLAG_B) ? 1 : 0)
+	lcd_write_cmd(LCD_CMD_DISPLAY_CTRL	/* set display mode */
+		      | ((lcd.flags & LCD_FLAG_D) ? LCD_CMD_DISPLAY_ON : 0)
+		      | ((lcd.flags & LCD_FLAG_C) ? LCD_CMD_CURSOR_ON : 0)
+		      | ((lcd.flags & LCD_FLAG_B) ? LCD_CMD_BLINK_ON : 0)
 	    );
 
 	lcd_backlight((lcd.flags & LCD_FLAG_L) ? 1 : 0);
@@ -1035,7 +1059,7 @@ static void lcd_init_display(void)
 	long_sleep(10);
 
 	/* entry mode set : increment, cursor shifting */
-	lcd_write_cmd(0x06);
+	lcd_write_cmd(LCD_CMD_ENTRY_MODE | LCD_CMD_CURSOR_INC);
 
 	lcd_clear_display();
 }
@@ -1119,7 +1143,7 @@ static inline int handle_lcd_special_code(void)
 		if (lcd.addr.x > 0) {
 			/* back one char if not at end of line */
 			if (lcd.addr.x < lcd.bwidth)
-				lcd_write_cmd(0x10);
+				lcd_write_cmd(LCD_CMD_SHIFT);
 			lcd.addr.x--;
 		}
 		processed = 1;
@@ -1127,21 +1151,20 @@ static inline int handle_lcd_special_code(void)
 	case 'r':	/* shift cursor right */
 		if (lcd.addr.x < lcd.width) {
 			/* allow the cursor to pass the end of the line */
-			if (lcd.addr.x <
-			    (lcd.bwidth - 1))
-				lcd_write_cmd(0x14);
+			if (lcd.addr.x < (lcd.bwidth - 1))
+				lcd_write_cmd(LCD_CMD_SHIFT |
+						LCD_CMD_SHIFT_RIGHT);
 			lcd.addr.x++;
 		}
 		processed = 1;
 		break;
 	case 'L':	/* shift display left */
-		lcd.left_shift++;
-		lcd_write_cmd(0x18);
+		lcd_write_cmd(LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT);
 		processed = 1;
 		break;
 	case 'R':	/* shift display right */
-		lcd.left_shift--;
-		lcd_write_cmd(0x1C);
+		lcd_write_cmd(LCD_CMD_SHIFT | LCD_CMD_DISPLAY_SHIFT |
+				LCD_CMD_SHIFT_RIGHT);
 		processed = 1;
 		break;
 	case 'k': {	/* kill end of line */
@@ -1157,7 +1180,6 @@ static inline int handle_lcd_special_code(void)
 	}
 	case 'I':	/* reinitialize display */
 		lcd_init_display();
-		lcd.left_shift = 0;
 		processed = 1;
 		break;
 	case 'G': {
@@ -1211,7 +1233,7 @@ static inline int handle_lcd_special_code(void)
 			esc++;
 		}
 
-		lcd_write_cmd(0x40 | (cgaddr * 8));
+		lcd_write_cmd(LCD_CMD_SET_CGRAM_ADDR | (cgaddr * 8));
 		for (addr = 0; addr < cgoffset; addr++)
 			lcd_write_data(cgbytes[addr]);
 
@@ -1244,21 +1266,29 @@ static inline int handle_lcd_special_code(void)
 		break;
 	}
 
+	/* TODO: This indent party here got ugly, clean it! */
 	/* Check whether one flag was changed */
 	if (oldflags != lcd.flags) {
 		/* check whether one of B,C,D flags were changed */
 		if ((oldflags ^ lcd.flags) &
 		    (LCD_FLAG_B | LCD_FLAG_C | LCD_FLAG_D))
 			/* set display mode */
-			lcd_write_cmd(0x08
-				      | ((lcd.flags & LCD_FLAG_D) ? 4 : 0)
-				      | ((lcd.flags & LCD_FLAG_C) ? 2 : 0)
-				      | ((lcd.flags & LCD_FLAG_B) ? 1 : 0));
+			lcd_write_cmd(LCD_CMD_DISPLAY_CTRL
+				      | ((lcd.flags & LCD_FLAG_D)
+						      ? LCD_CMD_DISPLAY_ON : 0)
+				      | ((lcd.flags & LCD_FLAG_C)
+						      ? LCD_CMD_CURSOR_ON : 0)
+				      | ((lcd.flags & LCD_FLAG_B)
+						      ? LCD_CMD_BLINK_ON : 0));
 		/* check whether one of F,N flags was changed */
 		else if ((oldflags ^ lcd.flags) & (LCD_FLAG_F | LCD_FLAG_N))
-			lcd_write_cmd(0x30
-				      | ((lcd.flags & LCD_FLAG_F) ? 4 : 0)
-				      | ((lcd.flags & LCD_FLAG_N) ? 8 : 0));
+			lcd_write_cmd(LCD_CMD_FUNCTION_SET
+				      | LCD_CMD_DATA_LEN_8BITS
+				      | ((lcd.flags & LCD_FLAG_F)
+						      ? LCD_CMD_TWO_LINES : 0)
+				      | ((lcd.flags & LCD_FLAG_N)
+						      ? LCD_CMD_FONT_5X10_DOTS
+								      : 0));
 		/* check whether L flag was changed */
 		else if ((oldflags ^ lcd.flags) & (LCD_FLAG_L)) {
 			if (lcd.flags & (LCD_FLAG_L))
@@ -1297,13 +1327,13 @@ static void lcd_write_char(char c)
 				   end of the line */
 				if (lcd.addr.x < lcd.bwidth)
 					/* back one char */
-					lcd_write_cmd(0x10);
+					lcd_write_cmd(LCD_CMD_SHIFT);
 				lcd.addr.x--;
 			}
 			/* replace with a space */
 			lcd_write_data(' ');
 			/* back one char again */
-			lcd_write_cmd(0x10);
+			lcd_write_cmd(LCD_CMD_SHIFT);
 			break;
 		case '\014':
 			/* quickly clear the display */
diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c
index d61842ed673e..da19145c49c5 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ap.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ap.c
@@ -509,7 +509,7 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level)
 		tx_ra_bitmap |= ((raid<<28)&0xf0000000);
 
 		DBG_88E("%s => mac_id:%d , raid:%d , bitmap = 0x%x, arg = 0x%x\n",
-			__func__ , psta->mac_id, raid , tx_ra_bitmap, arg);
+			__func__, psta->mac_id, raid, tx_ra_bitmap, arg);
 
 		/* bitmap[0:27] = tx_rate_bitmap */
 		/* bitmap[28:31]= Rate Adaptive id */
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index e4b7ee4c99d5..cd12dd70dd88 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -484,17 +484,8 @@ void mgt_dispatcher(struct adapter *padapter, struct recv_frame *precv_frame)
 		/* fall through */
 	case WIFI_ASSOCREQ:
 	case WIFI_REASSOCREQ:
-		_mgt_dispatcher(padapter, ptable, precv_frame);
-		break;
 	case WIFI_PROBEREQ:
-		if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
-			_mgt_dispatcher(padapter, ptable, precv_frame);
-		else
-			_mgt_dispatcher(padapter, ptable, precv_frame);
-		break;
 	case WIFI_BEACON:
-		_mgt_dispatcher(padapter, ptable, precv_frame);
-		break;
 	case WIFI_ACTION:
 		_mgt_dispatcher(padapter, ptable, precv_frame);
 		break;
@@ -577,13 +568,14 @@ unsigned int OnBeacon(struct adapter *padapter, struct recv_frame *precv_frame)
 	uint len = precv_frame->len;
 	struct wlan_bssid_ex *pbss;
 	int ret = _SUCCESS;
+	struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
 
 	if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
 		report_survey_event(padapter, precv_frame);
 		return _SUCCESS;
 	}
 
-	if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
+	if (!memcmp(GetAddr3Ptr(pframe), pnetwork->MacAddress, ETH_ALEN)) {
 		if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
 			/* we should update current network before auth, or some IE is wrong */
 			pbss = (struct wlan_bssid_ex *)rtw_malloc(sizeof(struct wlan_bssid_ex));
@@ -1445,10 +1437,10 @@ unsigned int OnDeAuth(struct adapter *padapter, struct recv_frame *precv_frame)
 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
 	u8 *pframe = precv_frame->rx_data;
+	struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
 
 	/* check A3 */
-	if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network),
-		   ETH_ALEN))
+	if (memcmp(GetAddr3Ptr(pframe), pnetwork->MacAddress, ETH_ALEN))
 		return _SUCCESS;
 
 	reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
@@ -1499,10 +1491,10 @@ unsigned int OnDisassoc(struct adapter *padapter, struct recv_frame *precv_frame
 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
 	u8 *pframe = precv_frame->rx_data;
+	struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
 
 	/* check A3 */
-	if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network),
-		   ETH_ALEN))
+	if (memcmp(GetAddr3Ptr(pframe), pnetwork->MacAddress, ETH_ALEN))
 		return _SUCCESS;
 
 	reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN));
@@ -2018,7 +2010,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms)
 
 	memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
 	memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
-	memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
+	memcpy(pwlanhdr->addr3, cur_network->MacAddress, ETH_ALEN);
 
 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
 	/* pmlmeext->mgnt_seq++; */
@@ -2422,6 +2414,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short
 	struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wlan_bssid_ex    *pnetwork = &(pmlmeinfo->network);
 
 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
 	if (pmgntframe == NULL)
@@ -2487,9 +2480,9 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short
 	} else {
 		__le32 le_tmp32;
 		__le16 le_tmp16;
-		memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
+		memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
 		memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
-		memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
+		memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
 
 		/*  setting auth algo number */
 		val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/*  0:OPEN System, 1:Shared key */
@@ -2582,7 +2575,7 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i
 
 	memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
 	memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
-	memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy((void *)GetAddr3Ptr(pwlanhdr), pnetwork->MacAddress, ETH_ALEN);
 
 
 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
@@ -2687,6 +2680,7 @@ void issue_assocreq(struct adapter *padapter)
 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
 	int	bssrate_len = 0, sta_bssrate_len = 0;
+	struct wlan_bssid_ex    *pnetwork = &(pmlmeinfo->network);
 
 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
 	if (pmgntframe == NULL)
@@ -2702,9 +2696,9 @@ void issue_assocreq(struct adapter *padapter)
 
 	fctrl = &(pwlanhdr->frame_ctl);
 	*(fctrl) = 0;
-	memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
 	memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
-	memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
 
 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
 	pmlmeext->mgnt_seq++;
@@ -2879,6 +2873,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
 	struct xmit_priv	*pxmitpriv;
 	struct mlme_ext_priv	*pmlmeext;
 	struct mlme_ext_info	*pmlmeinfo;
+	struct wlan_bssid_ex    *pnetwork;
 
 	if (!padapter)
 		goto exit;
@@ -2886,6 +2881,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
 	pxmitpriv = &(padapter->xmitpriv);
 	pmlmeext = &(padapter->mlmeextpriv);
 	pmlmeinfo = &(pmlmeext->mlmext_info);
+	pnetwork = &(pmlmeinfo->network);
 
 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
 	if (pmgntframe == NULL)
@@ -2914,7 +2910,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned
 
 	memcpy(pwlanhdr->addr1, da, ETH_ALEN);
 	memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
-	memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
 
 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
 	pmlmeext->mgnt_seq++;
@@ -2946,10 +2942,11 @@ int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int pow
 	u32 start = jiffies;
 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wlan_bssid_ex    *pnetwork = &(pmlmeinfo->network);
 
 	/* da == NULL, assume it's null data for sta to ap*/
 	if (da == NULL)
-		da = get_my_bssid(&(pmlmeinfo->network));
+		da = pnetwork->MacAddress;
 
 	do {
 		ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0 ? true : false);
@@ -2995,6 +2992,7 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wlan_bssid_ex    *pnetwork = &(pmlmeinfo->network);
 
 	DBG_88E("%s\n", __func__);
 
@@ -3038,7 +3036,7 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16
 
 	memcpy(pwlanhdr->addr1, da, ETH_ALEN);
 	memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
-	memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
 
 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
 	pmlmeext->mgnt_seq++;
@@ -3069,10 +3067,11 @@ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int
 	u32 start = jiffies;
 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wlan_bssid_ex    *pnetwork = &(pmlmeinfo->network);
 
 	/* da == NULL, assume it's null data for sta to ap*/
 	if (da == NULL)
-		da = get_my_bssid(&(pmlmeinfo->network));
+		da = pnetwork->MacAddress;
 
 	do {
 		ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0 ? true : false);
@@ -3115,6 +3114,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wlan_bssid_ex    *pnetwork = &(pmlmeinfo->network);
 	int ret = _FAIL;
 	__le16 le_tmp;
 
@@ -3137,7 +3137,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, unsigned s
 
 	memcpy(pwlanhdr->addr1, da, ETH_ALEN);
 	memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
-	memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
 
 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
 	pmlmeext->mgnt_seq++;
@@ -3288,6 +3288,7 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch
 	struct sta_info *psta;
 	struct sta_priv *pstapriv = &padapter->stapriv;
 	struct registry_priv *pregpriv = &padapter->registrypriv;
+	struct wlan_bssid_ex    *pnetwork = &(pmlmeinfo->network);
 
 	DBG_88E("%s, category=%d, action=%d, status=%d\n", __func__, category, action, status);
 
@@ -3310,7 +3311,7 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch
 	/* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
 	memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
 	memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
-	memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
 
 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
 	pmlmeext->mgnt_seq++;
@@ -3420,6 +3421,8 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
 	struct __queue *queue	= &(pmlmepriv->scanned_queue);
 	u8 InfoContent[16] = {0};
 	u8 ICS[8][15];
+	struct wlan_bssid_ex  *cur_network   = &(pmlmeinfo->network);
+
 	if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
 		return;
 
@@ -3449,9 +3452,9 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter)
 	fctrl = &(pwlanhdr->frame_ctl);
 	*(fctrl) = 0;
 
-	memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy(pwlanhdr->addr1, cur_network->MacAddress, ETH_ALEN);
 	memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
-	memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy(pwlanhdr->addr3, cur_network->MacAddress, ETH_ALEN);
 
 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
 	pmlmeext->mgnt_seq++;
@@ -4042,9 +4045,10 @@ unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr
 {
 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wlan_bssid_ex    *pnetwork = &(pmlmeinfo->network);
 
 	/* check A3 */
-	if (memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
+	if (memcmp(MacAddr, pnetwork->MacAddress, ETH_ALEN))
 		return _SUCCESS;
 
 	DBG_88E("%s\n", __func__);
@@ -4924,11 +4928,6 @@ void addba_timer_hdl(void *function_context)
 	}
 }
 
-u8 NULL_hdl(struct adapter *padapter, u8 *pbuf)
-{
-	return H2C_SUCCESS;
-}
-
 u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf)
 {
 	u8 type;
diff --git a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
index 324c1a7fd0bc..a3ffc691be9a 100644
--- a/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8188eu/core/rtw_wlan_util.c
@@ -405,11 +405,6 @@ int get_bsstype(unsigned short capability)
 		return 0;
 }
 
-__inline u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork)
-{
-	return pnetwork->MacAddress;
-}
-
 u16 get_beacon_interval(struct wlan_bssid_ex *bss)
 {
 	__le16 val;
@@ -936,6 +931,8 @@ int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len)
 	}
 
 	bssid = kzalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
+	if (!bssid)
+		return _FAIL;
 
 	subtype = GetFrameSubType(pframe) >> 4;
 
diff --git a/drivers/staging/rtl8188eu/hal/odm.c b/drivers/staging/rtl8188eu/hal/odm.c
index 9873998011d2..06477e834653 100644
--- a/drivers/staging/rtl8188eu/hal/odm.c
+++ b/drivers/staging/rtl8188eu/hal/odm.c
@@ -534,13 +534,8 @@ void odm_DIGInit(struct odm_dm_struct *pDM_Odm)
 	pDM_DigTable->RssiHighThresh	= DM_DIG_THRESH_HIGH;
 	pDM_DigTable->FALowThresh	= DM_false_ALARM_THRESH_LOW;
 	pDM_DigTable->FAHighThresh	= DM_false_ALARM_THRESH_HIGH;
-	if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) {
-		pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
-		pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
-	} else {
-		pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
-		pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
-	}
+	pDM_DigTable->rx_gain_range_max = DM_DIG_MAX_NIC;
+	pDM_DigTable->rx_gain_range_min = DM_DIG_MIN_NIC;
 	pDM_DigTable->BackoffVal = DM_DIG_BACKOFF_DEFAULT;
 	pDM_DigTable->BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
 	pDM_DigTable->BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
@@ -1138,16 +1133,9 @@ static void FindMinimumRSSI(struct adapter *pAdapter)
 {
 	struct hal_data_8188e	*pHalData = GET_HAL_DATA(pAdapter);
 	struct dm_priv	*pdmpriv = &pHalData->dmpriv;
-	struct mlme_priv	*pmlmepriv = &pAdapter->mlmepriv;
-
-	/* 1 1.Determine the minimum RSSI */
-	if ((check_fwstate(pmlmepriv, _FW_LINKED) == false) &&
-	    (pdmpriv->EntryMinUndecoratedSmoothedPWDB == 0))
-		pdmpriv->MinUndecoratedPWDBForDM = 0;
-	if (check_fwstate(pmlmepriv, _FW_LINKED) == true)	/*  Default port */
-		pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB;
-	else /*  associated entry pwdb */
-		pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB;
+
+	/* 1 1.Unconditionally set RSSI */
+	pdmpriv->MinUndecoratedPWDBForDM = pdmpriv->EntryMinUndecoratedSmoothedPWDB;
 }
 
 void odm_RSSIMonitorCheckCE(struct odm_dm_struct *pDM_Odm)
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
index 7f30dea1b53b..86347f2ccdfd 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
@@ -127,22 +127,6 @@ exit:
 	return ret;
 }
 
-u8 rtl8188e_set_rssi_cmd(struct adapter *adapt, u8 *param)
-{
-	u8 res = _SUCCESS;
-	struct hal_data_8188e *haldata = GET_HAL_DATA(adapt);
-
-	if (haldata->fw_ractrl) {
-		;
-	} else {
-		DBG_88E("==>%s fw dont support RA\n", __func__);
-		res = _FAIL;
-	}
-
-
-	return res;
-}
-
 u8 rtl8188e_set_raid_cmd(struct adapter *adapt, u32 mask)
 {
 	u8 buf[3];
@@ -276,7 +260,7 @@ static void ConstructBeacon(struct adapter *adapt, u8 *pframe, u32 *pLength)
 
 	memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
 	memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
-	memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
+	memcpy(pwlanhdr->addr3, cur_network->MacAddress, ETH_ALEN);
 
 	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
 	SetFrameSubType(pframe, WIFI_BEACON);
@@ -350,6 +334,7 @@ static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength)
 	struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
 	__le16 *fctrl;
+	struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
 
 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
 
@@ -363,7 +348,7 @@ static void ConstructPSPoll(struct adapter *adapt, u8 *pframe, u32 *pLength)
 	SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
 
 	/*  BSSID. */
-	memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+	memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
 
 	/*  TA. */
 	memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
@@ -386,6 +371,7 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
 	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
 	struct mlme_ext_priv *pmlmeext = &(adapt->mlmeextpriv);
 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
+	struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network);
 
 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
 
@@ -397,21 +383,21 @@ static void ConstructNullFunctionData(struct adapter *adapt, u8 *pframe,
 	switch (cur_network->network.InfrastructureMode) {
 	case Ndis802_11Infrastructure:
 		SetToDs(fctrl);
-		memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+		memcpy(pwlanhdr->addr1, pnetwork->MacAddress, ETH_ALEN);
 		memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
 		memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
 		break;
 	case Ndis802_11APMode:
 		SetFrDs(fctrl);
 		memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
-		memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+		memcpy(pwlanhdr->addr2, pnetwork->MacAddress, ETH_ALEN);
 		memcpy(pwlanhdr->addr3, myid(&(adapt->eeprompriv)), ETH_ALEN);
 		break;
 	case Ndis802_11IBSS:
 	default:
 		memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
 		memcpy(pwlanhdr->addr2, myid(&(adapt->eeprompriv)), ETH_ALEN);
-		memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+		memcpy(pwlanhdr->addr3, pnetwork->MacAddress, ETH_ALEN);
 		break;
 	}
 
@@ -498,6 +484,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
 	u16 BufIndex;
 	u32 TotalPacketLen;
 	struct rsvdpage_loc RsvdPageLoc;
+	struct wlan_bssid_ex *pnetwork;
 
 	DBG_88E("%s\n", __func__);
 	ReservedPagePacket = kzalloc(1000, GFP_KERNEL);
@@ -510,6 +497,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
 	pxmitpriv = &adapt->xmitpriv;
 	pmlmeext = &adapt->mlmeextpriv;
 	pmlmeinfo = &pmlmeext->mlmext_info;
+	pnetwork = &(pmlmeinfo->network);
 
 	TxDescLen = TXDESC_SIZE;
 	PageNum = 0;
@@ -541,7 +529,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
 
 	/* 3 (3) null data * 1 page */
 	RsvdPageLoc.LocNullData = PageNum;
-	ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], &NullDataLength, get_my_bssid(&pmlmeinfo->network), false, 0, 0, false);
+	ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex], &NullDataLength, pnetwork->MacAddress, false, 0, 0, false);
 	rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, false, false);
 
 	PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength);
@@ -551,7 +539,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
 
 	/* 3 (4) probe response * 1page */
 	RsvdPageLoc.LocProbeRsp = PageNum;
-	ConstructProbeRsp(adapt, &ReservedPagePacket[BufIndex], &ProbeRspLength, get_my_bssid(&pmlmeinfo->network), false);
+	ConstructProbeRsp(adapt, &ReservedPagePacket[BufIndex], &ProbeRspLength, pnetwork->MacAddress, false);
 	rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, false, false);
 
 	PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength);
@@ -562,7 +550,7 @@ static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
 	/* 3 (5) Qos null data */
 	RsvdPageLoc.LocQosNull = PageNum;
 	ConstructNullFunctionData(adapt, &ReservedPagePacket[BufIndex],
-				  &QosNullLength, get_my_bssid(&pmlmeinfo->network), true, 0, 0, false);
+				  &QosNullLength, pnetwork->MacAddress, true, 0, 0, false);
 	rtl8188e_fill_fake_txdesc(adapt, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, false, false);
 
 	PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength);
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
index 7d460eaafa35..3222d8d08b5b 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
@@ -242,20 +242,6 @@ void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc)
 	pHalFunc->hal_notch_filter = &hal_notch_filter_8188e;
 }
 
-u8 GetEEPROMSize8188E(struct adapter *padapter)
-{
-	u8 size = 0;
-	u32	cr;
-
-	cr = usb_read16(padapter, REG_9346CR);
-	/*  6: EEPROM used is 93C46, 4: boot from E-Fuse. */
-	size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
-
-	MSG_88E("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
-
-	return size;
-}
-
 /*  */
 /*  */
 /*  LLT R/W/Init function */
diff --git a/drivers/staging/rtl8188eu/include/osdep_service.h b/drivers/staging/rtl8188eu/include/osdep_service.h
index 82f58f87656a..3a274770364b 100644
--- a/drivers/staging/rtl8188eu/include/osdep_service.h
+++ b/drivers/staging/rtl8188eu/include/osdep_service.h
@@ -87,7 +87,7 @@ static inline void _init_timer(struct timer_list *ptimer,
 
 static inline void _set_timer(struct timer_list *ptimer, u32 delay_time)
 {
-	mod_timer(ptimer , (jiffies+(delay_time*HZ/1000)));
+	mod_timer(ptimer , (jiffies+msecs_to_jiffies(delay_time)));
 }
 
 #define RTW_TIMER_HDL_ARGS void *FunctionContext
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
index 0e78e2a357bd..42b1f22424eb 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_cmd.h
@@ -107,7 +107,6 @@ struct P2P_PS_CTWPeriod_t {
 /*  host message to firmware cmd */
 void rtl8188e_set_FwPwrMode_cmd(struct adapter *padapter, u8 Mode);
 void rtl8188e_set_FwJoinBssReport_cmd(struct adapter *padapter, u8 mstatus);
-u8 rtl8188e_set_rssi_cmd(struct adapter *padapter, u8 *param);
 u8 rtl8188e_set_raid_cmd(struct adapter *padapter, u32 mask);
 void rtl8188e_Add_RateATid(struct adapter *padapter, u32 bitmap, u8 arg,
 			   u8 rssi_level);
diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
index 42ab1d288bdc..b8c42eed98c4 100644
--- a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
+++ b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h
@@ -391,7 +391,6 @@ void rtl8188e_InitializeFirmwareVars(struct adapter *padapter);
 s32 InitLLTTable(struct adapter *padapter, u8 txpktbuf_bndy);
 
 /*  EFuse */
-u8 GetEEPROMSize8188E(struct adapter *padapter);
 void Hal_InitPGData88E(struct adapter *padapter);
 void Hal_EfuseParseIDCode88E(struct adapter *padapter, u8 *hwinfo);
 void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *hwinfo,
diff --git a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
index 8d72ccf5f2a0..4f05aee93c9c 100644
--- a/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
+++ b/drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
@@ -496,7 +496,6 @@ void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
 		    struct adapter *adapter, bool update_ie);
 
 int get_bsstype(unsigned short capability);
-u8 *get_my_bssid(struct wlan_bssid_ex *pnetwork);
 u16 get_beacon_interval(struct wlan_bssid_ex *bss);
 
 int is_client_associated_to_ap(struct adapter *padapter);
@@ -516,7 +515,7 @@ void ERP_IE_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE);
 void VCS_update(struct adapter *padapter, struct sta_info *psta);
 
 void update_beacon_info(struct adapter *padapter, u8 *pframe, uint len,
-		        struct sta_info *psta);
+			struct sta_info *psta);
 int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len);
 void update_IOT_info(struct adapter *padapter);
 void update_capinfo(struct adapter *adapter, u16 updatecap);
@@ -679,7 +678,6 @@ u8 read_bbreg_hdl(struct adapter *padapter, u8 *pbuf);
 u8 write_bbreg_hdl(struct adapter *padapter, u8 *pbuf);
 u8 read_rfreg_hdl(struct adapter *padapter, u8 *pbuf);
 u8 write_rfreg_hdl(struct adapter *padapter, u8 *pbuf);
-u8 NULL_hdl(struct adapter *padapter, u8 *pbuf);
 u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf);
 u8 disconnect_hdl(struct adapter *padapter, u8 *pbuf);
 u8 createbss_hdl(struct adapter *padapter, u8 *pbuf);
diff --git a/drivers/staging/rtl8188eu/include/usb_ops_linux.h b/drivers/staging/rtl8188eu/include/usb_ops_linux.h
index 01b3810379ec..4fdc536cba79 100644
--- a/drivers/staging/rtl8188eu/include/usb_ops_linux.h
+++ b/drivers/staging/rtl8188eu/include/usb_ops_linux.h
@@ -79,7 +79,6 @@ void usb_read_port_cancel(struct adapter *adapter);
 int usb_write8(struct adapter *adapter, u32 addr, u8 val);
 int usb_write16(struct adapter *adapter, u32 addr, u16 val);
 int usb_write32(struct adapter *adapter, u32 addr, u32 val);
-int usb_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata);
 
 u32 usb_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem);
 void usb_write_port_cancel(struct adapter *adapter);
diff --git a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
index d2efa9dfc8c0..80e7ef96d807 100644
--- a/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/usb_ops_linux.c
@@ -615,33 +615,6 @@ int usb_write32(struct adapter *adapter, u32 addr, u32 val)
 	return ret;
 }
 
-int usb_writeN(struct adapter *adapter, u32 addr, u32 length, u8 *pdata)
-{
-	u8 request;
-	u8 requesttype;
-	u16 wvalue;
-	u16 index;
-	u16 len;
-	u8 buf[VENDOR_CMD_MAX_DATA_LEN] = {0};
-	int ret;
-
-
-	request = 0x05;
-	requesttype = 0x00;/* write_out */
-	index = 0;/* n/a */
-
-	wvalue = (u16)(addr&0x0000ffff);
-	len = length;
-	 memcpy(buf, pdata, len);
-
-	ret = usbctrl_vendorreq(adapter, request, wvalue, index, buf, len, requesttype);
-
-
-	return RTW_STATUS_CODE(ret);
-}
-
-
-
 static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
 {
 	struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
index 6c64e0899ffd..89ea70b0d3aa 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.c
@@ -167,35 +167,6 @@ void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType,
 	RT_TRACE(COMP_SEC, "=========>after set key, usconfig:%x\n", usConfig);
 }
 
-void CAM_read_entry(struct net_device *dev, u32 iIndex)
-{
-	u32 target_command = 0;
-	u32 target_content = 0;
-	u8 entry_i = 0;
-	u32 ulStatus;
-	s32 i = 100;
-
-	for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
-		target_command = entry_i+CAM_CONTENT_COUNT*iIndex;
-		target_command = target_command | BIT31;
-
-		while ((i--) >= 0) {
-			ulStatus = read_nic_dword(dev, RWCAM);
-			if (ulStatus & BIT31)
-				continue;
-			else
-				break;
-		}
-		write_nic_dword(dev, RWCAM, target_command);
-		RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A0: %x\n",
-			 target_command);
-		target_content = read_nic_dword(dev, RCAMO);
-		RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x\n",
-			 target_content);
-	}
-	printk(KERN_INFO "\n");
-}
-
 void CamRestoreAllEntry(struct net_device *dev)
 {
 	u8 EntryId = 0;
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
index 7d075d3cbe62..3c4c0e61c181 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_cam.h
@@ -41,6 +41,4 @@ void write_cam(struct net_device *dev, u8 addr, u32 data);
 
 void CamRestoreAllEntry(struct net_device *dev);
 
-void CAM_read_entry(struct net_device *dev, u32 iIndex);
-
 #endif
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
index 885315cac3a4..b8891c62af3e 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
@@ -1661,8 +1661,8 @@ void dm_change_dynamic_initgain_thresh(struct net_device *dev,
 		dm_digtable.rssi_low_thresh = dm_value;
 	} else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
 		dm_digtable.rssi_high_power_highthresh = dm_value;
-	} else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
-		dm_digtable.rssi_high_power_highthresh = dm_value;
+	} else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_LOW) {
+		dm_digtable.rssi_high_power_lowthresh = dm_value;
 	} else if (dm_type == DIG_TYPE_ENABLE) {
 		dm_digtable.dig_state		= DM_STA_DIG_MAX;
 		dm_digtable.dig_enable_flag	= true;
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
index 8e1a5d55dce8..0b4f76481bf4 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.c
@@ -22,12 +22,6 @@
 #include "r8190P_rtl8256.h"
 #include "rtl_pm.h"
 
-int rtl8192E_save_state(struct pci_dev *dev, pm_message_t state)
-{
-	printk(KERN_NOTICE "r8192E save state call (state %u).\n", state.event);
-	return -EAGAIN;
-}
-
 
 int rtl8192E_suspend(struct pci_dev *pdev, pm_message_t state)
 {
@@ -124,11 +118,3 @@ out:
 	return 0;
 }
 
-
-int rtl8192E_enable_wake(struct pci_dev *dev, pm_message_t state, int enable)
-{
-	printk(KERN_NOTICE "r8192E enable wake call (state %u, enable %d).\n",
-	       state.event, enable);
-	return -EAGAIN;
-}
-
diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
index e5299fc3b34a..7bfe44817f23 100644
--- a/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
+++ b/drivers/staging/rtl8192e/rtl8192e/rtl_pm.h
@@ -23,9 +23,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 
-int rtl8192E_save_state(struct pci_dev *dev, pm_message_t state);
 int rtl8192E_suspend(struct pci_dev *dev, pm_message_t state);
 int rtl8192E_resume(struct pci_dev *dev);
-int rtl8192E_enable_wake(struct pci_dev *dev, pm_message_t state, int enable);
 
 #endif
diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c
index c7f45080061f..1ea426b7b7ac 100644
--- a/drivers/staging/rtl8192e/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c
@@ -34,13 +34,13 @@ u16 MCS_DATA_RATE[2][2][77] = {
 	 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182,
 	 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156,
 	 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273,
-	 312, 351, 312, 351, 390, 390, 429} ,
+	 312, 351, 312, 351, 390, 390, 429},
 	{14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
 	 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520,
 	 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231,
 	 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260,
 	 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390,
-	 433, 433, 477} } ,
+	 433, 433, 477} },
 	{{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486,
 	 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648,
 	 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324,
diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c
index 91e98e8e5bfc..0cf38091f8c5 100644
--- a/drivers/staging/rtl8192e/rtllib_module.c
+++ b/drivers/staging/rtl8192e/rtllib_module.c
@@ -202,9 +202,7 @@ void free_rtllib(struct net_device *dev)
 EXPORT_SYMBOL(free_rtllib);
 
 u32 rtllib_debug_level;
-static int debug = \
-			    RTLLIB_DL_ERR
-			    ;
+static int debug = RTLLIB_DL_ERR;
 static struct proc_dir_entry *rtllib_proc;
 
 static int show_debug_level(struct seq_file *m, void *v)
diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c
index cf11b042b93a..1664040efdab 100644
--- a/drivers/staging/rtl8192e/rtllib_rx.c
+++ b/drivers/staging/rtl8192e/rtllib_rx.c
@@ -70,8 +70,7 @@ rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq,
 		if (entry->skb != NULL &&
 		    time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
 			RTLLIB_DEBUG_FRAG(
-				"expiring fragment cache entry "
-				"seq=%u last_frag=%u\n",
+				"expiring fragment cache entry seq=%u last_frag=%u\n",
 				entry->seq, entry->last_frag);
 			dev_kfree_skb_any(entry->skb);
 			entry->skb = NULL;
@@ -188,8 +187,7 @@ static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee,
 
 	if (entry == NULL) {
 		RTLLIB_DEBUG_FRAG(
-			"could not invalidate fragment cache "
-			"entry (seq=%u)\n", seq);
+			"could not invalidate fragment cache entry (seq=%u)\n", seq);
 		return -1;
 	}
 
@@ -305,11 +303,9 @@ rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
 		RTLLIB_DEBUG_DROP(
-			"decryption failed (SA= %pM"
-			") res=%d\n", hdr->addr2, res);
+			"decryption failed (SA= %pM) res=%d\n", hdr->addr2, res);
 		if (res == -2)
-			RTLLIB_DEBUG_DROP("Decryption failed ICV "
-					     "mismatch (key %d)\n",
+			RTLLIB_DEBUG_DROP("Decryption failed ICV mismatch (key %d)\n",
 					     skb->data[hdrlen + 3] >> 6);
 		ieee->ieee_stats.rx_discards_undecryptable++;
 		return -1;
@@ -345,8 +341,7 @@ rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb,
 	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
-		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
-		       " (SA= %pM keyidx=%d)\n",
+		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed (SA= %pM keyidx=%d)\n",
 		       ieee->dev->name, hdr->addr2, keyidx);
 		return -1;
 	}
@@ -559,8 +554,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
 	bool bMatchWinStart = false, bPktInBuf = false;
 	unsigned long flags;
 
-	RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Seq is %d, pTS->RxIndicateSeq"
-		     " is %d, WinSize is %d\n", __func__, SeqNum,
+	RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Seq is %d, pTS->RxIndicateSeq is %d, WinSize is %d\n", __func__, SeqNum,
 		     pTS->RxIndicateSeq, WinSize);
 
 	spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
@@ -600,8 +594,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
 			pTS->RxIndicateSeq = SeqNum + 1 - WinSize;
 		else
 			pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum + 1)) + 1;
-		RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Window Shift! IndicateSeq: %d,"
-			     " NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum);
+		RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum);
 	}
 
 	/*
@@ -617,8 +610,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
 	 */
 	if (bMatchWinStart) {
 		/* Current packet is going to be indicated.*/
-		RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packets indication!! "
-				"IndicateSeq: %d, NewSeq: %d\n",
+		RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",
 				pTS->RxIndicateSeq, SeqNum);
 		ieee->prxbIndicateArray[0] = prxb;
 		index = 1;
@@ -636,9 +628,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
 
 			if (!AddReorderEntry(pTS, pReorderEntry)) {
 				RTLLIB_DEBUG(RTLLIB_DL_REORDER,
-					     "%s(): Duplicate packet is "
-					     "dropped!! IndicateSeq: %d, "
-					     "NewSeq: %d\n",
+					     "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n",
 					    __func__, pTS->RxIndicateSeq,
 					    SeqNum);
 				list_add_tail(&pReorderEntry->List,
@@ -652,8 +642,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
 				}
 			} else {
 				RTLLIB_DEBUG(RTLLIB_DL_REORDER,
-					 "Pkt insert into struct buffer!! "
-					 "IndicateSeq: %d, NewSeq: %d\n",
+					 "Pkt insert into struct buffer!! IndicateSeq: %d, NewSeq: %d\n",
 					 pTS->RxIndicateSeq, SeqNum);
 			}
 		} else {
@@ -663,9 +652,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
 			 * indicate all the packets in struct buffer and get
 			 * reorder entries.
 			 */
-			RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():"
-				     " There is no reorder entry!! Packet is "
-				     "dropped!!\n");
+			RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n");
 			{
 				int i;
 
@@ -687,8 +674,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
 				SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) {
 			/* This protect struct buffer from overflow. */
 			if (index >= REORDER_WIN_SIZE) {
-				RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicate"
-					     "Packet(): Buffer overflow!!\n");
+				RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!!\n");
 				bPktInBuf = true;
 				break;
 			}
@@ -699,8 +685,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
 				pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
 
 			ieee->prxbIndicateArray[index] = pReorderEntry->prxb;
-			RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate SeqNum"
-				     " %d!\n", __func__, pReorderEntry->SeqNum);
+			RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate SeqNum %d!\n", __func__, pReorderEntry->SeqNum);
 			index++;
 
 			list_add_tail(&pReorderEntry->List,
@@ -719,8 +704,7 @@ static void RxReorderIndicatePacket(struct rtllib_device *ieee,
 		pTS->RxTimeoutIndicateSeq = 0xffff;
 
 		if (index > REORDER_WIN_SIZE) {
-			RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():"
-				     " Rx Reorder struct buffer full!!\n");
+			RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket(): Rx Reorder struct buffer full!!\n");
 			spin_unlock_irqrestore(&(ieee->reorder_spinlock),
 					       flags);
 			return;
@@ -809,14 +793,11 @@ static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb,
 					   (nSubframe_Length << 8);
 
 			if (skb->len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
-				printk(KERN_INFO "%s: A-MSDU parse error!! "
-				       "pRfd->nTotalSubframe : %d\n",\
+				printk(KERN_INFO "%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
 				       __func__, rxb->nr_subframes);
-				printk(KERN_INFO "%s: A-MSDU parse error!! "
-				       "Subframe Length: %d\n", __func__,
+				printk(KERN_INFO "%s: A-MSDU parse error!! Subframe Length: %d\n", __func__,
 				       nSubframe_Length);
-				printk(KERN_INFO "nRemain_Length is %d and "
-				       "nSubframe_Length is : %d\n", skb->len,
+				printk(KERN_INFO "nRemain_Length is %d and nSubframe_Length is : %d\n", skb->len,
 				       nSubframe_Length);
 				printk(KERN_INFO "The Packet SeqNum is %d\n", SeqNum);
 				return 0;
@@ -844,8 +825,7 @@ static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb,
 			sub_skb->dev = ieee->dev;
 			rxb->subframes[rxb->nr_subframes++] = sub_skb;
 			if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
-				RTLLIB_DEBUG_RX("ParseSubframe(): Too many "
-						"Subframes! Packets dropped!\n");
+				RTLLIB_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n");
 				break;
 			}
 			skb_pull(skb, nSubframe_Length);
@@ -922,8 +902,7 @@ static int rtllib_rx_check_duplicate(struct rtllib_device *ieee,
 			pRxTS->RxLastFragNum = frag;
 			pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
 		} else {
-			RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!%s(): No TS!! Skip"
-				     " the check!!\n", __func__);
+			RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!%s(): No TS!! Skip the check!!\n", __func__);
 			return -1;
 		}
 	}
@@ -996,9 +975,7 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc,
 		    stype != RTLLIB_STYPE_QOS_DATA) {
 			if (stype != RTLLIB_STYPE_NULLFUNC)
 				RTLLIB_DEBUG_DROP(
-					"RX: dropped data frame "
-					"with no data (type=0x%02x, "
-					"subtype=0x%02x)\n",
+					"RX: dropped data frame with no data (type=0x%02x, subtype=0x%02x)\n",
 					type, stype);
 			return -1;
 		}
@@ -1041,8 +1018,7 @@ static int rtllib_rx_get_crypt(struct rtllib_device *ieee, struct sk_buff *skb,
 			 * frames from other than current BSS, so just drop the
 			 * frames silently instead of filling system log with
 			 * these reports. */
-			RTLLIB_DEBUG_DROP("Decryption failed (not set)"
-					     " (SA= %pM)\n",
+			RTLLIB_DEBUG_DROP("Decryption failed (not set) (SA= %pM)\n",
 					     hdr->addr2);
 			ieee->ieee_stats.rx_discards_undecryptable++;
 			return -1;
@@ -1086,8 +1062,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
 
 		if (!frag_skb) {
 			RTLLIB_DEBUG(RTLLIB_DL_RX | RTLLIB_DL_FRAG,
-					"Rx cannot get skb from fragment "
-					"cache (morefrag=%d seq=%u frag=%u)\n",
+					"Rx cannot get skb from fragment cache (morefrag=%d seq=%u frag=%u)\n",
 					(fc & RTLLIB_FCTL_MOREFRAGS) != 0,
 					WLAN_GET_SEQ_SEQ(sc), frag);
 			return -1;
@@ -1097,8 +1072,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
 			flen -= hdrlen;
 
 		if (frag_skb->tail + flen > frag_skb->end) {
-			printk(KERN_WARNING "%s: host decrypted and "
-			       "reassembled frame did not fit skb\n",
+			printk(KERN_WARNING "%s: host decrypted and reassembled frame did not fit skb\n",
 			       __func__);
 			rtllib_frag_cache_invalidate(ieee, hdr);
 			return -1;
@@ -1152,8 +1126,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
 						eap_get_type(eap->type));
 		} else {
 			RTLLIB_DEBUG_DROP(
-				"encryption configured, but RX "
-				"frame not encrypted (SA= %pM)\n",
+				"encryption configured, but RX frame not encrypted (SA= %pM)\n",
 				hdr->addr2);
 			return -1;
 		}
@@ -1170,9 +1143,7 @@ static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb,
 	if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep &&
 	    !rtllib_is_eapol_frame(ieee, skb, hdrlen)) {
 		RTLLIB_DEBUG_DROP(
-			"dropped unencrypted RX data "
-			"frame from %pM"
-			" (drop_unencrypted=1)\n",
+			"dropped unencrypted RX data frame from %pM (drop_unencrypted=1)\n",
 			hdr->addr2);
 		return -1;
 	}
@@ -1762,9 +1733,7 @@ int rtllib_parse_info_param(struct rtllib_device *ieee,
 
 	while (length >= sizeof(*info_element)) {
 		if (sizeof(*info_element) + info_element->len > length) {
-			RTLLIB_DEBUG_MGMT("Info elem: parse failed: "
-					     "info_element->len + 2 > left : "
-					     "info_element->len+2=%zd left=%d, id=%d.\n",
+			RTLLIB_DEBUG_MGMT("Info elem: parse failed: info_element->len + 2 > left : info_element->len+2=%zd left=%d, id=%d.\n",
 					     info_element->len +
 					     sizeof(*info_element),
 					     length, info_element->id);
@@ -2207,34 +2176,6 @@ int rtllib_parse_info_param(struct rtllib_device *ieee,
 	return 0;
 }
 
-static inline u8 rtllib_SignalStrengthTranslate(u8  CurrSS)
-{
-	u8 RetSS;
-
-	if (CurrSS >= 71 && CurrSS <= 100)
-		RetSS = 90 + ((CurrSS - 70) / 3);
-	else if (CurrSS >= 41 && CurrSS <= 70)
-		RetSS = 78 + ((CurrSS - 40) / 3);
-	else if (CurrSS >= 31 && CurrSS <= 40)
-		RetSS = 66 + (CurrSS - 30);
-	else if (CurrSS >= 21 && CurrSS <= 30)
-		RetSS = 54 + (CurrSS - 20);
-	else if (CurrSS >= 5 && CurrSS <= 20)
-		RetSS = 42 + (((CurrSS - 5) * 2) / 3);
-	else if (CurrSS == 4)
-		RetSS = 36;
-	else if (CurrSS == 3)
-		RetSS = 27;
-	else if (CurrSS == 2)
-		RetSS = 18;
-	else if (CurrSS == 1)
-		RetSS = 9;
-	else
-		RetSS = CurrSS;
-
-	return RetSS;
-}
-
 static long rtllib_translate_todbm(u8 signal_strength_index)
 {
 	long	signal_power;
@@ -2321,8 +2262,7 @@ static inline int rtllib_network_init(
 	}
 
 	if (network->mode == 0) {
-		RTLLIB_DEBUG_SCAN("Filtered out '%s (%pM)' "
-				     "network.\n",
+		RTLLIB_DEBUG_SCAN("Filtered out '%s (%pM)' network.\n",
 				     escape_essid(network->ssid,
 						  network->ssid_len),
 				     network->bssid);
@@ -2363,13 +2303,6 @@ static inline int is_same_network(struct rtllib_network *src,
 		(dst->capability & WLAN_CAPABILITY_ESS)));
 }
 
-static inline void update_ibss_network(struct rtllib_network *dst,
-				  struct rtllib_network *src)
-{
-	memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats));
-	dst->last_scanned = jiffies;
-}
-
 
 static inline void update_network(struct rtllib_network *dst,
 				  struct rtllib_network *src)
@@ -2568,8 +2501,7 @@ static inline void rtllib_process_probe_response(
 	if (WLAN_FC_GET_STYPE(le16_to_cpu(beacon->header.frame_ctl)) ==
 	    RTLLIB_STYPE_PROBE_RESP) {
 		if (IsPassiveChannel(ieee, network->channel)) {
-			printk(KERN_INFO "GetScanInfo(): For Global Domain, "
-			       "filter probe response at channel(%d).\n",
+			printk(KERN_INFO "GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n",
 			       network->channel);
 			goto free_network;
 		}
@@ -2618,8 +2550,7 @@ static inline void rtllib_process_probe_response(
 			/* If there are no more slots, expire the oldest */
 			list_del(&oldest->list);
 			target = oldest;
-			RTLLIB_DEBUG_SCAN("Expired '%s' ( %pM) from "
-					     "network list.\n",
+			RTLLIB_DEBUG_SCAN("Expired '%s' ( %pM) from network list.\n",
 					     escape_essid(target->ssid,
 							  target->ssid_len),
 					     target->bssid);
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
index cd196cec0dd9..1b4623c3f95e 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
@@ -4,6 +4,8 @@
  * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
  * WB 2008-05-27
  * *****************************************************************************************************************************/
+#include <asm/byteorder.h>
+#include <asm/unaligned.h>
 #include "ieee80211.h"
 #include "rtl819x_BA.h"
 
@@ -110,13 +112,12 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P
 	struct sk_buff *skb = NULL;
 	 struct ieee80211_hdr_3addr *BAReq = NULL;
 	u8 *tag = NULL;
-	__le16 tmp = 0;
 	u16 len = ieee->tx_headroom + 9;
 	//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
 	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __func__, type, Dst, ieee->dev);
-	if (pBA == NULL||ieee == NULL)
+	if (pBA == NULL)
 	{
-		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA is NULL\n");
 		return NULL;
 	}
 	skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
@@ -149,17 +150,17 @@ static struct sk_buff *ieee80211_ADDBA(struct ieee80211_device *ieee, u8 *Dst, P
 	{
 		// Status Code
 		printk("=====>to send ADDBARSP\n");
-		tmp = cpu_to_le16(StatusCode);
-		memcpy(tag, (u8 *)&tmp, 2);
+
+		put_unaligned_le16(StatusCode, tag);
 		tag += 2;
 	}
 	// BA Parameter Set
-	tmp = cpu_to_le16(pBA->BaParamSet.shortData);
-	memcpy(tag, (u8 *)&tmp, 2);
+
+	put_unaligned_le16(pBA->BaParamSet.shortData, tag);
 	tag += 2;
 	// BA Timeout Value
-	tmp = cpu_to_le16(pBA->BaTimeoutValue);
-	memcpy(tag, (u8 *)&tmp, 2);
+
+	put_unaligned_le16(pBA->BaTimeoutValue, tag);
 	tag += 2;
 
 	if (ACT_ADDBAREQ == type)
@@ -196,7 +197,6 @@ static struct sk_buff *ieee80211_DELBA(
 	struct sk_buff *skb = NULL;
 	 struct ieee80211_hdr_3addr *Delba = NULL;
 	u8 *tag = NULL;
-	__le16 tmp = 0;
 	//len = head len + DELBA Parameter Set(2) + Reason Code(2)
 	u16 len = 6 + ieee->tx_headroom;
 
@@ -230,12 +230,12 @@ static struct sk_buff *ieee80211_DELBA(
 	*tag ++= ACT_DELBA;
 
 	// DELBA Parameter Set
-	tmp = cpu_to_le16(DelbaParamSet.shortData);
-	memcpy(tag, (u8 *)&tmp, 2);
+
+	put_unaligned_le16(DelbaParamSet.shortData, tag);
 	tag += 2;
 	// Reason Code
-	tmp = cpu_to_le16(ReasonCode);
-	memcpy(tag, (u8 *)&tmp, 2);
+
+	put_unaligned_le16(ReasonCode, tag);
 	tag += 2;
 
 	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
diff --git a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
index c4514109d0ee..acaa723817e7 100644
--- a/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192u/ieee80211/rtl819x_TSProc.c
@@ -241,7 +241,7 @@ static PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee,
 {
 	//DIRECTION_VALUE	dir;
 	u8	dir;
-	bool				search_dir[4] = {0, 0, 0, 0};
+	bool				search_dir[4] = {0};
 	struct list_head		*psearch_list; //FIXME
 	PTS_COMMON_INFO	pRet = NULL;
 	if(ieee->iw_mode == IW_MODE_MASTER) //ap mode
diff --git a/drivers/staging/rtl8192u/r8190_rtl8256.c b/drivers/staging/rtl8192u/r8190_rtl8256.c
index 45514aa97698..1868352d3789 100644
--- a/drivers/staging/rtl8192u/r8190_rtl8256.c
+++ b/drivers/staging/rtl8192u/r8190_rtl8256.c
@@ -23,7 +23,7 @@
  * Return:      NONE
  * Note:	8226 support both 20M  and 40 MHz
  *---------------------------------------------------------------------------*/
-void PHY_SetRF8256Bandwidth(struct net_device *dev , HT_CHANNEL_WIDTH Bandwidth)
+void PHY_SetRF8256Bandwidth(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth)
 {
 	u8	eRFPath;
 	struct r8192_priv *priv = ieee80211_priv(dev);
diff --git a/drivers/staging/rtl8192u/r8192U_dm.c b/drivers/staging/rtl8192u/r8192U_dm.c
index 936565d46014..ee6b936efef2 100644
--- a/drivers/staging/rtl8192u/r8192U_dm.c
+++ b/drivers/staging/rtl8192u/r8192U_dm.c
@@ -21,14 +21,13 @@ Major Change History:
 #include "r8190_rtl8256.h"
 #include "r819xU_cmdpkt.h"
 /*---------------------------Define Local Constant---------------------------*/
-//
-// Indicate different AP vendor for IOT issue.
-//
-static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
-		{ 0x5e4322,	0x5e4322,	0x5e4322,	0x604322,	0xa44f,		0x5ea44f};
-static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
-		{ 0x5e4322,	0xa44f,		0x5e4322,	0x604322,	0x5ea44f,	0x5ea44f};
-
+/* Indicate different AP vendor for IOT issue. */
+static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
+	0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0x00a44f, 0x5ea44f
+};
+static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
+	0x5e4322, 0x00a44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f
+};
 
 #define RTK_UL_EDCA 0xa44f
 #define RTK_DL_EDCA 0x5e4322
@@ -36,11 +35,11 @@ static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
 
 
 /*------------------------Define global variable-----------------------------*/
-// Debug variable ?
+/* Debug variable ? */
 dig_t	dm_digtable;
-// Store current software write register content for MAC PHY.
-u8		dm_shadow[16][256] = {{0}};
-// For Dynamic Rx Path Selection by Signal Strength
+/* Store current software write register content for MAC PHY. */
+u8		dm_shadow[16][256] = { {0} };
+/* For Dynamic Rx Path Selection by Signal Strength */
 DRxPathSel	DM_RxPathSelTable;
 /*------------------------Define global variable-----------------------------*/
 
@@ -56,24 +55,21 @@ extern	void dm_check_fsync(struct net_device *dev);
 
 
 /*---------------------Define local function prototype-----------------------*/
-// DM --> Rate Adaptive
+/* DM --> Rate Adaptive */
 static	void	dm_check_rate_adaptive(struct net_device *dev);
 
-// DM --> Bandwidth switch
+/* DM --> Bandwidth switch */
 static	void	dm_init_bandwidth_autoswitch(struct net_device *dev);
 static	void	dm_bandwidth_autoswitch(struct net_device *dev);
 
-// DM --> TX power control
-//static	void	dm_initialize_txpower_tracking(struct net_device *dev);
+/* DM --> TX power control */
+/*static	void	dm_initialize_txpower_tracking(struct net_device *dev);*/
 
 static	void	dm_check_txpower_tracking(struct net_device *dev);
 
+/*static	void	dm_txpower_reset_recovery(struct net_device *dev);*/
 
-
-//static	void	dm_txpower_reset_recovery(struct net_device *dev);
-
-
-// DM --> Dynamic Init Gain by RSSI
+/* DM --> Dynamic Init Gain by RSSI */
 static	void	dm_dig_init(struct net_device *dev);
 static	void	dm_ctrl_initgain_byrssi(struct net_device *dev);
 static	void	dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
@@ -84,61 +80,58 @@ static	void	dm_pd_th(struct net_device *dev);
 static	void	dm_cs_ratio(struct net_device *dev);
 
 static	void dm_init_ctstoself(struct net_device *dev);
-// DM --> EDCA turbo mode control
+/* DM --> EDCA turbo mode control */
 static	void	dm_check_edca_turbo(struct net_device *dev);
 
-//static	void	dm_gpio_change_rf(struct net_device *dev);
-// DM --> Check PBC
+/*static	void	dm_gpio_change_rf(struct net_device *dev);*/
+/* DM --> Check PBC */
 static	void dm_check_pbc_gpio(struct net_device *dev);
 
-
-// DM --> Check current RX RF path state
+/* DM --> Check current RX RF path state */
 static	void	dm_check_rx_path_selection(struct net_device *dev);
 static	void dm_init_rxpath_selection(struct net_device *dev);
 static	void dm_rxpath_sel_byrssi(struct net_device *dev);
 
-
-// DM --> Fsync for broadcom ap
+/* DM --> Fsync for broadcom ap */
 static void dm_init_fsync(struct net_device *dev);
 static void dm_deInit_fsync(struct net_device *dev);
 
-//Added by vivi, 20080522
+/* Added by vivi, 20080522 */
 static	void	dm_check_txrateandretrycount(struct net_device *dev);
 
 /*---------------------Define local function prototype-----------------------*/
 
-/*---------------------Define of Tx Power Control For Near/Far Range --------*/   //Add by Jacken 2008/02/18
+/*---------------------Define of Tx Power Control For Near/Far Range --------*/   /*Add by Jacken 2008/02/18 */
 static	void	dm_init_dynamic_txpower(struct net_device *dev);
 static	void	dm_dynamic_txpower(struct net_device *dev);
 
-
-// DM --> For rate adaptive and DIG, we must send RSSI to firmware
+/* DM --> For rate adaptive and DIG, we must send RSSI to firmware */
 static	void dm_send_rssi_tofw(struct net_device *dev);
 static	void	dm_ctstoself(struct net_device *dev);
 /*---------------------------Define function prototype------------------------*/
-//================================================================================
-//	HW Dynamic mechanism interface.
-//================================================================================
-
-//
-//	Description:
-//		Prepare SW resource for HW dynamic mechanism.
-//
-//	Assumption:
-//		This function is only invoked at driver intialization once.
-//
-//
+/*
+ * ================================================================================
+ *	HW Dynamic mechanism interface.
+ * ================================================================================
+ *
+ *
+ *	Description:
+ *		Prepare SW resource for HW dynamic mechanism.
+ *
+ *	Assumption:
+ *		This function is only invoked at driver intialization once.
+ */
 void init_hal_dm(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-	// Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism.
+	/* Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. */
 	priv->undecorated_smoothed_pwdb = -1;
 
-	//Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
+	/* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
 	dm_init_dynamic_txpower(dev);
 	init_rate_adaptive(dev);
-	//dm_initialize_txpower_tracking(dev);
+	/*dm_initialize_txpower_tracking(dev);*/
 	dm_dig_init(dev);
 	dm_init_edca_turbo(dev);
 	dm_init_bandwidth_autoswitch(dev);
@@ -146,18 +139,16 @@ void init_hal_dm(struct net_device *dev)
 	dm_init_rxpath_selection(dev);
 	dm_init_ctstoself(dev);
 
-}	// InitHalDm
+}	/* InitHalDm */
 
 void deinit_hal_dm(struct net_device *dev)
 {
-
 	dm_deInit_fsync(dev);
-
 }
 
-
 #ifdef USB_RX_AGGREGATION_SUPPORT
-void dm_CheckRxAggregation(struct net_device *dev) {
+void dm_CheckRxAggregation(struct net_device *dev)
+{
 	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
 	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
 	static unsigned long	lastTxOkCnt;
@@ -186,14 +177,15 @@ void dm_CheckRxAggregation(struct net_device *dev) {
 	if ((curTxOkCnt + curRxOkCnt) < 15000000)
 		return;
 
-	if(curTxOkCnt > 4*curRxOkCnt) {
+	if (curTxOkCnt > 4*curRxOkCnt) {
 		if (priv->bCurrentRxAggrEnable) {
 			write_nic_dword(dev, 0x1a8, 0);
 			priv->bCurrentRxAggrEnable = false;
 		}
-	}else{
+	} else {
 		if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
 			u32 ulValue;
+
 			ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
 				(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
 			/*
@@ -208,16 +200,14 @@ void dm_CheckRxAggregation(struct net_device *dev) {
 
 	lastTxOkCnt = priv->stats.txbytesunicast;
 	lastRxOkCnt = priv->stats.rxbytesunicast;
-}	// dm_CheckEdcaTurbo
+}	/* dm_CheckEdcaTurbo */
 #endif
 
-
-
 void hal_dm_watchdog(struct net_device *dev)
 {
-	//struct r8192_priv *priv = ieee80211_priv(dev);
+	/*struct r8192_priv *priv = ieee80211_priv(dev);*/
 
-	//static u8	previous_bssid[6] ={0};
+	/*static u8	previous_bssid[6] ={0};*/
 
 	/*Add by amy 2008/05/15 ,porting from windows code.*/
 	dm_check_rate_adaptive(dev);
@@ -230,25 +220,23 @@ void hal_dm_watchdog(struct net_device *dev)
 	dm_check_rx_path_selection(dev);
 	dm_check_fsync(dev);
 
-	// Add by amy 2008-05-15 porting from windows code.
+	/* Add by amy 2008-05-15 porting from windows code. */
 	dm_check_pbc_gpio(dev);
 	dm_send_rssi_tofw(dev);
 	dm_ctstoself(dev);
 #ifdef USB_RX_AGGREGATION_SUPPORT
 	dm_CheckRxAggregation(dev);
 #endif
-}	//HalDmWatchDog
-
+}	/* HalDmWatchDog */
 
 /*
-  * Decide Rate Adaptive Set according to distance (signal strength)
-  *	01/11/2008	MHC		Modify input arguments and RATR table level.
-  *	01/16/2008	MHC		RF_Type is assigned in ReadAdapterInfo(). We must call
-  *						the function after making sure RF_Type.
-  */
+ * Decide Rate Adaptive Set according to distance (signal strength)
+ *	01/11/2008	MHC		Modify input arguments and RATR table level.
+ *	01/16/2008	MHC		RF_Type is assigned in ReadAdapterInfo(). We must call
+ *						the function after making sure RF_Type.
+ */
 void init_rate_adaptive(struct net_device *dev)
 {
-
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	prate_adaptive	pra = (prate_adaptive)&priv->rate_adaptive;
 
@@ -261,36 +249,33 @@ void init_rate_adaptive(struct net_device *dev)
 	pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
 	pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
 
-	if(priv->CustomerID == RT_CID_819x_Netcore)
+	if (priv->CustomerID == RT_CID_819x_Netcore)
 		pra->ping_rssi_enable = 1;
 	else
 		pra->ping_rssi_enable = 0;
 	pra->ping_rssi_thresh_for_ra = 15;
 
-
-	if (priv->rf_type == RF_2T4R)
-	{
-		// 07/10/08 MH Modify for RA smooth scheme.
-		/* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/
+	if (priv->rf_type == RF_2T4R) {
+		/*
+		 * 07/10/08 MH Modify for RA smooth scheme.
+		 * 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.
+		 */
 		pra->upper_rssi_threshold_ratr		=	0x8f0f0000;
 		pra->middle_rssi_threshold_ratr		=	0x8f0ff000;
 		pra->low_rssi_threshold_ratr		=	0x8f0ff001;
 		pra->low_rssi_threshold_ratr_40M	=	0x8f0ff005;
 		pra->low_rssi_threshold_ratr_20M	=	0x8f0ff001;
-		pra->ping_rssi_ratr	=	0x0000000d;//cosa add for test
-	}
-	else if (priv->rf_type == RF_1T2R)
-	{
+		pra->ping_rssi_ratr	=	0x0000000d;/* cosa add for test */
+	} else if (priv->rf_type == RF_1T2R) {
 		pra->upper_rssi_threshold_ratr		=	0x000f0000;
 		pra->middle_rssi_threshold_ratr		=	0x000ff000;
 		pra->low_rssi_threshold_ratr		=	0x000ff001;
 		pra->low_rssi_threshold_ratr_40M	=	0x000ff005;
 		pra->low_rssi_threshold_ratr_20M	=	0x000ff001;
-		pra->ping_rssi_ratr	=	0x0000000d;//cosa add for test
+		pra->ping_rssi_ratr	=	0x0000000d;/* cosa add for test */
 	}
 
-}	// InitRateAdaptive
-
+}	/* InitRateAdaptive */
 
 /*-----------------------------------------------------------------------------
  * Function:	dm_check_rate_adaptive()
@@ -318,149 +303,122 @@ static void dm_check_rate_adaptive(struct net_device *dev)
 	bool						bshort_gi_enabled = false;
 	static u8					ping_rssi_state;
 
-
-	if(!priv->up)
-	{
+	if (!priv->up) {
 		RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
 		return;
 	}
 
-	if(pra->rate_adaptive_disabled)//this variable is set by ioctl.
+	if (pra->rate_adaptive_disabled) /* this variable is set by ioctl. */
 		return;
 
-	// TODO: Only 11n mode is implemented currently,
-	if(!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
-		 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
-		 return;
+	/* TODO: Only 11n mode is implemented currently, */
+	if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
+	      priv->ieee80211->mode == WIRELESS_MODE_N_5G))
+		return;
 
-	if(priv->ieee80211->state == IEEE80211_LINKED)
-	{
-	//	RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
+	if (priv->ieee80211->state == IEEE80211_LINKED) {
+		/*RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");*/
 
-		//
-		// Check whether Short GI is enabled
-		//
+		/* Check whether Short GI is enabled */
 		bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
 			(!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
 
-
 		pra->upper_rssi_threshold_ratr =
-				(pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+				(pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
 
 		pra->middle_rssi_threshold_ratr =
-				(pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+				(pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
 
-		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
-		{
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
 			pra->low_rssi_threshold_ratr =
-				(pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
-		}
-		else
-		{
+				(pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
+		} else {
 			pra->low_rssi_threshold_ratr =
-			(pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+			(pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
 		}
-		//cosa add for test
+		/* cosa add for test */
 		pra->ping_rssi_ratr =
-				(pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+				(pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31:0);
 
 		/* 2007/10/08 MH We support RA smooth scheme now. When it is the first
 		   time to link with AP. We will not change upper/lower threshold. If
 		   STA stay in high or low level, we must change two different threshold
 		   to prevent jumping frequently. */
-		if (pra->ratr_state == DM_RATR_STA_HIGH)
-		{
+		if (pra->ratr_state == DM_RATR_STA_HIGH) {
 			HighRSSIThreshForRA	= pra->high2low_rssi_thresh_for_ra;
-			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
+			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
 					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
-		}
-		else if (pra->ratr_state == DM_RATR_STA_LOW)
-		{
+		} else if (pra->ratr_state == DM_RATR_STA_LOW) {
 			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
-			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
+			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
 					(pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
-		}
-		else
-		{
+		} else {
 			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
-			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
+			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
 					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
 		}
 
-		//DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);
-		if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
-		{
-			//DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);
+		/*DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);*/
+		if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) {
+			/*DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);*/
 			pra->ratr_state = DM_RATR_STA_HIGH;
 			targetRATR = pra->upper_rssi_threshold_ratr;
-		}else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA)
-		{
-			//DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);
+		} else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) {
+			/*DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);*/
 			pra->ratr_state = DM_RATR_STA_MIDDLE;
 			targetRATR = pra->middle_rssi_threshold_ratr;
-		}else
-		{
-			//DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);
+		} else {
+			/*DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);*/
 			pra->ratr_state = DM_RATR_STA_LOW;
 			targetRATR = pra->low_rssi_threshold_ratr;
 		}
 
-			//cosa add for test
-		if(pra->ping_rssi_enable)
-		{
-			//pHalData->UndecoratedSmoothedPWDB = 19;
-			if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5))
-			{
-				if((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
-					ping_rssi_state)
-				{
-					//DbgPrint("TestRSSI = %d, set RATR to 0x%x \n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);
+		/* cosa add for test */
+		if (pra->ping_rssi_enable) {
+			/*pHalData->UndecoratedSmoothedPWDB = 19;*/
+			if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) {
+				if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
+					ping_rssi_state) {
+					/*DbgPrint("TestRSSI = %d, set RATR to 0x%x\n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);*/
 					pra->ratr_state = DM_RATR_STA_LOW;
 					targetRATR = pra->ping_rssi_ratr;
 					ping_rssi_state = 1;
 				}
-				//else
-				//	DbgPrint("TestRSSI is between the range. \n");
-			}
-			else
-			{
-				//DbgPrint("TestRSSI Recover to 0x%x \n", targetRATR);
+				/*else
+					DbgPrint("TestRSSI is between the range.\n");*/
+			} else {
+				/*DbgPrint("TestRSSI Recover to 0x%x\n", targetRATR);*/
 				ping_rssi_state = 0;
 			}
 		}
 
-		// 2008.04.01
-		// For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
-		if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
-			targetRATR &=  0xf00fffff;
+		/*
+		 * 2008.04.01
+		 * For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
+		 */
+		if (priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
+			targetRATR &= 0xf00fffff;
 
-		//
-		// Check whether updating of RATR0 is required
-		//
+		/* Check whether updating of RATR0 is required */
 		read_nic_dword(dev, RATR0, &currentRATR);
-		if(targetRATR !=  currentRATR)
-		{
+		if (targetRATR !=  currentRATR) {
 			u32 ratr_value;
+
 			ratr_value = targetRATR;
-			RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
-			if(priv->rf_type == RF_1T2R)
-			{
+			RT_TRACE(COMP_RATE, "currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
+			if (priv->rf_type == RF_1T2R)
 				ratr_value &= ~(RATE_ALL_OFDM_2SS);
-			}
 			write_nic_dword(dev, RATR0, ratr_value);
 			write_nic_byte(dev, UFWP, 1);
 
 			pra->last_ratr = targetRATR;
 		}
 
-	}
-	else
-	{
+	} else {
 		pra->ratr_state = DM_RATR_STA_MAX;
 	}
 
-}	// dm_CheckRateAdaptive
-
+}	/* dm_CheckRateAdaptive */
 
 static void dm_init_bandwidth_autoswitch(struct net_device *dev)
 {
@@ -471,78 +429,74 @@ static void dm_init_bandwidth_autoswitch(struct net_device *dev)
 	priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
 	priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
 
-}	// dm_init_bandwidth_autoswitch
-
+}	/* dm_init_bandwidth_autoswitch */
 
 static void dm_bandwidth_autoswitch(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-	if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){
+	if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 || !priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable)
 		return;
-	}else{
-		if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40
-			if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
-				priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
-		}else{//in force send packets in 20 Mhz in 20/40
-			if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
-				priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
-
-		}
+	if (priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false) { /* If send packets in 40 Mhz in 20/40 */
+		if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
+			priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
+	} else { /* in force send packets in 20 Mhz in 20/40 */
+		if (priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
+			priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
 	}
-}	// dm_BandwidthAutoSwitch
+}	/* dm_BandwidthAutoSwitch */
 
-//OFDM default at 0db, index=6.
+/* OFDM default at 0db, index=6. */
 static u32 OFDMSwingTable[OFDM_Table_Length] = {
-	0x7f8001fe,	// 0, +6db
-	0x71c001c7,	// 1, +5db
-	0x65400195,	// 2, +4db
-	0x5a400169,	// 3, +3db
-	0x50800142,	// 4, +2db
-	0x47c0011f,	// 5, +1db
-	0x40000100,	// 6, +0db ===> default, upper for higher temperature, lower for low temperature
-	0x390000e4,	// 7, -1db
-	0x32c000cb,	// 8, -2db
-	0x2d4000b5,	// 9, -3db
-	0x288000a2,	// 10, -4db
-	0x24000090,	// 11, -5db
-	0x20000080,	// 12, -6db
-	0x1c800072,	// 13, -7db
-	0x19800066,	// 14, -8db
-	0x26c0005b,	// 15, -9db
-	0x24400051,	// 16, -10db
-	0x12000048,	// 17, -11db
-	0x10000040	// 18, -12db
+	0x7f8001fe,	/* 0, +6db */
+	0x71c001c7,	/* 1, +5db */
+	0x65400195,	/* 2, +4db */
+	0x5a400169,	/* 3, +3db */
+	0x50800142,	/* 4, +2db */
+	0x47c0011f,	/* 5, +1db */
+	0x40000100,	/* 6, +0db ===> default, upper for higher temperature, lower for low temperature */
+	0x390000e4,	/* 7, -1db */
+	0x32c000cb,	/* 8, -2db */
+	0x2d4000b5,	/* 9, -3db */
+	0x288000a2,	/* 10, -4db */
+	0x24000090,	/* 11, -5db */
+	0x20000080,	/* 12, -6db */
+	0x1c800072,	/* 13, -7db */
+	0x19800066,	/* 14, -8db */
+	0x26c0005b,	/* 15, -9db */
+	0x24400051,	/* 16, -10db */
+	0x12000048,	/* 17, -11db */
+	0x10000040	/* 18, -12db */
 };
 
 static u8	CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
-	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},	// 0, +0db ===> CCK40M default
-	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},	// 1, -1db
-	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},	// 2, -2db
-	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},	// 3, -3db
-	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},	// 4, -4db
-	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},	// 5, -5db
-	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},	// 6, -6db ===> CCK20M default
-	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},	// 7, -7db
-	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},	// 8, -8db
-	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},	// 9, -9db
-	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},	// 10, -10db
-	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}	// 11, -11db
+	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},	/* 0, +0db ===> CCK40M default */
+	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},	/* 1, -1db */
+	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},	/* 2, -2db */
+	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},	/* 3, -3db */
+	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},	/* 4, -4db */
+	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},	/* 5, -5db */
+	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},	/* 6, -6db ===> CCK20M default */
+	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},	/* 7, -7db */
+	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},	/* 8, -8db */
+	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},	/* 9, -9db */
+	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},	/* 10, -10db */
+	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}	/* 11, -11db */
 };
 
 static u8	CCKSwingTable_Ch14[CCK_Table_length][8] = {
-	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},	// 0, +0db  ===> CCK40M default
-	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},	// 1, -1db
-	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},	// 2, -2db
-	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},	// 3, -3db
-	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},	// 4, -4db
-	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},	// 5, -5db
-	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},	// 6, -6db  ===> CCK20M default
-	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},	// 7, -7db
-	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},	// 8, -8db
-	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},	// 9, -9db
-	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},	// 10, -10db
-	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}	// 11, -11db
+	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},	/* 0, +0db  ===> CCK40M default */
+	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},	/* 1, -1db */
+	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},	/* 2, -2db */
+	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},	/* 3, -3db */
+	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},	/* 4, -4db */
+	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},	/* 5, -5db */
+	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},	/* 6, -6db  ===> CCK20M default */
+	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},	/* 7, -7db */
+	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},	/* 8, -8db */
+	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},	/* 9, -9db */
+	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},	/* 10, -10db */
+	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}	/* 11, -11db */
 };
 
 static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
@@ -551,14 +505,14 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
 	bool						bHighpowerstate, viviflag = FALSE;
 	DCMD_TXCMD_T			tx_cmd;
 	u8						powerlevelOFDM24G;
-	int						i =0, j = 0, k = 0;
-	u8						RF_Type, tmp_report[5]={0, 0, 0, 0, 0};
+	int						i = 0, j = 0, k = 0;
+	u8						RF_Type, tmp_report[5] = {0, 0, 0, 0, 0};
 	u32						Value;
 	u8						Pwr_Flag;
-	u16						Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0;
-	//RT_STATUS				rtStatus = RT_STATUS_SUCCESS;
+	u16						Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0;
+	/*RT_STATUS				rtStatus = RT_STATUS_SUCCESS;*/
 	bool rtStatus = true;
-	u32						delta=0;
+	u32						delta = 0;
 
 	write_nic_byte(dev, 0x1ba, 0);
 
@@ -571,109 +525,87 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
 
 	RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
 
-	for(j = 0; j<=30; j++)
-{	//fill tx_cmd
-
-	tx_cmd.Op		= TXCMD_SET_TX_PWR_TRACKING;
-	tx_cmd.Length	= 4;
-	tx_cmd.Value		= Value;
-	rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
-	if (rtStatus == RT_STATUS_FAILURE)
-	{
-		RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
-	}
-	mdelay(1);
-	//DbgPrint("hi, vivi, strange\n");
-	for(i = 0;i <= 30; i++)
-	{
-		read_nic_byte(dev, 0x1ba, &Pwr_Flag);
-
-		if (Pwr_Flag == 0)
-		{
-			mdelay(1);
-			continue;
-		}
-		read_nic_word(dev, 0x13c, &Avg_TSSI_Meas);
-		if(Avg_TSSI_Meas == 0)
-		{
-			write_nic_byte(dev, 0x1ba, 0);
-			break;
-		}
+	for (j = 0; j <= 30; j++) { /* fill tx_cmd */
+		tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING;
+		tx_cmd.Length = 4;
+		tx_cmd.Value = Value;
+		rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
+		if (rtStatus == RT_STATUS_FAILURE)
+			RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
+		mdelay(1);
+		/*DbgPrint("hi, vivi, strange\n");*/
+		for (i = 0; i <= 30; i++) {
+			read_nic_byte(dev, 0x1ba, &Pwr_Flag);
+
+			if (Pwr_Flag == 0) {
+				mdelay(1);
+				continue;
+			}
+			read_nic_word(dev, 0x13c, &Avg_TSSI_Meas);
+			if (Avg_TSSI_Meas == 0) {
+				write_nic_byte(dev, 0x1ba, 0);
+				break;
+			}
 
-		for(k = 0;k < 5; k++)
-		{
-			if(k !=4)
-				read_nic_byte(dev, 0x134+k, &tmp_report[k]);
-			else
-				read_nic_byte(dev, 0x13e, &tmp_report[k]);
-			RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
-		}
+			for (k = 0; k < 5; k++) {
+				if (k != 4)
+					read_nic_byte(dev, 0x134+k, &tmp_report[k]);
+				else
+					read_nic_byte(dev, 0x13e, &tmp_report[k]);
+				RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
+			}
 
-		//check if the report value is right
-		for(k = 0;k < 5; k++)
-		{
-			if(tmp_report[k] <= 20)
-			{
-				viviflag =TRUE;
+			/* check if the report value is right */
+			for (k = 0; k < 5; k++) {
+				if (tmp_report[k] <= 20) {
+					viviflag = TRUE;
+					break;
+				}
+			}
+			if (viviflag == TRUE) {
+				write_nic_byte(dev, 0x1ba, 0);
+				viviflag = FALSE;
+				RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n");
+				for (k = 0; k < 5; k++)
+					tmp_report[k] = 0;
 				break;
 			}
-		}
-		if(viviflag ==TRUE)
-		{
-			write_nic_byte(dev, 0x1ba, 0);
-			viviflag = FALSE;
-			RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n");
-			for(k = 0;k < 5; k++)
-				tmp_report[k] = 0;
-			break;
-		}
 
-		for(k = 0;k < 5; k++)
-		{
-			Avg_TSSI_Meas_from_driver += tmp_report[k];
-		}
-
-		Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
-		RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
-		TSSI_13dBm = priv->TSSI_13dBm;
-		RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
+			for (k = 0; k < 5; k++)
+				Avg_TSSI_Meas_from_driver += tmp_report[k];
 
-		//if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)
-		// For MacOS-compatible
-		if(Avg_TSSI_Meas_from_driver > TSSI_13dBm)
-			delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
-		else
-			delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
+			Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
+			RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
+			TSSI_13dBm = priv->TSSI_13dBm;
+			RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
 
-		if(delta <= E_FOR_TX_POWER_TRACK)
-		{
-			priv->ieee80211->bdynamic_txpower_enable = TRUE;
-			write_nic_byte(dev, 0x1ba, 0);
-			RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
-			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
-			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
-			RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
-			RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
-			return;
-		}
-		else
-		{
-			if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
-			{
-				if (priv->rfa_txpowertrackingindex > 0)
-				{
+			/*if (abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)*/
+			/* For MacOS-compatible */
+			if (Avg_TSSI_Meas_from_driver > TSSI_13dBm)
+				delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
+			else
+				delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
+
+			if (delta <= E_FOR_TX_POWER_TRACK) {
+				priv->ieee80211->bdynamic_txpower_enable = TRUE;
+				write_nic_byte(dev, 0x1ba, 0);
+				RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
+				RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
+				RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
+				RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
+				RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
+				return;
+			}
+			if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) {
+				if (priv->rfa_txpowertrackingindex > 0) {
 					priv->rfa_txpowertrackingindex--;
-					if(priv->rfa_txpowertrackingindex_real > 4)
-					{
+					if (priv->rfa_txpowertrackingindex_real > 4) {
 						priv->rfa_txpowertrackingindex_real--;
 						rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
 					}
 				}
-			}
-			else
-			{
-				if (priv->rfa_txpowertrackingindex < 36)
-				{
+			} else {
+				if (priv->rfa_txpowertrackingindex < 36) {
 					priv->rfa_txpowertrackingindex++;
 					priv->rfa_txpowertrackingindex_real++;
 					rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
@@ -683,52 +615,44 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
 			priv->cck_present_attentuation_difference
 				= priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
 
-			if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
+			if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
 				priv->cck_present_attentuation
-				= priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
+					= priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
 			else
 				priv->cck_present_attentuation
-				= priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
+					= priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
 
-			if(priv->cck_present_attentuation > -1&&priv->cck_present_attentuation <23)
-			{
-				if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
-				{
+			if (priv->cck_present_attentuation > -1 && priv->cck_present_attentuation < 23) {
+				if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
 					priv->bcck_in_ch14 = TRUE;
-					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
-				}
-				else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
-				{
+					dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
+				} else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
 					priv->bcck_in_ch14 = FALSE;
-					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
-				}
-				else
-					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+					dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
+				} else
+					dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
 			}
-		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
-		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
-		RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
-		RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
-
-		if (priv->cck_present_attentuation_difference <= -12||priv->cck_present_attentuation_difference >= 24)
-		{
-			priv->ieee80211->bdynamic_txpower_enable = TRUE;
-			write_nic_byte(dev, 0x1ba, 0);
-			RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
-			return;
-		}
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
 
+			if (priv->cck_present_attentuation_difference <= -12 || priv->cck_present_attentuation_difference >= 24) {
+				priv->ieee80211->bdynamic_txpower_enable = TRUE;
+				write_nic_byte(dev, 0x1ba, 0);
+				RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
+				return;
+			}
 
+			write_nic_byte(dev, 0x1ba, 0);
+			Avg_TSSI_Meas_from_driver = 0;
+			for (k = 0; k < 5; k++)
+				tmp_report[k] = 0;
+			break;
+		}
 	}
-		write_nic_byte(dev, 0x1ba, 0);
-		Avg_TSSI_Meas_from_driver = 0;
-		for(k = 0;k < 5; k++)
-			tmp_report[k] = 0;
-		break;
-	}
-}
-		priv->ieee80211->bdynamic_txpower_enable = TRUE;
-		write_nic_byte(dev, 0x1ba, 0);
+	priv->ieee80211->bdynamic_txpower_enable = TRUE;
+	write_nic_byte(dev, 0x1ba, 0);
 }
 
 static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
@@ -737,107 +661,96 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u32 tmpRegA, TempCCk;
 	u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
-	int i =0, CCKSwingNeedUpdate=0;
-
-	if(!priv->btxpower_trackingInit)
-	{
-		//Query OFDM default setting
-		tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
-		for(i=0; i<OFDM_Table_Length; i++)	//find the index
-		{
-			if(tmpRegA == OFDMSwingTable[i])
-			{
-				priv->OFDM_index= (u8)i;
+	int i = 0, CCKSwingNeedUpdate = 0;
+
+	if (!priv->btxpower_trackingInit) {
+		/* Query OFDM default setting */
+		tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
+		for (i = 0; i < OFDM_Table_Length; i++) { /* find the index */
+			if (tmpRegA == OFDMSwingTable[i]) {
+				priv->OFDM_index = (u8)i;
 				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
 					rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
 			}
 		}
 
-		//Query CCK default setting From 0xa22
+		/* Query CCK default setting From 0xa22 */
 		TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
-		for(i=0 ; i<CCK_Table_length ; i++)
-		{
-			if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0])
-			{
-				priv->CCK_index =(u8) i;
+		for (i = 0; i < CCK_Table_length; i++) {
+			if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
+				priv->CCK_index = (u8) i;
 				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
 					rCCK0_TxFilter1, TempCCk, priv->CCK_index);
 				break;
 			}
 		}
 		priv->btxpower_trackingInit = TRUE;
-		//pHalData->TXPowercount = 0;
+		/*pHalData->TXPowercount = 0;*/
 		return;
 	}
 
-	//==========================
-	// this is only for test, should be masked
-	//==========================
-
-	// read and filter out unreasonable value
-	tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);	// 0x12: RF Reg[10:7]
-	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
-	if(tmpRegA < 3 || tmpRegA > 13)
+	/*
+	 * ==========================
+	 * this is only for test, should be masked
+	 * ==========================
+	 */
+
+	/* read and filter out unreasonable value */
+	tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);	/* 0x12: RF Reg[10:7] */
+	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
+	if (tmpRegA < 3 || tmpRegA > 13)
 		return;
-	if(tmpRegA >= 12)	// if over 12, TP will be bad when high temperature
+	if (tmpRegA >= 12)	/* if over 12, TP will be bad when high temperature */
 		tmpRegA = 12;
-	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA);
-	priv->ThermalMeter[0] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
-	priv->ThermalMeter[1] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
+	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
+	priv->ThermalMeter[0] = ThermalMeterVal;	/* We use fixed value by Bryant's suggestion */
+	priv->ThermalMeter[1] = ThermalMeterVal;	/* We use fixed value by Bryant's suggestion */
 
-	//Get current RF-A temperature index
-	if(priv->ThermalMeter[0] >= (u8)tmpRegA)	//lower temperature
-	{
+	/* Get current RF-A temperature index */
+	if (priv->ThermalMeter[0] >= (u8)tmpRegA) {	/* lower temperature */
 		tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
 		tmpCCK40Mindex = tmpCCK20Mindex - 6;
-		if(tmpOFDMindex >= OFDM_Table_Length)
+		if (tmpOFDMindex >= OFDM_Table_Length)
 			tmpOFDMindex = OFDM_Table_Length-1;
-		if(tmpCCK20Mindex >= CCK_Table_length)
+		if (tmpCCK20Mindex >= CCK_Table_length)
 			tmpCCK20Mindex = CCK_Table_length-1;
-		if(tmpCCK40Mindex >= CCK_Table_length)
+		if (tmpCCK40Mindex >= CCK_Table_length)
 			tmpCCK40Mindex = CCK_Table_length-1;
-	}
-	else
-	{
+	} else {
 		tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
-		if(tmpval >= 6)								// higher temperature
-			tmpOFDMindex = tmpCCK20Mindex = 0;		// max to +6dB
+
+		if (tmpval >= 6) /* higher temperature */
+			tmpOFDMindex = tmpCCK20Mindex = 0; /* max to +6dB */
 		else
 			tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
 		tmpCCK40Mindex = 0;
 	}
-	//DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
-		//((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
-		//tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);
-	if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)	//40M
+	/*DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
+		((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
+		tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);*/
+	if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)	/* 40M */
 		tmpCCKindex = tmpCCK40Mindex;
 	else
 		tmpCCKindex = tmpCCK20Mindex;
 
-	if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
-	{
+	if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
 		priv->bcck_in_ch14 = TRUE;
 		CCKSwingNeedUpdate = 1;
-	}
-	else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
-	{
+	} else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
 		priv->bcck_in_ch14 = FALSE;
 		CCKSwingNeedUpdate = 1;
 	}
 
-	if(priv->CCK_index != tmpCCKindex)
-	{
+	if (priv->CCK_index != tmpCCKindex) {
 		priv->CCK_index = tmpCCKindex;
 		CCKSwingNeedUpdate = 1;
 	}
 
-	if(CCKSwingNeedUpdate)
-	{
-		//DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);
+	if (CCKSwingNeedUpdate) {
+		/*DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);*/
 		dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
 	}
-	if(priv->OFDM_index != tmpOFDMindex)
-	{
+	if (priv->OFDM_index != tmpOFDMindex) {
 		priv->OFDM_index = tmpOFDMindex;
 		rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
 		RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
@@ -848,100 +761,100 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
 
 void dm_txpower_trackingcallback(struct work_struct *work)
 {
-	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
-       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
-       struct net_device *dev = priv->ieee80211->dev;
+	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+	struct r8192_priv *priv = container_of(dwork, struct r8192_priv, txpower_tracking_wq);
+	struct net_device *dev = priv->ieee80211->dev;
 
-	if(priv->bDcut == TRUE)
+	if (priv->bDcut == TRUE)
 		dm_TXPowerTrackingCallback_TSSI(dev);
 	else
 		dm_TXPowerTrackingCallback_ThermalMeter(dev);
 }
 
-
 static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
 {
-
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-	//Initial the Tx BB index and mapping value
+	/* Initial the Tx BB index and mapping value */
 	priv->txbbgain_table[0].txbb_iq_amplifygain =			12;
-	priv->txbbgain_table[0].txbbgain_value=0x7f8001fe;
+	priv->txbbgain_table[0].txbbgain_value = 0x7f8001fe;
 	priv->txbbgain_table[1].txbb_iq_amplifygain =			11;
-	priv->txbbgain_table[1].txbbgain_value=0x788001e2;
+	priv->txbbgain_table[1].txbbgain_value = 0x788001e2;
 	priv->txbbgain_table[2].txbb_iq_amplifygain =			10;
-	priv->txbbgain_table[2].txbbgain_value=0x71c001c7;
+	priv->txbbgain_table[2].txbbgain_value = 0x71c001c7;
 	priv->txbbgain_table[3].txbb_iq_amplifygain =			9;
-	priv->txbbgain_table[3].txbbgain_value=0x6b8001ae;
+	priv->txbbgain_table[3].txbbgain_value = 0x6b8001ae;
 	priv->txbbgain_table[4].txbb_iq_amplifygain =		       8;
-	priv->txbbgain_table[4].txbbgain_value=0x65400195;
+	priv->txbbgain_table[4].txbbgain_value = 0x65400195;
 	priv->txbbgain_table[5].txbb_iq_amplifygain =		       7;
-	priv->txbbgain_table[5].txbbgain_value=0x5fc0017f;
+	priv->txbbgain_table[5].txbbgain_value = 0x5fc0017f;
 	priv->txbbgain_table[6].txbb_iq_amplifygain =		       6;
-	priv->txbbgain_table[6].txbbgain_value=0x5a400169;
+	priv->txbbgain_table[6].txbbgain_value = 0x5a400169;
 	priv->txbbgain_table[7].txbb_iq_amplifygain =		       5;
-	priv->txbbgain_table[7].txbbgain_value=0x55400155;
+	priv->txbbgain_table[7].txbbgain_value = 0x55400155;
 	priv->txbbgain_table[8].txbb_iq_amplifygain =		       4;
-	priv->txbbgain_table[8].txbbgain_value=0x50800142;
+	priv->txbbgain_table[8].txbbgain_value = 0x50800142;
 	priv->txbbgain_table[9].txbb_iq_amplifygain =		       3;
-	priv->txbbgain_table[9].txbbgain_value=0x4c000130;
+	priv->txbbgain_table[9].txbbgain_value = 0x4c000130;
 	priv->txbbgain_table[10].txbb_iq_amplifygain =		       2;
-	priv->txbbgain_table[10].txbbgain_value=0x47c0011f;
+	priv->txbbgain_table[10].txbbgain_value = 0x47c0011f;
 	priv->txbbgain_table[11].txbb_iq_amplifygain =		       1;
-	priv->txbbgain_table[11].txbbgain_value=0x43c0010f;
+	priv->txbbgain_table[11].txbbgain_value = 0x43c0010f;
 	priv->txbbgain_table[12].txbb_iq_amplifygain =		       0;
-	priv->txbbgain_table[12].txbbgain_value=0x40000100;
+	priv->txbbgain_table[12].txbbgain_value = 0x40000100;
 	priv->txbbgain_table[13].txbb_iq_amplifygain =		       -1;
-	priv->txbbgain_table[13].txbbgain_value=0x3c8000f2;
+	priv->txbbgain_table[13].txbbgain_value = 0x3c8000f2;
 	priv->txbbgain_table[14].txbb_iq_amplifygain =		     -2;
-	priv->txbbgain_table[14].txbbgain_value=0x390000e4;
+	priv->txbbgain_table[14].txbbgain_value = 0x390000e4;
 	priv->txbbgain_table[15].txbb_iq_amplifygain =		     -3;
-	priv->txbbgain_table[15].txbbgain_value=0x35c000d7;
+	priv->txbbgain_table[15].txbbgain_value = 0x35c000d7;
 	priv->txbbgain_table[16].txbb_iq_amplifygain =		     -4;
-	priv->txbbgain_table[16].txbbgain_value=0x32c000cb;
+	priv->txbbgain_table[16].txbbgain_value = 0x32c000cb;
 	priv->txbbgain_table[17].txbb_iq_amplifygain =		     -5;
-	priv->txbbgain_table[17].txbbgain_value=0x300000c0;
+	priv->txbbgain_table[17].txbbgain_value = 0x300000c0;
 	priv->txbbgain_table[18].txbb_iq_amplifygain =			    -6;
-	priv->txbbgain_table[18].txbbgain_value=0x2d4000b5;
+	priv->txbbgain_table[18].txbbgain_value = 0x2d4000b5;
 	priv->txbbgain_table[19].txbb_iq_amplifygain =		     -7;
-	priv->txbbgain_table[19].txbbgain_value=0x2ac000ab;
+	priv->txbbgain_table[19].txbbgain_value = 0x2ac000ab;
 	priv->txbbgain_table[20].txbb_iq_amplifygain =		     -8;
-	priv->txbbgain_table[20].txbbgain_value=0x288000a2;
+	priv->txbbgain_table[20].txbbgain_value = 0x288000a2;
 	priv->txbbgain_table[21].txbb_iq_amplifygain =		     -9;
-	priv->txbbgain_table[21].txbbgain_value=0x26000098;
+	priv->txbbgain_table[21].txbbgain_value = 0x26000098;
 	priv->txbbgain_table[22].txbb_iq_amplifygain =		     -10;
-	priv->txbbgain_table[22].txbbgain_value=0x24000090;
+	priv->txbbgain_table[22].txbbgain_value = 0x24000090;
 	priv->txbbgain_table[23].txbb_iq_amplifygain =		     -11;
-	priv->txbbgain_table[23].txbbgain_value=0x22000088;
+	priv->txbbgain_table[23].txbbgain_value = 0x22000088;
 	priv->txbbgain_table[24].txbb_iq_amplifygain =		     -12;
-	priv->txbbgain_table[24].txbbgain_value=0x20000080;
+	priv->txbbgain_table[24].txbbgain_value = 0x20000080;
 	priv->txbbgain_table[25].txbb_iq_amplifygain =		     -13;
-	priv->txbbgain_table[25].txbbgain_value=0x1a00006c;
+	priv->txbbgain_table[25].txbbgain_value = 0x1a00006c;
 	priv->txbbgain_table[26].txbb_iq_amplifygain =		     -14;
-	priv->txbbgain_table[26].txbbgain_value=0x1c800072;
+	priv->txbbgain_table[26].txbbgain_value = 0x1c800072;
 	priv->txbbgain_table[27].txbb_iq_amplifygain =		     -15;
-	priv->txbbgain_table[27].txbbgain_value=0x18000060;
+	priv->txbbgain_table[27].txbbgain_value = 0x18000060;
 	priv->txbbgain_table[28].txbb_iq_amplifygain =		     -16;
-	priv->txbbgain_table[28].txbbgain_value=0x19800066;
+	priv->txbbgain_table[28].txbbgain_value = 0x19800066;
 	priv->txbbgain_table[29].txbb_iq_amplifygain =		     -17;
-	priv->txbbgain_table[29].txbbgain_value=0x15800056;
+	priv->txbbgain_table[29].txbbgain_value = 0x15800056;
 	priv->txbbgain_table[30].txbb_iq_amplifygain =		     -18;
-	priv->txbbgain_table[30].txbbgain_value=0x26c0005b;
+	priv->txbbgain_table[30].txbbgain_value = 0x26c0005b;
 	priv->txbbgain_table[31].txbb_iq_amplifygain =		     -19;
-	priv->txbbgain_table[31].txbbgain_value=0x14400051;
+	priv->txbbgain_table[31].txbbgain_value = 0x14400051;
 	priv->txbbgain_table[32].txbb_iq_amplifygain =		     -20;
-	priv->txbbgain_table[32].txbbgain_value=0x24400051;
+	priv->txbbgain_table[32].txbbgain_value = 0x24400051;
 	priv->txbbgain_table[33].txbb_iq_amplifygain =		     -21;
-	priv->txbbgain_table[33].txbbgain_value=0x1300004c;
+	priv->txbbgain_table[33].txbbgain_value = 0x1300004c;
 	priv->txbbgain_table[34].txbb_iq_amplifygain =		     -22;
-	priv->txbbgain_table[34].txbbgain_value=0x12000048;
+	priv->txbbgain_table[34].txbbgain_value = 0x12000048;
 	priv->txbbgain_table[35].txbb_iq_amplifygain =		     -23;
-	priv->txbbgain_table[35].txbbgain_value=0x11000044;
+	priv->txbbgain_table[35].txbbgain_value = 0x11000044;
 	priv->txbbgain_table[36].txbb_iq_amplifygain =		     -24;
-	priv->txbbgain_table[36].txbbgain_value=0x10000040;
+	priv->txbbgain_table[36].txbbgain_value = 0x10000040;
 
-	//ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
-	//This Table is for CH1~CH13
+	/*
+	 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
+	 * This Table is for CH1~CH13
+	 */
 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
 	priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
@@ -1149,8 +1062,10 @@ static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
 	priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
 
-	//ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
-	//This Table is for CH14
+	/*
+	 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
+	 * This Table is for CH14
+	 */
 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
 	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
@@ -1368,10 +1283,12 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-	// Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism
-	// can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
-	// 3-wire by driver causes RF to go into a wrong state.
-	if(priv->ieee80211->FwRWRF)
+	/*
+	 * Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism
+	 * can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
+	 * 3-wire by driver causes RF to go into a wrong state.
+	 */
+	if (priv->ieee80211->FwRWRF)
 		priv->btxpower_tracking = TRUE;
 	else
 		priv->btxpower_tracking = FALSE;
@@ -1379,57 +1296,46 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
 	priv->btxpower_trackingInit = FALSE;
 }
 
-
 void dm_initialize_txpower_tracking(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	if(priv->bDcut == TRUE)
+
+	if (priv->bDcut == TRUE)
 		dm_InitializeTXPowerTracking_TSSI(dev);
 	else
 		dm_InitializeTXPowerTracking_ThermalMeter(dev);
-}// dm_InitializeTXPowerTracking
-
+} /* dm_InitializeTXPowerTracking */
 
 static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	static u32 tx_power_track_counter;
 
-	if(!priv->btxpower_tracking)
+	if (!priv->btxpower_tracking)
 		return;
-	else
-	{
-		if((tx_power_track_counter % 30 == 0)&&(tx_power_track_counter != 0))
-		{
-				queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
-		}
-		tx_power_track_counter++;
-	}
-
+	if ((tx_power_track_counter % 30 == 0) && (tx_power_track_counter != 0))
+		queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
+	tx_power_track_counter++;
 }
 
-
 static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	static u8	TM_Trigger;
-	//DbgPrint("dm_CheckTXPowerTracking() \n");
-	if(!priv->btxpower_tracking)
+	/*DbgPrint("dm_CheckTXPowerTracking()\n");*/
+	if (!priv->btxpower_tracking)
+		return;
+	if (priv->txpower_count  <= 2) {
+		priv->txpower_count++;
 		return;
-	else
-	{
-		if(priv->txpower_count  <= 2)
-		{
-			priv->txpower_count++;
-			return;
-		}
 	}
 
-	if(!TM_Trigger)
-	{
-		//Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash
-		//actually write reg0x02 bit1=0, then bit1=1.
-		//DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
+	if (!TM_Trigger) {
+		/*
+		 * Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash
+		 * actually write reg0x02 bit1=0, then bit1=1.
+		 * DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
+		 */
 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
@@ -1437,93 +1343,84 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
 		TM_Trigger = 1;
 		return;
 	}
-	else
-	{
-		//DbgPrint("Schedule TxPowerTrackingWorkItem\n");
-			queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
-		TM_Trigger = 0;
-	}
+	/*DbgPrint("Schedule TxPowerTrackingWorkItem\n");*/
+		queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
+	TM_Trigger = 0;
 }
 
-
 static void dm_check_txpower_tracking(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	//static u32 tx_power_track_counter = 0;
+	/*static u32 tx_power_track_counter = 0;*/
 
-#ifdef  RTL8190P
+#ifdef RTL8190P
 	dm_CheckTXPowerTracking_TSSI(dev);
 #else
-	if(priv->bDcut == TRUE)
+	if (priv->bDcut == TRUE)
 		dm_CheckTXPowerTracking_TSSI(dev);
 	else
 		dm_CheckTXPowerTracking_ThermalMeter(dev);
 #endif
 
-}	// dm_CheckTXPowerTracking
-
+}	/* dm_CheckTXPowerTracking */
 
 static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool  bInCH14)
 {
 	u32 TempVal;
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	//Write 0xa22 0xa23
+
+	/* Write 0xa22 0xa23 */
 	TempVal = 0;
-	if(!bInCH14){
-		//Write 0xa22 0xa23
+	if (!bInCH14) {
+		/* Write 0xa22 0xa23 */
 		TempVal =	priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
-					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ;
+					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8);
 
 		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
-		//Write 0xa24 ~ 0xa27
+		/* Write 0xa24 ~ 0xa27 */
 		TempVal =	priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
 					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
 					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+
 					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
 		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
-		//Write 0xa28  0xa29
+		/* Write 0xa28  0xa29 */
 		TempVal =	priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
-					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ;
+					(priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8);
 
 		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
-	}
-	else
-	{
+	} else {
 		TempVal =	priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
-					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ;
+					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8);
 
 		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
-		//Write 0xa24 ~ 0xa27
+		/* Write 0xa24 ~ 0xa27 */
 		TempVal =	priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
 					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
 					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+
 					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
 		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
-		//Write 0xa28  0xa29
+		/* Write 0xa28  0xa29 */
 		TempVal =	priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
-					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ;
+					(priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8);
 
 		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
 	}
-
-
 }
 
-static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,	bool  bInCH14)
+static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool  bInCH14)
 {
 	u32 TempVal;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
 	TempVal = 0;
-	if(!bInCH14)
-	{
-		//Write 0xa22 0xa23
+	if (!bInCH14) {
+		/* Write 0xa22 0xa23 */
 		TempVal =	CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
-					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8);
 		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
 		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
 			rCCK0_TxFilter1, TempVal);
-		//Write 0xa24 ~ 0xa27
+		/* Write 0xa24 ~ 0xa27 */
 		TempVal =	CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
 					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
 					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+
@@ -1531,25 +1428,23 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,	bool  bInCH
 		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
 		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
 			rCCK0_TxFilter2, TempVal);
-		//Write 0xa28  0xa29
+		/* Write 0xa28  0xa29 */
 		TempVal =	CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
-					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8);
 
 		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
 		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
 			rCCK0_DebugPort, TempVal);
-	}
-	else
-	{
-//		priv->CCKTxPowerAdjustCntNotCh14++;	//cosa add for debug.
-		//Write 0xa22 0xa23
+	} else {
+		/*priv->CCKTxPowerAdjustCntNotCh14++;	cosa add for debug.*/
+		/* Write 0xa22 0xa23 */
 		TempVal =	CCKSwingTable_Ch14[priv->CCK_index][0] +
-					(CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
+					(CCKSwingTable_Ch14[priv->CCK_index][1]<<8);
 
 		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
 		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
 			rCCK0_TxFilter1, TempVal);
-		//Write 0xa24 ~ 0xa27
+		/* Write 0xa24 ~ 0xa27 */
 		TempVal =	CCKSwingTable_Ch14[priv->CCK_index][2] +
 					(CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
 					(CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+
@@ -1557,9 +1452,9 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,	bool  bInCH
 		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
 		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
 			rCCK0_TxFilter2, TempVal);
-		//Write 0xa28  0xa29
+		/* Write 0xa28  0xa29 */
 		TempVal =	CCKSwingTable_Ch14[priv->CCK_index][6] +
-					(CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
+					(CCKSwingTable_Ch14[priv->CCK_index][7]<<8);
 
 		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
 		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
@@ -1567,20 +1462,17 @@ static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,	bool  bInCH
 	}
 }
 
-
-
 void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
-{	// dm_CCKTxPowerAdjust
-
+{	/*  dm_CCKTxPowerAdjust */
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	if(priv->bDcut == TRUE)
+
+	if (priv->bDcut == TRUE)
 		dm_CCKTxPowerAdjust_TSSI(dev, binch14);
 	else
 		dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
 }
 
-
-#ifndef  RTL8192U
+#ifndef RTL8192U
 static void dm_txpower_reset_recovery(
 	struct net_device *dev
 )
@@ -1589,75 +1481,71 @@ static void dm_txpower_reset_recovery(
 
 	RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
 	rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
-	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
-	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",priv->rfa_txpowertrackingindex);
-	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
-	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",priv->cck_present_attentuation);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n", priv->rfa_txpowertrackingindex);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n", priv->cck_present_attentuation);
 	dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
 
 	rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
-	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
-	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex);
-	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n", priv->rfc_txpowertrackingindex);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
 
-}	// dm_TXPowerResetRecovery
+}	/* dm_TXPowerResetRecovery */
 
 void dm_restore_dynamic_mechanism_state(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u32	reg_ratr = priv->rate_adaptive.last_ratr;
 
-	if(!priv->up)
-	{
+	if (!priv->up) {
 		RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
 		return;
 	}
 
-	//
-	// Restore previous state for rate adaptive
-	//
-	if(priv->rate_adaptive.rate_adaptive_disabled)
+	/* Restore previous state for rate adaptive */
+	if (priv->rate_adaptive.rate_adaptive_disabled)
 		return;
-	// TODO: Only 11n mode is implemented currently,
-	if(!(priv->ieee80211->mode==WIRELESS_MODE_N_24G ||
-		 priv->ieee80211->mode==WIRELESS_MODE_N_5G))
-		 return;
+	/* TODO: Only 11n mode is implemented currently, */
+	if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
+		priv->ieee80211->mode == WIRELESS_MODE_N_5G))
+		return;
+
 	{
 			/* 2007/11/15 MH Copy from 8190PCI. */
 			u32 ratr_value;
+
 			ratr_value = reg_ratr;
-			if(priv->rf_type == RF_1T2R)	// 1T2R, Spatial Stream 2 should be disabled
-			{
+			if (priv->rf_type == RF_1T2R) {	/* 1T2R, Spatial Stream 2 should be disabled */
 				ratr_value &= ~(RATE_ALL_OFDM_2SS);
-				//DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);
+				/*DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);*/
 			}
-			//DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);
-			//cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);
+			/*DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);*/
+			/*cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);*/
 			write_nic_dword(dev, RATR0, ratr_value);
 			write_nic_byte(dev, UFWP, 1);
 	}
-	//Restore TX Power Tracking Index
+	/* Restore TX Power Tracking Index */
 	if (priv->btxpower_trackingInit && priv->btxpower_tracking)
 		dm_txpower_reset_recovery(dev);
 
-	//
-	//Restore BB Initial Gain
-	//
+	/* Restore BB Initial Gain */
 	dm_bb_initialgain_restore(dev);
 
-}	// DM_RestoreDynamicMechanismState
+}	/* DM_RestoreDynamicMechanismState */
 
 static void dm_bb_initialgain_restore(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	u32 bit_mask = 0x7f; //Bit0~ Bit6
+	u32 bit_mask = 0x7f; /* Bit0~ Bit6 */
 
-	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
+	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
 		return;
 
-	//Disable Initial Gain
-	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
-	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+	/* Disable Initial Gain */
+	/*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
+	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	/* Only clear byte 1 and rewrite. */
 	rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
 	rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
 	rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
@@ -1665,41 +1553,39 @@ static void dm_bb_initialgain_restore(struct net_device *dev)
 	bit_mask  = bMaskByte2;
 	rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
 
-	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
-	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
-	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
-	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
-	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
-	//Enable Initial Gain
-	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);
-	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
-
-}	// dm_BBInitialGainRestore
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca);
+	/* Enable Initial Gain */
+	/*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);*/
+	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	/* Only clear byte 1 and rewrite. */
 
+}	/* dm_BBInitialGainRestore */
 
 void dm_backup_dynamic_mechanism_state(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-	// Fsync to avoid reset
+	/* Fsync to avoid reset */
 	priv->bswitch_fsync  = false;
 	priv->bfsync_processing = false;
-	//Backup BB InitialGain
+	/* Backup BB InitialGain */
 	dm_bb_initialgain_backup(dev);
 
-}	// DM_BackupDynamicMechanismState
-
+}	/* DM_BackupDynamicMechanismState */
 
 static void dm_bb_initialgain_backup(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	u32 bit_mask = bMaskByte0; //Bit0~ Bit6
+	u32 bit_mask = bMaskByte0; /* Bit0~ Bit6 */
 
-	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
+	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
 		return;
 
-	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
-	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+	/*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
+	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	/* Only clear byte 1 and rewrite. */
 	priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
 	priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
 	priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
@@ -1707,13 +1593,13 @@ static void dm_bb_initialgain_backup(struct net_device *dev)
 	bit_mask  = bMaskByte2;
 	priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
 
-	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
-	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
-	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
-	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
-	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca);
 
-}   // dm_BBInitialGainBakcup
+}   /* dm_BBInitialGainBakcup */
 
 #endif
 /*-----------------------------------------------------------------------------
@@ -1736,67 +1622,44 @@ static void dm_bb_initialgain_backup(struct net_device *dev)
 void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type,
 				       u32 dm_value)
 {
-	if (dm_type == DIG_TYPE_THRESH_HIGH)
-	{
+	if (dm_type == DIG_TYPE_THRESH_HIGH) {
 		dm_digtable.rssi_high_thresh = dm_value;
-	}
-	else if (dm_type == DIG_TYPE_THRESH_LOW)
-	{
+	} else if (dm_type == DIG_TYPE_THRESH_LOW) {
 		dm_digtable.rssi_low_thresh = dm_value;
-	}
-	else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
-	{
+	} else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
 		dm_digtable.rssi_high_power_highthresh = dm_value;
-	}
-	else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
-	{
+	} else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
 		dm_digtable.rssi_high_power_highthresh = dm_value;
-	}
-	else if (dm_type == DIG_TYPE_ENABLE)
-	{
+	} else if (dm_type == DIG_TYPE_ENABLE) {
 		dm_digtable.dig_state		= DM_STA_DIG_MAX;
 		dm_digtable.dig_enable_flag	= true;
-	}
-	else if (dm_type == DIG_TYPE_DISABLE)
-	{
+	} else if (dm_type == DIG_TYPE_DISABLE) {
 		dm_digtable.dig_state		= DM_STA_DIG_MAX;
 		dm_digtable.dig_enable_flag	= false;
-	}
-	else if (dm_type == DIG_TYPE_DBG_MODE)
-	{
-		if(dm_value >= DM_DBG_MAX)
+	} else if (dm_type == DIG_TYPE_DBG_MODE) {
+		if (dm_value >= DM_DBG_MAX)
 			dm_value = DM_DBG_OFF;
 		dm_digtable.dbg_mode		= (u8)dm_value;
-	}
-	else if (dm_type == DIG_TYPE_RSSI)
-	{
-		if(dm_value > 100)
+	} else if (dm_type == DIG_TYPE_RSSI) {
+		if (dm_value > 100)
 			dm_value = 30;
 		dm_digtable.rssi_val			= (long)dm_value;
-	}
-	else if (dm_type == DIG_TYPE_ALGORITHM)
-	{
+	} else if (dm_type == DIG_TYPE_ALGORITHM) {
 		if (dm_value >= DIG_ALGO_MAX)
 			dm_value = DIG_ALGO_BY_FALSE_ALARM;
-		if(dm_digtable.dig_algorithm != (u8)dm_value)
+		if (dm_digtable.dig_algorithm != (u8)dm_value)
 			dm_digtable.dig_algorithm_switch = 1;
 		dm_digtable.dig_algorithm	= (u8)dm_value;
-	}
-	else if (dm_type == DIG_TYPE_BACKOFF)
-	{
-		if(dm_value > 30)
+	} else if (dm_type == DIG_TYPE_BACKOFF) {
+		if (dm_value > 30)
 			dm_value = 30;
 		dm_digtable.backoff_val		= (u8)dm_value;
-	}
-	else if(dm_type == DIG_TYPE_RX_GAIN_MIN)
-	{
-		if(dm_value == 0)
+	} else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
+		if (dm_value == 0)
 			dm_value = 0x1;
 		dm_digtable.rx_gain_range_min = (u8)dm_value;
-	}
-	else if(dm_type == DIG_TYPE_RX_GAIN_MAX)
-	{
-		if(dm_value > 0x50)
+	} else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
+		if (dm_value > 0x50)
 			dm_value = 0x50;
 		dm_digtable.rx_gain_range_max = (u8)dm_value;
 	}
@@ -1824,7 +1687,7 @@ static void dm_dig_init(struct net_device *dev)
 	/* 2007/10/05 MH Disable DIG scheme now. Not tested. */
 	dm_digtable.dig_enable_flag	= true;
 	dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
-	dm_digtable.dbg_mode = DM_DBG_OFF;	//off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
+	dm_digtable.dbg_mode = DM_DBG_OFF;	/* off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig */
 	dm_digtable.dig_algorithm_switch = 0;
 
 	/* 2007/10/04 MH Define init gain threshold. */
@@ -1838,17 +1701,16 @@ static void dm_dig_init(struct net_device *dev)
 	dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
 	dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
 
-	dm_digtable.rssi_val = 50;	//for new dig debug rssi value
+	dm_digtable.rssi_val = 50;	/* for new dig debug rssi value */
 	dm_digtable.backoff_val = DM_DIG_BACKOFF;
 	dm_digtable.rx_gain_range_max = DM_DIG_MAX;
-	if(priv->CustomerID == RT_CID_819x_Netcore)
+	if (priv->CustomerID == RT_CID_819x_Netcore)
 		dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
 	else
 		dm_digtable.rx_gain_range_min = DM_DIG_MIN;
 
 }	/* dm_dig_init */
 
-
 /*-----------------------------------------------------------------------------
  * Function:	dm_ctrl_initgain_byrssi()
  *
@@ -1868,20 +1730,18 @@ static void dm_dig_init(struct net_device *dev)
  *---------------------------------------------------------------------------*/
 static void dm_ctrl_initgain_byrssi(struct net_device *dev)
 {
-
 	if (dm_digtable.dig_enable_flag == false)
 		return;
 
-	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
+	if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
 		dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
-	else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
+	else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
 		dm_ctrl_initgain_byrssi_by_driverrssi(dev);
-//		;
+	/* ; */
 	else
 		return;
 }
 
-
 static void dm_ctrl_initgain_byrssi_by_driverrssi(
 	struct net_device *dev)
 {
@@ -1892,32 +1752,33 @@ static void dm_ctrl_initgain_byrssi_by_driverrssi(
 	if (dm_digtable.dig_enable_flag == false)
 		return;
 
-	//DbgPrint("Dig by Sw Rssi \n");
-	if(dm_digtable.dig_algorithm_switch)	// if switched algorithm, we have to disable FW Dig.
+	/*DbgPrint("Dig by Sw Rssi\n");*/
+	if (dm_digtable.dig_algorithm_switch)	/* if switched algorithm, we have to disable FW Dig. */
 		fw_dig = 0;
-	if(fw_dig <= 3)	// execute several times to make sure the FW Dig is disabled
-	{// FW DIG Off
-		for(i=0; i<3; i++)
-			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+
+	if (fw_dig <= 3) { /* execute several times to make sure the FW Dig is disabled */
+		/* FW DIG Off */
+		for (i = 0; i < 3; i++)
+			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	/* Only clear byte 1 and rewrite. */
 		fw_dig++;
-		dm_digtable.dig_state = DM_STA_DIG_OFF;	//fw dig off.
+		dm_digtable.dig_state = DM_STA_DIG_OFF;	/* fw dig off. */
 	}
 
-	if(priv->ieee80211->state == IEEE80211_LINKED)
+	if (priv->ieee80211->state == IEEE80211_LINKED)
 		dm_digtable.cur_connect_state = DIG_CONNECT;
 	else
 		dm_digtable.cur_connect_state = DIG_DISCONNECT;
 
-	//DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n",
-		//DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);
+	/*DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d\n",
+		DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);*/
 
-	if(dm_digtable.dbg_mode == DM_DBG_OFF)
+	if (dm_digtable.dbg_mode == DM_DBG_OFF)
 		dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
-	//DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val);
+	/*DbgPrint("DM_DigTable.Rssi_val = %d\n", DM_DigTable.Rssi_val);*/
 	dm_initial_gain(dev);
 	dm_pd_th(dev);
 	dm_cs_ratio(dev);
-	if(dm_digtable.dig_algorithm_switch)
+	if (dm_digtable.dig_algorithm_switch)
 		dm_digtable.dig_algorithm_switch = 0;
 	dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
 
@@ -1933,152 +1794,138 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
 	if (dm_digtable.dig_enable_flag == false)
 		return;
 
-	if(dm_digtable.dig_algorithm_switch)
-	{
+	if (dm_digtable.dig_algorithm_switch) {
 		dm_digtable.dig_state = DM_STA_DIG_MAX;
-		// Fw DIG On.
-		for(i=0; i<3; i++)
-			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
+		/* Fw DIG On. */
+		for (i = 0; i < 3; i++)
+			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	/* Only clear byte 1 and rewrite.*/
 		dm_digtable.dig_algorithm_switch = 0;
 	}
 
 	if (priv->ieee80211->state != IEEE80211_LINKED)
 		return;
 
-	// For smooth, we can not change DIG state.
+	/* For smooth, we can not change DIG state. */
 	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
 		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
-	{
 		return;
-	}
-	//DbgPrint("Dig by Fw False Alarm\n");
-	//if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)
+
+	/*DbgPrint("Dig by Fw False Alarm\n");*/
+	/*if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)*/
 	/*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
 	pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
 	DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
 	/* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
 		  and then execute the step below. */
-	if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
-	{
+	if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
 		/* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
 		   will be reset to init value. We must prevent the condition. */
 		if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
-			(priv->reset_count == reset_cnt))
-		{
+		    (priv->reset_count == reset_cnt)) {
 			return;
 		}
-		else
-		{
-			reset_cnt = priv->reset_count;
-		}
+		reset_cnt = priv->reset_count;
 
-		// If DIG is off, DIG high power state must reset.
+		/* If DIG is off, DIG high power state must reset. */
 		dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
 		dm_digtable.dig_state = DM_STA_DIG_OFF;
 
-		// 1.1 DIG Off.
-		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+		/*  1.1 DIG Off. */
+		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	/*  Only clear byte 1 and rewrite. */
 
-		// 1.2 Set initial gain.
+		/*  1.2 Set initial gain. */
 		write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
 		write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
 		write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
 		write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
 
-		// 1.3 Lower PD_TH for OFDM.
-		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
-		{
-			/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
-			// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+		/*  1.3 Lower PD_TH for OFDM. */
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
+			/*
+			 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
+			 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+			 */
 			write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
 			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 				write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
+			else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+			else
+				PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
 			*/
-			//else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
-
-
-			//else
-				//PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
-		}
-		else
+		} else
 			write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
 
-		// 1.4 Lower CS ratio for CCK.
+		/* 1.4 Lower CS ratio for CCK. */
 		write_nic_byte(dev, 0xa0a, 0x08);
 
-		// 1.5 Higher EDCCA.
-		//PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
+		/* 1.5 Higher EDCCA. */
+		/*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);*/
 		return;
 
 	}
 
 	/* 2. When RSSI increase, We have to judge if it is larger than a threshold
 		  and then execute the step below.  */
-	if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh))
-	{
+	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
 		u8 reset_flag = 0;
 
 		if (dm_digtable.dig_state == DM_STA_DIG_ON &&
-			(priv->reset_count == reset_cnt))
-		{
+			(priv->reset_count == reset_cnt)) {
 			dm_ctrl_initgain_byrssi_highpwr(dev);
 			return;
 		}
-		else
-		{
-			if (priv->reset_count != reset_cnt)
-				reset_flag = 1;
+		if (priv->reset_count != reset_cnt)
+			reset_flag = 1;
 
-			reset_cnt = priv->reset_count;
-		}
+		reset_cnt = priv->reset_count;
 
 		dm_digtable.dig_state = DM_STA_DIG_ON;
-		//DbgPrint("DIG ON\n\r");
+		/*DbgPrint("DIG ON\n\r");*/
 
-		// 2.1 Set initial gain.
-		// 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
-		if (reset_flag == 1)
-		{
+		/*
+		 * 2.1 Set initial gain.
+		 * 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
+		 */
+		if (reset_flag == 1) {
 			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
 			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
 			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
 			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
-		}
-		else
-		{
+		} else {
 			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
 			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
 			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
 			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
 		}
 
-		// 2.2 Higher PD_TH for OFDM.
-		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
-		{
-			/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
-			// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+		/* 2.2 Higher PD_TH for OFDM. */
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
+			/*
+			 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
+			 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+			 */
 			write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
 			/*
 			else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 				write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+			else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+			else
+				PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
 			*/
-			//else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
-
-			//else
-				//PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
-		}
-		else
+		} else
 			write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
 
-		// 2.3 Higher CS ratio for CCK.
+		/* 2.3 Higher CS ratio for CCK. */
 		write_nic_byte(dev, 0xa0a, 0xcd);
 
-		// 2.4 Lower EDCCA.
-		/* 2008/01/11 MH 90/92 series are the same. */
-		//PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
+		/*
+		 * 2.4 Lower EDCCA.
+		 * 2008/01/11 MH 90/92 series are the same.
+		 */
+		/*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);*/
 
-		// 2.5 DIG On.
-		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
+		/* 2.5 DIG On. */
+		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	/*  Only clear byte 1 and rewrite. */
 
 	}
 
@@ -2086,7 +1933,6 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
 
 }	/* dm_CtrlInitGainByRssi */
 
-
 /*-----------------------------------------------------------------------------
  * Function:	dm_ctrl_initgain_byrssi_highpwr()
  *
@@ -2109,58 +1955,49 @@ static void dm_ctrl_initgain_byrssi_highpwr(
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	static u32 reset_cnt_highpwr;
 
-	// For smooth, we can not change high power DIG state in the range.
+	/*  For smooth, we can not change high power DIG state in the range. */
 	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
 		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
-	{
 		return;
-	}
 
-	/* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
-		  it is larger than a threshold and then execute the step below.  */
-	// 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
-	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
-	{
+	/*
+	 * 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
+	 *    it is larger than a threshold and then execute the step below.
+	 *
+	 * 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
+	 */
+	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) {
 		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
 			(priv->reset_count == reset_cnt_highpwr))
 			return;
-		else
-			dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
+		dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
 
-		// 3.1 Higher PD_TH for OFDM for high power state.
-		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
-		{
+		/* 3.1 Higher PD_TH for OFDM for high power state. */
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
 			write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
 
 			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 				write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
 			*/
 
-		}
-		else
+		} else
 			write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
-	}
-	else
-	{
-		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
+	} else {
+		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
 			(priv->reset_count == reset_cnt_highpwr))
 			return;
-		else
-			dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
+		dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
 
 		if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
-			 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
-		{
-			// 3.2 Recover PD_TH for OFDM for normal power region.
-			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
-			{
+			 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
+			/*  3.2 Recover PD_TH for OFDM for normal power region. */
+			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
 				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
 				/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
 				*/
 
-			}
-			else
+			} else
 				write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
 		}
 	}
@@ -2169,51 +2006,42 @@ static void dm_ctrl_initgain_byrssi_highpwr(
 
 }	/* dm_CtrlInitGainByRssiHighPwr */
 
-
 static void dm_initial_gain(
 	struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	u8					initial_gain=0;
+	u8					initial_gain = 0;
 	static u8				initialized, force_write;
 	static u32			reset_cnt;
 	u8				tmp;
 
-	if(dm_digtable.dig_algorithm_switch)
-	{
+	if (dm_digtable.dig_algorithm_switch) {
 		initialized = 0;
 		reset_cnt = 0;
 	}
 
-	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
-	{
-		if(dm_digtable.cur_connect_state == DIG_CONNECT)
-		{
-			if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
+	if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
+		if (dm_digtable.cur_connect_state == DIG_CONNECT) {
+			if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
 				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
-			else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
+			else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
 				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
 			else
 				dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
-		}
-		else		//current state is disconnected
-		{
-			if(dm_digtable.cur_ig_value == 0)
+		} else {	/* current state is disconnected */
+			if (dm_digtable.cur_ig_value == 0)
 				dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
 			else
 				dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
 		}
-	}
-	else	// disconnected -> connected or connected -> disconnected
-	{
+	} else { /*  disconnected -> connected or connected -> disconnected */
 		dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
 		dm_digtable.pre_ig_value = 0;
 	}
-	//DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);
+	/*DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);*/
 
-	// if silent reset happened, we should rewrite the values back
-	if(priv->reset_count != reset_cnt)
-	{
+	/* if silent reset happened, we should rewrite the values back */
+	if (priv->reset_count != reset_cnt) {
 		force_write = 1;
 		reset_cnt = priv->reset_count;
 	}
@@ -2223,12 +2051,11 @@ static void dm_initial_gain(
 		force_write = 1;
 
 	{
-		if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
-			|| !initialized || force_write)
-		{
+		if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
+			|| !initialized || force_write) {
 			initial_gain = (u8)dm_digtable.cur_ig_value;
-			//DbgPrint("Write initial gain = 0x%x\n", initial_gain);
-			// Set initial gain.
+			/*DbgPrint("Write initial gain = 0x%x\n", initial_gain);*/
+			/*  Set initial gain. */
 			write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
 			write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
 			write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
@@ -2247,93 +2074,77 @@ static void dm_pd_th(
 	static u8				initialized, force_write;
 	static u32			reset_cnt;
 
-	if(dm_digtable.dig_algorithm_switch)
-	{
+	if (dm_digtable.dig_algorithm_switch) {
 		initialized = 0;
 		reset_cnt = 0;
 	}
 
-	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
-	{
-		if(dm_digtable.cur_connect_state == DIG_CONNECT)
-		{
+	if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
+		if (dm_digtable.cur_connect_state == DIG_CONNECT) {
 			if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
 				dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
-			else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
+			else if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
 				dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
 			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
 					(dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
 				dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
 			else
 				dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
-		}
-		else
-		{
+		} else {
 			dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
 		}
-	}
-	else	// disconnected -> connected or connected -> disconnected
-	{
+	} else { /* disconnected -> connected or connected -> disconnected */
 		dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
 	}
 
-	// if silent reset happened, we should rewrite the values back
-	if(priv->reset_count != reset_cnt)
-	{
+	/*  if silent reset happened, we should rewrite the values back */
+	if (priv->reset_count != reset_cnt) {
 		force_write = 1;
 		reset_cnt = priv->reset_count;
 	}
 
 	{
-		if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
-			(initialized<=3) || force_write)
-		{
-			//DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);
-			if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
-			{
-				// Lower PD_TH for OFDM.
-				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
-				{
-					/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
-					// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+		if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
+		    (initialized <= 3) || force_write) {
+			/*DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);*/
+			if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
+				/*  Lower PD_TH for OFDM. */
+				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
+					/*
+					 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
+					 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+					 */
 					write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
 					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 						write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
 					*/
-				}
-				else
+				} else
 					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
-			}
-			else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
-			{
-				// Higher PD_TH for OFDM.
-				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
-				{
-					/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
-					// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+			} else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) {
+				/* Higher PD_TH for OFDM. */
+				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
+					/*
+					 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
+					 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+					 */
 					write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
 					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 						write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
 					*/
-				}
-				else
+				} else
 					write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
-			}
-			else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
-			{
-				// Higher PD_TH for OFDM for high power state.
-				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
-				{
+			} else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
+				/* Higher PD_TH for OFDM for high power state. */
+				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
 					write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
 					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 						write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
 					*/
-				}
-				else
+				} else
 					write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
 			}
 			dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
-			if(initialized <= 3)
+			if (initialized <= 3)
 				initialized++;
 			force_write = 0;
 		}
@@ -2347,54 +2158,40 @@ static	void dm_cs_ratio(
 	static u8				initialized, force_write;
 	static u32			reset_cnt;
 
-	if(dm_digtable.dig_algorithm_switch)
-	{
+	if (dm_digtable.dig_algorithm_switch) {
 		initialized = 0;
 		reset_cnt = 0;
 	}
 
-	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
-	{
-		if(dm_digtable.cur_connect_state == DIG_CONNECT)
-		{
-			if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
+	if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
+		if (dm_digtable.cur_connect_state == DIG_CONNECT) {
+			if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
 				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
-			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh))
+			else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
 				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
 			else
 				dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
-		}
-		else
-		{
+		} else {
 			dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
 		}
-	}
-	else	// disconnected -> connected or connected -> disconnected
-	{
+	} else	/* disconnected -> connected or connected -> disconnected */
 		dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
-	}
 
-	// if silent reset happened, we should rewrite the values back
-	if(priv->reset_count != reset_cnt)
-	{
+	/* if silent reset happened, we should rewrite the values back */
+	if (priv->reset_count != reset_cnt) {
 		force_write = 1;
 		reset_cnt = priv->reset_count;
 	}
 
-
 	{
-		if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
-			!initialized || force_write)
-		{
-			//DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);
-			if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
-			{
-				// Lower CS ratio for CCK.
+		if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
+			!initialized || force_write) {
+			/*DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);*/
+			if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) {
+				/*  Lower CS ratio for CCK. */
 				write_nic_byte(dev, 0xa0a, 0x08);
-			}
-			else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
-			{
-				// Higher CS ratio for CCK.
+			} else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) {
+				/*  Higher CS ratio for CCK. */
 				write_nic_byte(dev, 0xa0a, 0xcd);
 			}
 			dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
@@ -2411,53 +2208,46 @@ void dm_init_edca_turbo(struct net_device *dev)
 	priv->bcurrent_turbo_EDCA = false;
 	priv->ieee80211->bis_any_nonbepkts = false;
 	priv->bis_cur_rdlstate = false;
-}	// dm_init_edca_turbo
+}	/* dm_init_edca_turbo */
 
 static void dm_check_edca_turbo(
 	struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
-	//PSTA_QOS			pStaQos = pMgntInfo->pStaQos;
+	/*PSTA_QOS			pStaQos = pMgntInfo->pStaQos;*/
 
-	// Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
+	/* Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. */
 	static unsigned long			lastTxOkCnt;
 	static unsigned long			lastRxOkCnt;
 	unsigned long				curTxOkCnt = 0;
 	unsigned long				curRxOkCnt = 0;
 
-	//
-	// Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
-	// should follow the settings from QAP. By Bruce, 2007-12-07.
-	//
-	if(priv->ieee80211->state != IEEE80211_LINKED)
+	/*
+	 * Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
+	 * should follow the settings from QAP. By Bruce, 2007-12-07.
+	 */
+	if (priv->ieee80211->state != IEEE80211_LINKED)
 		goto dm_CheckEdcaTurbo_EXIT;
-	// We do not turn on EDCA turbo mode for some AP that has IOT issue
-	if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
+	/* We do not turn on EDCA turbo mode for some AP that has IOT issue */
+	if (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
 		goto dm_CheckEdcaTurbo_EXIT;
 
-//	printk("========>%s():bis_any_nonbepkts is %d\n",__func__,priv->bis_any_nonbepkts);
-	// Check the status for current condition.
-	if(!priv->ieee80211->bis_any_nonbepkts)
-	{
+	/*printk("========>%s():bis_any_nonbepkts is %d\n", __func__, priv->bis_any_nonbepkts);*/
+	/* Check the status for current condition. */
+	if (!priv->ieee80211->bis_any_nonbepkts) {
 		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
 		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
-		// For RT-AP, we needs to turn it on when Rx>Tx
-		if(curRxOkCnt > 4*curTxOkCnt)
-		{
-			//printk("%s():curRxOkCnt > 4*curTxOkCnt\n");
-			if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
-			{
+		/* For RT-AP, we needs to turn it on when Rx>Tx */
+		if (curRxOkCnt > 4*curTxOkCnt) {
+			/*printk("%s():curRxOkCnt > 4*curTxOkCnt\n");*/
+			if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
 				write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
 				priv->bis_cur_rdlstate = true;
 			}
-		}
-		else
-		{
-
-			//printk("%s():curRxOkCnt < 4*curTxOkCnt\n");
-			if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
-			{
+		} else {
+			/*printk("%s():curRxOkCnt < 4*curTxOkCnt\n");*/
+			if (priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
 				write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
 				priv->bis_cur_rdlstate = false;
 			}
@@ -2465,50 +2255,47 @@ static void dm_check_edca_turbo(
 		}
 
 		priv->bcurrent_turbo_EDCA = true;
-	}
-	else
-	{
-		//
-		// Turn Off EDCA turbo here.
-		// Restore original EDCA according to the declaration of AP.
-		//
-		 if(priv->bcurrent_turbo_EDCA)
-		{
-
+	} else {
+		/*
+		 * Turn Off EDCA turbo here.
+		 * Restore original EDCA according to the declaration of AP.
+		 */
+		if (priv->bcurrent_turbo_EDCA) {
 			{
 				u8		u1bAIFS;
 				u32		u4bAcParam;
 				struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
 				u8 mode = priv->ieee80211->mode;
 
-			// For Each time updating EDCA parameter, reset EDCA turbo mode status.
+				/*  For Each time updating EDCA parameter, reset EDCA turbo mode status. */
 				dm_init_edca_turbo(dev);
-				u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
-				u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
-					(((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
-					(((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
+				u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime;
+				u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0])) << AC_PARAM_TXOP_LIMIT_OFFSET)|
+					(((u32)(qos_parameters->cw_max[0])) << AC_PARAM_ECW_MAX_OFFSET)|
+					(((u32)(qos_parameters->cw_min[0])) << AC_PARAM_ECW_MIN_OFFSET)|
 					((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
-			//write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
+				/*write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);*/
 				write_nic_dword(dev, EDCAPARA_BE,  u4bAcParam);
 
-			// Check ACM bit.
-			// If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
+				/*
+				 * Check ACM bit.
+				 * If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
+				 */
 				{
-			// TODO:  Modified this part and try to set acm control in only 1 IO processing!!
+					/*  TODO:  Modified this part and try to set acm control in only 1 IO processing!! */
 
 					PACI_AIFSN	pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
 					u8		AcmCtrl;
+
 					read_nic_byte(dev, AcmHwCtrl, &AcmCtrl);
-					if(pAciAifsn->f.ACM)
-					{ // ACM bit is 1.
+
+					if (pAciAifsn->f.ACM) { /*  ACM bit is 1. */
 						AcmCtrl |= AcmHw_BeqEn;
-					}
-					else
-					{ // ACM bit is 0.
+					} else {	/* ACM bit is 0. */
 						AcmCtrl &= (~AcmHw_BeqEn);
 					}
 
-					RT_TRACE(COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl) ;
+					RT_TRACE(COMP_QOS, "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
 					write_nic_byte(dev, AcmHwCtrl, AcmCtrl);
 				}
 			}
@@ -2516,13 +2303,12 @@ static void dm_check_edca_turbo(
 		}
 	}
 
-
 dm_CheckEdcaTurbo_EXIT:
-	// Set variables for next time.
+	/* Set variables for next time. */
 	priv->ieee80211->bis_any_nonbepkts = false;
 	lastTxOkCnt = priv->stats.txbytesunicast;
 	lastRxOkCnt = priv->stats.rxbytesunicast;
-}	// dm_CheckEdcaTurbo
+}	/* dm_CheckEdcaTurbo */
 
 static void dm_init_ctstoself(struct net_device *dev)
 {
@@ -2541,8 +2327,7 @@ static void dm_ctstoself(struct net_device *dev)
 	unsigned long						curTxOkCnt = 0;
 	unsigned long						curRxOkCnt = 0;
 
-	if(priv->ieee80211->bCTSToSelfEnable != TRUE)
-	{
+	if (priv->ieee80211->bCTSToSelfEnable != TRUE) {
 		pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
 		return;
 	}
@@ -2552,17 +2337,13 @@ static void dm_ctstoself(struct net_device *dev)
 	3. <50 disable, >55 enable
 	*/
 
-	if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
-	{
+	if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
 		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
 		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
-		if(curRxOkCnt > 4*curTxOkCnt)	//downlink, disable CTS to self
-		{
+		if (curRxOkCnt > 4*curTxOkCnt) { /* downlink, disable CTS to self */
 			pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
-			//DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");
-		}
-		else	//uplink
-		{
+			/*DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");*/
+		} else { /* uplink */
 			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
 		}
 
@@ -2592,15 +2373,15 @@ static	void	dm_check_pbc_gpio(struct net_device *dev)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u8 tmp1byte;
 
-
 	read_nic_byte(dev, GPI, &tmp1byte);
-	if(tmp1byte == 0xff)
+	if (tmp1byte == 0xff)
 		return;
 
-	if (tmp1byte&BIT6 || tmp1byte&BIT0)
-	{
-		// Here we only set bPbcPressed to TRUE
-		// After trigger PBC, the variable will be set to FALSE
+	if (tmp1byte&BIT6 || tmp1byte&BIT0) {
+		/*
+		 * Here we only set bPbcPressed to TRUE
+		 * After trigger PBC, the variable will be set to FALSE
+		 */
 		RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
 		priv->bpbc_pressed = true;
 	}
@@ -2625,26 +2406,24 @@ static	void	dm_check_pbc_gpio(struct net_device *dev)
  *---------------------------------------------------------------------------*/
 void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
 {
-	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
-       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
-       struct net_device *dev =priv->ieee80211->dev;
-	//bool bactually_set = false;
+	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+	struct r8192_priv *priv = container_of(dwork, struct r8192_priv, rfpath_check_wq);
+	struct net_device *dev = priv->ieee80211->dev;
+	/*bool bactually_set = false;*/
 	u8 rfpath = 0, i;
 
-
 	/* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
 	   always be the same. We only read 0xc04 now. */
 	read_nic_byte(dev, 0xc04, &rfpath);
 
-	// Check Bit 0-3, it means if RF A-D is enabled.
-	for (i = 0; i < RF90_PATH_MAX; i++)
-	{
+	/* Check Bit 0-3, it means if RF A-D is enabled. */
+	for (i = 0; i < RF90_PATH_MAX; i++) {
 		if (rfpath & (0x01<<i))
 			priv->brfpath_rxenable[i] = 1;
 		else
 			priv->brfpath_rxenable[i] = 0;
 	}
-	if(!DM_RxPathSelTable.Enable)
+	if (!DM_RxPathSelTable.Enable)
 		return;
 
 	dm_rxpath_sel_byrssi(dev);
@@ -2654,17 +2433,17 @@ static void dm_init_rxpath_selection(struct net_device *dev)
 {
 	u8 i;
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	DM_RxPathSelTable.Enable = 1;	//default enabled
+
+	DM_RxPathSelTable.Enable = 1;	/* default enabled */
 	DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
 	DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
-	if(priv->CustomerID == RT_CID_819x_Netcore)
+	if (priv->CustomerID == RT_CID_819x_Netcore)
 		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
 	else
 		DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
 	DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
 	DM_RxPathSelTable.disabledRF = 0;
-	for(i=0; i<4; i++)
-	{
+	for (i = 0; i < 4; i++) {
 		DM_RxPathSelTable.rf_rssi[i] = 50;
 		DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
 		DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
@@ -2674,22 +2453,21 @@ static void dm_init_rxpath_selection(struct net_device *dev)
 static void dm_rxpath_sel_byrssi(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	u8				i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
-	u8				tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
-	u8				cck_default_Rx=0x2;	//RF-C
-	u8				cck_optional_Rx=0x3;//RF-D
-	long				tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
-	u8				cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
+	u8				i, max_rssi_index = 0, min_rssi_index = 0, sec_rssi_index = 0, rf_num = 0;
+	u8				tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
+	u8				cck_default_Rx = 0x2;  /* RF-C */
+	u8				cck_optional_Rx = 0x3; /* RF-D */
+	long				tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
+	u8				cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0, cck_rx_ver2_sec_index = 0;
 	u8				cur_rf_rssi;
 	long				cur_cck_pwdb;
 	static u8			disabled_rf_cnt, cck_Rx_Path_initialized;
 	u8				update_cck_rx_path;
 
-	if(priv->rf_type != RF_2T4R)
+	if (priv->rf_type != RF_2T4R)
 		return;
 
-	if(!cck_Rx_Path_initialized)
-	{
+	if (!cck_Rx_Path_initialized) {
 		read_nic_byte(dev, 0xa07, &DM_RxPathSelTable.cck_Rx_path);
 		DM_RxPathSelTable.cck_Rx_path &= 0xf;
 		cck_Rx_Path_initialized = 1;
@@ -2698,90 +2476,63 @@ static void dm_rxpath_sel_byrssi(struct net_device *dev)
 	read_nic_byte(dev, 0xc04, &DM_RxPathSelTable.disabledRF);
 	DM_RxPathSelTable.disabledRF = ~DM_RxPathSelTable.disabledRF & 0xf;
 
-	if(priv->ieee80211->mode == WIRELESS_MODE_B)
-	{
-		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;	//pure B mode, fixed cck version2
-		//DbgPrint("Pure B mode, use cck rx version2 \n");
+	if (priv->ieee80211->mode == WIRELESS_MODE_B) {
+		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;	/* pure B mode, fixed cck version2 */
+		/*DbgPrint("Pure B mode, use cck rx version2\n");*/
 	}
 
-	//decide max/sec/min rssi index
-	for (i=0; i<RF90_PATH_MAX; i++)
-	{
-		if(!DM_RxPathSelTable.DbgMode)
+	/* decide max/sec/min rssi index */
+	for (i = 0; i < RF90_PATH_MAX; i++) {
+		if (!DM_RxPathSelTable.DbgMode)
 			DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
 
-		if(priv->brfpath_rxenable[i])
-		{
+		if (priv->brfpath_rxenable[i]) {
 			rf_num++;
 			cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
 
-			if(rf_num == 1)	// find first enabled rf path and the rssi values
-			{	//initialize, set all rssi index to the same one
+			if (rf_num == 1) { /* find first enabled rf path and the rssi values */
+				/* initialize, set all rssi index to the same one */
 				max_rssi_index = min_rssi_index = sec_rssi_index = i;
 				tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
-			}
-			else if(rf_num == 2)
-			{	// we pick up the max index first, and let sec and min to be the same one
-				if(cur_rf_rssi >= tmp_max_rssi)
-				{
+			} else if (rf_num == 2) { /* we pick up the max index first, and let sec and min to be the same one */
+				if (cur_rf_rssi >= tmp_max_rssi) {
 					tmp_max_rssi = cur_rf_rssi;
 					max_rssi_index = i;
-				}
-				else
-				{
+				} else {
 					tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
 					sec_rssi_index = min_rssi_index = i;
 				}
-			}
-			else
-			{
-				if(cur_rf_rssi > tmp_max_rssi)
-				{
+			} else {
+				if (cur_rf_rssi > tmp_max_rssi) {
 					tmp_sec_rssi = tmp_max_rssi;
 					sec_rssi_index = max_rssi_index;
 					tmp_max_rssi = cur_rf_rssi;
 					max_rssi_index = i;
-				}
-				else if(cur_rf_rssi == tmp_max_rssi)
-				{	// let sec and min point to the different index
+				} else if (cur_rf_rssi == tmp_max_rssi) {	/* let sec and min point to the different index */
 					tmp_sec_rssi = cur_rf_rssi;
 					sec_rssi_index = i;
-				}
-				else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
-				{
+				} else if ((cur_rf_rssi < tmp_max_rssi) && (cur_rf_rssi > tmp_sec_rssi)) {
 					tmp_sec_rssi = cur_rf_rssi;
 					sec_rssi_index = i;
-				}
-				else if(cur_rf_rssi == tmp_sec_rssi)
-				{
-					if(tmp_sec_rssi == tmp_min_rssi)
-					{	// let sec and min point to the different index
+				} else if (cur_rf_rssi == tmp_sec_rssi) {
+					if (tmp_sec_rssi == tmp_min_rssi) {
+						/* let sec and min point to the different index */
 						tmp_sec_rssi = cur_rf_rssi;
 						sec_rssi_index = i;
+					} else {
+						/* This case we don't need to set any index */
 					}
-					else
-					{
-						// This case we don't need to set any index
-					}
-				}
-				else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
-				{
-					// This case we don't need to set any index
-				}
-				else if(cur_rf_rssi == tmp_min_rssi)
-				{
-					if(tmp_sec_rssi == tmp_min_rssi)
-					{	// let sec and min point to the different index
+				} else if ((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi)) {
+					/* This case we don't need to set any index */
+				} else if (cur_rf_rssi == tmp_min_rssi) {
+					if (tmp_sec_rssi == tmp_min_rssi) {
+						/* let sec and min point to the different index */
 						tmp_min_rssi = cur_rf_rssi;
 						min_rssi_index = i;
+					} else {
+						/* This case we don't need to set any index */
 					}
-					else
-					{
-						// This case we don't need to set any index
-					}
-				}
-				else if(cur_rf_rssi < tmp_min_rssi)
-				{
+				} else if (cur_rf_rssi < tmp_min_rssi) {
 					tmp_min_rssi = cur_rf_rssi;
 					min_rssi_index = i;
 				}
@@ -2790,83 +2541,51 @@ static void dm_rxpath_sel_byrssi(struct net_device *dev)
 	}
 
 	rf_num = 0;
-	// decide max/sec/min cck pwdb index
-	if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
-	{
-		for (i=0; i<RF90_PATH_MAX; i++)
-		{
-			if(priv->brfpath_rxenable[i])
-			{
+	/* decide max/sec/min cck pwdb index */
+	if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
+		for (i = 0; i < RF90_PATH_MAX; i++) {
+			if (priv->brfpath_rxenable[i]) {
 				rf_num++;
 				cur_cck_pwdb =  DM_RxPathSelTable.cck_pwdb_sta[i];
 
-				if(rf_num == 1)	// find first enabled rf path and the rssi values
-				{	//initialize, set all rssi index to the same one
+				if (rf_num == 1) {	/* find first enabled rf path and the rssi values */
+					/* initialize, set all rssi index to the same one */
 					cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
 					tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
-				}
-				else if(rf_num == 2)
-				{	// we pick up the max index first, and let sec and min to be the same one
-					if(cur_cck_pwdb >= tmp_cck_max_pwdb)
-					{
+				} else if (rf_num == 2) {	/* we pick up the max index first, and let sec and min to be the same one */
+					if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
 						tmp_cck_max_pwdb = cur_cck_pwdb;
 						cck_rx_ver2_max_index = i;
-					}
-					else
-					{
+					} else {
 						tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
 						cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
 					}
-				}
-				else
-				{
-					if(cur_cck_pwdb > tmp_cck_max_pwdb)
-					{
+				} else {
+					if (cur_cck_pwdb > tmp_cck_max_pwdb) {
 						tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
 						cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
 						tmp_cck_max_pwdb = cur_cck_pwdb;
 						cck_rx_ver2_max_index = i;
-					}
-					else if(cur_cck_pwdb == tmp_cck_max_pwdb)
-					{	// let sec and min point to the different index
+					} else if (cur_cck_pwdb == tmp_cck_max_pwdb) {
+						/* let sec and min point to the different index */
 						tmp_cck_sec_pwdb = cur_cck_pwdb;
 						cck_rx_ver2_sec_index = i;
-					}
-					else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
-					{
+					} else if ((cur_cck_pwdb < tmp_cck_max_pwdb) && (cur_cck_pwdb > tmp_cck_sec_pwdb)) {
 						tmp_cck_sec_pwdb = cur_cck_pwdb;
 						cck_rx_ver2_sec_index = i;
-					}
-					else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
-					{
-						if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
-						{	// let sec and min point to the different index
-							tmp_cck_sec_pwdb = cur_cck_pwdb;
-							cck_rx_ver2_sec_index = i;
-						}
-						else
-						{
-							// This case we don't need to set any index
-						}
-					}
-					else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
-					{
-						// This case we don't need to set any index
-					}
-					else if(cur_cck_pwdb == tmp_cck_min_pwdb)
-					{
-						if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
-						{	// let sec and min point to the different index
-							tmp_cck_min_pwdb = cur_cck_pwdb;
-							cck_rx_ver2_min_index = i;
-						}
-						else
-						{
-							// This case we don't need to set any index
-						}
-					}
-					else if(cur_cck_pwdb < tmp_cck_min_pwdb)
-					{
+					} else if (cur_cck_pwdb == tmp_cck_sec_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
+						/* let sec and min point to the different index */
+						tmp_cck_sec_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_sec_index = i;
+						/* otherwise we don't need to set any index */
+					} else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb)) {
+						/*  This case we don't need to set any index */
+					} else if (cur_cck_pwdb == tmp_cck_min_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
+						/*  let sec and min point to the different index */
+						tmp_cck_min_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_min_index = i;
+						/* otherwise we don't need to set any index */
+					} else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
 						tmp_cck_min_pwdb = cur_cck_pwdb;
 						cck_rx_ver2_min_index = i;
 					}
@@ -2876,56 +2595,48 @@ static void dm_rxpath_sel_byrssi(struct net_device *dev)
 		}
 	}
 
-
-	// Set CCK Rx path
-	// reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
+	/*
+	 * Set CCK Rx path
+	 * reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
+	 */
 	update_cck_rx_path = 0;
-	if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
-	{
+	if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
 		cck_default_Rx = cck_rx_ver2_max_index;
 		cck_optional_Rx = cck_rx_ver2_sec_index;
-		if(tmp_cck_max_pwdb != -64)
+		if (tmp_cck_max_pwdb != -64)
 			update_cck_rx_path = 1;
 	}
 
-	if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
-	{
-		if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
-		{
-			//record the enabled rssi threshold
+	if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) {
+		if ((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH) {
+			/* record the enabled rssi threshold */
 			DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
-			//disable the BB Rx path, OFDM
-			rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	// 0xc04[3:0]
-			rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	// 0xd04[3:0]
+			/* disable the BB Rx path, OFDM */
+			rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	/* 0xc04[3:0] */
+			rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	/* 0xd04[3:0] */
 			disabled_rf_cnt++;
 		}
-		if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
-		{
+		if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) {
 			cck_default_Rx = max_rssi_index;
 			cck_optional_Rx = sec_rssi_index;
-			if(tmp_max_rssi)
+			if (tmp_max_rssi)
 				update_cck_rx_path = 1;
 		}
 	}
 
-	if(update_cck_rx_path)
-	{
+	if (update_cck_rx_path) {
 		DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
 		rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
 	}
 
-	if(DM_RxPathSelTable.disabledRF)
-	{
-		for(i=0; i<4; i++)
-		{
-			if((DM_RxPathSelTable.disabledRF>>i) & 0x1)	//disabled rf
-			{
-				if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
-				{
-					//enable the BB Rx path
-					//DbgPrint("RF-%d is enabled. \n", 0x1<<i);
-					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);	// 0xc04[3:0]
-					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);	// 0xd04[3:0]
+	if (DM_RxPathSelTable.disabledRF) {
+		for (i = 0; i < 4; i++) {
+			if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) {	/* disabled rf */
+				if (tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) {
+					/* enable the BB Rx path */
+					/*DbgPrint("RF-%d is enabled.\n", 0x1<<i);*/
+					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);	/* 0xc04[3:0] */
+					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);	/* 0xd04[3:0] */
 					DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
 					disabled_rf_cnt--;
 				}
@@ -2950,14 +2661,14 @@ static void dm_rxpath_sel_byrssi(struct net_device *dev)
  *	05/28/2008	amy		Create Version 0 porting from windows code.
  *
  *---------------------------------------------------------------------------*/
-static	void	dm_check_rx_path_selection(struct net_device *dev)
+static void dm_check_rx_path_selection(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
-}	/* dm_CheckRxRFPath */
 
+	queue_delayed_work(priv->priv_wq, &priv->rfpath_check_wq, 0);
+}	/* dm_CheckRxRFPath */
 
-static void dm_init_fsync (struct net_device *dev)
+static void dm_init_fsync(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
@@ -2966,20 +2677,20 @@ static void dm_init_fsync (struct net_device *dev)
 	priv->ieee80211->fsync_rssi_threshold = 30;
 	priv->ieee80211->bfsync_enable = false;
 	priv->ieee80211->fsync_multiple_timeinterval = 3;
-	priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
-	priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
+	priv->ieee80211->fsync_firstdiff_ratethreshold = 100;
+	priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
 	priv->ieee80211->fsync_state = Default_Fsync;
-	priv->framesyncMonitor = 1;	// current default 0xc38 monitor on
+	priv->framesyncMonitor = 1;	/* current default 0xc38 monitor on */
 
 	init_timer(&priv->fsync_timer);
 	priv->fsync_timer.data = (unsigned long)dev;
 	priv->fsync_timer.function = dm_fsync_timer_callback;
 }
 
-
 static void dm_deInit_fsync(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
+
 	del_timer_sync(&priv->fsync_timer);
 }
 
@@ -2987,102 +2698,84 @@ void dm_fsync_timer_callback(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
-	u32 rate_index, rate_count = 0, rate_count_diff=0;
+	u32 rate_index, rate_count = 0, rate_count_diff = 0;
 	bool		bSwitchFromCountDiff = false;
 	bool		bDoubleTimeInterval = false;
 
-	if(priv->ieee80211->state == IEEE80211_LINKED &&
+	if (priv->ieee80211->state == IEEE80211_LINKED &&
 		priv->ieee80211->bfsync_enable &&
-		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
-	{
-		 // Count rate 54, MCS [7], [12, 13, 14, 15]
+		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
+		/* Count rate 54, MCS [7], [12, 13, 14, 15] */
 		u32 rate_bitmap;
-		for(rate_index = 0; rate_index <= 27; rate_index++)
-		{
+
+		for (rate_index = 0; rate_index <= 27; rate_index++) {
 			rate_bitmap  = 1 << rate_index;
-			if(priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
-				rate_count+= priv->stats.received_rate_histogram[1][rate_index];
+			if (priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
+				rate_count += priv->stats.received_rate_histogram[1][rate_index];
 		}
 
-		if(rate_count < priv->rate_record)
+		if (rate_count < priv->rate_record)
 			rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
 		else
 			rate_count_diff = rate_count - priv->rate_record;
-		if(rate_count_diff < priv->rateCountDiffRecord)
-		{
-
+		if (rate_count_diff < priv->rateCountDiffRecord) {
 			u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
-			// Continue count
-			if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
+			/* Continue count */
+			if (DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
 				priv->ContinueDiffCount++;
 			else
 				priv->ContinueDiffCount = 0;
 
-			// Continue count over
-			if(priv->ContinueDiffCount >=2)
-			{
+			/* Continue count over */
+			if (priv->ContinueDiffCount >= 2) {
 				bSwitchFromCountDiff = true;
 				priv->ContinueDiffCount = 0;
 			}
-		}
-		else
-		{
-			// Stop the continued count
+		} else {
+			/* Stop the continued count */
 			priv->ContinueDiffCount = 0;
 		}
 
-		//If Count diff <= FsyncRateCountThreshold
-		if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
-		{
+		/* If Count diff <= FsyncRateCountThreshold */
+		if (rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) {
 			bSwitchFromCountDiff = true;
 			priv->ContinueDiffCount = 0;
 		}
 		priv->rate_record = rate_count;
 		priv->rateCountDiffRecord = rate_count_diff;
-		RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
-		// if we never receive those mcs rate and rssi > 30 % then switch fsyn
-		if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
-		{
+		RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
+		/* if we never receive those mcs rate and rssi > 30 % then switch fsyn */
+		if (priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff) {
 			bDoubleTimeInterval = true;
 			priv->bswitch_fsync = !priv->bswitch_fsync;
-			if(priv->bswitch_fsync)
-			{
+			if (priv->bswitch_fsync) {
 				write_nic_byte(dev, 0xC36, 0x1c);
 				write_nic_byte(dev, 0xC3e, 0x90);
-			}
-			else
-			{
+			} else {
 				write_nic_byte(dev, 0xC36, 0x5c);
 				write_nic_byte(dev, 0xC3e, 0x96);
 			}
-		}
-		else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
-		{
-			if(priv->bswitch_fsync)
-			{
+		} else if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) {
+			if (priv->bswitch_fsync) {
 				priv->bswitch_fsync  = false;
 				write_nic_byte(dev, 0xC36, 0x5c);
 				write_nic_byte(dev, 0xC3e, 0x96);
 			}
 		}
-		if(bDoubleTimeInterval){
-			if(timer_pending(&priv->fsync_timer))
+		if (bDoubleTimeInterval) {
+			if (timer_pending(&priv->fsync_timer))
 				del_timer_sync(&priv->fsync_timer);
 			priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
 			add_timer(&priv->fsync_timer);
-		}
-		else{
-			if(timer_pending(&priv->fsync_timer))
+		} else {
+			if (timer_pending(&priv->fsync_timer))
 				del_timer_sync(&priv->fsync_timer);
 			priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
 			add_timer(&priv->fsync_timer);
 		}
-	}
-	else
-	{
-		// Let Register return to default value;
-		if(priv->bswitch_fsync)
-		{
+	} else {
+		/* Let Register return to default value; */
+		if (priv->bswitch_fsync) {
 			priv->bswitch_fsync  = false;
 			write_nic_byte(dev, 0xC36, 0x5c);
 			write_nic_byte(dev, 0xC3e, 0x96);
@@ -3091,7 +2784,7 @@ void dm_fsync_timer_callback(unsigned long data)
 		write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
 	}
 	RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
-	RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
+	RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
 }
 
 static void dm_StartHWFsync(struct net_device *dev)
@@ -3108,9 +2801,8 @@ static void dm_EndSWFsync(struct net_device *dev)
 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
 	del_timer_sync(&(priv->fsync_timer));
 
-	// Let Register return to default value;
-	if(priv->bswitch_fsync)
-	{
+	/* Let Register return to default value; */
+	if (priv->bswitch_fsync) {
 		priv->bswitch_fsync  = false;
 
 		write_nic_byte(dev, 0xC36, 0x5c);
@@ -3130,30 +2822,26 @@ static void dm_StartSWFsync(struct net_device *dev)
 	u32			rateBitmap;
 
 	RT_TRACE(COMP_HALDM, "%s\n", __func__);
-	// Initial rate record to zero, start to record.
+	/* Initial rate record to zero, start to record. */
 	priv->rate_record = 0;
-	// Initialize continue diff count to zero, start to record.
+	/* Initialize continue diff count to zero, start to record. */
 	priv->ContinueDiffCount = 0;
 	priv->rateCountDiffRecord = 0;
 	priv->bswitch_fsync  = false;
 
-	if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
-	{
-		priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
+	if (priv->ieee80211->mode == WIRELESS_MODE_N_24G) {
+		priv->ieee80211->fsync_firstdiff_ratethreshold = 600;
 		priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
-	}
-	else
-	{
-		priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
+	} else {
+		priv->ieee80211->fsync_firstdiff_ratethreshold = 200;
 		priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
 	}
-	for(rateIndex = 0; rateIndex <= 27; rateIndex++)
-	{
-		rateBitmap  = 1 << rateIndex;
-		if(priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
+	for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
+		rateBitmap = 1 << rateIndex;
+		if (priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
 			priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
 	}
-	if(timer_pending(&priv->fsync_timer))
+	if (timer_pending(&priv->fsync_timer))
 		del_timer_sync(&priv->fsync_timer);
 	priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
 	add_timer(&priv->fsync_timer);
@@ -3173,139 +2861,112 @@ static void dm_EndHWFsync(struct net_device *dev)
 void dm_check_fsync(struct net_device *dev)
 {
 #define	RegC38_Default				0
-#define	RegC38_NonFsync_Other_AP	1
-#define	RegC38_Fsync_AP_BCM		2
+#define	RegC38_NonFsync_Other_AP		1
+#define	RegC38_Fsync_AP_BCM			2
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	//u32			framesyncC34;
-	static u8		reg_c38_State=RegC38_Default;
+	/*u32			framesyncC34;*/
+	static u8		reg_c38_State = RegC38_Default;
 	static u32	reset_cnt;
 
 	RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval);
 	RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold);
 
-	if(priv->ieee80211->state == IEEE80211_LINKED &&
-		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
-	{
-		if(priv->ieee80211->bfsync_enable == 0)
-		{
-			switch (priv->ieee80211->fsync_state)
-			{
-				case Default_Fsync:
-					dm_StartHWFsync(dev);
-					priv->ieee80211->fsync_state = HW_Fsync;
-					break;
-				case SW_Fsync:
-					dm_EndSWFsync(dev);
-					dm_StartHWFsync(dev);
-					priv->ieee80211->fsync_state = HW_Fsync;
-					break;
-				case HW_Fsync:
-				default:
-					break;
+	if (priv->ieee80211->state == IEEE80211_LINKED &&
+		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
+		if (priv->ieee80211->bfsync_enable == 0) {
+			switch (priv->ieee80211->fsync_state) {
+			case Default_Fsync:
+				dm_StartHWFsync(dev);
+				priv->ieee80211->fsync_state = HW_Fsync;
+				break;
+			case SW_Fsync:
+				dm_EndSWFsync(dev);
+				dm_StartHWFsync(dev);
+				priv->ieee80211->fsync_state = HW_Fsync;
+				break;
+			case HW_Fsync:
+			default:
+				break;
 			}
-		}
-		else
-		{
-			switch (priv->ieee80211->fsync_state)
-			{
-				case Default_Fsync:
-					dm_StartSWFsync(dev);
-					priv->ieee80211->fsync_state = SW_Fsync;
-					break;
-				case HW_Fsync:
-					dm_EndHWFsync(dev);
-					dm_StartSWFsync(dev);
-					priv->ieee80211->fsync_state = SW_Fsync;
-					break;
-				case SW_Fsync:
-				default:
-					break;
-
+		} else {
+			switch (priv->ieee80211->fsync_state) {
+			case Default_Fsync:
+				dm_StartSWFsync(dev);
+				priv->ieee80211->fsync_state = SW_Fsync;
+				break;
+			case HW_Fsync:
+				dm_EndHWFsync(dev);
+				dm_StartSWFsync(dev);
+				priv->ieee80211->fsync_state = SW_Fsync;
+				break;
+			case SW_Fsync:
+			default:
+				break;
 			}
 		}
-		if(priv->framesyncMonitor)
-		{
-			if(reg_c38_State != RegC38_Fsync_AP_BCM)
-			{	//For broadcom AP we write different default value
+		if (priv->framesyncMonitor) {
+			if (reg_c38_State != RegC38_Fsync_AP_BCM) {
+				/* For broadcom AP we write different default value */
 				write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
 
 				reg_c38_State = RegC38_Fsync_AP_BCM;
 			}
 		}
-	}
-	else
-	{
-		switch (priv->ieee80211->fsync_state)
-		{
-			case HW_Fsync:
-				dm_EndHWFsync(dev);
-				priv->ieee80211->fsync_state = Default_Fsync;
-				break;
-			case SW_Fsync:
-				dm_EndSWFsync(dev);
-				priv->ieee80211->fsync_state = Default_Fsync;
-				break;
-			case Default_Fsync:
-			default:
-				break;
+	} else {
+		switch (priv->ieee80211->fsync_state) {
+		case HW_Fsync:
+			dm_EndHWFsync(dev);
+			priv->ieee80211->fsync_state = Default_Fsync;
+			break;
+		case SW_Fsync:
+			dm_EndSWFsync(dev);
+			priv->ieee80211->fsync_state = Default_Fsync;
+			break;
+		case Default_Fsync:
+		default:
+			break;
 		}
 
-		if(priv->framesyncMonitor)
-		{
-			if(priv->ieee80211->state == IEEE80211_LINKED)
-			{
-				if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
-				{
-					if(reg_c38_State != RegC38_NonFsync_Other_AP)
-					{
+		if (priv->framesyncMonitor) {
+			if (priv->ieee80211->state == IEEE80211_LINKED) {
+				if (priv->undecorated_smoothed_pwdb <= RegC38_TH) {
+					if (reg_c38_State != RegC38_NonFsync_Other_AP) {
 						write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
 
 						reg_c38_State = RegC38_NonFsync_Other_AP;
 					}
-				}
-				else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
-				{
-					if(reg_c38_State)
-					{
+				} else if (priv->undecorated_smoothed_pwdb >= (RegC38_TH+5)) {
+					if (reg_c38_State) {
 						write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
 						reg_c38_State = RegC38_Default;
-						//DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync);
+						/*DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x\n", pHalData->framesync);*/
 					}
 				}
-			}
-			else
-			{
-				if(reg_c38_State)
-				{
+			} else {
+				if (reg_c38_State) {
 					write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
 					reg_c38_State = RegC38_Default;
-					//DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync);
+					/*DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x\n", pHalData->framesync);*/
 				}
 			}
 		}
 	}
-	if(priv->framesyncMonitor)
-	{
-		if(priv->reset_count != reset_cnt)
-		{	//After silent reset, the reg_c38_State will be returned to default value
+	if (priv->framesyncMonitor) {
+		if (priv->reset_count != reset_cnt) { /* After silent reset, the reg_c38_State will be returned to default value */
 			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
 			reg_c38_State = RegC38_Default;
 			reset_cnt = priv->reset_count;
-			//DbgPrint("reg_c38_State = 0 for silent reset. \n");
+			/*DbgPrint("reg_c38_State = 0 for silent reset.\n");*/
 		}
-	}
-	else
-	{
-		if(reg_c38_State)
-		{
+	} else {
+		if (reg_c38_State) {
 			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
 			reg_c38_State = RegC38_Default;
-			//DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync);
+			/*DbgPrint("framesync no monitor, write 0xc38 = 0x%x\n", pHalData->framesync);*/
 		}
 	}
 }
 
-
 /*-----------------------------------------------------------------------------
  * Function:	dm_shadow_init()
  *
@@ -3328,10 +2989,9 @@ void dm_shadow_init(struct net_device *dev)
 	u16	offset;
 
 	for (page = 0; page < 5; page++)
-		for (offset = 0; offset < 256; offset++)
-		{
+		for (offset = 0; offset < 256; offset++) {
 			read_nic_byte(dev, offset+page*256, &dm_shadow[page][offset]);
-			//DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);
+			/*DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);*/
 		}
 
 	for (page = 8; page < 11; page++)
@@ -3366,8 +3026,8 @@ static void dm_init_dynamic_txpower(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-	//Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
-	priv->ieee80211->bdynamic_txpower_enable = true;    //Default to enable Tx Power Control
+	/* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
+	priv->ieee80211->bdynamic_txpower_enable = true;    /* Default to enable Tx Power Control */
 	priv->bLastDTPFlag_High = false;
 	priv->bLastDTPFlag_Low = false;
 	priv->bDynamicTxHighPower = false;
@@ -3377,91 +3037,77 @@ static void dm_init_dynamic_txpower(struct net_device *dev)
 static void dm_dynamic_txpower(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-	unsigned int txhipower_threshhold=0;
-	unsigned int txlowpower_threshold=0;
-	if(priv->ieee80211->bdynamic_txpower_enable != true)
-	{
+	unsigned int txhipower_threshhold = 0;
+	unsigned int txlowpower_threshold = 0;
+
+	if (priv->ieee80211->bdynamic_txpower_enable != true) {
 		priv->bDynamicTxHighPower = false;
 		priv->bDynamicTxLowPower = false;
 		return;
 	}
-	//printk("priv->ieee80211->current_network.unknown_cap_exist is %d ,priv->ieee80211->current_network.broadcom_cap_exist is %d\n",priv->ieee80211->current_network.unknown_cap_exist,priv->ieee80211->current_network.broadcom_cap_exist);
-	if((priv->ieee80211->current_network.atheros_cap_exist) && (priv->ieee80211->mode == IEEE_G)){
+	/*printk("priv->ieee80211->current_network.unknown_cap_exist is %d , priv->ieee80211->current_network.broadcom_cap_exist is %d\n", priv->ieee80211->current_network.unknown_cap_exist, priv->ieee80211->current_network.broadcom_cap_exist);*/
+	if ((priv->ieee80211->current_network.atheros_cap_exist) && (priv->ieee80211->mode == IEEE_G)) {
 		txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
 		txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
-	}
-	else
-	{
+	} else {
 		txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
 		txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
 	}
 
-//	printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__func__,txhipower_threshhold,txlowpower_threshold);
-	RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb);
+	/*printk("=======>%s(): txhipower_threshhold is %d, txlowpower_threshold is %d\n", __func__, txhipower_threshhold, txlowpower_threshold);*/
+	RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n", priv->undecorated_smoothed_pwdb);
 
-	if(priv->ieee80211->state == IEEE80211_LINKED)
-	{
-		if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
-		{
+	if (priv->ieee80211->state == IEEE80211_LINKED) {
+		if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
 			priv->bDynamicTxHighPower = true;
 			priv->bDynamicTxLowPower = false;
-		}
-		else
-		{
-			// high power state check
-			if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
-			{
+		} else {
+			/* high power state check */
+			if (priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
 				priv->bDynamicTxHighPower = false;
-			}
-			// low power state check
-			if(priv->undecorated_smoothed_pwdb < 35)
-			{
+
+			/* low power state check */
+			if (priv->undecorated_smoothed_pwdb < 35)
 				priv->bDynamicTxLowPower = true;
-			}
-			else if(priv->undecorated_smoothed_pwdb >= 40)
-			{
+			else if (priv->undecorated_smoothed_pwdb >= 40)
 				priv->bDynamicTxLowPower = false;
-			}
 		}
-	}
-	else
-	{
-		//pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
+	} else {
+		/*pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;*/
 		priv->bDynamicTxHighPower = false;
 		priv->bDynamicTxLowPower = false;
 	}
 
-	if((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
-		(priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low))
-	{
-		RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190()  channel = %d \n" , priv->ieee80211->current_network.channel);
+	if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
+		(priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
+		RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190()  channel = %d\n", priv->ieee80211->current_network.channel);
 
 #if  defined(RTL8190P) || defined(RTL8192E)
-		SetTxPowerLevel8190(Adapter,pHalData->CurrentChannel);
+		SetTxPowerLevel8190(Adapter, pHalData->CurrentChannel);
 #endif
 
-		rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
-		//pHalData->bStartTxCtrlByTPCNFR = FALSE;    //Clear th flag of Set TX Power from Sitesurvey
+		rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel);
+		/*pHalData->bStartTxCtrlByTPCNFR = FALSE;    Clear th flag of Set TX Power from Sitesurvey*/
 	}
 	priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
 	priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
 
 }	/* dm_dynamic_txpower */
 
-//added by vivi, for read tx rate and retrycount
+/* added by vivi, for read tx rate and retrycount */
 static void dm_check_txrateandretrycount(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_device *ieee = priv->ieee80211;
-	//for 11n tx rate
-//	priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
+	/* for 11n tx rate */
+	/*priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);*/
 	read_nic_byte(dev, Current_Tx_Rate_Reg, &ieee->softmac_stats.CurrentShowTxate);
-	//printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);
-	//for initial tx rate
-//	priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);
+	/*printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);*/
+	/* for initial tx rate */
+	/*priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);*/
 	read_nic_byte(dev, Initial_Tx_Rate_Reg, &ieee->softmac_stats.last_packet_rate);
-	//for tx tx retry count
-//	priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
+	/* for tx tx retry count */
+	/*priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);*/
 	read_nic_dword(dev, Tx_Retry_Count_Reg, &ieee->softmac_stats.txretrycount);
 }
 
@@ -3469,11 +3115,12 @@ static void dm_send_rssi_tofw(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-	// If we test chariot, we should stop the TX command ?
-	// Because 92E will always silent reset when we send tx command. We use register
-	// 0x1e0(byte) to notify driver.
+	/*
+	 * If we test chariot, we should stop the TX command ?
+	 * Because 92E will always silent reset when we send tx command. We use register
+	 * 0x1e0(byte) to notify driver.
+	 */
 	write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
-	return;
 }
 
 /*---------------------------Define function prototype------------------------*/
diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h
index 3d0a98b6d8e5..e62543d22b86 100644
--- a/drivers/staging/rtl8712/drv_types.h
+++ b/drivers/staging/rtl8712/drv_types.h
@@ -129,8 +129,8 @@ struct dvobj_priv {
 	struct _adapter *padapter;
 	u32 nr_endpoint;
 	u8   ishighspeed;
-	uint(*inirp_init)(struct _adapter *adapter);
-	uint(*inirp_deinit)(struct _adapter *adapter);
+	uint (*inirp_init)(struct _adapter *adapter);
+	uint (*inirp_deinit)(struct _adapter *adapter);
 	struct usb_device *pusbdev;
 };
 
@@ -166,7 +166,7 @@ struct _adapter {
 	 pid_t evtThread;
 	struct task_struct *xmitThread;
 	pid_t recvThread;
-	uint(*dvobj_init)(struct _adapter *adapter);
+	uint (*dvobj_init)(struct _adapter *adapter);
 	void (*dvobj_deinit)(struct _adapter *adapter);
 	struct net_device *pnetdev;
 	int bup;
diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h
index 5153ad9c2c75..36348d900d34 100644
--- a/drivers/staging/rtl8712/osdep_service.h
+++ b/drivers/staging/rtl8712/osdep_service.h
@@ -71,7 +71,7 @@ static inline void _init_timer(struct timer_list *ptimer,
 
 static inline void _set_timer(struct timer_list *ptimer, u32 delay_time)
 {
-	mod_timer(ptimer, (jiffies+(delay_time*HZ/1000)));
+	mod_timer(ptimer, (jiffies+msecs_to_jiffies(delay_time)));
 }
 
 static inline void _cancel_timer(struct timer_list *ptimer, u8 *bcancelled)
@@ -101,12 +101,9 @@ static inline void sleep_schedulable(int ms)
 {
 	u32 delta;
 
-	delta = (ms * HZ) / 1000;/*(ms)*/
-	if (delta == 0)
-		delta = 1;/* 1 ms */
+	delta = msecs_to_jiffies(ms);/*(ms)*/
 	set_current_state(TASK_INTERRUPTIBLE);
-	if (schedule_timeout(delta) != 0)
-		return;
+	schedule_timeout(delta);
 }
 
 static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer)
diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c
index 0631f3638257..409c8c897256 100644
--- a/drivers/staging/rtl8712/recv_linux.c
+++ b/drivers/staging/rtl8712/recv_linux.c
@@ -137,20 +137,6 @@ _recv_indicatepkt_drop:
 	 precvpriv->rx_drop++;
 }
 
-void r8712_os_read_port(struct _adapter *padapter, struct recv_buf *precvbuf)
-{
-	struct recv_priv *precvpriv = &padapter->recvpriv;
-
-	precvbuf->ref_cnt--;
-	/*free skb in recv_buf*/
-	dev_kfree_skb_any(precvbuf->pskb);
-	precvbuf->pskb = NULL;
-	precvbuf->reuse = false;
-	if (!precvbuf->irp_pending)
-		r8712_read_port(padapter, precvpriv->ff_hwaddr, 0,
-			 (unsigned char *)precvbuf);
-}
-
 static void _r8712_reordering_ctrl_timeout_handler (void *FunctionContext)
 {
 	struct recv_reorder_ctrl *preorder_ctrl =
diff --git a/drivers/staging/rtl8712/recv_osdep.h b/drivers/staging/rtl8712/recv_osdep.h
index f4384ef00868..1f4986e940a3 100644
--- a/drivers/staging/rtl8712/recv_osdep.h
+++ b/drivers/staging/rtl8712/recv_osdep.h
@@ -46,7 +46,6 @@ int r8712_os_recvbuf_resource_alloc(struct _adapter *padapter,
 				    struct recv_buf *precvbuf);
 int r8712_os_recvbuf_resource_free(struct _adapter *padapter,
 				   struct recv_buf *precvbuf);
-void r8712_os_read_port(struct _adapter *padapter, struct recv_buf *precvbuf);
 void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl);
 
 #endif
diff --git a/drivers/staging/rtl8712/rtl8712_cmd.h b/drivers/staging/rtl8712/rtl8712_cmd.h
index 039ab3e97172..67e9e910aef9 100644
--- a/drivers/staging/rtl8712/rtl8712_cmd.h
+++ b/drivers/staging/rtl8712/rtl8712_cmd.h
@@ -109,16 +109,16 @@ enum rtl8712_h2c_cmd {
 	GEN_CMD_CODE(_DisconnectCtrlEx), /*61*/
 
 	/* To do, modify these h2c cmd, add or delete */
-	GEN_CMD_CODE(_GetH2cLbk) ,
+	GEN_CMD_CODE(_GetH2cLbk),
 
 	/* WPS extra IE */
-	GEN_CMD_CODE(_SetProbeReqExtraIE) ,
-	GEN_CMD_CODE(_SetAssocReqExtraIE) ,
-	GEN_CMD_CODE(_SetProbeRspExtraIE) ,
-	GEN_CMD_CODE(_SetAssocRspExtraIE) ,
+	GEN_CMD_CODE(_SetProbeReqExtraIE),
+	GEN_CMD_CODE(_SetAssocReqExtraIE),
+	GEN_CMD_CODE(_SetProbeRspExtraIE),
+	GEN_CMD_CODE(_SetAssocRspExtraIE),
 
 	/* the following is driver will do */
-	GEN_CMD_CODE(_GetCurDataRate) ,
+	GEN_CMD_CODE(_GetCurDataRate),
 
 	GEN_CMD_CODE(_GetTxRetrycnt),  /* to record times that Tx retry to
 					* transmit packet after association
diff --git a/drivers/staging/rtl8712/rtl8712_event.h b/drivers/staging/rtl8712/rtl8712_event.h
index 3d7f79efa2c1..29a4c23a0d23 100644
--- a/drivers/staging/rtl8712/rtl8712_event.h
+++ b/drivers/staging/rtl8712/rtl8712_event.h
@@ -27,7 +27,7 @@
 #define _RTL8712_EVENT_H_
 
 void r8712_event_handle(struct _adapter *padapter, uint *peventbuf);
-void r8712_got_addbareq_event_callback(struct _adapter *adapter , u8 *pbuf);
+void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf);
 
 enum rtl8712_c2h_event {
 	GEN_EVT_CODE(_Read_MACREG) = 0,		/*0*/
diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
index 73b7d864ccbd..9bb364f04fd4 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -196,7 +196,7 @@ static inline char *translate_scan(struct _adapter *padapter,
 	if (p && ht_ielen > 0) {
 		ht_cap = true;
 		pht_capie = (struct ieee80211_ht_cap *)(p + 2);
-		memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
+		memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
 	}
 	/* Add the protocol name */
 	iwe.cmd = SIOCGIWNAME;
@@ -1436,7 +1436,7 @@ static int r8711_wx_get_rate(struct net_device *dev,
 		if (p && ht_ielen > 0) {
 			ht_cap = true;
 			pht_capie = (struct ieee80211_ht_cap *)(p + 2);
-			memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
+			memcpy(&mcs_rate, pht_capie->supp_mcs_set, 2);
 			bw_40MHz = (pht_capie->cap_info &
 				    IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
 			short_GI = (pht_capie->cap_info &
diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c
index b7462e8145d6..977a83358056 100644
--- a/drivers/staging/rtl8712/rtl871x_mlme.c
+++ b/drivers/staging/rtl8712/rtl871x_mlme.c
@@ -93,7 +93,7 @@ struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv)
 		return NULL;
 	spin_lock_irqsave(&free_queue->lock, irqL);
 	plist = free_queue->queue.next;
-	pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list);
+	pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
 	list_del_init(&pnetwork->list);
 	pnetwork->last_scanned = jiffies;
 	pmlmepriv->num_of_scanned++;
@@ -499,7 +499,7 @@ static int is_desired_network(struct _adapter *adapter,
 }
 
 /* TODO: Perry : For Power Management */
-void r8712_atimdone_event_callback(struct _adapter *adapter , u8 *pbuf)
+void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf)
 {
 }
 
diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
index a16f15e91992..0b5461208eb9 100644
--- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
+++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.c
@@ -575,26 +575,6 @@ uint oid_rt_pro_set_single_tone_tx_hdl(struct oid_par_priv
 	return RNDIS_STATUS_SUCCESS;
 }
 
-uint oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	uint status = RNDIS_STATUS_SUCCESS;
-	struct ndis_802_11_ssid *pssid;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	*poid_par_priv->bytes_needed = (u32)sizeof(struct ndis_802_11_ssid);
-	*poid_par_priv->bytes_rw = 0;
-	if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
-		return RNDIS_STATUS_INVALID_LENGTH;
-	pssid = (struct ndis_802_11_ssid *)poid_par_priv->information_buf;
-	if (mp_start_joinbss(Adapter, pssid) == _FAIL)
-		status = RNDIS_STATUS_NOT_ACCEPTED;
-	*poid_par_priv->bytes_rw = sizeof(struct ndis_802_11_ssid);
-	return status;
-}
-
 uint oid_rt_pro_read_register_hdl(struct oid_par_priv
 					 *poid_par_priv)
 {
@@ -696,172 +676,6 @@ uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv)
 	return status;
 }
 
-uint oid_rt_pro_burst_read_register_hdl(struct oid_par_priv
-					       *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	struct burst_rw_reg *pBstRwReg;
-
-	if (poid_par_priv->type_of_oid != QUERY_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
-	r8712_read_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
-		 pBstRwReg->Data);
-	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_burst_write_register_hdl(struct oid_par_priv
-						*poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	struct burst_rw_reg *pBstRwReg;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	pBstRwReg = (struct burst_rw_reg *)poid_par_priv->information_buf;
-	r8712_write_mem(Adapter, pBstRwReg->offset, (u32)pBstRwReg->len,
-		  pBstRwReg->Data);
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv)
-{
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	struct eeprom_rw_param *pEEPROM;
-
-	if (poid_par_priv->type_of_oid != QUERY_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
-	pEEPROM->value = r8712_eeprom_read16(Adapter,
-					     (u16)(pEEPROM->offset >> 1));
-	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	struct eeprom_rw_param *pEEPROM;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	pEEPROM = (struct eeprom_rw_param *)poid_par_priv->information_buf;
-	r8712_eeprom_write16(Adapter, (u16)(pEEPROM->offset >> 1),
-			     pEEPROM->value);
-	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	struct mp_wiparam *pwi_param;
-
-	if (poid_par_priv->type_of_oid != QUERY_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	if (poid_par_priv->information_buf_len < sizeof(struct mp_wiparam))
-		return RNDIS_STATUS_INVALID_LENGTH;
-	if (Adapter->mppriv.workparam.bcompleted == false)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	pwi_param = (struct mp_wiparam *)poid_par_priv->information_buf;
-	memcpy(pwi_param, &Adapter->mppriv.workparam,
-		sizeof(struct mp_wiparam));
-	Adapter->mppriv.act_in_progress = false;
-	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-
-	if (poid_par_priv->type_of_oid != QUERY_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	if (poid_par_priv->information_buf_len < sizeof(uint) * 2)
-		return RNDIS_STATUS_INVALID_LENGTH;
-	if (*(uint *)poid_par_priv->information_buf == 1)
-		Adapter->mppriv.rx_pktloss = 0;
-	*((uint *)poid_par_priv->information_buf+1) =
-					 Adapter->mppriv.rx_pktloss;
-	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
-{
-	if (poid_par_priv->type_of_oid != QUERY_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv)
-{
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	uint status = RNDIS_STATUS_SUCCESS;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	if (r8712_setrfintfs_cmd(Adapter, *(unsigned char *)
-	    poid_par_priv->information_buf) == _FAIL)
-		status = RNDIS_STATUS_NOT_ACCEPTED;
-	return status;
-}
-
-uint oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-
-	if (poid_par_priv->type_of_oid != QUERY_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	memcpy(poid_par_priv->information_buf,
-		(unsigned char *)&Adapter->mppriv.rxstat,
-		sizeof(struct recv_stat));
-	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_cfg_debug_message_hdl(struct oid_par_priv
-					     *poid_par_priv)
-{
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_set_data_rate_ex_hdl(struct oid_par_priv
-					    *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	uint status = RNDIS_STATUS_SUCCESS;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	if (r8712_setdatarate_cmd(Adapter,
-	    poid_par_priv->information_buf) != _SUCCESS)
-		status = RNDIS_STATUS_NOT_ACCEPTED;
-	return status;
-}
-
 uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv)
 {
 	struct _adapter *Adapter = (struct _adapter *)
@@ -890,251 +704,6 @@ uint oid_rt_get_thermal_meter_hdl(struct oid_par_priv *poid_par_priv)
 	return RNDIS_STATUS_SUCCESS;
 }
 
-uint oid_rt_pro_set_power_tracking_hdl(struct oid_par_priv
-					      *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	uint status = RNDIS_STATUS_SUCCESS;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	if (poid_par_priv->information_buf_len < sizeof(u8))
-		return RNDIS_STATUS_INVALID_LENGTH;
-	if (!r8712_setptm_cmd(Adapter, *((u8 *)poid_par_priv->information_buf)))
-		status = RNDIS_STATUS_NOT_ACCEPTED;
-	return status;
-}
-
-uint oid_rt_pro_set_basic_rate_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
-	uint status = RNDIS_STATUS_SUCCESS;
-	u32 ratevalue;
-	u8 datarates[NumRates];
-	int i;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	ratevalue = *((u32 *)poid_par_priv->information_buf);
-	for (i = 0; i < NumRates; i++) {
-		if (ratevalue == mpdatarate[i])
-			datarates[i] = mpdatarate[i];
-		else
-			datarates[i] = 0xff;
-	}
-	if (r8712_setbasicrate_cmd(Adapter, datarates) != _SUCCESS)
-		status = RNDIS_STATUS_NOT_ACCEPTED;
-	return status;
-}
-
-uint oid_rt_pro_qry_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-
-	if (poid_par_priv->type_of_oid != QUERY_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	if (poid_par_priv->information_buf_len < 8)
-		return RNDIS_STATUS_INVALID_LENGTH;
-	*poid_par_priv->bytes_rw = 8;
-	memcpy(poid_par_priv->information_buf,
-		&(Adapter->pwrctrlpriv.pwr_mode), 8);
-	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_set_pwrstate_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	uint pwr_mode, smart_ps;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	*poid_par_priv->bytes_rw = 0;
-	*poid_par_priv->bytes_needed = 8;
-	if (poid_par_priv->information_buf_len < 8)
-		return RNDIS_STATUS_INVALID_LENGTH;
-	pwr_mode = *(uint *)(poid_par_priv->information_buf);
-	smart_ps = *(uint *)((addr_t)poid_par_priv->information_buf + 4);
-	if (pwr_mode != Adapter->pwrctrlpriv.pwr_mode || smart_ps !=
-			Adapter->pwrctrlpriv.smart_ps)
-		r8712_set_ps_mode(Adapter, pwr_mode, smart_ps);
-	*poid_par_priv->bytes_rw = 8;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_h2c_set_rate_table_hdl(struct oid_par_priv
-					      *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	uint status = RNDIS_STATUS_SUCCESS;
-	struct setratable_parm *prate_table;
-	u8 res;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	*poid_par_priv->bytes_needed  = sizeof(struct setratable_parm);
-	if (poid_par_priv->information_buf_len <
-	    sizeof(struct setratable_parm))
-		return RNDIS_STATUS_INVALID_LENGTH;
-	prate_table = (struct setratable_parm *)poid_par_priv->information_buf;
-	res = r8712_setrttbl_cmd(Adapter, prate_table);
-	if (res == _FAIL)
-		status = RNDIS_STATUS_FAILURE;
-	return status;
-}
-
-uint oid_rt_pro_h2c_get_rate_table_hdl(struct oid_par_priv
-					      *poid_par_priv)
-{
-	if (poid_par_priv->type_of_oid != QUERY_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv
-					   *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	struct security_priv *psecuritypriv = &Adapter->securitypriv;
-	enum ENCRY_CTRL_STATE encry_mode = 0;
-
-	*poid_par_priv->bytes_needed = sizeof(u8);
-	if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
-		return RNDIS_STATUS_INVALID_LENGTH;
-
-	if (poid_par_priv->type_of_oid == SET_OID) {
-		encry_mode = *((u8 *)poid_par_priv->information_buf);
-		switch (encry_mode) {
-		case HW_CONTROL:
-			psecuritypriv->sw_decrypt = false;
-			psecuritypriv->sw_encrypt = false;
-			break;
-		case SW_CONTROL:
-			psecuritypriv->sw_decrypt = true;
-			psecuritypriv->sw_encrypt = true;
-			break;
-		case HW_ENCRY_SW_DECRY:
-			psecuritypriv->sw_decrypt = true;
-			psecuritypriv->sw_encrypt = false;
-			break;
-		case SW_ENCRY_HW_DECRY:
-			psecuritypriv->sw_decrypt = false;
-			psecuritypriv->sw_encrypt = true;
-			break;
-		}
-	} else {
-		if ((psecuritypriv->sw_encrypt == false) &&
-		    (psecuritypriv->sw_decrypt == false))
-			encry_mode = HW_CONTROL;
-		else if ((psecuritypriv->sw_encrypt == false) &&
-			 (psecuritypriv->sw_decrypt == true))
-			encry_mode = HW_ENCRY_SW_DECRY;
-		else if ((psecuritypriv->sw_encrypt == true) &&
-			 (psecuritypriv->sw_decrypt == false))
-			encry_mode = SW_ENCRY_HW_DECRY;
-		else if ((psecuritypriv->sw_encrypt == true) &&
-			 (psecuritypriv->sw_decrypt == true))
-			encry_mode = SW_CONTROL;
-		*(u8 *)poid_par_priv->information_buf =  encry_mode;
-		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-	}
-	return RNDIS_STATUS_SUCCESS;
-}
-/*----------------------------------------------------------------------*/
-uint oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-
-	uint status = RNDIS_STATUS_SUCCESS;
-
-	struct sta_info	*psta = NULL;
-	u8	*macaddr;
-
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-
-	*poid_par_priv->bytes_needed = ETH_ALEN;
-	if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
-		return RNDIS_STATUS_INVALID_LENGTH;
-	macaddr = (u8 *) poid_par_priv->information_buf;
-	psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
-	if (psta == NULL) { /* the sta in sta_info_queue => do nothing*/
-		psta = r8712_alloc_stainfo(&Adapter->stapriv, macaddr);
-		if (psta == NULL)
-			status = RNDIS_STATUS_FAILURE;
-	}
-	return status;
-}
-/*-------------------------------------------------------------------------*/
-uint oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-
-	unsigned long			irqL;
-
-	struct sta_info		*psta = NULL;
-	u8			*macaddr;
-
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-
-	*poid_par_priv->bytes_needed = ETH_ALEN;
-	if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
-		return RNDIS_STATUS_INVALID_LENGTH;
-
-	macaddr = (u8 *)poid_par_priv->information_buf;
-
-	psta = r8712_get_stainfo(&Adapter->stapriv, macaddr);
-	if (psta != NULL) {
-		spin_lock_irqsave(&(Adapter->stapriv.sta_hash_lock), irqL);
-		r8712_free_stainfo(Adapter, psta);
-		spin_unlock_irqrestore(&(Adapter->stapriv.sta_hash_lock), irqL);
-	}
-
-	return RNDIS_STATUS_SUCCESS;
-}
-/*--------------------------------------------------------------------------*/
-static u32 mp_query_drv_var(struct _adapter *padapter, u8 offset, u32 var)
-{
-	return var;
-}
-
-uint oid_rt_pro_query_dr_variable_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-
-	struct DR_VARIABLE_STRUCT *pdrv_var;
-
-	if (poid_par_priv->type_of_oid != QUERY_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	*poid_par_priv->bytes_needed = sizeof(struct DR_VARIABLE_STRUCT);
-	if (poid_par_priv->information_buf_len < *poid_par_priv->bytes_needed)
-		return RNDIS_STATUS_INVALID_LENGTH;
-	pdrv_var = (struct DR_VARIABLE_STRUCT *)poid_par_priv->information_buf;
-	pdrv_var->variable = mp_query_drv_var(Adapter, pdrv_var->offset,
-					      pdrv_var->variable);
-	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
-	return RNDIS_STATUS_SUCCESS;
-}
-
-/*--------------------------------------------------------------------------*/
-uint oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv)
-{
-	return RNDIS_STATUS_SUCCESS;
-}
-/*------------------------------------------------------------------------*/
 uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv)
 {
 	struct _adapter *Adapter = (struct _adapter *)
@@ -1192,38 +761,6 @@ uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv)
 	return status;
 }
 /*----------------------------------------------------------------------*/
-uint oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	uint status = RNDIS_STATUS_SUCCESS;
-	struct PGPKT_STRUCT	*ppgpkt;
-
-	*poid_par_priv->bytes_rw = 0;
-	if (poid_par_priv->information_buf_len < sizeof(struct PGPKT_STRUCT))
-		return RNDIS_STATUS_INVALID_LENGTH;
-	ppgpkt = (struct PGPKT_STRUCT *)poid_par_priv->information_buf;
-	if (poid_par_priv->type_of_oid == QUERY_OID) {
-		if (r8712_efuse_pg_packet_read(Adapter, ppgpkt->offset,
-		    ppgpkt->data) == true)
-			*poid_par_priv->bytes_rw =
-				 poid_par_priv->information_buf_len;
-		else
-			status = RNDIS_STATUS_FAILURE;
-	} else {
-		if (r8712_efuse_reg_init(Adapter) == true) {
-			if (r8712_efuse_pg_packet_write(Adapter, ppgpkt->offset,
-			    ppgpkt->word_en, ppgpkt->data) == true)
-				*poid_par_priv->bytes_rw =
-					 poid_par_priv->information_buf_len;
-			else
-				status = RNDIS_STATUS_FAILURE;
-			r8712_efuse_reg_uninit(Adapter);
-		} else
-			status = RNDIS_STATUS_FAILURE;
-	}
-	return status;
-}
 
 uint oid_rt_get_efuse_current_size_hdl(struct oid_par_priv
 					      *poid_par_priv)
@@ -1319,24 +856,6 @@ uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv)
 	return RNDIS_STATUS_SUCCESS;
 }
 
-uint oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	u32		crystal_cap = 0;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	if (poid_par_priv->information_buf_len < sizeof(u32))
-		return RNDIS_STATUS_INVALID_LENGTH;
-	crystal_cap = *((u32 *)poid_par_priv->information_buf);/*4*/
-	if (crystal_cap > 0xf)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	Adapter->mppriv.curr_crystalcap = crystal_cap;
-	r8712_SetCrystalCap(Adapter);
-	return RNDIS_STATUS_SUCCESS;
-}
-
 uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv
 					   *poid_par_priv)
 {
@@ -1378,50 +897,6 @@ uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv
 	return RNDIS_STATUS_SUCCESS;
 }
 
-uint oid_rt_pro_set_tx_agc_offset_hdl(struct oid_par_priv
-					     *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	u32 txagc;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-	if (poid_par_priv->information_buf_len < sizeof(u32))
-		return RNDIS_STATUS_INVALID_LENGTH;
-	txagc = *(u32 *)poid_par_priv->information_buf;
-	r8712_SetTxAGCOffset(Adapter, txagc);
-	return RNDIS_STATUS_SUCCESS;
-}
-
-uint oid_rt_pro_set_pkt_test_mode_hdl(struct oid_par_priv
-					     *poid_par_priv)
-{
-	struct _adapter *Adapter = (struct _adapter *)
-				   (poid_par_priv->adapter_context);
-	uint status = RNDIS_STATUS_SUCCESS;
-	struct mlme_priv	*pmlmepriv = &Adapter->mlmepriv;
-	struct mp_priv		*pmppriv = &Adapter->mppriv;
-	u32			type;
-
-	if (poid_par_priv->type_of_oid != SET_OID)
-		return RNDIS_STATUS_NOT_ACCEPTED;
-
-	if (poid_par_priv->information_buf_len < sizeof(u32))
-		return RNDIS_STATUS_INVALID_LENGTH;
-
-	type = *(u32 *)poid_par_priv->information_buf;
-
-	if (_LOOPBOOK_MODE_ == type) {
-		pmppriv->mode = type;
-		set_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE); /*append txdesc*/
-	} else if (_2MAC_MODE_ == type) {
-		pmppriv->mode = type;
-		_clr_fwstate_(pmlmepriv, WIFI_MP_LPBK_STATE);
-	} else
-		status = RNDIS_STATUS_NOT_ACCEPTED;
-	return status;
-}
 /*--------------------------------------------------------------------------*/
 /*Linux*/
 unsigned int mp_ioctl_xmit_packet_hdl(struct oid_par_priv *poid_par_priv)
diff --git a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
index 850143d5dee3..8e7c7f8b69f9 100644
--- a/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
+++ b/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
@@ -86,41 +86,8 @@ struct DR_VARIABLE_STRUCT {
 int mp_start_joinbss(struct _adapter *padapter, struct ndis_802_11_ssid *pssid);
 
 /* oid_rtl_seg_87_11_00 */
-uint oid_rt_pro8711_join_bss_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_pro_read_register_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_pro_write_register_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_burst_read_register_hdl(struct oid_par_priv*
-					       poid_par_priv);
-uint oid_rt_pro_burst_write_register_hdl(struct oid_par_priv*
-						poid_par_priv);
-uint oid_rt_pro_write_txcmd_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_read16_eeprom_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_write16_eeprom_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro8711_wi_poll_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro8711_pkt_loss_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_rd_attrib_mem_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_wr_attrib_mem_hdl(struct oid_par_priv *poid_par_priv);
-uint  oid_rt_pro_set_rf_intfs_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_poll_rx_status_hdl(struct oid_par_priv *poid_par_priv);
-/* oid_rtl_seg_87_11_20 */
-uint oid_rt_pro_cfg_debug_message_hdl(
-				struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_set_data_rate_ex_hdl(
-				struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_set_basic_rate_hdl(
-				struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_set_power_tracking_hdl(
-				struct oid_par_priv *poid_par_priv);
-/* oid_rtl_seg_87_11_50 */
-uint oid_rt_pro_qry_pwrstate_hdl(
-				struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_set_pwrstate_hdl(
-				struct oid_par_priv *poid_par_priv);
-/* oid_rtl_seg_87_11_F0 */
-uint oid_rt_pro_h2c_set_rate_table_hdl(
-				struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_h2c_get_rate_table_hdl(
-				struct oid_par_priv *poid_par_priv);
 /* oid_rtl_seg_81_80_00 */
 uint oid_rt_pro_set_data_rate_hdl(
 				struct oid_par_priv *poid_par_priv);
@@ -159,28 +126,15 @@ uint oid_rt_pro_write_rf_reg_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_pro_read_rf_reg_hdl(struct oid_par_priv *poid_par_priv);
 /* oid_rtl_seg_81_85 */
 uint oid_rt_wireless_mode_hdl(struct oid_par_priv *poid_par_priv);
-/* oid_rtl_seg_87_12_00 */
-uint oid_rt_pro_encryption_ctrl_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_add_sta_info_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_dele_sta_info_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_query_dr_variable_hdl(
-				struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_pro_read_efuse_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_pro_write_efuse_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_rw_efuse_pgpkt_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_get_efuse_current_size_hdl(
 				struct oid_par_priv *poid_par_priv);
 uint oid_rt_pro_efuse_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_pro_efuse_map_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_set_bandwidth_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_set_crystal_cap_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_set_rx_packet_type_hdl(struct oid_par_priv *poid_par_priv);
 uint oid_rt_get_efuse_max_size_hdl(struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_set_tx_agc_offset_hdl(
-				struct oid_par_priv *poid_par_priv);
-uint oid_rt_pro_set_pkt_test_mode_hdl(
-				struct oid_par_priv *poid_par_priv);
 uint oid_rt_get_thermal_meter_hdl(
 				struct oid_par_priv *poid_par_priv);
 uint oid_rt_reset_phy_rx_packet_count_hdl(
diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
index 0526ba077bfc..dbfb55523545 100644
--- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h
+++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h
@@ -33,17 +33,17 @@
 #define CMD_ALIVE	BIT(2)
 
 enum Power_Mgnt {
-	PS_MODE_ACTIVE	= 0	,
-	PS_MODE_MIN			,
-	PS_MODE_MAX			,
-	PS_MODE_DTIM			,
-	PS_MODE_VOIP			,
-	PS_MODE_UAPSD_WMM	,
-	PS_MODE_UAPSD			,
-	PS_MODE_IBSS			,
-	PS_MODE_WWLAN		,
-	PM_Radio_Off			,
-	PM_Card_Disable		,
+	PS_MODE_ACTIVE	= 0,
+	PS_MODE_MIN,
+	PS_MODE_MAX,
+	PS_MODE_DTIM,
+	PS_MODE_VOIP,
+	PS_MODE_UAPSD_WMM,
+	PS_MODE_UAPSD,
+	PS_MODE_IBSS,
+	PS_MODE_WWLAN,
+	PM_Radio_Off,
+	PM_Card_Disable,
 	PS_MODE_NUM
 };
 
diff --git a/drivers/staging/rtl8712/rtl871x_sta_mgt.c b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
index 4c9b98e8210e..1752121ff494 100644
--- a/drivers/staging/rtl8712/rtl871x_sta_mgt.c
+++ b/drivers/staging/rtl8712/rtl871x_sta_mgt.c
@@ -83,9 +83,8 @@ static void mfree_all_stainfo(struct sta_priv *pstapriv)
 	spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
 	phead = &pstapriv->free_sta_queue.queue;
 	plist = phead->next;
-	while ((end_of_queue_search(phead, plist)) == false) {
+	while ((end_of_queue_search(phead, plist)) == false)
 		plist = plist->next;
-	}
 
 	spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
 }
@@ -228,7 +227,7 @@ void r8712_free_all_stainfo(struct _adapter *padapter)
 					      struct sta_info, hash_list);
 			plist = plist->next;
 			if (pbcmc_stainfo != psta)
-				r8712_free_stainfo(padapter , psta);
+				r8712_free_stainfo(padapter, psta);
 		}
 	}
 	spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c
index 62a377e7fdc7..a28af03c9d8a 100644
--- a/drivers/staging/rtl8712/rtl871x_xmit.c
+++ b/drivers/staging/rtl8712/rtl871x_xmit.c
@@ -471,7 +471,7 @@ static sint xmitframe_swencrypt(struct _adapter *padapter,
 	return _SUCCESS;
 }
 
-static sint make_wlanhdr(struct _adapter *padapter , u8 *hdr,
+static sint make_wlanhdr(struct _adapter *padapter, u8 *hdr,
 			 struct pkt_attrib *pattrib)
 {
 	u16 *qc;
diff --git a/drivers/staging/rtl8712/sta_info.h b/drivers/staging/rtl8712/sta_info.h
index c4e0ef2f52c6..742dfa0ca817 100644
--- a/drivers/staging/rtl8712/sta_info.h
+++ b/drivers/staging/rtl8712/sta_info.h
@@ -135,7 +135,7 @@ u32 _r8712_init_sta_priv(struct sta_priv *pstapriv);
 u32 _r8712_free_sta_priv(struct sta_priv *pstapriv);
 struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv,
 				     u8 *hwaddr);
-void r8712_free_stainfo(struct _adapter *padapter , struct sta_info *psta);
+void r8712_free_stainfo(struct _adapter *padapter, struct sta_info *psta);
 void r8712_free_all_stainfo(struct _adapter *padapter);
 struct sta_info *r8712_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr);
 void r8712_init_bcmc_stainfo(struct _adapter *padapter);
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
index 7d0d1719b136..f8b5b332e7c3 100644
--- a/drivers/staging/rtl8712/usb_intf.c
+++ b/drivers/staging/rtl8712/usb_intf.c
@@ -366,7 +366,6 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
 	struct net_device *pnetdev;
 	struct usb_device *udev;
 
-	printk(KERN_INFO "r8712u: Staging version\n");
 	/* In this probe function, O.S. will provide the usb interface pointer
 	 * to driver. We have to increase the reference count of the usb device
 	 * structure by using the usb_get_dev function.
@@ -463,7 +462,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
 				/* Use the mac address stored in the Efuse
 				 * offset = 0x12 for usb in efuse
 				 */
-				memcpy(mac, &pdata[0x12], ETH_ALEN);
+				ether_addr_copy(mac, &pdata[0x12]);
 			}
 			eeprom_CustomerID = pdata[0x52];
 			switch (eeprom_CustomerID) {
@@ -580,7 +579,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
 		} else
 			dev_info(&udev->dev,
 				"r8712u: MAC Address from efuse = %pM\n", mac);
-		memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
+		ether_addr_copy(pnetdev->dev_addr, mac);
 	}
 	/* step 6. Load the firmware asynchronously */
 	if (rtl871x_load_fw(padapter))
diff --git a/drivers/staging/rtl8723au/core/rtw_ap.c b/drivers/staging/rtl8723au/core/rtw_ap.c
index e394d12c36b0..c6327c072918 100644
--- a/drivers/staging/rtl8723au/core/rtw_ap.c
+++ b/drivers/staging/rtl8723au/core/rtw_ap.c
@@ -456,8 +456,8 @@ static void update_bmc_sta(struct rtw_adapter *padapter)
 		       sizeof(struct stainfo_stats));
 
 		/* prepare for add_RATid23a */
-		supportRateNum = rtw_get_rateset_len23a((u8*)&pcur_network->SupportedRates);
-		network_type = rtw_check_network_type23a((u8*)&pcur_network->SupportedRates, supportRateNum, 1);
+		supportRateNum = rtw_get_rateset_len23a((u8 *)&pcur_network->SupportedRates);
+		network_type = rtw_check_network_type23a((u8 *)&pcur_network->SupportedRates, supportRateNum, 1);
 
 		memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
 		psta->bssratelen = supportRateNum;
@@ -897,7 +897,7 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter,
 	pairwise_cipher = 0;
 	psecuritypriv->wpa_group_cipher = 0;
 	psecuritypriv->wpa_pairwise_cipher = 0;
-	for (p = ie; ;p += (ie_len + 2)) {
+	for (p = ie; ; p += (ie_len + 2)) {
 		p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
 				  pbss_network->IELength - (ie_len + 2));
 		if ((p) && (!memcmp(p+2, RTW_WPA_OUI23A_TYPE, 4))) {
@@ -924,7 +924,7 @@ int rtw_check_beacon_data23a(struct rtw_adapter *padapter,
 	ie_len = 0;
 	pmlmepriv->qos_option = 0;
 	if (pregistrypriv->wmm_enable) {
-		for (p = ie; ;p += (ie_len + 2)) {
+		for (p = ie; ; p += (ie_len + 2)) {
 			p = rtw_get_ie23a(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len,
 					  (pbss_network->IELength -
 					   (ie_len + 2)));
@@ -1204,7 +1204,7 @@ static void update_bcn_p2p_ie(struct rtw_adapter *padapter)
 {
 }
 
-static void update_bcn_vendor_spec_ie(struct rtw_adapter *padapter, u8*oui)
+static void update_bcn_vendor_spec_ie(struct rtw_adapter *padapter, u8 *oui)
 {
 	DBG_8723A("%s\n", __func__);
 
diff --git a/drivers/staging/rtl8723au/core/rtw_cmd.c b/drivers/staging/rtl8723au/core/rtw_cmd.c
index 60e0ded8ae02..2447a56df838 100644
--- a/drivers/staging/rtl8723au/core/rtw_cmd.c
+++ b/drivers/staging/rtl8723au/core/rtw_cmd.c
@@ -245,11 +245,6 @@ exit:
 	return res;
 }
 
-void rtw_cmd_clr_isr23a(struct	cmd_priv *pcmdpriv)
-{
-	pcmdpriv->cmd_done_cnt++;
-}
-
 void rtw_free_cmd_obj23a(struct cmd_obj *pcmd)
 {
 
@@ -852,62 +847,6 @@ exit:
 	return res;
 }
 
-/*
- * This is only ever called from on_action_spct23a_ch_switch () which isn't
- * called from anywhere itself
- */
-int rtw_set_ch_cmd23a(struct rtw_adapter *padapter, u8 ch, u8 bw, u8 ch_offset,
-		      u8 enqueue)
-{
-	struct cmd_obj *pcmdobj;
-	struct set_ch_parm *set_ch_parm;
-	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
-	int res = _SUCCESS;
-
-	DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
-		  padapter->pnetdev->name, ch, bw, ch_offset);
-
-	/* check input parameter */
-
-	/* prepare cmd parameter */
-	set_ch_parm = kzalloc(sizeof(*set_ch_parm), GFP_KERNEL);
-	if (!set_ch_parm) {
-		res = _FAIL;
-		goto exit;
-	}
-	set_ch_parm->ch = ch;
-	set_ch_parm->bw = bw;
-	set_ch_parm->ch_offset = ch_offset;
-
-	if (enqueue) {
-		/* need enqueue, prepare cmd_obj and enqueue */
-		pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
-		if (!pcmdobj) {
-			kfree(set_ch_parm);
-			res = _FAIL;
-			goto exit;
-		}
-
-		init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm,
-					   GEN_CMD_CODE(_SetChannel));
-		res = rtw_enqueue_cmd23a(pcmdpriv, pcmdobj);
-	} else {
-		/* no need to enqueue, do the cmd hdl directly and
-		   free cmd parameter */
-		if (H2C_SUCCESS != set_ch_hdl23a(padapter, (u8 *)set_ch_parm))
-			res = _FAIL;
-
-		kfree(set_ch_parm);
-	}
-
-	/* do something based on res... */
-exit:
-
-	DBG_8723A("%s(%s): res:%u\n", __func__, padapter->pnetdev->name, res);
-
-	return res;
-}
-
 static void traffic_status_watchdog(struct rtw_adapter *padapter)
 {
 	u8 bEnterPS;
diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c
index 81960e788f89..a6deddc02291 100644
--- a/drivers/staging/rtl8723au/core/rtw_efuse.c
+++ b/drivers/staging/rtl8723au/core/rtw_efuse.c
@@ -327,15 +327,9 @@ EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address)
  *---------------------------------------------------------------------------*/
 
 void
-EFUSE_Write1Byte(
-	struct rtw_adapter *	Adapter,
-	u16		Address,
-	u8		Value);
+EFUSE_Write1Byte(struct rtw_adapter *Adapter, u16 Address, u8 Value);
 void
-EFUSE_Write1Byte(
-	struct rtw_adapter *	Adapter,
-	u16		Address,
-	u8		Value)
+EFUSE_Write1Byte(struct rtw_adapter *Adapter, u16 Address, u8 Value)
 {
 	u8	Bytetemp = {0x00};
 	u8	temp = {0x00};
@@ -635,10 +629,7 @@ Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, u8 *Efuse)
  *
  *---------------------------------------------------------------------------*/
 static void
-efuse_ShadowRead1Byte(
-	struct rtw_adapter *	pAdapter,
-	u16		Offset,
-	u8		*Value)
+efuse_ShadowRead1Byte(struct rtw_adapter *pAdapter, u16 Offset, u8 *Value)
 {
 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
 
@@ -647,10 +638,7 @@ efuse_ShadowRead1Byte(
 
 /* Read Two Bytes */
 static void
-efuse_ShadowRead2Byte(
-	struct rtw_adapter *	pAdapter,
-	u16		Offset,
-	u16		*Value)
+efuse_ShadowRead2Byte(struct rtw_adapter *pAdapter, u16 Offset, u16 *Value)
 {
 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
 
@@ -660,10 +648,7 @@ efuse_ShadowRead2Byte(
 
 /* Read Four Bytes */
 static void
-efuse_ShadowRead4Byte(
-	struct rtw_adapter *	pAdapter,
-	u16		Offset,
-	u32		*Value)
+efuse_ShadowRead4Byte(struct rtw_adapter *pAdapter, u16 Offset, u32 *Value)
 {
 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
 
@@ -722,11 +707,8 @@ void EFUSE_ShadowMapUpdate23a(struct rtw_adapter *pAdapter, u8 efuseType)
  *
  *---------------------------------------------------------------------------*/
 void
-EFUSE_ShadowRead23a(
-	struct rtw_adapter *	pAdapter,
-	u8		Type,
-	u16		Offset,
-	u32		*Value)
+EFUSE_ShadowRead23a(struct rtw_adapter *pAdapter,
+		    u8 Type, u16 Offset, u32 *Value)
 {
 	if (Type == 1)
 		efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
diff --git a/drivers/staging/rtl8723au/core/rtw_xmit.c b/drivers/staging/rtl8723au/core/rtw_xmit.c
index 7a5e6bf0d1ae..1c82dffcf596 100644
--- a/drivers/staging/rtl8723au/core/rtw_xmit.c
+++ b/drivers/staging/rtl8723au/core/rtw_xmit.c
@@ -2372,12 +2372,3 @@ int rtw_ack_tx_wait23a(struct xmit_priv *pxmitpriv, u32 timeout_ms)
 	return rtw_sctx_wait23a(pack_tx_ops);
 }
 
-void rtw_ack_tx_done23a(struct xmit_priv *pxmitpriv, int status)
-{
-	struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
-
-	if (pxmitpriv->ack_tx)
-		rtw23a_sctx_done_err(&pack_tx_ops, status);
-	else
-		DBG_8723A("%s ack_tx not set\n", __func__);
-}
diff --git a/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c b/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c
index 1da4eece6f9a..33777d2852f4 100644
--- a/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c
+++ b/drivers/staging/rtl8723au/hal/HalPwrSeqCmd.c
@@ -47,11 +47,11 @@ u8 HalPwrSeqCmdParsing23a(struct rtw_adapter *padapter, u8 CutVersion,
 		       u8 FabVersion, u8 InterfaceType,
 		       struct wlan_pwr_cfg PwrSeqCmd[])
 {
-	struct wlan_pwr_cfg PwrCfgCmd = { 0 };
-	u8 bPollingBit = false;
+	struct wlan_pwr_cfg PwrCfgCmd;
+	u8 bPollingBit;
 	u32 AryIdx = 0;
-	u8 value = 0;
-	u32 offset = 0;
+	u8 value;
+	u32 offset;
 	u32 pollingCount = 0;	/*  polling autoload done. */
 	u32 maxPollingCnt = 5000;
 
diff --git a/drivers/staging/rtl8723au/hal/odm.c b/drivers/staging/rtl8723au/hal/odm.c
index 1c0f106d5996..5269b46445f4 100644
--- a/drivers/staging/rtl8723au/hal/odm.c
+++ b/drivers/staging/rtl8723au/hal/odm.c
@@ -187,24 +187,13 @@ void odm23a_DynBBPSInit(struct dm_odm_t *pDM_Odm);
 
 void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm);
 
-void odm_1R_CCA23a(struct dm_odm_t *pDM_Odm);
 /* END---------BB POWER SAVE----------------------- */
 
-void odm_RefreshRateAdaptiveMask23aMP23a(struct dm_odm_t *pDM_Odm);
-
 void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm);
 
-void odm_RefreshRateAdaptiveMask23aAPADSL23a(struct dm_odm_t *pDM_Odm);
-
 void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm);
 
-void odm_RSSIMonitorInit(struct dm_odm_t *pDM_Odm);
-
-void odm_RSSIMonitorCheck23aMP(struct dm_odm_t *pDM_Odm);
-
 void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm);
-void odm_RSSIMonitorCheck23aAP(struct dm_odm_t *pDM_Odm);
-
 void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm);
 void odm_DynamicTxPower23a(struct dm_odm_t *pDM_Odm);
 
@@ -212,16 +201,12 @@ void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm);
 
 void ODM_TXPowerTrackingCheck23a(struct dm_odm_t *pDM_Odm);
 
-void odm_TXPowerTrackingCheckAP(struct dm_odm_t *pDM_Odm);
-
 void odm_RateAdaptiveMaskInit23a(struct dm_odm_t *pDM_Odm);
 
 void odm_TXPowerTrackingThermalMeterInit23a(struct dm_odm_t *pDM_Odm);
 
 void odm_TXPowerTrackingInit23a(struct dm_odm_t *pDM_Odm);
 
-void odm_TXPowerTrackingCheckMP(struct dm_odm_t *pDM_Odm);
-
 void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm);
 
 static void odm_EdcaTurboCheck23a(struct dm_odm_t *pDM_Odm);
@@ -946,47 +931,13 @@ void odm_DynamicBBPowerSaving23a(struct dm_odm_t *pDM_Odm)
 	return;
 }
 
-void odm_1R_CCA23a(struct dm_odm_t *pDM_Odm)
-{
-	struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable;
-
-	if (pDM_Odm->RSSI_Min != 0xFF) {
-		if (pDM_PSTable->PreCCAState == CCA_2R) {
-			if (pDM_Odm->RSSI_Min >= 35)
-				pDM_PSTable->CurCCAState = CCA_1R;
-			else
-				pDM_PSTable->CurCCAState = CCA_2R;
-		} else {
-			if (pDM_Odm->RSSI_Min <= 30)
-				pDM_PSTable->CurCCAState = CCA_2R;
-			else
-				pDM_PSTable->CurCCAState = CCA_1R;
-		}
-	} else {
-		pDM_PSTable->CurCCAState = CCA_MAX;
-	}
-
-	if (pDM_PSTable->PreCCAState != pDM_PSTable->CurCCAState) {
-		if (pDM_PSTable->CurCCAState == CCA_1R) {
-			if (pDM_Odm->RFType == ODM_2T2R)
-				ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x13);
-			else
-				ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x23);
-		} else {
-			ODM_SetBBReg(pDM_Odm, 0xc04, bMaskByte0, 0x33);
-			/* PHY_SetBBReg(pAdapter, 0xe70, bMaskByte3, 0x63); */
-		}
-		pDM_PSTable->PreCCAState = pDM_PSTable->CurCCAState;
-	}
-}
-
 void ODM_RF_Saving23a(struct dm_odm_t *pDM_Odm, u8 bForceInNormal)
 {
 	struct dynamic_pwr_sav *pDM_PSTable = &pDM_Odm->DM_PSTable;
-	u8 Rssi_Up_bound = 30 ;
+	u8 Rssi_Up_bound = 30;
 	u8 Rssi_Low_bound = 25;
 	if (pDM_Odm->PatchID == 40) { /* RT_CID_819x_FUNAI_TV */
-		Rssi_Up_bound = 50 ;
+		Rssi_Up_bound = 50;
 		Rssi_Low_bound = 45;
 	}
 	if (pDM_PSTable->initialize == 0) {
@@ -1177,10 +1128,6 @@ void odm_RefreshRateAdaptiveMask23a(struct dm_odm_t *pDM_Odm)
 	odm_RefreshRateAdaptiveMask23aCE23a(pDM_Odm);
 }
 
-void odm_RefreshRateAdaptiveMask23aMP23a(struct dm_odm_t *pDM_Odm)
-{
-}
-
 void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm)
 {
 	u8 i;
@@ -1216,10 +1163,6 @@ void odm_RefreshRateAdaptiveMask23aCE23a(struct dm_odm_t *pDM_Odm)
 
 }
 
-void odm_RefreshRateAdaptiveMask23aAPADSL23a(struct dm_odm_t *pDM_Odm)
-{
-}
-
 /*  Return Value: bool */
 /*  - true: RATRState is changed. */
 bool ODM_RAStateCheck23a(struct dm_odm_t *pDM_Odm, s32 RSSI, bool bForceUpdate,
@@ -1284,14 +1227,6 @@ void odm_DynamicTxPower23aInit(struct dm_odm_t *pDM_Odm)
 	pdmpriv->DynamicTxHighPowerLvl = TxHighPwrLevel_Normal;
 }
 
-/* 3 ============================================================ */
-/* 3 RSSI Monitor */
-/* 3 ============================================================ */
-
-void odm_RSSIMonitorInit(struct dm_odm_t *pDM_Odm)
-{
-}
-
 void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm)
 {
 	/*  For AP/ADSL use struct rtl8723a_priv * */
@@ -1306,10 +1241,6 @@ void odm_RSSIMonitorCheck23a(struct dm_odm_t *pDM_Odm)
 	odm_RSSIMonitorCheck23aCE(pDM_Odm);
 }	/*  odm_RSSIMonitorCheck23a */
 
-void odm_RSSIMonitorCheck23aMP(struct dm_odm_t *pDM_Odm)
-{
-}
-
 static void
 FindMinimumRSSI(
 	struct rtw_adapter *pAdapter
@@ -1378,10 +1309,6 @@ void odm_RSSIMonitorCheck23aCE(struct dm_odm_t *pDM_Odm)
 	ODM_CmnInfoUpdate23a(&pHalData->odmpriv, ODM_CMNINFO_RSSI_MIN, pdmpriv->MinUndecoratedPWDBForDM);
 }
 
-void odm_RSSIMonitorCheck23aAP(struct dm_odm_t *pDM_Odm)
-{
-}
-
 /* endif */
 /* 3 ============================================================ */
 /* 3 Tx Power Tracking */
@@ -1422,19 +1349,12 @@ void odm_TXPowerTrackingCheckCE23a(struct dm_odm_t *pDM_Odm)
 {
 }
 
-void odm_TXPowerTrackingCheckMP(struct dm_odm_t *pDM_Odm)
-{
-}
-
-void odm_TXPowerTrackingCheckAP(struct dm_odm_t *pDM_Odm)
-{
-}
-
 /* EDCA Turbo */
 static void ODM_EdcaTurboInit23a(struct dm_odm_t *pDM_Odm)
 {
 
 	struct rtw_adapter *Adapter = pDM_Odm->Adapter;
+
 	pDM_Odm->DM_EDCA_Table.bCurrentTurboEDCA = false;
 	pDM_Odm->DM_EDCA_Table.bIsCurRDLState = false;
 	Adapter->recvpriv.bIsAnyNonBEPkts = false;
@@ -1591,6 +1511,7 @@ ConvertTo_dB23a(
 void ODM_SingleDualAntennaDefaultSetting(struct dm_odm_t *pDM_Odm)
 {
 	struct sw_ant_sw *pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
+
 	pDM_SWAT_Table->ANTA_ON = true;
 	pDM_SWAT_Table->ANTB_ON = true;
 }
diff --git a/drivers/staging/rtl8723au/hal/odm_HWConfig.c b/drivers/staging/rtl8723au/hal/odm_HWConfig.c
index fb3cc872f205..33aafa01f900 100644
--- a/drivers/staging/rtl8723au/hal/odm_HWConfig.c
+++ b/drivers/staging/rtl8723au/hal/odm_HWConfig.c
@@ -113,7 +113,7 @@ static void odm_RxPhyStatus92CSeries_Parsing(struct dm_odm_t *pDM_Odm,
 
 		cck_highpwr = pDM_Odm->bCckHighPower;
 
-		cck_agc_rpt =  pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a ;
+		cck_agc_rpt =  pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a;
 
 		/* The RSSI formula should be modified according to the gain table */
 		if (!cck_highpwr) {
@@ -138,16 +138,16 @@ static void odm_RxPhyStatus92CSeries_Parsing(struct dm_odm_t *pDM_Odm,
 			report = (cck_agc_rpt & 0x60)>>5;
 			switch (report) {
 			case 0x3:
-				rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f)<<1) ;
+				rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f)<<1);
 				break;
 			case 0x2:
 				rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f)<<1);
 				break;
 			case 0x1:
-				rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f)<<1) ;
+				rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f)<<1);
 				break;
 			case 0x0:
-				rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f)<<1) ;
+				rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f)<<1);
 				break;
 			}
 		}
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
index 86a83975f4f0..73cfddd6df9a 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_bt-coexist.c
@@ -7255,63 +7255,19 @@ btdm_2AntTdmaDurationAdjust(struct rtw_adapter *padapter, u8 bScoHid,
 		RTPRINT(FBT, BT_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n"));
 		if (bScoHid) {
 			if (bTxPause) {
-				if (maxInterval == 1) {
-					btdm_2AntPsTdma(padapter, true, 15);
-					pBtdm8723->psTdmaDuAdjType = 15;
-				} else if (maxInterval == 2) {
-					btdm_2AntPsTdma(padapter, true, 15);
-					pBtdm8723->psTdmaDuAdjType = 15;
-				} else if (maxInterval == 3) {
-					btdm_2AntPsTdma(padapter, true, 15);
-					pBtdm8723->psTdmaDuAdjType = 15;
-				} else {
-					btdm_2AntPsTdma(padapter, true, 15);
-					pBtdm8723->psTdmaDuAdjType = 15;
-				}
+				btdm_2AntPsTdma(padapter, true, 15);
+				pBtdm8723->psTdmaDuAdjType = 15;
 			} else {
-				if (maxInterval == 1) {
-					btdm_2AntPsTdma(padapter, true, 11);
-					pBtdm8723->psTdmaDuAdjType = 11;
-				} else if (maxInterval == 2) {
-					btdm_2AntPsTdma(padapter, true, 11);
-					pBtdm8723->psTdmaDuAdjType = 11;
-				} else if (maxInterval == 3) {
-					btdm_2AntPsTdma(padapter, true, 11);
-					pBtdm8723->psTdmaDuAdjType = 11;
-				} else {
-					btdm_2AntPsTdma(padapter, true, 11);
-					pBtdm8723->psTdmaDuAdjType = 11;
-				}
+				btdm_2AntPsTdma(padapter, true, 11);
+				pBtdm8723->psTdmaDuAdjType = 11;
 			}
 		} else {
 			if (bTxPause) {
-				if (maxInterval == 1) {
-					btdm_2AntPsTdma(padapter, true, 7);
-					pBtdm8723->psTdmaDuAdjType = 7;
-				} else if (maxInterval == 2) {
-					btdm_2AntPsTdma(padapter, true, 7);
-					pBtdm8723->psTdmaDuAdjType = 7;
-				} else if (maxInterval == 3) {
-					btdm_2AntPsTdma(padapter, true, 7);
-					pBtdm8723->psTdmaDuAdjType = 7;
-				} else {
-					btdm_2AntPsTdma(padapter, true, 7);
-					pBtdm8723->psTdmaDuAdjType = 7;
-				}
+				btdm_2AntPsTdma(padapter, true, 7);
+				pBtdm8723->psTdmaDuAdjType = 7;
 			} else {
-				if (maxInterval == 1) {
-					btdm_2AntPsTdma(padapter, true, 3);
-					pBtdm8723->psTdmaDuAdjType = 3;
-				} else if (maxInterval == 2) {
-					btdm_2AntPsTdma(padapter, true, 3);
-					pBtdm8723->psTdmaDuAdjType = 3;
-				} else if (maxInterval == 3) {
-					btdm_2AntPsTdma(padapter, true, 3);
-					pBtdm8723->psTdmaDuAdjType = 3;
-				} else {
-					btdm_2AntPsTdma(padapter, true, 3);
-					pBtdm8723->psTdmaDuAdjType = 3;
-				}
+				btdm_2AntPsTdma(padapter, true, 3);
+				pBtdm8723->psTdmaDuAdjType = 3;
 			}
 		}
 		up = 0;
@@ -9145,7 +9101,7 @@ u32 BTDM_BtTxRxCounterL(struct rtw_adapter *padapter)
 	u32	counters = 0;
 
 	counters = pHalData->bt_coexist.halCoex8723.lowPriorityTx+
-		pHalData->bt_coexist.halCoex8723.lowPriorityRx ;
+		pHalData->bt_coexist.halCoex8723.lowPriorityRx;
 	return counters;
 }
 
diff --git a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
index 88e91cd8ebb9..19dc5e3b2e2e 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723a_phycfg.c
@@ -698,7 +698,7 @@ storePwrIndexDiffRateOffset(struct rtw_adapter *Adapter, u32 RegAddr,
  * 11/10/2008	tynli	Modify to mew files.
  *---------------------------------------------------------------------------*/
 static	int
-phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter, u8 ConfigType)
+phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter)
 {
 	int i;
 	u32 *Rtl819XPHY_REGArray_Table_PG;
@@ -707,17 +707,15 @@ phy_ConfigBBWithPgHeaderFile(struct rtw_adapter *Adapter, u8 ConfigType)
 	PHY_REGArrayPGLen = Rtl8723_PHY_REG_Array_PGLength;
 	Rtl819XPHY_REGArray_Table_PG = (u32 *)Rtl8723_PHY_REG_Array_PG;
 
-	if (ConfigType == BaseBand_Config_PHY_REG) {
-		for (i = 0; i < PHY_REGArrayPGLen; i = i + 3) {
-			storePwrIndexDiffRateOffset(Adapter,
-				Rtl819XPHY_REGArray_Table_PG[i],
-				Rtl819XPHY_REGArray_Table_PG[i+1],
-				Rtl819XPHY_REGArray_Table_PG[i+2]);
-		}
+	for (i = 0; i < PHY_REGArrayPGLen; i = i + 3) {
+		storePwrIndexDiffRateOffset(Adapter,
+					    Rtl819XPHY_REGArray_Table_PG[i],
+					    Rtl819XPHY_REGArray_Table_PG[i+1],
+					    Rtl819XPHY_REGArray_Table_PG[i+2]);
 	}
 
 	return _SUCCESS;
-}	/* phy_ConfigBBWithPgHeaderFile */
+}
 
 static void
 phy_BB8192C_Config_1T(struct rtw_adapter *Adapter)
@@ -768,8 +766,7 @@ phy_BB8723a_Config_ParaFile(struct rtw_adapter *Adapter)
 	if (pEEPROM->bautoload_fail_flag == false) {
 		pHalData->pwrGroupCnt = 0;
 
-		rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter,
-							BaseBand_Config_PHY_REG);
+		rtStatus = phy_ConfigBBWithPgHeaderFile(Adapter);
 	}
 
 	if (rtStatus != _SUCCESS)
@@ -923,9 +920,6 @@ _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter)
 	u8 regBwOpMode;
 	u8 regRRSR_RSC;
 
-	if (pHalData->rf_chip == RF_PSEUDO_11N)
-		return;
-
 	/*  There is no 40MHz mode in RF_8225. */
 	if (pHalData->rf_chip == RF_8225)
 		return;
@@ -1021,10 +1015,6 @@ _PHY_SetBWMode23a92C(struct rtw_adapter *Adapter)
 		/*  PHY_SetRF8258Bandwidth(); */
 		break;
 
-	case RF_PSEUDO_11N:
-		/*  Do Nothing */
-		break;
-
 	case RF_6052:
 		rtl8723a_phy_rf6052set_bw(Adapter, pHalData->CurrentChannelBW);
 		break;
@@ -1074,7 +1064,7 @@ PHY_SetBWMode23a8723A(struct rtw_adapter *Adapter,
 
 static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
 {
-	u8 eRFPath;
+	enum RF_RADIO_PATH eRFPath;
 	u32 param1, param2;
 	struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 
@@ -1088,7 +1078,7 @@ static void _PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
 	for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) {
 		pHalData->RfRegChnlVal[eRFPath] =
 			(pHalData->RfRegChnlVal[eRFPath] & 0xfffffc00) | param2;
-		PHY_SetRFReg(Adapter, (enum RF_RADIO_PATH)eRFPath, param1,
+		PHY_SetRFReg(Adapter, eRFPath, param1,
 			     bRFRegOffsetMask, pHalData->RfRegChnlVal[eRFPath]);
 	}
 
@@ -1101,11 +1091,6 @@ void PHY_SwChnl8723A(struct rtw_adapter *Adapter, u8 channel)
 	u8 tmpchannel = pHalData->CurrentChannel;
 	bool  result = true;
 
-	if (pHalData->rf_chip == RF_PSEUDO_11N) {
-		/* return immediately if it is peudo-phy */
-		return;
-	}
-
 	if (channel == 0)
 		channel = 1;
 
diff --git a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
index 6070510bb470..1759487329ab 100644
--- a/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
+++ b/drivers/staging/rtl8723au/hal/rtl8723au_xmit.c
@@ -79,7 +79,7 @@ static void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxd
 	}
 }
 
-static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
+static void fill_txdesc_vcs(struct pkt_attrib *pattrib, __le32 *pdw)
 {
 	/* DBG_8723A("cvs_mode =%d\n", pattrib->vcs_mode); */
 
@@ -114,7 +114,7 @@ static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
 	}
 }
 
-static void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
+static void fill_txdesc_phy(struct pkt_attrib *pattrib, __le32 *pdw)
 {
 	if (pattrib->ht_en) {
 		*pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0;
diff --git a/drivers/staging/rtl8723au/hal/usb_halinit.c b/drivers/staging/rtl8723au/hal/usb_halinit.c
index febe5cedef8f..adbf1c2dd383 100644
--- a/drivers/staging/rtl8723au/hal/usb_halinit.c
+++ b/drivers/staging/rtl8723au/hal/usb_halinit.c
@@ -625,10 +625,10 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter)
 	}
 
 	/* reducing 80M spur */
-	PHY_SetBBReg(Adapter, RF_T_METER, bMaskDWord, 0x0381808d);
-	PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83);
-	PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff82);
-	PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83);
+	PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, bMaskDWord, 0x0381808d);
+	PHY_SetBBReg(Adapter, REG_AFE_PLL_CTRL, bMaskDWord, 0xf0ffff83);
+	PHY_SetBBReg(Adapter, REG_AFE_PLL_CTRL, bMaskDWord, 0xf0ffff82);
+	PHY_SetBBReg(Adapter, REG_AFE_PLL_CTRL, bMaskDWord, 0xf0ffff83);
 
 	/* RFSW Control */
 	PHY_SetBBReg(Adapter, rFPGA0_TxInfo, bMaskDWord, 0x00000003);	/* 0x804[14]= 0 */
@@ -640,8 +640,10 @@ int rtl8723au_hal_init(struct rtw_adapter *Adapter)
 	/*  */
 	/*  Joseph Note: Keep RfRegChnlVal for later use. */
 	/*  */
-	pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)0, RF_CHNLBW, bRFRegOffsetMask);
-	pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)1, RF_CHNLBW, bRFRegOffsetMask);
+	pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, RF_PATH_A,
+						   RF_CHNLBW, bRFRegOffsetMask);
+	pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, RF_PATH_B,
+						   RF_CHNLBW, bRFRegOffsetMask);
 
 	if (!mac_on) {
 		_InitQueueReservedPage(Adapter);
diff --git a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
index 688f20412bca..2247d9874719 100644
--- a/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
+++ b/drivers/staging/rtl8723au/include/Hal8723APhyCfg.h
@@ -17,46 +17,9 @@
 #define __INC_HAL8723PHYCFG_H__
 
 /*--------------------------Define Parameters-------------------------------*/
-#define LOOP_LIMIT				5
-#define MAX_STALL_TIME		50		/* us */
-#define AntennaDiversityValue	0x80
-#define MAX_TXPWR_IDX_NMODE_92S	63
-#define Reset_Cnt_Limit		3
-
-
 #define MAX_AGGR_NUM	0x0909
 
-/*--------------------------Define Parameters-------------------------------*/
-
-
 /*------------------------------Define structure----------------------------*/
-enum swchnlcmdid {
-	CmdID_End,
-	CmdID_SetTxPowerLevel,
-	CmdID_BBRegWrite10,
-	CmdID_WritePortUlong,
-	CmdID_WritePortUshort,
-	CmdID_WritePortUchar,
-	CmdID_RF_WriteReg,
-};
-
-
-/* 1. Switch channel related */
-struct swchnlcmd {
-	enum swchnlcmdid	CmdID;
-	u32			Para1;
-	u32			Para2;
-	u32			msDelay;
-};
-
-enum HW90_BLOCK {
-	HW90_BLOCK_MAC = 0,
-	HW90_BLOCK_PHY0 = 1,
-	HW90_BLOCK_PHY1 = 2,
-	HW90_BLOCK_RF = 3,
-	HW90_BLOCK_MAXIMUM = 4, /*  Never use this */
-};
-
 enum RF_RADIO_PATH {
 	RF_PATH_A = 0,			/* Radio Path A */
 	RF_PATH_B = 1,			/* Radio Path B */
@@ -64,7 +27,6 @@ enum RF_RADIO_PATH {
 };
 
 #define CHANNEL_MAX_NUMBER		14	/*  14 is the max channel number */
-#define CHANNEL_GROUP_MAX		3	/*  ch1~3, ch4~9, ch10~14 total three groups */
 
 enum WIRELESS_MODE {
 	WIRELESS_MODE_UNKNOWN	= 0x00,
@@ -77,22 +39,6 @@ enum WIRELESS_MODE {
 	WIRELESS_MODE_AC	= BIT(6)
 };
 
-enum baseband_config_type {
-	BaseBand_Config_PHY_REG = 0,			/* Radio Path A */
-	BaseBand_Config_AGC_TAB = 1,			/* Radio Path B */
-};
-
-enum ra_offset_area {
-	RA_OFFSET_LEGACY_OFDM1,
-	RA_OFFSET_LEGACY_OFDM2,
-	RA_OFFSET_HT_OFDM1,
-	RA_OFFSET_HT_OFDM2,
-	RA_OFFSET_HT_OFDM3,
-	RA_OFFSET_HT_OFDM4,
-	RA_OFFSET_HT_CCK,
-};
-
-
 /* BB/RF related */
 enum rf_type_8190p {
 	RF_TYPE_MIN,		/*  0 */
@@ -100,7 +46,6 @@ enum rf_type_8190p {
 	RF_8256 = 2,		/*  2 11b/g/n */
 	RF_8258 = 3,		/*  3 11a/b/g/n RF */
 	RF_6052 = 4,		/*  4 11b/g/n RF */
-	RF_PSEUDO_11N = 5,	/*  5, It is a temporality RF. */
 };
 
 struct bb_reg_define {
diff --git a/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h b/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h
index 4a1f58f2982c..3771d6bb5774 100644
--- a/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h
+++ b/drivers/staging/rtl8723au/include/Hal8723PwrSeq.h
@@ -39,10 +39,10 @@
  * { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value },  comments here
  */
 #define RTL8723A_TRANS_CARDEMU_TO_ACT														\
-	{0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \
-	{0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/	\
-	{0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/   \
-	{0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), 0}, /*0x00[5] = 1b'0 release analog Ips to digital , 1:isolation*/   \
+	{0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \
+	{0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/	\
+	{0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/   \
+	{0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), 0}, /*0x00[5] = 1b'0 release analog Ips to digital , 1:isolation*/   \
 	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0},/* disable SW LPS 0x04[10]= 0*/	\
 	{0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)},/* wait till 0x04[17] = 1    power ready*/	\
 	{0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)},/* release WLON reset  0x04[16]= 1*/ \
@@ -57,48 +57,28 @@
 	{0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/*0x4C[23] = 0x4E[7] = 0, switch DPDT_SEL_P output from register 0x65[2] */\
 	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, /*0x04[9] = 1 turn off MAC by HW state machine*/	\
 	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/	\
-	{0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)}, /*0x00[5] = 1b'1 analog Ips to digital , 1:isolation*/   \
-	{0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/   \
+	{0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)}, /*0x00[5] = 1b'1 analog Ips to digital , 1:isolation*/   \
+	{0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/   \
 
 
 #define RTL8723A_TRANS_CARDEMU_TO_SUS													\
-	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), (BIT(4)|BIT(3))}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/	\
-	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/	\
-	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/   \
-	{0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/   \
-	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/	\
-	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*Set SDIO suspend local register*/	\
-	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/
+	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/
 
 #define RTL8723A_TRANS_SUS_TO_CARDEMU													\
 	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, /*clear suspend enable and power down enable*/	\
-	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/	\
-	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, /*wait power state to suspend*/\
-	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/   \
 	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/
 
 #define RTL8723A_TRANS_CARDEMU_TO_CARDDIS													\
-	{0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07 = 0x20 , SOP option to disable BG/MB*/	\
-	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/	\
-	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, /*0x04[10] = 1, enable SW LPS*/	\
-	{0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 1}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/   \
-	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/   \
-	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*Set SDIO suspend local register*/	\
-	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0}, /*wait power state to suspend*/
+	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)}, /*0x04[12:11] = 2b'01 enable WL suspend*/	\
+	{0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/
 
 #define RTL8723A_TRANS_CARDDIS_TO_CARDEMU													\
 	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, /*clear suspend enable and power down enable*/	\
-	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, /*Set SDIO suspend local register*/	\
-	{0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, /*wait power state to suspend*/\
 	{0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/   \
-	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/\
-	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/   \
-	{0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/
-
+	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, /*0x04[12:11] = 2b'01enable WL suspend*/
 
 #define RTL8723A_TRANS_CARDEMU_TO_PDN												\
-	{0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), BIT(4)}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/   \
-	{0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/   \
+	{0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/   \
 	{0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0},/* 0x04[16] = 0*/\
 	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)},/* 0x04[15] = 1*/
 
@@ -106,7 +86,6 @@
 	{0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0},/* 0x04[15] = 0*/
 
 #define RTL8723A_TRANS_ACT_TO_LPS														\
-	{0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/	\
 	{0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/	\
 	{0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/	\
 	{0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/	\
@@ -117,13 +96,10 @@
 	{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*Whole BB is reset*/	\
 	{0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/	\
 	{0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0},/*check if removed later*/	\
-	{0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/	\
 	{0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)},/*Respond TxOK to scheduler*/
 
 #define RTL8723A_TRANS_LPS_TO_ACT															\
-	{0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\
 	{0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\
-	{0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\
 	{0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\
 	{0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, /*.	0x08[4] = 0		 switch TSF to 40M*/\
 	{0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, /*Polling 0x109[7]= 0  TSF in 40M*/\
diff --git a/drivers/staging/rtl8723au/include/osdep_intf.h b/drivers/staging/rtl8723au/include/osdep_intf.h
index 33afa62f31b1..a157eb2e78df 100644
--- a/drivers/staging/rtl8723au/include/osdep_intf.h
+++ b/drivers/staging/rtl8723au/include/osdep_intf.h
@@ -19,9 +19,6 @@
 #include <osdep_service.h>
 #include <drv_types.h>
 
-int rtw_hw_suspend23a(struct rtw_adapter *padapter);
-int rtw_hw_resume23a(struct rtw_adapter *padapter);
-
 int rtw_init_drv_sw23a(struct rtw_adapter *padapter);
 int rtw_free_drv_sw23a(struct rtw_adapter *padapter);
 int rtw_reset_drv_sw23a(struct rtw_adapter *padapter);
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h b/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h
index 05069652bae1..7add5dfe015f 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_bt-coexist.h
@@ -31,8 +31,8 @@ enum rt_media_status {
 
 void BT_SignalCompensation(struct rtw_adapter *padapter,
 			   u8 *rssi_wifi, u8 *rssi_bt);
-void BT_HaltProcess(struct rtw_adapter * padapter);
-void BT_LpsLeave(struct rtw_adapter * padapter);
+void BT_HaltProcess(struct rtw_adapter *padapter);
+void BT_LpsLeave(struct rtw_adapter *padapter);
 
 
 #define	BT_HsConnectionEstablished(Adapter)		false
@@ -1092,17 +1092,20 @@ enum hci_ext_bp_operation {
 	BTHCI_StateMachine(_Adapter, _StateToEnter, _StateCmd, _EntryNum);\
 }
 
-void BTHCI_EventParse(struct rtw_adapter * padapter, void *pEvntData, u32 dataLen);
+void BTHCI_EventParse(struct rtw_adapter *padapter, void *pEvntData,
+		      u32 dataLen);
 #define BT_EventParse BTHCI_EventParse
-u8 BTHCI_HsConnectionEstablished(struct rtw_adapter * padapter);
-void BTHCI_UpdateBTProfileRTKToMoto(struct rtw_adapter * padapter);
-void BTHCI_WifiScanNotify(struct rtw_adapter * padapter, u8 scanType);
-void BTHCI_StateMachine(struct rtw_adapter * padapter, u8 StateToEnter, enum hci_state_with_cmd StateCmd, u8 EntryNum);
-void BTHCI_DisconnectPeer(struct rtw_adapter * padapter, u8 EntryNum);
-void BTHCI_EventNumOfCompletedDataBlocks(struct rtw_adapter * padapter);
-void BTHCI_EventAMPStatusChange(struct rtw_adapter * padapter, u8 AMP_Status);
-void BTHCI_DisconnectAll(struct rtw_adapter * padapter);
-enum hci_status BTHCI_HandleHCICMD(struct rtw_adapter * padapter, struct packet_irp_hcicmd_data *pHciCmd);
+u8 BTHCI_HsConnectionEstablished(struct rtw_adapter *padapter);
+void BTHCI_UpdateBTProfileRTKToMoto(struct rtw_adapter *padapter);
+void BTHCI_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType);
+void BTHCI_StateMachine(struct rtw_adapter *padapter, u8 StateToEnter,
+			enum hci_state_with_cmd StateCmd, u8 EntryNum);
+void BTHCI_DisconnectPeer(struct rtw_adapter *padapter, u8 EntryNum);
+void BTHCI_EventNumOfCompletedDataBlocks(struct rtw_adapter *padapter);
+void BTHCI_EventAMPStatusChange(struct rtw_adapter *padapter, u8 AMP_Status);
+void BTHCI_DisconnectAll(struct rtw_adapter *padapter);
+enum hci_status BTHCI_HandleHCICMD(struct rtw_adapter *padapter,
+				   struct packet_irp_hcicmd_data *pHciCmd);
 
 /*  ===== End of sync from SD7 driver COMMON/bt_hci.h ===== */
 
@@ -1157,9 +1160,10 @@ struct btdm_8723a_1ant {
 	u8		bRAChanged;
 };
 
-void BTDM_1AntSignalCompensation(struct rtw_adapter * padapter, u8 *rssi_wifi, u8 *rssi_bt);
-void BTDM_1AntForDhcp(struct rtw_adapter * padapter);
-void BTDM_1AntBtCoexist8723A(struct rtw_adapter * padapter);
+void BTDM_1AntSignalCompensation(struct rtw_adapter *padapter,
+				 u8 *rssi_wifi, u8 *rssi_bt);
+void BTDM_1AntForDhcp(struct rtw_adapter *padapter);
+void BTDM_1AntBtCoexist8723A(struct rtw_adapter *padapter);
 
 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.h ===== */
 
@@ -1241,7 +1245,7 @@ struct btdm_8723a_2ant {
 	u8	btStatus;
 };
 
-void BTDM_2AntBtCoexist8723A(struct rtw_adapter * padapter);
+void BTDM_2AntBtCoexist8723A(struct rtw_adapter *padapter);
 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.h ===== */
 
 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc8723.h ===== */
@@ -1310,15 +1314,17 @@ struct bt_coexist_8723a {
 	struct btdm_8723a_1ant			btdm1Ant;
 };
 
-void BTDM_SetFwChnlInfo(struct rtw_adapter * padapter, enum rt_media_status mstatus);
-u8 BTDM_IsWifiConnectionExist(struct rtw_adapter * padapter);
-void BTDM_SetFw3a(struct rtw_adapter * padapter, u8 byte1, u8 byte2, u8 byte3, u8 byte4, u8 byte5);
-void BTDM_QueryBtInformation(struct rtw_adapter * padapter);
-void BTDM_SetSwRfRxLpfCorner(struct rtw_adapter * padapter, u8 type);
-void BTDM_SetSwPenaltyTxRateAdaptive(struct rtw_adapter * padapter, u8 raType);
-void BTDM_SetFwDecBtPwr(struct rtw_adapter * padapter, u8 bDecBtPwr);
-u8 BTDM_BtProfileSupport(struct rtw_adapter * padapter);
-void BTDM_LpsLeave(struct rtw_adapter * padapter);
+void BTDM_SetFwChnlInfo(struct rtw_adapter *padapter,
+			enum rt_media_status mstatus);
+u8 BTDM_IsWifiConnectionExist(struct rtw_adapter *padapter);
+void BTDM_SetFw3a(struct rtw_adapter *padapter, u8 byte1, u8 byte2, u8 byte3,
+		  u8 byte4, u8 byte5);
+void BTDM_QueryBtInformation(struct rtw_adapter *padapter);
+void BTDM_SetSwRfRxLpfCorner(struct rtw_adapter *padapter, u8 type);
+void BTDM_SetSwPenaltyTxRateAdaptive(struct rtw_adapter *padapter, u8 raType);
+void BTDM_SetFwDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr);
+u8 BTDM_BtProfileSupport(struct rtw_adapter *padapter);
+void BTDM_LpsLeave(struct rtw_adapter *padapter);
 
 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc8723.h ===== */
 
@@ -1340,8 +1346,9 @@ enum BT_A2DP_INDEX{
 #define BTDM_ANT_BT						2
 
 
-void BTDM_SingleAnt(struct rtw_adapter * padapter, u8 bSingleAntOn, u8 bInterruptOn, u8 bMultiNAVOn);
-void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter * padapter);
+void BTDM_SingleAnt(struct rtw_adapter *padapter, u8 bSingleAntOn,
+		    u8 bInterruptOn, u8 bMultiNAVOn);
+void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter *padapter);
 
 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.h ===== */
 
@@ -1361,7 +1368,8 @@ void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter * padapter);
 #define	BT_DACSWING_M7				2
 #define	BT_DACSWING_M10				3
 
-void BTDM_DiminishWiFi(struct rtw_adapter * Adapter, u8 bDACOn, u8 bInterruptOn, u8 DACSwingLevel, u8 bNAVOn);
+void BTDM_DiminishWiFi(struct rtw_adapter *Adapter, u8 bDACOn, u8 bInterruptOn,
+		       u8 DACSwingLevel, u8 bNAVOn);
 
 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.h ===== */
 
@@ -1534,58 +1542,63 @@ struct bt_coexist_str {
 	u8			fw3aVal[5];
 };
 
-void BTDM_CheckAntSelMode(struct rtw_adapter * padapter);
-void BTDM_FwC2hBtRssi(struct rtw_adapter * padapter, u8 *tmpBuf);
+void BTDM_CheckAntSelMode(struct rtw_adapter *padapter);
+void BTDM_FwC2hBtRssi(struct rtw_adapter *padapter, u8 *tmpBuf);
 #define BT_FwC2hBtRssi BTDM_FwC2hBtRssi
-void BTDM_DisplayBtCoexInfo(struct rtw_adapter * padapter);
+void BTDM_DisplayBtCoexInfo(struct rtw_adapter *padapter);
 #define BT_DisplayBtCoexInfo BTDM_DisplayBtCoexInfo
-void BTDM_RejectAPAggregatedPacket(struct rtw_adapter * padapter, u8 bReject);
-u8 BTDM_IsHT40(struct rtw_adapter * padapter);
-u8 BTDM_Legacy(struct rtw_adapter * padapter);
-void BTDM_CheckWiFiState(struct rtw_adapter * padapter);
-s32 BTDM_GetRxSS(struct rtw_adapter * padapter);
-u8 BTDM_CheckCoexBcnRssiState(struct rtw_adapter * padapter, u8 levelNum, u8 RssiThresh, u8 RssiThresh1);
-u8 BTDM_CheckCoexRSSIState1(struct rtw_adapter * padapter, u8 levelNum, u8 RssiThresh, u8 RssiThresh1);
-u8 BTDM_CheckCoexRSSIState(struct rtw_adapter * padapter, u8 levelNum, u8 RssiThresh, u8 RssiThresh1);
-void BTDM_Balance(struct rtw_adapter * padapter, u8 bBalanceOn, u8 ms0, u8 ms1);
-void BTDM_AGCTable(struct rtw_adapter * padapter, u8 type);
-void BTDM_BBBackOffLevel(struct rtw_adapter * padapter, u8 type);
-void BTDM_FWCoexAllOff(struct rtw_adapter * padapter);
-void BTDM_SWCoexAllOff(struct rtw_adapter * padapter);
-void BTDM_HWCoexAllOff(struct rtw_adapter * padapter);
-void BTDM_CoexAllOff(struct rtw_adapter * padapter);
-void BTDM_TurnOffBtCoexistBeforeEnterIPS(struct rtw_adapter * padapter);
-void BTDM_SignalCompensation(struct rtw_adapter * padapter, u8 *rssi_wifi, u8 *rssi_bt);
-void BTDM_UpdateCoexState(struct rtw_adapter * padapter);
-u8 BTDM_IsSameCoexistState(struct rtw_adapter * padapter);
-void BTDM_PWDBMonitor(struct rtw_adapter * padapter);
-u8 BTDM_IsBTBusy(struct rtw_adapter * padapter);
+void BTDM_RejectAPAggregatedPacket(struct rtw_adapter *padapter, u8 bReject);
+u8 BTDM_IsHT40(struct rtw_adapter *padapter);
+u8 BTDM_Legacy(struct rtw_adapter *padapter);
+void BTDM_CheckWiFiState(struct rtw_adapter *padapter);
+s32 BTDM_GetRxSS(struct rtw_adapter *padapter);
+u8 BTDM_CheckCoexBcnRssiState(struct rtw_adapter *padapter, u8 levelNum,
+			      u8 RssiThresh, u8 RssiThresh1);
+u8 BTDM_CheckCoexRSSIState1(struct rtw_adapter *padapter, u8 levelNum,
+			    u8 RssiThresh, u8 RssiThresh1);
+u8 BTDM_CheckCoexRSSIState(struct rtw_adapter *padapter, u8 levelNum,
+			   u8 RssiThresh, u8 RssiThresh1);
+void BTDM_Balance(struct rtw_adapter *padapter, u8 bBalanceOn, u8 ms0, u8 ms1);
+void BTDM_AGCTable(struct rtw_adapter *padapter, u8 type);
+void BTDM_BBBackOffLevel(struct rtw_adapter *padapter, u8 type);
+void BTDM_FWCoexAllOff(struct rtw_adapter *padapter);
+void BTDM_SWCoexAllOff(struct rtw_adapter *padapter);
+void BTDM_HWCoexAllOff(struct rtw_adapter *padapter);
+void BTDM_CoexAllOff(struct rtw_adapter *padapter);
+void BTDM_TurnOffBtCoexistBeforeEnterIPS(struct rtw_adapter *padapter);
+void BTDM_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi,
+			     u8 *rssi_bt);
+void BTDM_UpdateCoexState(struct rtw_adapter *padapter);
+u8 BTDM_IsSameCoexistState(struct rtw_adapter *padapter);
+void BTDM_PWDBMonitor(struct rtw_adapter *padapter);
+u8 BTDM_IsBTBusy(struct rtw_adapter *padapter);
 #define BT_IsBtBusy BTDM_IsBTBusy
-u8 BTDM_IsWifiBusy(struct rtw_adapter * padapter);
-u8 BTDM_IsCoexistStateChanged(struct rtw_adapter * padapter);
-u8 BTDM_IsWifiUplink(struct rtw_adapter * padapter);
-u8 BTDM_IsWifiDownlink(struct rtw_adapter * padapter);
-u8 BTDM_IsBTHSMode(struct rtw_adapter * padapter);
-u8 BTDM_IsBTUplink(struct rtw_adapter * padapter);
-u8 BTDM_IsBTDownlink(struct rtw_adapter * padapter);
-void BTDM_AdjustForBtOperation(struct rtw_adapter * padapter);
-void BTDM_ForHalt(struct rtw_adapter * padapter);
-void BTDM_WifiScanNotify(struct rtw_adapter * padapter, u8 scanType);
-void BTDM_WifiAssociateNotify(struct rtw_adapter * padapter, u8 action);
-void BTDM_MediaStatusNotify(struct rtw_adapter * padapter, enum rt_media_status mstatus);
-void BTDM_ForDhcp(struct rtw_adapter * padapter);
-void BTDM_ResetActionProfileState(struct rtw_adapter * padapter);
-void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter * padapter, u8 antNum);
+u8 BTDM_IsWifiBusy(struct rtw_adapter *padapter);
+u8 BTDM_IsCoexistStateChanged(struct rtw_adapter *padapter);
+u8 BTDM_IsWifiUplink(struct rtw_adapter *padapter);
+u8 BTDM_IsWifiDownlink(struct rtw_adapter *padapter);
+u8 BTDM_IsBTHSMode(struct rtw_adapter *padapter);
+u8 BTDM_IsBTUplink(struct rtw_adapter *padapter);
+u8 BTDM_IsBTDownlink(struct rtw_adapter *padapter);
+void BTDM_AdjustForBtOperation(struct rtw_adapter *padapter);
+void BTDM_ForHalt(struct rtw_adapter *padapter);
+void BTDM_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType);
+void BTDM_WifiAssociateNotify(struct rtw_adapter *padapter, u8 action);
+void BTDM_MediaStatusNotify(struct rtw_adapter *padapter,
+			    enum rt_media_status mstatus);
+void BTDM_ForDhcp(struct rtw_adapter *padapter);
+void BTDM_ResetActionProfileState(struct rtw_adapter *padapter);
+void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum);
 #define BT_SetBtCoexCurrAntNum BTDM_SetBtCoexCurrAntNum
-u8 BTDM_IsActionSCO(struct rtw_adapter * padapter);
-u8 BTDM_IsActionHID(struct rtw_adapter * padapter);
-u8 BTDM_IsActionA2DP(struct rtw_adapter * padapter);
-u8 BTDM_IsActionPAN(struct rtw_adapter * padapter);
-u8 BTDM_IsActionHIDA2DP(struct rtw_adapter * padapter);
-u8 BTDM_IsActionHIDPAN(struct rtw_adapter * padapter);
-u8 BTDM_IsActionPANA2DP(struct rtw_adapter * padapter);
-u32 BTDM_BtTxRxCounterH(struct rtw_adapter * padapter);
-u32 BTDM_BtTxRxCounterL(struct rtw_adapter * padapter);
+u8 BTDM_IsActionSCO(struct rtw_adapter *padapter);
+u8 BTDM_IsActionHID(struct rtw_adapter *padapter);
+u8 BTDM_IsActionA2DP(struct rtw_adapter *padapter);
+u8 BTDM_IsActionPAN(struct rtw_adapter *padapter);
+u8 BTDM_IsActionHIDA2DP(struct rtw_adapter *padapter);
+u8 BTDM_IsActionHIDPAN(struct rtw_adapter *padapter);
+u8 BTDM_IsActionPANA2DP(struct rtw_adapter *padapter);
+u32 BTDM_BtTxRxCounterH(struct rtw_adapter *padapter);
+u32 BTDM_BtTxRxCounterL(struct rtw_adapter *padapter);
 
 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtCoexist.h ===== */
 
@@ -1593,14 +1606,14 @@ u32 BTDM_BtTxRxCounterL(struct rtw_adapter * padapter);
 
 #define RTS_CTS_NO_LEN_LIMIT	0
 
-u8 HALBT_GetPGAntNum(struct rtw_adapter * padapter);
+u8 HALBT_GetPGAntNum(struct rtw_adapter *padapter);
 #define BT_GetPGAntNum HALBT_GetPGAntNum
-void HALBT_SetKey(struct rtw_adapter * padapter, u8 EntryNum);
-void HALBT_RemoveKey(struct rtw_adapter * padapter, u8 EntryNum);
-u8 HALBT_IsBTExist(struct rtw_adapter * padapter);
+void HALBT_SetKey(struct rtw_adapter *padapter, u8 EntryNum);
+void HALBT_RemoveKey(struct rtw_adapter *padapter, u8 EntryNum);
+u8 HALBT_IsBTExist(struct rtw_adapter *padapter);
 #define BT_IsBtExist HALBT_IsBTExist
-u8 HALBT_BTChipType(struct rtw_adapter * padapter);
-void HALBT_SetRtsCtsNoLenLimit(struct rtw_adapter * padapter);
+u8 HALBT_BTChipType(struct rtw_adapter *padapter);
+void HALBT_SetRtsCtsNoLenLimit(struct rtw_adapter *padapter);
 
 /*  ===== End of sync from SD7 driver HAL/HalBT.c ===== */
 
diff --git a/drivers/staging/rtl8723au/include/rtl8723a_recv.h b/drivers/staging/rtl8723au/include/rtl8723a_recv.h
index 0177bbc1c1cf..875d37b3b94c 100644
--- a/drivers/staging/rtl8723au/include/rtl8723a_recv.h
+++ b/drivers/staging/rtl8723au/include/rtl8723a_recv.h
@@ -56,8 +56,8 @@ struct interrupt_msg_format {
 	unsigned int  MSG_EX;
 };
 
-int rtl8723au_init_recv_priv(struct rtw_adapter * padapter);
-void rtl8723au_free_recv_priv(struct rtw_adapter * padapter);
+int rtl8723au_init_recv_priv(struct rtw_adapter *padapter);
+void rtl8723au_free_recv_priv(struct rtw_adapter *padapter);
 void rtl8723a_process_phy_info(struct rtw_adapter *padapter, void *prframe);
 void update_recvframe_attrib(struct recv_frame *precvframe, struct recv_stat *prxstat);
 void update_recvframe_phyinfo(struct recv_frame *precvframe, struct phy_stat *pphy_info);
diff --git a/drivers/staging/rtl8723au/include/rtw_cmd.h b/drivers/staging/rtl8723au/include/rtw_cmd.h
index 71044107d13b..775dcdc1e7b9 100644
--- a/drivers/staging/rtl8723au/include/rtw_cmd.h
+++ b/drivers/staging/rtl8723au/include/rtw_cmd.h
@@ -99,7 +99,6 @@ int rtw_init_cmd_priv23a(struct cmd_priv *pcmdpriv);
 
 u32 rtw_init_evt_priv23a (struct evt_priv *pevtpriv);
 void rtw_free_evt_priv23a (struct evt_priv *pevtpriv);
-void rtw_cmd_clr_isr23a(struct cmd_priv *pcmdpriv);
 void rtw_evt_notify_isr(struct evt_priv *pevtpriv);
 
 enum rtw_drvextra_cmd_id
@@ -689,10 +688,10 @@ int rtw_disassoc_cmd23a(struct rtw_adapter *padapter, u32 deauth_timeout_ms, boo
 int rtw_setopmode_cmd23a(struct rtw_adapter *padapter, enum nl80211_iftype ifmode);
 int rtw_setdatarate_cmd(struct rtw_adapter  *padapter, u8 *rateset);
 int rtw_setbasicrate_cmd(struct rtw_adapter  *padapter, u8 *rateset);
-int rtw_setbbreg_cmd(struct rtw_adapter * padapter, u8 offset, u8 val);
-int rtw_setrfreg_cmd(struct rtw_adapter * padapter, u8 offset, u32 val);
-int rtw_getbbreg_cmd(struct rtw_adapter * padapter, u8 offset, u8 * pval);
-int rtw_getrfreg_cmd(struct rtw_adapter * padapter, u8 offset, u8 * pval);
+int rtw_setbbreg_cmd(struct rtw_adapter *padapter, u8 offset, u8 val);
+int rtw_setrfreg_cmd(struct rtw_adapter *padapter, u8 offset, u32 val);
+int rtw_getbbreg_cmd(struct rtw_adapter *padapter, u8 offset, u8 *pval);
+int rtw_getrfreg_cmd(struct rtw_adapter *padapter, u8 offset, u8 *pval);
 int rtw_setrfintfs_cmd(struct rtw_adapter  *padapter, u8 mode);
 int rtw_setrttbl_cmd(struct rtw_adapter  *padapter, struct setratable_parm *prate_table);
 int rtw_getrttbl_cmd(struct rtw_adapter  *padapter, struct getratable_rsp *pval);
@@ -713,7 +712,6 @@ int rtw_ps_cmd23a(struct rtw_adapter*padapter);
 int rtw_chk_hi_queue_cmd23a(struct rtw_adapter*padapter);
 #endif
 
-int rtw_set_ch_cmd23a(struct rtw_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue);
 int rtw_set_chplan_cmd(struct rtw_adapter*padapter, u8 chplan, u8 enqueue);
 int rtw_led_blink_cmd(struct rtw_adapter*padapter, struct led_8723a *pLed);
 int rtw_set_csa_cmd(struct rtw_adapter*padapter, u8 new_ch_no);
diff --git a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
index 51dba1fa4c5d..ffb37b252fc1 100644
--- a/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
+++ b/drivers/staging/rtl8723au/include/rtw_mlme_ext.h
@@ -509,7 +509,7 @@ int rtw_check_bcn_info23a(struct rtw_adapter *Adapter,
 			  struct ieee80211_mgmt *mgmt, u32 packet_len);
 void update_IOT_info23a(struct rtw_adapter *padapter);
 void update_capinfo23a(struct rtw_adapter *Adapter, u16 updateCap);
-void update_wireless_mode23a(struct rtw_adapter * padapter);
+void update_wireless_mode23a(struct rtw_adapter *padapter);
 void update_tx_basic_rate23a(struct rtw_adapter *padapter, u8 modulation);
 void update_bmc_sta_support_rate23a(struct rtw_adapter *padapter, u32 mac_id);
 int update_sta_support_rate23a(struct rtw_adapter *padapter, u8 *pvar_ie,
diff --git a/drivers/staging/rtl8723au/include/wifi.h b/drivers/staging/rtl8723au/include/wifi.h
index fd3da3b5cf31..25d573c3e232 100644
--- a/drivers/staging/rtl8723au/include/wifi.h
+++ b/drivers/staging/rtl8723au/include/wifi.h
@@ -26,9 +26,9 @@
 ------------------------------------------------------------------------------*/
 
 struct AC_param {
-	unsigned char		ACI_AIFSN;
-	unsigned char		CW;
-	unsigned short	TXOP_limit;
+	u8			ACI_AIFSN;
+	u8			CW;
+	__le16			TXOP_limit;
 }  __packed;
 
 struct WMM_para_element {
@@ -38,10 +38,10 @@ struct WMM_para_element {
 }  __packed;
 
 struct ADDBA_request {
-	unsigned char		dialog_token;
-	unsigned short	BA_para_set;
-	unsigned short	BA_timeout_value;
-	unsigned short	BA_starting_seqctrl;
+	u8		dialog_token;
+	__le16		BA_para_set;
+	__le16		BA_timeout_value;
+	__le16		BA_starting_seqctrl;
 }  __packed;
 
 
diff --git a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
index c5800ae71fcf..537bd8214efe 100644
--- a/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
+++ b/drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
@@ -1468,9 +1468,8 @@ static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv,
 		return 0;
 	}
 
-	if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) {
+	if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
 		psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
-	}
 
 /*
 	if (wpa_version & NL80211_WPA_VERSION_2)
diff --git a/drivers/staging/rtl8723au/os_dep/os_intfs.c b/drivers/staging/rtl8723au/os_dep/os_intfs.c
index 9966d16342b3..1b23eb13222b 100644
--- a/drivers/staging/rtl8723au/os_dep/os_intfs.c
+++ b/drivers/staging/rtl8723au/os_dep/os_intfs.c
@@ -91,7 +91,7 @@ static int rtw_bt_iso = 2;/*  0:Low, 1:High, 2:From Efuse */
 /*  0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, 5.OtherBusy */
 static int rtw_bt_sco = 3;
 /*  0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
-static int rtw_bt_ampdu = 1 ;
+static int rtw_bt_ampdu = 1;
 #endif
 
 /*  0:Reject AP's Add BA req, 1:Accept AP's Add BA req. */
diff --git a/drivers/staging/rtl8723au/os_dep/usb_intf.c b/drivers/staging/rtl8723au/os_dep/usb_intf.c
index 373a617ace54..05755b870a5f 100644
--- a/drivers/staging/rtl8723au/os_dep/usb_intf.c
+++ b/drivers/staging/rtl8723au/os_dep/usb_intf.c
@@ -80,11 +80,9 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
 	struct usb_config_descriptor *pconf_desc;
 	struct usb_host_interface *phost_iface;
 	struct usb_interface_descriptor *piface_desc;
-	struct usb_host_endpoint *phost_endp;
 	struct usb_endpoint_descriptor *pendp_desc;
-	struct usb_device		 *pusbd;
-	int	i;
-	int	status = _FAIL;
+	struct usb_device *pusbd;
+	int i, status = _FAIL;
 
 	pdvobjpriv = kzalloc(sizeof(*pdvobjpriv), GFP_KERNEL);
 	if (!pdvobjpriv)
@@ -114,42 +112,38 @@ static struct dvobj_priv *usb_dvobj_init(struct usb_interface *usb_intf)
 	pdvobjpriv->nr_endpoint = piface_desc->bNumEndpoints;
 
 	for (i = 0; i < pdvobjpriv->nr_endpoint; i++) {
-		phost_endp = phost_iface->endpoint + i;
-		if (phost_endp) {
-			pendp_desc = &phost_endp->desc;
-
-			DBG_8723A("\nusb_endpoint_descriptor(%d):\n", i);
-			DBG_8723A("bLength =%x\n", pendp_desc->bLength);
-			DBG_8723A("bDescriptorType =%x\n",
-				  pendp_desc->bDescriptorType);
-			DBG_8723A("bEndpointAddress =%x\n",
-				  pendp_desc->bEndpointAddress);
-			DBG_8723A("wMaxPacketSize =%d\n",
-				  le16_to_cpu(pendp_desc->wMaxPacketSize));
-			DBG_8723A("bInterval =%x\n", pendp_desc->bInterval);
-
-			if (usb_endpoint_is_bulk_in(pendp_desc)) {
-				DBG_8723A("usb_endpoint_is_bulk_in = %x\n",
-					  usb_endpoint_num(pendp_desc));
-				pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
-					usb_endpoint_num(pendp_desc);
-				pdvobjpriv->RtNumInPipes++;
-			} else if (usb_endpoint_is_int_in(pendp_desc)) {
-				DBG_8723A("usb_endpoint_is_int_in = %x, Interval = %x\n",
-					  usb_endpoint_num(pendp_desc),
-					  pendp_desc->bInterval);
-				pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
-					usb_endpoint_num(pendp_desc);
-				pdvobjpriv->RtNumInPipes++;
-			} else if (usb_endpoint_is_bulk_out(pendp_desc)) {
-				DBG_8723A("usb_endpoint_is_bulk_out = %x\n",
-					  usb_endpoint_num(pendp_desc));
-				pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] =
-					usb_endpoint_num(pendp_desc);
-				pdvobjpriv->RtNumOutPipes++;
-			}
-			pdvobjpriv->ep_num[i] = usb_endpoint_num(pendp_desc);
+		pendp_desc = &phost_iface->endpoint[i].desc;
+
+		DBG_8723A("\nusb_endpoint_descriptor(%d):\n", i);
+		DBG_8723A("bLength =%x\n", pendp_desc->bLength);
+		DBG_8723A("bDescriptorType =%x\n", pendp_desc->bDescriptorType);
+		DBG_8723A("bEndpointAddress =%x\n",
+			  pendp_desc->bEndpointAddress);
+		DBG_8723A("wMaxPacketSize =%d\n",
+			  le16_to_cpu(pendp_desc->wMaxPacketSize));
+		DBG_8723A("bInterval =%x\n", pendp_desc->bInterval);
+
+		if (usb_endpoint_is_bulk_in(pendp_desc)) {
+			DBG_8723A("usb_endpoint_is_bulk_in = %x\n",
+				  usb_endpoint_num(pendp_desc));
+			pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
+				usb_endpoint_num(pendp_desc);
+			pdvobjpriv->RtNumInPipes++;
+		} else if (usb_endpoint_is_int_in(pendp_desc)) {
+			DBG_8723A("usb_endpoint_is_int_in = %x, Interval = "
+				  "%x\n", usb_endpoint_num(pendp_desc),
+				  pendp_desc->bInterval);
+			pdvobjpriv->RtInPipe[pdvobjpriv->RtNumInPipes] =
+				usb_endpoint_num(pendp_desc);
+			pdvobjpriv->RtNumInPipes++;
+		} else if (usb_endpoint_is_bulk_out(pendp_desc)) {
+			DBG_8723A("usb_endpoint_is_bulk_out = %x\n",
+				  usb_endpoint_num(pendp_desc));
+			pdvobjpriv->RtOutPipe[pdvobjpriv->RtNumOutPipes] =
+				usb_endpoint_num(pendp_desc);
+			pdvobjpriv->RtNumOutPipes++;
 		}
+		pdvobjpriv->ep_num[i] = usb_endpoint_num(pendp_desc);
 	}
 	DBG_8723A("nr_endpoint =%d, in_num =%d, out_num =%d\n\n",
 		  pdvobjpriv->nr_endpoint, pdvobjpriv->RtNumInPipes,
@@ -273,104 +267,6 @@ static void rtw_dev_unload(struct rtw_adapter *padapter)
 	RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("-rtw_dev_unload\n"));
 }
 
-int rtw_hw_suspend23a(struct rtw_adapter *padapter)
-{
-	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-	struct net_device *pnetdev = padapter->pnetdev;
-	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
-	if ((!padapter->bup) || (padapter->bDriverStopped) ||
-	    (padapter->bSurpriseRemoved)) {
-		DBG_8723A("padapter->bup =%d bDriverStopped =%d bSurpriseRemoved = %d\n",
-			  padapter->bup, padapter->bDriverStopped,
-			  padapter->bSurpriseRemoved);
-		goto error_exit;
-	}
-
-	if (padapter) { /* system suspend */
-		LeaveAllPowerSaveMode23a(padapter);
-
-		DBG_8723A("==> rtw_hw_suspend23a\n");
-		down(&pwrpriv->lock);
-		pwrpriv->bips_processing = true;
-		/* padapter->net_closed = true; */
-		/* s1. */
-		if (pnetdev) {
-			netif_carrier_off(pnetdev);
-			netif_tx_stop_all_queues(pnetdev);
-		}
-
-		/* s2. */
-		rtw_disassoc_cmd23a(padapter, 500, false);
-
-		/* s2-2.  indicate disconnect to os */
-		/* rtw_indicate_disconnect23a(padapter); */
-		if (check_fwstate(pmlmepriv, _FW_LINKED)) {
-			_clr_fwstate_(pmlmepriv, _FW_LINKED);
-
-			rtw_os_indicate_disconnect23a(padapter);
-
-			/* donnot enqueue cmd */
-			rtw_lps_ctrl_wk_cmd23a(padapter,
-					       LPS_CTRL_DISCONNECT, 0);
-		}
-		/* s2-3. */
-		rtw_free_assoc_resources23a(padapter, 1);
-
-		/* s2-4. */
-		rtw_free_network_queue23a(padapter);
-		rtw_ips_dev_unload23a(padapter);
-		pwrpriv->rf_pwrstate = rf_off;
-		pwrpriv->bips_processing = false;
-		up(&pwrpriv->lock);
-	} else {
-		goto error_exit;
-	}
-	return 0;
-error_exit:
-	DBG_8723A("%s, failed\n", __func__);
-	return -1;
-}
-
-int rtw_hw_resume23a(struct rtw_adapter *padapter)
-{
-	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
-	struct net_device *pnetdev = padapter->pnetdev;
-
-	if (padapter) { /* system resume */
-		DBG_8723A("==> rtw_hw_resume23a\n");
-		down(&pwrpriv->lock);
-		pwrpriv->bips_processing = true;
-		rtw_reset_drv_sw23a(padapter);
-
-		if (pm_netdev_open23a(pnetdev, false)) {
-			up(&pwrpriv->lock);
-			goto error_exit;
-		}
-
-		netif_device_attach(pnetdev);
-		netif_carrier_on(pnetdev);
-
-		if (!rtw_netif_queue_stopped(pnetdev))
-			netif_tx_start_all_queues(pnetdev);
-		else
-			netif_tx_wake_all_queues(pnetdev);
-
-		pwrpriv->bkeepfwalive = false;
-
-		pwrpriv->rf_pwrstate = rf_on;
-		pwrpriv->bips_processing = false;
-
-		up(&pwrpriv->lock);
-	} else {
-		goto error_exit;
-	}
-	return 0;
-error_exit:
-	DBG_8723A("%s, Open net dev failed\n", __func__);
-	return -1;
-}
-
 static int rtw_suspend(struct usb_interface *pusb_intf, pm_message_t message)
 {
 	struct dvobj_priv *dvobj = usb_get_intfdata(pusb_intf);
diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c
index b4612fb615f6..a47a19135d49 100644
--- a/drivers/staging/rts5208/ms.c
+++ b/drivers/staging/rts5208/ms.c
@@ -781,7 +781,7 @@ static int msxc_change_power(struct rtsx_chip *chip, u8 mode)
 	buf[4] = 0;
 	buf[5] = 0;
 
-	retval = ms_write_bytes(chip, PRO_WRITE_REG , 6, NO_WAIT_INT, buf, 6);
+	retval = ms_write_bytes(chip, PRO_WRITE_REG, 6, NO_WAIT_INT, buf, 6);
 	if (retval != STATUS_SUCCESS)
 		TRACE_RET(chip, STATUS_FAIL);
 
@@ -1291,7 +1291,7 @@ static int ms_write_extra_data(struct rtsx_chip *chip,
 	for (i = 6; i < MS_EXTRA_SIZE + 6; i++)
 		data[i] = buf[i - 6];
 
-	retval = ms_write_bytes(chip, WRITE_REG , (6+MS_EXTRA_SIZE),
+	retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE),
 				NO_WAIT_INT, data, 16);
 	if (retval != STATUS_SUCCESS)
 		TRACE_RET(chip, STATUS_FAIL);
@@ -1342,7 +1342,7 @@ static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num)
 	data[4] = 0x20;
 	data[5] = page_num;
 
-	retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6);
+	retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6);
 	if (retval != STATUS_SUCCESS)
 		TRACE_RET(chip, STATUS_FAIL);
 
@@ -1619,7 +1619,7 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
 		data[4] = 0x20;
 		data[5] = i;
 
-		retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT,
+		retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT,
 					data, 6);
 		if (retval != STATUS_SUCCESS)
 			TRACE_RET(chip, STATUS_FAIL);
@@ -1695,7 +1695,7 @@ static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk,
 		}
 
 		retval = ms_set_rw_reg_addr(chip, OverwriteFlag,
-				MS_EXTRA_SIZE, SystemParm, (6+MS_EXTRA_SIZE));
+				MS_EXTRA_SIZE, SystemParm, (6 + MS_EXTRA_SIZE));
 
 		ms_set_err_code(chip, MS_NO_ERROR);
 
@@ -1988,7 +1988,7 @@ RE_SEARCH:
 		RTSX_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88);
 		RTSX_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0);
 
-		retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG , 1,
+		retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG, 1,
 					NO_WAIT_INT);
 		if (retval != STATUS_SUCCESS)
 			TRACE_RET(chip, STATUS_FAIL);
diff --git a/drivers/staging/rts5208/rtsx_transport.c b/drivers/staging/rts5208/rtsx_transport.c
index 756a9687c293..dab1995d1a6a 100644
--- a/drivers/staging/rts5208/rtsx_transport.c
+++ b/drivers/staging/rts5208/rtsx_transport.c
@@ -271,7 +271,7 @@ int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout)
 
 	/* Wait for TRANS_OK_INT */
 	timeleft = wait_for_completion_interruptible_timeout(
-		&trans_done, timeout * HZ / 1000);
+		&trans_done, msecs_to_jiffies(timeout));
 	if (timeleft <= 0) {
 		dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
 			chip->int_reg);
@@ -431,7 +431,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
 	spin_unlock_irq(&rtsx->reg_lock);
 
 	timeleft = wait_for_completion_interruptible_timeout(
-		&trans_done, timeout * HZ / 1000);
+		&trans_done, msecs_to_jiffies(timeout));
 	if (timeleft <= 0) {
 		dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
 			__func__, __LINE__);
@@ -455,7 +455,7 @@ static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
 		init_completion(&trans_done);
 		spin_unlock_irq(&rtsx->reg_lock);
 		timeleft = wait_for_completion_interruptible_timeout(
-			&trans_done, timeout * HZ / 1000);
+			&trans_done, msecs_to_jiffies(timeout));
 		if (timeleft <= 0) {
 			dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
 				__func__, __LINE__);
@@ -575,7 +575,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
 		spin_unlock_irq(&rtsx->reg_lock);
 
 		timeleft = wait_for_completion_interruptible_timeout(
-			&trans_done, timeout * HZ / 1000);
+			&trans_done, msecs_to_jiffies(timeout));
 		if (timeleft <= 0) {
 			dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
 				__func__, __LINE__);
@@ -602,7 +602,7 @@ static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
 		init_completion(&trans_done);
 		spin_unlock_irq(&rtsx->reg_lock);
 		timeleft = wait_for_completion_interruptible_timeout(
-			&trans_done, timeout * HZ / 1000);
+			&trans_done, msecs_to_jiffies(timeout));
 		if (timeleft <= 0) {
 			dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
 				__func__, __LINE__);
@@ -688,7 +688,7 @@ static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf,
 
 	/* Wait for TRANS_OK_INT */
 	timeleft = wait_for_completion_interruptible_timeout(
-		&trans_done, timeout * HZ / 1000);
+		&trans_done, msecs_to_jiffies(timeout));
 	if (timeleft <= 0) {
 		dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
 			__func__, __LINE__);
diff --git a/drivers/staging/skein/skein_block.c b/drivers/staging/skein/skein_block.c
index 66261ab25c88..9bd69ce3be00 100644
--- a/drivers/staging/skein/skein_block.c
+++ b/drivers/staging/skein/skein_block.c
@@ -82,10 +82,7 @@ do {                                                                      \
 } while (0)
 #else
 /* looping version */
-#define R256(p0, p1, p2, p3, ROT, r_num) \
-do { \
-	ROUND256(p0, p1, p2, p3, ROT, r_num); \
-} while (0)
+#define R256(p0, p1, p2, p3, ROT, r_num) ROUND256(p0, p1, p2, p3, ROT, r_num)
 
 #define I256(R) \
 do { \
@@ -174,9 +171,7 @@ do {                                                                      \
 
 #else /* looping version */
 #define R512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num)                 \
-do {                                                                     \
-	ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num);            \
-} while (0)
+	ROUND512(p0, p1, p2, p3, p4, p5, p6, p7, ROT, r_num)             \
 
 #define I512(R)                                                           \
 do {                                                                      \
@@ -263,10 +258,8 @@ do {                                                                          \
 #if SKEIN_UNROLL_1024 == 0
 #define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
 	      ROT, rn)                                                        \
-do {                                                                          \
 	ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
-		  pF, ROT, rn);                                               \
-} while (0)
+		  pF, ROT, rn)                                                \
 
 #define I1024(R)                                                          \
 do {                                                                      \
@@ -291,10 +284,8 @@ do {                                                                      \
 #else /* looping version */
 #define R1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, pF, \
 	      ROT, rn)                                                        \
-do {                                                                          \
 	ROUND1024(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pA, pB, pC, pD, pE, \
-		  pF, ROT, rn);                                               \
-} while (0)
+		  pF, ROT, rn)                                                \
 
 #define I1024(R)                                                           \
 do {                                                                       \
diff --git a/drivers/staging/skein/skein_generic.c b/drivers/staging/skein/skein_generic.c
index 85bd7d0168b0..899078f1b8bc 100644
--- a/drivers/staging/skein/skein_generic.c
+++ b/drivers/staging/skein/skein_generic.c
@@ -191,7 +191,6 @@ static int __init skein_generic_init(void)
 
 	return 0;
 
-		
 unreg512:
 	crypto_unregister_shash(&alg512);
 unreg256:
diff --git a/drivers/staging/sm7xxfb/Kconfig b/drivers/staging/sm7xxfb/Kconfig
new file mode 100644
index 000000000000..e2922ae3a3ee
--- /dev/null
+++ b/drivers/staging/sm7xxfb/Kconfig
@@ -0,0 +1,13 @@
+config FB_SM7XX
+	tristate "Silicon Motion SM7XX framebuffer support"
+	depends on FB && PCI
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Frame buffer driver for the Silicon Motion SM710, SM712, SM721
+	  and SM722 chips.
+
+	  This driver is also available as a module. The module will be
+	  called sm7xxfb. If you want to compile it as a module, say M
+	  here and read <file:Documentation/kbuild/modules.txt>.
diff --git a/drivers/staging/sm7xxfb/Makefile b/drivers/staging/sm7xxfb/Makefile
new file mode 100644
index 000000000000..48f471cf9f36
--- /dev/null
+++ b/drivers/staging/sm7xxfb/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_FB_SM7XX) += sm7xxfb.o
diff --git a/drivers/staging/sm7xxfb/TODO b/drivers/staging/sm7xxfb/TODO
new file mode 100644
index 000000000000..7cb0b242f204
--- /dev/null
+++ b/drivers/staging/sm7xxfb/TODO
@@ -0,0 +1,12 @@
+TODO:
+- Dual head support
+- 2D acceleration support
+- use kernel coding style
+- refine the code and remove unused code
+- move it to drivers/video/fbdev/sm7xxfb.c
+
+Please send any patches to
+	Greg Kroah-Hartman <greg@kroah.com>
+	Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+	Teddy Wang <teddy.wang@siliconmotion.com>
+	Sudip Mukherjee <sudip@vectorindia.org>
diff --git a/drivers/staging/sm7xxfb/sm7xx.h b/drivers/staging/sm7xxfb/sm7xx.h
new file mode 100644
index 000000000000..7cc1896938b6
--- /dev/null
+++ b/drivers/staging/sm7xxfb/sm7xx.h
@@ -0,0 +1,779 @@
+/*
+ * Silicon Motion SM712 frame buffer device
+ *
+ * Copyright (C) 2006 Silicon Motion Technology Corp.
+ * Authors:	Ge Wang, gewang@siliconmotion.com
+ *		Boyod boyod.yang@siliconmotion.com.cn
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author: Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#define NR_PALETTE        256
+
+#define FB_ACCEL_SMI_LYNX 88
+
+#define SCREEN_X_RES      1024
+#define SCREEN_Y_RES      600
+#define SCREEN_BPP        16
+
+/*Assume SM712 graphics chip has 4MB VRAM */
+#define SM712_VIDEOMEMORYSIZE	  0x00400000
+/*Assume SM722 graphics chip has 8MB VRAM */
+#define SM722_VIDEOMEMORYSIZE	  0x00800000
+
+#define dac_reg	(0x3c8)
+#define dac_val	(0x3c9)
+
+extern void __iomem *smtc_regbaseaddress;
+#define smtc_mmiowb(dat, reg)	writeb(dat, smtc_regbaseaddress + reg)
+#define smtc_mmioww(dat, reg)	writew(dat, smtc_regbaseaddress + reg)
+#define smtc_mmiowl(dat, reg)	writel(dat, smtc_regbaseaddress + reg)
+
+#define smtc_mmiorb(reg)	readb(smtc_regbaseaddress + reg)
+#define smtc_mmiorw(reg)	readw(smtc_regbaseaddress + reg)
+#define smtc_mmiorl(reg)	readl(smtc_regbaseaddress + reg)
+
+#define SIZE_SR00_SR04      (0x04 - 0x00 + 1)
+#define SIZE_SR10_SR24      (0x24 - 0x10 + 1)
+#define SIZE_SR30_SR75      (0x75 - 0x30 + 1)
+#define SIZE_SR80_SR93      (0x93 - 0x80 + 1)
+#define SIZE_SRA0_SRAF      (0xAF - 0xA0 + 1)
+#define SIZE_GR00_GR08      (0x08 - 0x00 + 1)
+#define SIZE_AR00_AR14      (0x14 - 0x00 + 1)
+#define SIZE_CR00_CR18      (0x18 - 0x00 + 1)
+#define SIZE_CR30_CR4D      (0x4D - 0x30 + 1)
+#define SIZE_CR90_CRA7      (0xA7 - 0x90 + 1)
+#define SIZE_VPR		(0x6C + 1)
+#define SIZE_DPR		(0x44 + 1)
+
+static inline void smtc_crtcw(int reg, int val)
+{
+	smtc_mmiowb(reg, 0x3d4);
+	smtc_mmiowb(val, 0x3d5);
+}
+
+static inline unsigned int smtc_crtcr(int reg)
+{
+	smtc_mmiowb(reg, 0x3d4);
+	return smtc_mmiorb(0x3d5);
+}
+
+static inline void smtc_grphw(int reg, int val)
+{
+	smtc_mmiowb(reg, 0x3ce);
+	smtc_mmiowb(val, 0x3cf);
+}
+
+static inline unsigned int smtc_grphr(int reg)
+{
+	smtc_mmiowb(reg, 0x3ce);
+	return smtc_mmiorb(0x3cf);
+}
+
+static inline void smtc_attrw(int reg, int val)
+{
+	smtc_mmiorb(0x3da);
+	smtc_mmiowb(reg, 0x3c0);
+	smtc_mmiorb(0x3c1);
+	smtc_mmiowb(val, 0x3c0);
+}
+
+static inline void smtc_seqw(int reg, int val)
+{
+	smtc_mmiowb(reg, 0x3c4);
+	smtc_mmiowb(val, 0x3c5);
+}
+
+static inline unsigned int smtc_seqr(int reg)
+{
+	smtc_mmiowb(reg, 0x3c4);
+	return smtc_mmiorb(0x3c5);
+}
+
+/* The next structure holds all information relevant for a specific video mode.
+ */
+
+struct ModeInit {
+	int mmsizex;
+	int mmsizey;
+	int bpp;
+	int hz;
+	unsigned char init_misc;
+	unsigned char init_sr00_sr04[SIZE_SR00_SR04];
+	unsigned char init_sr10_sr24[SIZE_SR10_SR24];
+	unsigned char init_sr30_sr75[SIZE_SR30_SR75];
+	unsigned char init_sr80_sr93[SIZE_SR80_SR93];
+	unsigned char init_sra0_sraf[SIZE_SRA0_SRAF];
+	unsigned char init_gr00_gr08[SIZE_GR00_GR08];
+	unsigned char init_ar00_ar14[SIZE_AR00_AR14];
+	unsigned char init_cr00_cr18[SIZE_CR00_CR18];
+	unsigned char init_cr30_cr4d[SIZE_CR30_CR4D];
+	unsigned char init_cr90_cra7[SIZE_CR90_CRA7];
+};
+
+/**********************************************************************
+			 SM712 Mode table.
+ **********************************************************************/
+struct ModeInit vgamode[] = {
+	{
+	 /*  mode#0: 640 x 480  16Bpp  60Hz */
+	 640, 480, 16, 60,
+	 /*  Init_MISC */
+	 0xE3,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x00, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x30, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
+	  0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
+	  0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
+	  0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
+	  0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
+	  0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
+	  0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+	  0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
+	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
+	  0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
+	  0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
+	  0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
+	  0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
+	  0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
+	  },
+	 },
+	{
+	 /*  mode#1: 640 x 480  24Bpp  60Hz */
+	 640, 480, 24, 60,
+	 /*  Init_MISC */
+	 0xE3,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x00, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x30, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
+	  0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
+	  0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
+	  0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
+	  0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
+	  0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
+	  0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+	  0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
+	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
+	  0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
+	  0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
+	  0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
+	  0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
+	  0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
+	  },
+	 },
+	{
+	 /*  mode#0: 640 x 480  32Bpp  60Hz */
+	 640, 480, 32, 60,
+	 /*  Init_MISC */
+	 0xE3,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x00, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x30, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
+	  0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
+	  0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
+	  0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
+	  0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
+	  0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
+	  0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+	  0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
+	  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
+	  0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
+	  0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
+	  0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
+	  0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
+	  0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
+	  },
+	 },
+
+	{			/*  mode#2: 800 x 600  16Bpp  60Hz */
+	 800, 600, 16, 60,
+	 /*  Init_MISC */
+	 0x2B,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x03, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x30, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
+	  0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
+	  0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
+	  0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
+	  0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
+	  0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
+	  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+	  0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
+	  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
+	  0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
+	  0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
+	  0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
+	  0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
+	  0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
+	  },
+	 },
+	{			/*  mode#3: 800 x 600  24Bpp  60Hz */
+	 800, 600, 24, 60,
+	 0x2B,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x03, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x30, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36,
+	  0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36,
+	  0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
+	  0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36,
+	  0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
+	  0x02, 0x45, 0x30, 0x30, 0x40, 0x20,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36,
+	  0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+	  0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
+	  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
+	  0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
+	  0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
+	  0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
+	  0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
+	  0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
+	  },
+	 },
+	{			/*  mode#7: 800 x 600  32Bpp  60Hz */
+	 800, 600, 32, 60,
+	 /*  Init_MISC */
+	 0x2B,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x03, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x30, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
+	  0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
+	  0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
+	  0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
+	  0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
+	  0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
+	  0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
+	  0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
+	  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
+	  0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
+	  0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
+	  0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
+	  0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
+	  0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
+	  },
+	 },
+	/* We use 1024x768 table to light 1024x600 panel for lemote */
+	{			/*  mode#4: 1024 x 600  16Bpp  60Hz  */
+	 1024, 600, 16, 60,
+	 /*  Init_MISC */
+	 0xEB,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x00, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20,
+	  0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x30, 0x02, 0x00, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22,
+	  0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22,
+	  0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+	  0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22,
+	  0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02,
+	  0x04, 0x45, 0x3F, 0x30, 0x40, 0x20,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+	  0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+	  0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+	  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+	  0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+	  0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00,
+	  0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+	  0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+	  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+	  },
+	 },
+	{			/*  mode#5: 1024 x 768  24Bpp  60Hz */
+	 1024, 768, 24, 60,
+	 /*  Init_MISC */
+	 0xEB,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x03, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x30, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+	  0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+	  0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+	  0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+	  0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
+	  0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+	  0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+	  0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+	  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+	  0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+	  0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
+	  0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+	  0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+	  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+	  },
+	 },
+	{			/*  mode#4: 1024 x 768  32Bpp  60Hz */
+	 1024, 768, 32, 60,
+	 /*  Init_MISC */
+	 0xEB,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x03, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x32, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+	  0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+	  0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+	  0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+	  0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
+	  0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+	  0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+	  0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+	  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+	  0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+	  0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
+	  0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+	  0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+	  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+	  },
+	 },
+	{			/*  mode#6: 320 x 240  16Bpp  60Hz */
+	 320, 240, 16, 60,
+	 /*  Init_MISC */
+	 0xEB,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x03, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x32, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+	  0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+	  0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+	  0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+	  0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
+	  0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+	  0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+	  0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+	  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+	  0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+	  0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
+	  0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+	  0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+	  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+	  },
+	 },
+
+	{			/*  mode#8: 320 x 240  32Bpp  60Hz */
+	 320, 240, 32, 60,
+	 /*  Init_MISC */
+	 0xEB,
+	 {			/*  Init_SR0_SR4 */
+	  0x03, 0x01, 0x0F, 0x03, 0x0E,
+	  },
+	 {			/*  Init_SR10_SR24 */
+	  0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
+	  0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0xC4, 0x32, 0x02, 0x01, 0x01,
+	  },
+	 {			/*  Init_SR30_SR75 */
+	  0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
+	  0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
+	  0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
+	  0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
+	  0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
+	  0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
+	  0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
+	  0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
+	  0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
+	  },
+	 {			/*  Init_SR80_SR93 */
+	  0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
+	  0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
+	  0x00, 0x00, 0x00, 0x00,
+	  },
+	 {			/*  Init_SRA0_SRAF */
+	  0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
+	  0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
+	  },
+	 {			/*  Init_GR00_GR08 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+	  0xFF,
+	  },
+	 {			/*  Init_AR00_AR14 */
+	  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x00, 0x0F, 0x00, 0x00,
+	  },
+	 {			/*  Init_CR00_CR18 */
+	  0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
+	  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
+	  0xFF,
+	  },
+	 {			/*  Init_CR30_CR4D */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
+	  0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
+	  0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
+	  0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
+	  },
+	 {			/*  Init_CR90_CRA7 */
+	  0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
+	  0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
+	  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
+	  },
+	 },
+};
+
+#define numvgamodes		ARRAY_SIZE(vgamode)
diff --git a/drivers/staging/sm7xxfb/sm7xxfb.c b/drivers/staging/sm7xxfb/sm7xxfb.c
new file mode 100644
index 000000000000..ebd95365ffae
--- /dev/null
+++ b/drivers/staging/sm7xxfb/sm7xxfb.c
@@ -0,0 +1,1024 @@
+/*
+ * Silicon Motion SM7XX frame buffer device
+ *
+ * Copyright (C) 2006 Silicon Motion Technology Corp.
+ * Authors:  Ge Wang, gewang@siliconmotion.com
+ *	     Boyod boyod.yang@siliconmotion.com.cn
+ *
+ * Copyright (C) 2009 Lemote, Inc.
+ * Author:   Wu Zhangjin, wuzhangjin@gmail.com
+ *
+ * Copyright (C) 2011 Igalia, S.L.
+ * Author:   Javier M. Mellid <jmunhoz@igalia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Framebuffer driver for Silicon Motion SM710, SM712, SM721 and SM722 chips
+ */
+
+#include <linux/io.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/console.h>
+#include <linux/screen_info.h>
+
+#ifdef CONFIG_PM
+#include <linux/pm.h>
+#endif
+
+#include "sm7xx.h"
+
+/*
+* Private structure
+*/
+struct smtcfb_info {
+	struct pci_dev *pdev;
+	struct fb_info fb;
+	u16 chip_id;
+	u8  chip_rev_id;
+
+	void __iomem *lfb;	/* linear frame buffer */
+	void __iomem *dp_regs;	/* drawing processor control regs */
+	void __iomem *vp_regs;	/* video processor control regs */
+	void __iomem *cp_regs;	/* capture processor control regs */
+	void __iomem *mmio;	/* memory map IO port */
+
+	u_int width;
+	u_int height;
+	u_int hz;
+
+	u32 colreg[17];
+};
+
+void __iomem *smtc_regbaseaddress;	/* Memory Map IO starting address */
+
+static struct fb_var_screeninfo smtcfb_var = {
+	.xres           = 1024,
+	.yres           = 600,
+	.xres_virtual   = 1024,
+	.yres_virtual   = 600,
+	.bits_per_pixel = 16,
+	.red            = {16, 8, 0},
+	.green          = {8, 8, 0},
+	.blue           = {0, 8, 0},
+	.activate       = FB_ACTIVATE_NOW,
+	.height         = -1,
+	.width          = -1,
+	.vmode          = FB_VMODE_NONINTERLACED,
+	.nonstd         = 0,
+	.accel_flags    = FB_ACCELF_TEXT,
+};
+
+static struct fb_fix_screeninfo smtcfb_fix = {
+	.id             = "smXXXfb",
+	.type           = FB_TYPE_PACKED_PIXELS,
+	.visual         = FB_VISUAL_TRUECOLOR,
+	.line_length    = 800 * 3,
+	.accel          = FB_ACCEL_SMI_LYNX,
+	.type_aux       = 0,
+	.xpanstep       = 0,
+	.ypanstep       = 0,
+	.ywrapstep      = 0,
+};
+
+struct vesa_mode {
+	char index[6];
+	u16  lfb_width;
+	u16  lfb_height;
+	u16  lfb_depth;
+};
+
+static struct vesa_mode vesa_mode_table[] = {
+	{"0x301", 640,  480,  8},
+	{"0x303", 800,  600,  8},
+	{"0x305", 1024, 768,  8},
+	{"0x307", 1280, 1024, 8},
+
+	{"0x311", 640,  480,  16},
+	{"0x314", 800,  600,  16},
+	{"0x317", 1024, 768,  16},
+	{"0x31A", 1280, 1024, 16},
+
+	{"0x312", 640,  480,  24},
+	{"0x315", 800,  600,  24},
+	{"0x318", 1024, 768,  24},
+	{"0x31B", 1280, 1024, 24},
+};
+
+static struct screen_info smtc_scr_info;
+
+/* process command line options, get vga parameter */
+static int __init sm7xx_vga_setup(char *options)
+{
+	int i;
+
+	if (!options || !*options)
+		return -EINVAL;
+
+	smtc_scr_info.lfb_width = 0;
+	smtc_scr_info.lfb_height = 0;
+	smtc_scr_info.lfb_depth = 0;
+
+	pr_debug("sm7xx_vga_setup = %s\n", options);
+
+	for (i = 0; i < ARRAY_SIZE(vesa_mode_table); i++) {
+		if (strstr(options, vesa_mode_table[i].index)) {
+			smtc_scr_info.lfb_width  = vesa_mode_table[i].lfb_width;
+			smtc_scr_info.lfb_height =
+						vesa_mode_table[i].lfb_height;
+			smtc_scr_info.lfb_depth  = vesa_mode_table[i].lfb_depth;
+			return 0;
+		}
+	}
+
+	return -1;
+}
+__setup("vga=", sm7xx_vga_setup);
+
+static void sm712_setpalette(int regno, unsigned red, unsigned green,
+			     unsigned blue, struct fb_info *info)
+{
+	/* set bit 5:4 = 01 (write LCD RAM only) */
+	smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10);
+
+	smtc_mmiowb(regno, dac_reg);
+	smtc_mmiowb(red >> 10, dac_val);
+	smtc_mmiowb(green >> 10, dac_val);
+	smtc_mmiowb(blue >> 10, dac_val);
+}
+
+/* chan_to_field
+ *
+ * convert a colour value into a field position
+ *
+ * from pxafb.c
+ */
+
+static inline unsigned int chan_to_field(unsigned int chan,
+					 struct fb_bitfield *bf)
+{
+	chan &= 0xffff;
+	chan >>= 16 - bf->length;
+	return chan << bf->offset;
+}
+
+static int smtc_blank(int blank_mode, struct fb_info *info)
+{
+	/* clear DPMS setting */
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+		/* Screen On: HSync: On, VSync : On */
+		smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
+		smtc_seqw(0x6a, 0x16);
+		smtc_seqw(0x6b, 0x02);
+		smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
+		smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
+		smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
+		smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
+		smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
+		break;
+	case FB_BLANK_NORMAL:
+		/* Screen Off: HSync: On, VSync : On   Soft blank */
+		smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
+		smtc_seqw(0x6a, 0x16);
+		smtc_seqw(0x6b, 0x02);
+		smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
+		smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
+		smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
+		smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+		break;
+	case FB_BLANK_VSYNC_SUSPEND:
+		/* Screen On: HSync: On, VSync : Off */
+		smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
+		smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
+		smtc_seqw(0x6a, 0x0c);
+		smtc_seqw(0x6b, 0x02);
+		smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+		smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
+		smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
+		smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+		smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+		smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+		break;
+	case FB_BLANK_HSYNC_SUSPEND:
+		/* Screen On: HSync: Off, VSync : On */
+		smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
+		smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
+		smtc_seqw(0x6a, 0x0c);
+		smtc_seqw(0x6b, 0x02);
+		smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+		smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
+		smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
+		smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+		smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+		smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+		break;
+	case FB_BLANK_POWERDOWN:
+		/* Screen On: HSync: Off, VSync : Off */
+		smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
+		smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
+		smtc_seqw(0x6a, 0x0c);
+		smtc_seqw(0x6b, 0x02);
+		smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
+		smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
+		smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
+		smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
+		smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
+		smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
+			  unsigned blue, unsigned trans, struct fb_info *info)
+{
+	struct smtcfb_info *sfb;
+	u32 val;
+
+	sfb = info->par;
+
+	if (regno > 255)
+		return 1;
+
+	switch (sfb->fb.fix.visual) {
+	case FB_VISUAL_DIRECTCOLOR:
+	case FB_VISUAL_TRUECOLOR:
+		/*
+		 * 16/32 bit true-colour, use pseudo-palette for 16 base color
+		 */
+		if (regno < 16) {
+			if (sfb->fb.var.bits_per_pixel == 16) {
+				u32 *pal = sfb->fb.pseudo_palette;
+
+				val = chan_to_field(red, &sfb->fb.var.red);
+				val |= chan_to_field(green, &sfb->fb.var.green);
+				val |= chan_to_field(blue, &sfb->fb.var.blue);
+#ifdef __BIG_ENDIAN
+				pal[regno] =
+				    ((red & 0xf800) >> 8) |
+				    ((green & 0xe000) >> 13) |
+				    ((green & 0x1c00) << 3) |
+				    ((blue & 0xf800) >> 3);
+#else
+				pal[regno] = val;
+#endif
+			} else {
+				u32 *pal = sfb->fb.pseudo_palette;
+
+				val = chan_to_field(red, &sfb->fb.var.red);
+				val |= chan_to_field(green, &sfb->fb.var.green);
+				val |= chan_to_field(blue, &sfb->fb.var.blue);
+#ifdef __BIG_ENDIAN
+				val =
+				    (val & 0xff00ff00 >> 8) |
+				    (val & 0x00ff00ff << 8);
+#endif
+				pal[regno] = val;
+			}
+		}
+		break;
+
+	case FB_VISUAL_PSEUDOCOLOR:
+		/* color depth 8 bit */
+		sm712_setpalette(regno, red, green, blue, info);
+		break;
+
+	default:
+		return 1;	/* unknown type */
+	}
+
+	return 0;
+}
+
+#ifdef __BIG_ENDIAN
+static ssize_t smtcfb_read(struct fb_info *info, char __user *buf, size_t
+				count, loff_t *ppos)
+{
+	unsigned long p = *ppos;
+
+	u32 *buffer, *dst;
+	u32 __iomem *src;
+	int c, i, cnt = 0, err = 0;
+	unsigned long total_size;
+
+	if (!info || !info->screen_base)
+		return -ENODEV;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return -EPERM;
+
+	total_size = info->screen_size;
+
+	if (total_size == 0)
+		total_size = info->fix.smem_len;
+
+	if (p >= total_size)
+		return 0;
+
+	if (count >= total_size)
+		count = total_size;
+
+	if (count + p > total_size)
+		count = total_size - p;
+
+	buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	src = (u32 __iomem *) (info->screen_base + p);
+
+	if (info->fbops->fb_sync)
+		info->fbops->fb_sync(info);
+
+	while (count) {
+		c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+		dst = buffer;
+		for (i = c >> 2; i--;) {
+			*dst = fb_readl(src++);
+			*dst =
+			    (*dst & 0xff00ff00 >> 8) |
+			    (*dst & 0x00ff00ff << 8);
+			dst++;
+		}
+		if (c & 3) {
+			u8 *dst8 = (u8 *)dst;
+			u8 __iomem *src8 = (u8 __iomem *)src;
+
+			for (i = c & 3; i--;) {
+				if (i & 1) {
+					*dst8++ = fb_readb(++src8);
+				} else {
+					*dst8++ = fb_readb(--src8);
+					src8 += 2;
+				}
+			}
+			src = (u32 __iomem *)src8;
+		}
+
+		if (copy_to_user(buf, buffer, c)) {
+			err = -EFAULT;
+			break;
+		}
+		*ppos += c;
+		buf += c;
+		cnt += c;
+		count -= c;
+	}
+
+	kfree(buffer);
+
+	return (err) ? err : cnt;
+}
+
+static ssize_t
+smtcfb_write(struct fb_info *info, const char __user *buf, size_t count,
+	     loff_t *ppos)
+{
+	unsigned long p = *ppos;
+
+	u32 *buffer, *src;
+	u32 __iomem *dst;
+	int c, i, cnt = 0, err = 0;
+	unsigned long total_size;
+
+	if (!info || !info->screen_base)
+		return -ENODEV;
+
+	if (info->state != FBINFO_STATE_RUNNING)
+		return -EPERM;
+
+	total_size = info->screen_size;
+
+	if (total_size == 0)
+		total_size = info->fix.smem_len;
+
+	if (p > total_size)
+		return -EFBIG;
+
+	if (count > total_size) {
+		err = -EFBIG;
+		count = total_size;
+	}
+
+	if (count + p > total_size) {
+		if (!err)
+			err = -ENOSPC;
+
+		count = total_size - p;
+	}
+
+	buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	dst = (u32 __iomem *) (info->screen_base + p);
+
+	if (info->fbops->fb_sync)
+		info->fbops->fb_sync(info);
+
+	while (count) {
+		c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
+		src = buffer;
+
+		if (copy_from_user(src, buf, c)) {
+			err = -EFAULT;
+			break;
+		}
+
+		for (i = c >> 2; i--;) {
+			fb_writel((*src & 0xff00ff00 >> 8) |
+				  (*src & 0x00ff00ff << 8), dst++);
+			src++;
+		}
+		if (c & 3) {
+			u8 *src8 = (u8 *)src;
+			u8 __iomem *dst8 = (u8 __iomem *)dst;
+
+			for (i = c & 3; i--;) {
+				if (i & 1) {
+					fb_writeb(*src8++, ++dst8);
+				} else {
+					fb_writeb(*src8++, --dst8);
+					dst8 += 2;
+				}
+			}
+			dst = (u32 __iomem *)dst8;
+		}
+
+		*ppos += c;
+		buf += c;
+		cnt += c;
+		count -= c;
+	}
+
+	kfree(buffer);
+
+	return (cnt) ? cnt : err;
+}
+#endif	/* ! __BIG_ENDIAN */
+
+static void sm7xx_set_timing(struct smtcfb_info *sfb)
+{
+	int i = 0, j = 0;
+	u32 m_nscreenstride;
+
+	dev_dbg(&sfb->pdev->dev,
+		"sfb->width=%d sfb->height=%d sfb->fb.var.bits_per_pixel=%d sfb->hz=%d\n",
+		sfb->width, sfb->height, sfb->fb.var.bits_per_pixel, sfb->hz);
+
+	for (j = 0; j < numvgamodes; j++) {
+		if (vgamode[j].mmsizex == sfb->width &&
+		    vgamode[j].mmsizey == sfb->height &&
+		    vgamode[j].bpp == sfb->fb.var.bits_per_pixel &&
+		    vgamode[j].hz == sfb->hz) {
+			dev_dbg(&sfb->pdev->dev,
+				"vgamode[j].mmsizex=%d vgamode[j].mmSizeY=%d vgamode[j].bpp=%d vgamode[j].hz=%d\n",
+				vgamode[j].mmsizex, vgamode[j].mmsizey,
+				vgamode[j].bpp, vgamode[j].hz);
+
+			dev_dbg(&sfb->pdev->dev, "vgamode index=%d\n", j);
+
+			smtc_mmiowb(0x0, 0x3c6);
+
+			smtc_seqw(0, 0x1);
+
+			smtc_mmiowb(vgamode[j].init_misc, 0x3c2);
+
+			/* init SEQ register SR00 - SR04 */
+			for (i = 0; i < SIZE_SR00_SR04; i++)
+				smtc_seqw(i, vgamode[j].init_sr00_sr04[i]);
+
+			/* init SEQ register SR10 - SR24 */
+			for (i = 0; i < SIZE_SR10_SR24; i++)
+				smtc_seqw(i + 0x10,
+					  vgamode[j].init_sr10_sr24[i]);
+
+			/* init SEQ register SR30 - SR75 */
+			for (i = 0; i < SIZE_SR30_SR75; i++)
+				if ((i + 0x30) != 0x62 &&
+				    (i + 0x30) != 0x6a &&
+				    (i + 0x30) != 0x6b)
+					smtc_seqw(i + 0x30,
+						  vgamode[j].init_sr30_sr75[i]);
+
+			/* init SEQ register SR80 - SR93 */
+			for (i = 0; i < SIZE_SR80_SR93; i++)
+				smtc_seqw(i + 0x80,
+					  vgamode[j].init_sr80_sr93[i]);
+
+			/* init SEQ register SRA0 - SRAF */
+			for (i = 0; i < SIZE_SRA0_SRAF; i++)
+				smtc_seqw(i + 0xa0,
+					  vgamode[j].init_sra0_sraf[i]);
+
+			/* init Graphic register GR00 - GR08 */
+			for (i = 0; i < SIZE_GR00_GR08; i++)
+				smtc_grphw(i, vgamode[j].init_gr00_gr08[i]);
+
+			/* init Attribute register AR00 - AR14 */
+			for (i = 0; i < SIZE_AR00_AR14; i++)
+				smtc_attrw(i, vgamode[j].init_ar00_ar14[i]);
+
+			/* init CRTC register CR00 - CR18 */
+			for (i = 0; i < SIZE_CR00_CR18; i++)
+				smtc_crtcw(i, vgamode[j].init_cr00_cr18[i]);
+
+			/* init CRTC register CR30 - CR4D */
+			for (i = 0; i < SIZE_CR30_CR4D; i++)
+				smtc_crtcw(i + 0x30,
+					   vgamode[j].init_cr30_cr4d[i]);
+
+			/* init CRTC register CR90 - CRA7 */
+			for (i = 0; i < SIZE_CR90_CRA7; i++)
+				smtc_crtcw(i + 0x90,
+					   vgamode[j].init_cr90_cra7[i]);
+		}
+	}
+	smtc_mmiowb(0x67, 0x3c2);
+
+	/* set VPR registers */
+	writel(0x0, sfb->vp_regs + 0x0C);
+	writel(0x0, sfb->vp_regs + 0x40);
+
+	/* set data width */
+	m_nscreenstride =
+		(sfb->width * sfb->fb.var.bits_per_pixel) / 64;
+	switch (sfb->fb.var.bits_per_pixel) {
+	case 8:
+		writel(0x0, sfb->vp_regs + 0x0);
+		break;
+	case 16:
+		writel(0x00020000, sfb->vp_regs + 0x0);
+		break;
+	case 24:
+		writel(0x00040000, sfb->vp_regs + 0x0);
+		break;
+	case 32:
+		writel(0x00030000, sfb->vp_regs + 0x0);
+		break;
+	}
+	writel((u32) (((m_nscreenstride + 2) << 16) | m_nscreenstride),
+	       sfb->vp_regs + 0x10);
+}
+
+static void smtc_set_timing(struct smtcfb_info *sfb)
+{
+	switch (sfb->chip_id) {
+	case 0x710:
+	case 0x712:
+	case 0x720:
+		sm7xx_set_timing(sfb);
+		break;
+	}
+}
+
+static void smtcfb_setmode(struct smtcfb_info *sfb)
+{
+	switch (sfb->fb.var.bits_per_pixel) {
+	case 32:
+		sfb->fb.fix.visual       = FB_VISUAL_TRUECOLOR;
+		sfb->fb.fix.line_length  = sfb->fb.var.xres * 4;
+		sfb->fb.var.red.length   = 8;
+		sfb->fb.var.green.length = 8;
+		sfb->fb.var.blue.length  = 8;
+		sfb->fb.var.red.offset   = 16;
+		sfb->fb.var.green.offset = 8;
+		sfb->fb.var.blue.offset  = 0;
+		break;
+	case 24:
+		sfb->fb.fix.visual       = FB_VISUAL_TRUECOLOR;
+		sfb->fb.fix.line_length  = sfb->fb.var.xres * 3;
+		sfb->fb.var.red.length   = 8;
+		sfb->fb.var.green.length = 8;
+		sfb->fb.var.blue.length  = 8;
+		sfb->fb.var.red.offset   = 16;
+		sfb->fb.var.green.offset = 8;
+		sfb->fb.var.blue.offset  = 0;
+		break;
+	case 8:
+		sfb->fb.fix.visual       = FB_VISUAL_PSEUDOCOLOR;
+		sfb->fb.fix.line_length  = sfb->fb.var.xres;
+		sfb->fb.var.red.length   = 3;
+		sfb->fb.var.green.length = 3;
+		sfb->fb.var.blue.length  = 2;
+		sfb->fb.var.red.offset   = 5;
+		sfb->fb.var.green.offset = 2;
+		sfb->fb.var.blue.offset  = 0;
+		break;
+	case 16:
+	default:
+		sfb->fb.fix.visual       = FB_VISUAL_TRUECOLOR;
+		sfb->fb.fix.line_length  = sfb->fb.var.xres * 2;
+		sfb->fb.var.red.length   = 5;
+		sfb->fb.var.green.length = 6;
+		sfb->fb.var.blue.length  = 5;
+		sfb->fb.var.red.offset   = 11;
+		sfb->fb.var.green.offset = 5;
+		sfb->fb.var.blue.offset  = 0;
+		break;
+	}
+
+	sfb->width  = sfb->fb.var.xres;
+	sfb->height = sfb->fb.var.yres;
+	sfb->hz = 60;
+	smtc_set_timing(sfb);
+}
+
+static int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	/* sanity checks */
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+
+	/* set valid default bpp */
+	if ((var->bits_per_pixel != 8)  && (var->bits_per_pixel != 16) &&
+	    (var->bits_per_pixel != 24) && (var->bits_per_pixel != 32))
+		var->bits_per_pixel = 16;
+
+	return 0;
+}
+
+static int smtc_set_par(struct fb_info *info)
+{
+	smtcfb_setmode(info->par);
+
+	return 0;
+}
+
+static struct fb_ops smtcfb_ops = {
+	.owner        = THIS_MODULE,
+	.fb_check_var = smtc_check_var,
+	.fb_set_par   = smtc_set_par,
+	.fb_setcolreg = smtc_setcolreg,
+	.fb_blank     = smtc_blank,
+	.fb_fillrect  = cfb_fillrect,
+	.fb_imageblit = cfb_imageblit,
+	.fb_copyarea  = cfb_copyarea,
+#ifdef __BIG_ENDIAN
+	.fb_read      = smtcfb_read,
+	.fb_write     = smtcfb_write,
+#endif
+};
+
+/*
+ * alloc struct smtcfb_info and assign default values
+ */
+static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *pdev)
+{
+	struct smtcfb_info *sfb;
+
+	sfb = kzalloc(sizeof(*sfb), GFP_KERNEL);
+
+	if (!sfb)
+		return NULL;
+
+	sfb->pdev = pdev;
+
+	sfb->fb.flags          = FBINFO_FLAG_DEFAULT;
+	sfb->fb.fbops          = &smtcfb_ops;
+	sfb->fb.fix            = smtcfb_fix;
+	sfb->fb.var            = smtcfb_var;
+	sfb->fb.pseudo_palette = sfb->colreg;
+	sfb->fb.par            = sfb;
+
+	return sfb;
+}
+
+/*
+ * free struct smtcfb_info
+ */
+static void smtc_free_fb_info(struct smtcfb_info *sfb)
+{
+	kfree(sfb);
+}
+
+/*
+ * Unmap in the memory mapped IO registers
+ */
+
+static void smtc_unmap_mmio(struct smtcfb_info *sfb)
+{
+	if (sfb && smtc_regbaseaddress)
+		smtc_regbaseaddress = NULL;
+}
+
+/*
+ * Map in the screen memory
+ */
+
+static int smtc_map_smem(struct smtcfb_info *sfb,
+			 struct pci_dev *pdev, u_long smem_len)
+{
+	sfb->fb.fix.smem_start = pci_resource_start(pdev, 0);
+
+#ifdef __BIG_ENDIAN
+	if (sfb->fb.var.bits_per_pixel == 32)
+		sfb->fb.fix.smem_start += 0x800000;
+#endif
+
+	sfb->fb.fix.smem_len = smem_len;
+
+	sfb->fb.screen_base = sfb->lfb;
+
+	if (!sfb->fb.screen_base) {
+		dev_err(&pdev->dev,
+			"%s: unable to map screen memory\n", sfb->fb.fix.id);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/*
+ * Unmap in the screen memory
+ *
+ */
+static void smtc_unmap_smem(struct smtcfb_info *sfb)
+{
+	if (sfb && sfb->fb.screen_base) {
+		iounmap(sfb->fb.screen_base);
+		sfb->fb.screen_base = NULL;
+	}
+}
+
+/*
+ * We need to wake up the device and make sure its in linear memory mode.
+ */
+static inline void sm7xx_init_hw(void)
+{
+	outb_p(0x18, 0x3c4);
+	outb_p(0x11, 0x3c5);
+}
+
+static int smtcfb_pci_probe(struct pci_dev *pdev,
+			    const struct pci_device_id *ent)
+{
+	struct smtcfb_info *sfb;
+	u_long smem_size = 0x00800000;	/* default 8MB */
+	int err;
+	unsigned long mmio_base;
+
+	dev_info(&pdev->dev, "Silicon Motion display driver.");
+
+	err = pci_enable_device(pdev);	/* enable SMTC chip */
+	if (err)
+		return err;
+
+	sprintf(smtcfb_fix.id, "sm%Xfb", ent->device);
+
+	sfb = smtc_alloc_fb_info(pdev);
+
+	if (!sfb) {
+		err = -ENOMEM;
+		goto failed_free;
+	}
+
+	sfb->chip_id = ent->device;
+
+	pci_set_drvdata(pdev, sfb);
+
+	sm7xx_init_hw();
+
+	/* get mode parameter from smtc_scr_info */
+	if (smtc_scr_info.lfb_width != 0) {
+		sfb->fb.var.xres = smtc_scr_info.lfb_width;
+		sfb->fb.var.yres = smtc_scr_info.lfb_height;
+		sfb->fb.var.bits_per_pixel = smtc_scr_info.lfb_depth;
+	} else {
+		/* default resolution 1024x600 16bit mode */
+		sfb->fb.var.xres = SCREEN_X_RES;
+		sfb->fb.var.yres = SCREEN_Y_RES;
+		sfb->fb.var.bits_per_pixel = SCREEN_BPP;
+	}
+
+#ifdef __BIG_ENDIAN
+	if (sfb->fb.var.bits_per_pixel == 24)
+		sfb->fb.var.bits_per_pixel = (smtc_scr_info.lfb_depth = 32);
+#endif
+	/* Map address and memory detection */
+	mmio_base = pci_resource_start(pdev, 0);
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &sfb->chip_rev_id);
+
+	switch (sfb->chip_id) {
+	case 0x710:
+	case 0x712:
+		sfb->fb.fix.mmio_start = mmio_base + 0x00400000;
+		sfb->fb.fix.mmio_len = 0x00400000;
+		smem_size = SM712_VIDEOMEMORYSIZE;
+#ifdef __BIG_ENDIAN
+		sfb->lfb = ioremap(mmio_base, 0x00c00000);
+#else
+		sfb->lfb = ioremap(mmio_base, 0x00800000);
+#endif
+		sfb->mmio = (smtc_regbaseaddress =
+		    sfb->lfb + 0x00700000);
+		sfb->dp_regs = sfb->lfb + 0x00408000;
+		sfb->vp_regs = sfb->lfb + 0x0040c000;
+#ifdef __BIG_ENDIAN
+		if (sfb->fb.var.bits_per_pixel == 32) {
+			sfb->lfb += 0x800000;
+			dev_info(&pdev->dev, "sfb->lfb=%p", sfb->lfb);
+		}
+#endif
+		if (!smtc_regbaseaddress) {
+			dev_err(&pdev->dev,
+				"%s: unable to map memory mapped IO!",
+				sfb->fb.fix.id);
+			err = -ENOMEM;
+			goto failed_fb;
+		}
+
+		/* set MCLK = 14.31818 * (0x16 / 0x2) */
+		smtc_seqw(0x6a, 0x16);
+		smtc_seqw(0x6b, 0x02);
+		smtc_seqw(0x62, 0x3e);
+		/* enable PCI burst */
+		smtc_seqw(0x17, 0x20);
+		/* enable word swap */
+#ifdef __BIG_ENDIAN
+		if (sfb->fb.var.bits_per_pixel == 32)
+			smtc_seqw(0x17, 0x30);
+#endif
+		break;
+	case 0x720:
+		sfb->fb.fix.mmio_start = mmio_base;
+		sfb->fb.fix.mmio_len = 0x00200000;
+		smem_size = SM722_VIDEOMEMORYSIZE;
+		sfb->dp_regs = ioremap(mmio_base, 0x00a00000);
+		sfb->lfb = sfb->dp_regs + 0x00200000;
+		sfb->mmio = (smtc_regbaseaddress =
+		    sfb->dp_regs + 0x000c0000);
+		sfb->vp_regs = sfb->dp_regs + 0x800;
+
+		smtc_seqw(0x62, 0xff);
+		smtc_seqw(0x6a, 0x0d);
+		smtc_seqw(0x6b, 0x02);
+		break;
+	default:
+		dev_err(&pdev->dev,
+			"No valid Silicon Motion display chip was detected!");
+
+		goto failed_fb;
+	}
+
+	/* can support 32 bpp */
+	if (15 == sfb->fb.var.bits_per_pixel)
+		sfb->fb.var.bits_per_pixel = 16;
+
+	sfb->fb.var.xres_virtual = sfb->fb.var.xres;
+	sfb->fb.var.yres_virtual = sfb->fb.var.yres;
+	err = smtc_map_smem(sfb, pdev, smem_size);
+	if (err)
+		goto failed;
+
+	smtcfb_setmode(sfb);
+
+	err = register_framebuffer(&sfb->fb);
+	if (err < 0)
+		goto failed;
+
+	dev_info(&pdev->dev,
+		 "Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.",
+		 sfb->chip_id, sfb->chip_rev_id, sfb->fb.var.xres,
+		 sfb->fb.var.yres, sfb->fb.var.bits_per_pixel);
+
+	return 0;
+
+failed:
+	dev_err(&pdev->dev, "Silicon Motion, Inc. primary display init fail.");
+
+	smtc_unmap_smem(sfb);
+	smtc_unmap_mmio(sfb);
+failed_fb:
+	smtc_free_fb_info(sfb);
+
+failed_free:
+	pci_disable_device(pdev);
+
+	return err;
+}
+
+/*
+ * 0x710 (LynxEM)
+ * 0x712 (LynxEM+)
+ * 0x720 (Lynx3DM, Lynx3DM+)
+ */
+static const struct pci_device_id smtcfb_pci_table[] = {
+	{ PCI_DEVICE(0x126f, 0x710), },
+	{ PCI_DEVICE(0x126f, 0x712), },
+	{ PCI_DEVICE(0x126f, 0x720), },
+	{0,}
+};
+
+static void smtcfb_pci_remove(struct pci_dev *pdev)
+{
+	struct smtcfb_info *sfb;
+
+	sfb = pci_get_drvdata(pdev);
+	smtc_unmap_smem(sfb);
+	smtc_unmap_mmio(sfb);
+	unregister_framebuffer(&sfb->fb);
+	smtc_free_fb_info(sfb);
+}
+
+#ifdef CONFIG_PM
+static int smtcfb_pci_suspend(struct device *device)
+{
+	struct pci_dev *pdev = to_pci_dev(device);
+	struct smtcfb_info *sfb;
+
+	sfb = pci_get_drvdata(pdev);
+
+	/* set the hw in sleep mode use external clock and self memory refresh
+	 * so that we can turn off internal PLLs later on
+	 */
+	smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0));
+	smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7));
+
+	console_lock();
+	fb_set_suspend(&sfb->fb, 1);
+	console_unlock();
+
+	/* additionally turn off all function blocks including internal PLLs */
+	smtc_seqw(0x21, 0xff);
+
+	return 0;
+}
+
+static int smtcfb_pci_resume(struct device *device)
+{
+	struct pci_dev *pdev = to_pci_dev(device);
+	struct smtcfb_info *sfb;
+
+	sfb = pci_get_drvdata(pdev);
+
+	/* reinit hardware */
+	sm7xx_init_hw();
+	switch (sfb->chip_id) {
+	case 0x710:
+	case 0x712:
+		/* set MCLK = 14.31818 *  (0x16 / 0x2) */
+		smtc_seqw(0x6a, 0x16);
+		smtc_seqw(0x6b, 0x02);
+		smtc_seqw(0x62, 0x3e);
+		/* enable PCI burst */
+		smtc_seqw(0x17, 0x20);
+#ifdef __BIG_ENDIAN
+		if (sfb->fb.var.bits_per_pixel == 32)
+			smtc_seqw(0x17, 0x30);
+#endif
+		break;
+	case 0x720:
+		smtc_seqw(0x62, 0xff);
+		smtc_seqw(0x6a, 0x0d);
+		smtc_seqw(0x6b, 0x02);
+		break;
+	}
+
+	smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0));
+	smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb));
+
+	smtcfb_setmode(sfb);
+
+	console_lock();
+	fb_set_suspend(&sfb->fb, 0);
+	console_unlock();
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(sm7xx_pm_ops, smtcfb_pci_suspend, smtcfb_pci_resume);
+#define SM7XX_PM_OPS (&sm7xx_pm_ops)
+
+#else  /* !CONFIG_PM */
+
+#define SM7XX_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
+
+static struct pci_driver smtcfb_driver = {
+	.name = "smtcfb",
+	.id_table = smtcfb_pci_table,
+	.probe = smtcfb_pci_probe,
+	.remove = smtcfb_pci_remove,
+	.driver.pm  = SM7XX_PM_OPS,
+};
+
+module_pci_driver(smtcfb_driver);
+
+MODULE_AUTHOR("Siliconmotion ");
+MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/speakup/i18n.h b/drivers/staging/speakup/i18n.h
index 16a0871373d9..326d086f9d5a 100644
--- a/drivers/staging/speakup/i18n.h
+++ b/drivers/staging/speakup/i18n.h
@@ -3,7 +3,7 @@
 /* Internationalization declarations */
 
 enum msg_index_t {
-	MSG_FIRST_INDEX ,
+	MSG_FIRST_INDEX,
 	MSG_ANNOUNCEMENTS_START = MSG_FIRST_INDEX,
 	MSG_BLANK = MSG_ANNOUNCEMENTS_START,
 	MSG_IAM_ALIVE,
diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c
index b12c76de60b0..3708bc13ae86 100644
--- a/drivers/staging/speakup/kobjects.c
+++ b/drivers/staging/speakup/kobjects.c
@@ -566,7 +566,7 @@ ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr,
 				if (ch >= ' ' && ch < '~')
 					*cp1++ = ch;
 				else
-					cp1 += sprintf(cp1, "\\""x%02x", ch);
+					cp1 += sprintf(cp1, "\\x%02x", ch);
 			}
 			*cp1++ = '"';
 			*cp1++ = '\n';
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c
index 507fc9a1776e..a0315701c7d9 100644
--- a/drivers/staging/speakup/selection.c
+++ b/drivers/staging/speakup/selection.c
@@ -157,7 +157,7 @@ static void __speakup_paste_selection(struct work_struct *work)
 		pasted += count;
 	}
 	remove_wait_queue(&vc->paste_wait, &wait);
-	current->state = TASK_RUNNING;
+	__set_current_state(TASK_RUNNING);
 
 	tty_buffer_unlock_exclusive(&vc->port);
 	tty_ldisc_deref(ld);
diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c
index f3aa4239dc68..01eddab93c66 100644
--- a/drivers/staging/speakup/synth.c
+++ b/drivers/staging/speakup/synth.c
@@ -30,9 +30,9 @@ struct speakup_info_t speakup_info = {
 	 * must be taken at each kernel->speakup transition and released at
 	 * each corresponding speakup->kernel transition.
 	 *
-	 * The progression thread only interferes with the speakup machinery through
-	 * the synth buffer, so only needs to take the lock while tinkering with
-	 * the buffer.
+	 * The progression thread only interferes with the speakup machinery
+	 * through the synth buffer, so only needs to take the lock
+	 * while tinkering with the buffer.
 	 *
 	 * We use spin_lock/trylock_irqsave and spin_unlock_irqrestore with this
 	 * spinlock because speakup needs to disable the keyboard IRQ.
diff --git a/drivers/staging/unisys/Kconfig b/drivers/staging/unisys/Kconfig
index ac080c9dcf46..19fcb3465509 100644
--- a/drivers/staging/unisys/Kconfig
+++ b/drivers/staging/unisys/Kconfig
@@ -12,7 +12,6 @@ if UNISYSSPAR
 source "drivers/staging/unisys/visorutil/Kconfig"
 source "drivers/staging/unisys/visorchannel/Kconfig"
 source "drivers/staging/unisys/visorchipset/Kconfig"
-source "drivers/staging/unisys/channels/Kconfig"
 source "drivers/staging/unisys/uislib/Kconfig"
 source "drivers/staging/unisys/virtpci/Kconfig"
 source "drivers/staging/unisys/virthba/Kconfig"
diff --git a/drivers/staging/unisys/Makefile b/drivers/staging/unisys/Makefile
index b988d6940aae..68b9925e7d5e 100644
--- a/drivers/staging/unisys/Makefile
+++ b/drivers/staging/unisys/Makefile
@@ -4,7 +4,6 @@
 obj-$(CONFIG_UNISYS_VISORUTIL)		+= visorutil/
 obj-$(CONFIG_UNISYS_VISORCHANNEL)	+= visorchannel/
 obj-$(CONFIG_UNISYS_VISORCHIPSET)	+= visorchipset/
-obj-$(CONFIG_UNISYS_CHANNELSTUB)	+= channels/
 obj-$(CONFIG_UNISYS_UISLIB)		+= uislib/
 obj-$(CONFIG_UNISYS_VIRTPCI)		+= virtpci/
 obj-$(CONFIG_UNISYS_VIRTHBA)		+= virthba/
diff --git a/drivers/staging/unisys/channels/Kconfig b/drivers/staging/unisys/channels/Kconfig
deleted file mode 100644
index 179c6cea2824..000000000000
--- a/drivers/staging/unisys/channels/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# Unisys channels configuration
-#
-
-config UNISYS_CHANNELSTUB
-	tristate "Unisys channelstub driver"
-	depends on UNISYSSPAR && UNISYS_VISORUTIL
-	---help---
-	If you say Y here, you will enable the Unisys channels driver.
-
diff --git a/drivers/staging/unisys/channels/Makefile b/drivers/staging/unisys/channels/Makefile
deleted file mode 100644
index adc184206035..000000000000
--- a/drivers/staging/unisys/channels/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for Unisys channelstub
-#
-
-obj-$(CONFIG_UNISYS_CHANNELSTUB)	+= visorchannelstub.o
-
-visorchannelstub-y := channel.o chanstub.o
-
-ccflags-y += -Idrivers/staging/unisys/include
-ccflags-y += -Idrivers/staging/unisys/common-spar/include
-ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels
diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c
deleted file mode 100644
index 74cc4d6b515f..000000000000
--- a/drivers/staging/unisys/channels/channel.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- */
-
-#include <linux/kernel.h>
-#ifdef CONFIG_MODVERSIONS
-#include <config/modversions.h>
-#endif
-#include <linux/module.h>
-#include <linux/init.h>		/* for module_init and module_exit */
-#include <linux/slab.h>		/* for memcpy */
-#include <linux/types.h>
-
-/* Implementation of exported functions for Supervisor channels */
-#include "channel.h"
-
-/*
- * 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)
-{
-	void __iomem *psignal;
-	unsigned int head, tail, nof;
-
-	struct signal_queue_header __iomem *pqhdr =
-	    (struct signal_queue_header __iomem *)
-		((char __iomem *)ch + readq(&ch->ch_space_offset))
-		+ queue;
-
-	/* capture current head and tail */
-	head = readl(&pqhdr->head);
-	tail = readl(&pqhdr->tail);
-
-	/* queue is full if (head + 1) % n equals tail */
-	if (((head + 1) % readl(&pqhdr->max_slots)) == tail) {
-		nof = readq(&pqhdr->num_overflows) + 1;
-		writeq(nof, &pqhdr->num_overflows);
-		return 0;
-	}
-
-	/* increment the head index */
-	head = (head + 1) % readl(&pqhdr->max_slots);
-
-	/* copy signal to the head location from the area pointed to
-	 * by pSignal
-	 */
-	psignal = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) +
-		(head * readl(&pqhdr->signal_size));
-	memcpy_toio(psignal, sig, readl(&pqhdr->signal_size));
-
-	mb(); /* channel synch */
-	writel(head, &pqhdr->head);
-
-	writeq(readq(&pqhdr->num_sent) + 1, &pqhdr->num_sent);
-	return 1;
-}
-EXPORT_SYMBOL_GPL(spar_signal_insert);
-
-/*
- * 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)
-{
-	void __iomem *psource;
-	unsigned int head, tail;
-	struct signal_queue_header __iomem *pqhdr =
-	    (struct signal_queue_header __iomem *)((char __iomem *)ch +
-				    readq(&ch->ch_space_offset)) + queue;
-
-	/* capture current head and tail */
-	head = readl(&pqhdr->head);
-	tail = readl(&pqhdr->tail);
-
-	/* queue is empty if the head index equals the tail index */
-	if (head == tail) {
-		writeq(readq(&pqhdr->num_empty) + 1, &pqhdr->num_empty);
-		return 0;
-	}
-
-	/* advance past the 'empty' front slot */
-	tail = (tail + 1) % readl(&pqhdr->max_slots);
-
-	/* copy signal from tail location to the area pointed to by pSignal */
-	psource = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) +
-		(tail * readl(&pqhdr->signal_size));
-	memcpy_fromio(sig, psource, readl(&pqhdr->signal_size));
-
-	mb(); /* channel synch */
-	writel(tail, &pqhdr->tail);
-
-	writeq(readq(&pqhdr->num_received) + 1,
-	       &pqhdr->num_received);
-	return 1;
-}
-EXPORT_SYMBOL_GPL(spar_signal_remove);
-
-/*
- * 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)
-{
-	void *psource;
-	unsigned int head, tail, count = 0;
-	struct signal_queue_header *pqhdr =
-	    (struct signal_queue_header *)((char *)ch +
-				    ch->ch_space_offset) + queue;
-
-	/* capture current head and tail */
-	head = pqhdr->head;
-	tail = pqhdr->tail;
-
-	/* queue is empty if the head index equals the tail index */
-	if (head == tail)
-		return 0;
-
-	while (head != tail) {
-		/* advance past the 'empty' front slot */
-		tail = (tail + 1) % pqhdr->max_slots;
-
-		/* copy signal from tail location to the area pointed
-		 * to by pSignal
-		 */
-		psource =
-		    (char *)pqhdr + pqhdr->sig_base_offset +
-		    (tail * pqhdr->signal_size);
-		memcpy((char *)sig + (pqhdr->signal_size * count),
-		       psource, pqhdr->signal_size);
-
-		mb(); /* channel synch */
-		pqhdr->tail = tail;
-
-		count++;
-		pqhdr->num_received++;
-	}
-
-	return count;
-}
-
-/*
- * 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)
-{
-	struct signal_queue_header __iomem *pqhdr =
-	    (struct signal_queue_header __iomem *)((char __iomem *)ch +
-				    readq(&ch->ch_space_offset)) + queue;
-	return readl(&pqhdr->head) == readl(&pqhdr->tail);
-}
-EXPORT_SYMBOL_GPL(spar_signalqueue_empty);
-
diff --git a/drivers/staging/unisys/channels/chanstub.c b/drivers/staging/unisys/channels/chanstub.c
deleted file mode 100644
index b6fd126f16f1..000000000000
--- a/drivers/staging/unisys/channels/chanstub.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- */
-
-#define EXPORT_SYMTAB
-#include <linux/kernel.h>
-#ifdef CONFIG_MODVERSIONS
-#include <config/modversions.h>
-#endif
-#include <linux/module.h>
-#include <linux/init.h>		/* for module_init and module_exit */
-#include <linux/slab.h>		/* for memcpy */
-#include <linux/types.h>
-
-#include "channel.h"
-#include "chanstub.h"
-#include "timskmod.h"
-#include "version.h"
-
-static __init int
-channel_mod_init(void)
-{
-	if (!unisys_spar_platform)
-		return -ENODEV;
-	return 0;
-}
-
-static __exit void
-channel_mod_exit(void)
-{
-}
-
-unsigned char
-SignalInsert_withLock(struct channel_header __iomem *pChannel, u32 Queue,
-		      void *pSignal, spinlock_t *lock)
-{
-	unsigned char result;
-	unsigned long flags;
-
-	spin_lock_irqsave(lock, flags);
-	result = spar_signal_insert(pChannel, Queue, pSignal);
-	spin_unlock_irqrestore(lock, flags);
-	return result;
-}
-
-unsigned char
-SignalRemove_withLock(struct channel_header __iomem *pChannel, u32 Queue,
-		      void *pSignal, spinlock_t *lock)
-{
-	unsigned char result;
-
-	spin_lock(lock);
-	result = spar_signal_remove(pChannel, Queue, pSignal);
-	spin_unlock(lock);
-	return result;
-}
-
-module_init(channel_mod_init);
-module_exit(channel_mod_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Bryan Glaudel");
-MODULE_ALIAS("uischan");
-	/* this is extracted during depmod and kept in modules.dep */
diff --git a/drivers/staging/unisys/channels/chanstub.h b/drivers/staging/unisys/channels/chanstub.h
deleted file mode 100644
index 1531759a1b31..000000000000
--- a/drivers/staging/unisys/channels/chanstub.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- */
-
-#ifndef __CHANSTUB_H__
-#define __CHANSTUB_H__
-unsigned char SignalInsert_withLock(struct channel_header __iomem *pChannel,
-				    u32 Queue, void *pSignal, spinlock_t *lock);
-unsigned char SignalRemove_withLock(struct channel_header __iomem *pChannel,
-				    u32 Queue, void *pSignal, spinlock_t *lock);
-
-#endif
diff --git a/drivers/staging/unisys/common-spar/include/version.h b/drivers/staging/unisys/common-spar/include/version.h
index f25208fc3ed1..83d1da7a2f81 100644
--- a/drivers/staging/unisys/common-spar/include/version.h
+++ b/drivers/staging/unisys/common-spar/include/version.h
@@ -30,7 +30,6 @@
 #define SPARVER4 "0"
 
 #define  VERSION        SPARVER1 "." SPARVER2 "." SPARVER3 "." SPARVER4
-#define  VERSIONDATE    __DATE__
 
 /* Here are various version forms needed in Windows environments.
  */
diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h
index cff7983dab85..4019a0d63645 100644
--- a/drivers/staging/unisys/include/timskmod.h
+++ b/drivers/staging/unisys/include/timskmod.h
@@ -133,7 +133,7 @@
  *  x - the number of seconds to sleep.
  */
 #define SLEEP(x)					     \
-	do { current->state = TASK_INTERRUPTIBLE;	     \
+	do { __set_current_state(TASK_INTERRUPTIBLE);        \
 		schedule_timeout((x)*HZ);		     \
 	} while (0)
 
@@ -141,7 +141,7 @@
  *  x - the number of jiffies to sleep.
  */
 #define SLEEPJIFFIES(x)						    \
-	do { current->state = TASK_INTERRUPTIBLE;		    \
+	do { __set_current_state(TASK_INTERRUPTIBLE);		    \
 		schedule_timeout(x);				    \
 	} while (0)
 
diff --git a/drivers/staging/unisys/uislib/Kconfig b/drivers/staging/unisys/uislib/Kconfig
index 6b134e267904..a712eb82224a 100644
--- a/drivers/staging/unisys/uislib/Kconfig
+++ b/drivers/staging/unisys/uislib/Kconfig
@@ -4,7 +4,7 @@
 
 config UNISYS_UISLIB
 	tristate "Unisys uislib driver"
-	depends on UNISYSSPAR && UNISYS_VISORCHIPSET && UNISYS_CHANNELSTUB && HAS_IOMEM
+	depends on UNISYSSPAR && UNISYS_VISORCHIPSET && HAS_IOMEM
 	---help---
 	If you say Y here, you will enable the Unisys uislib driver.
 
diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c
index 7c87452a9f14..a9eeddeba735 100644
--- a/drivers/staging/unisys/uislib/uislib.c
+++ b/drivers/staging/unisys/uislib/uislib.c
@@ -41,7 +41,6 @@
 
 #include "sparstop.h"
 #include "visorchipset.h"
-#include "chanstub.h"
 #include "version.h"
 #include "guestlinuxdebug.h"
 
@@ -59,8 +58,8 @@
 /* global function pointers that act as callback functions into virtpcimod */
 int (*virt_control_chan_func)(struct guest_msgs *);
 
-static int ProcReadBufferValid;
-static char *ProcReadBuffer;	/* Note this MUST be global,
+static int debug_buf_valid;
+static char *debug_buf;	/* Note this MUST be global,
 					 * because the contents must */
 static unsigned int chipset_inited;
 
@@ -71,24 +70,24 @@ static unsigned int chipset_inited;
 		UIS_THREAD_WAIT;	\
 	} while (1)
 
-static struct bus_info *BusListHead;
-static rwlock_t BusListLock;
-static int BusListCount;	/* number of buses in the list */
-static int MaxBusCount;		/* maximum number of buses expected */
-static u64 PhysicalDataChan;
-static int PlatformNumber;
+static struct bus_info *bus_list;
+static rwlock_t bus_list_lock;
+static int bus_list_count;	/* number of buses in the list */
+static int max_bus_count;		/* maximum number of buses expected */
+static u64 phys_data_chan;
+static int platform_no;
 
-static struct uisthread_info Incoming_ThreadInfo;
-static BOOL Incoming_Thread_Started = FALSE;
-static LIST_HEAD(List_Polling_Device_Channels);
+static struct uisthread_info incoming_ti;
+static BOOL incoming_started = FALSE;
+static LIST_HEAD(poll_dev_chan);
 static unsigned long long tot_moved_to_tail_cnt;
 static unsigned long long tot_wait_cnt;
 static unsigned long long tot_wakeup_cnt;
 static unsigned long long tot_schedule_cnt;
 static int en_smart_wakeup = 1;
-static DEFINE_SEMAPHORE(Lock_Polling_Device_Channels);	/* unlocked */
-static DECLARE_WAIT_QUEUE_HEAD(Wakeup_Polling_Device_Channels);
-static int Go_Polling_Device_Channels;
+static DEFINE_SEMAPHORE(poll_dev_lock);	/* unlocked */
+static DECLARE_WAIT_QUEUE_HEAD(poll_dev_wake_q);
+static int poll_dev_start;
 
 #define CALLHOME_PROC_ENTRY_FN "callhome"
 #define CALLHOME_THROTTLED_PROC_ENTRY_FN "callhome_throttled"
@@ -115,7 +114,7 @@ static unsigned long long cycles_before_wait, wait_cycles;
 /*****************************************************/
 
 static ssize_t info_debugfs_read(struct file *file, char __user *buf,
-			      size_t len, loff_t *offset);
+				 size_t len, loff_t *offset);
 static const struct file_operations debugfs_info_fops = {
 	.read = info_debugfs_read,
 };
@@ -129,58 +128,52 @@ init_msg_header(struct controlvm_message *msg, u32 id, uint rsp, uint svr)
 	msg->hdr.flags.server = svr;
 }
 
-static __iomem void *
-init_vbus_channel(u64 channelAddr, u32 channelBytes)
+static __iomem void *init_vbus_channel(u64 ch_addr, u32 ch_bytes)
 {
-	void __iomem *rc = NULL;
-	void __iomem *pChan = uislib_ioremap_cache(channelAddr, channelBytes);
+	void __iomem *ch = uislib_ioremap_cache(ch_addr, ch_bytes);
 
-	if (!pChan) {
+	if (!ch) {
 		LOGERR("CONTROLVM_BUS_CREATE error: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
-		     (unsigned long long) channelAddr,
-		     (unsigned long long) channelBytes);
-		rc = NULL;
-		goto Away;
+		       (unsigned long long)ch_addr,
+		       (unsigned long long)ch_bytes);
+		return NULL;
 	}
-	if (!SPAR_VBUS_CHANNEL_OK_CLIENT(pChan)) {
+	if (!SPAR_VBUS_CHANNEL_OK_CLIENT(ch)) {
 		ERRDRV("%s channel cannot be used", __func__);
-		uislib_iounmap(pChan);
-		rc = NULL;
-		goto Away;
+		uislib_iounmap(ch);
+		return NULL;
 	}
-	rc = pChan;
-Away:
-	return rc;
+	return ch;
 }
 
 static int
 create_bus(struct controlvm_message *msg, char *buf)
 {
-	u32 busNo, deviceCount;
+	u32 bus_no, dev_count;
 	struct bus_info *tmp, *bus;
 	size_t size;
 
-	if (MaxBusCount == BusListCount) {
+	if (max_bus_count == bus_list_count) {
 		LOGERR("CONTROLVM_BUS_CREATE Failed: max buses:%d already created\n",
-		     MaxBusCount);
-		POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, MaxBusCount,
+		       max_bus_count);
+		POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, max_bus_count,
 				 POSTCODE_SEVERITY_ERR);
 		return CONTROLVM_RESP_ERROR_MAX_BUSES;
 	}
 
-	busNo = msg->cmd.create_bus.bus_no;
-	deviceCount = msg->cmd.create_bus.dev_count;
+	bus_no = msg->cmd.create_bus.bus_no;
+	dev_count = msg->cmd.create_bus.dev_count;
 
-	POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC, busNo, deviceCount,
+	POSTCODE_LINUX_4(BUS_CREATE_ENTRY_PC, bus_no, dev_count,
 			 POSTCODE_SEVERITY_INFO);
 
 	size =
 	    sizeof(struct bus_info) +
-	    (deviceCount * sizeof(struct device_info *));
+	    (dev_count * sizeof(struct device_info *));
 	bus = kzalloc(size, GFP_ATOMIC);
 	if (!bus) {
 		LOGERR("CONTROLVM_BUS_CREATE Failed: kmalloc for bus failed.\n");
-		POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, busNo,
+		POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus_no,
 				 POSTCODE_SEVERITY_ERR);
 		return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
 	}
@@ -191,27 +184,29 @@ create_bus(struct controlvm_message *msg, char *buf)
 	if (msg->hdr.flags.test_message) {
 		/* This implies we're the IOVM so set guest handle to 0... */
 		bus->guest_handle = 0;
-		bus->bus_no = busNo;
+		bus->bus_no = bus_no;
 		bus->local_vnic = 1;
-	} else
-		bus->bus_no = bus->guest_handle = busNo;
-	sprintf(bus->name, "%d", (int) bus->bus_no);
-	bus->device_count = deviceCount;
+	} else {
+		bus->bus_no = bus_no;
+		bus->guest_handle = bus_no;
+	}
+	sprintf(bus->name, "%d", (int)bus->bus_no);
+	bus->device_count = dev_count;
 	bus->device =
-	    (struct device_info **) ((char *) bus + sizeof(struct bus_info));
+	    (struct device_info **)((char *)bus + sizeof(struct bus_info));
 	bus->bus_inst_uuid = msg->cmd.create_bus.bus_inst_uuid;
 	bus->bus_channel_bytes = 0;
 	bus->bus_channel = NULL;
 
 	/* add bus to our bus list - but check for duplicates first */
-	read_lock(&BusListLock);
-	for (tmp = BusListHead; tmp; tmp = tmp->next) {
+	read_lock(&bus_list_lock);
+	for (tmp = bus_list; tmp; tmp = tmp->next) {
 		if (tmp->bus_no == bus->bus_no)
 			break;
 	}
-	read_unlock(&BusListLock);
+	read_unlock(&bus_list_lock);
 	if (tmp) {
-		/* found a bus already in the list with same busNo -
+		/* found a bus already in the list with same bus_no -
 		 * reject add
 		 */
 		LOGERR("CONTROLVM_BUS_CREATE Failed: bus %d already exists.\n",
@@ -221,8 +216,8 @@ create_bus(struct controlvm_message *msg, char *buf)
 		kfree(bus);
 		return CONTROLVM_RESP_ERROR_ALREADY_DONE;
 	}
-	if ((msg->cmd.create_bus.channel_addr != 0)
-	    && (msg->cmd.create_bus.channel_bytes != 0)) {
+	if ((msg->cmd.create_bus.channel_addr != 0) &&
+	    (msg->cmd.create_bus.channel_bytes != 0)) {
 		bus->bus_channel_bytes = msg->cmd.create_bus.channel_bytes;
 		bus->bus_channel =
 		    init_vbus_channel(msg->cmd.create_bus.channel_addr,
@@ -233,9 +228,9 @@ create_bus(struct controlvm_message *msg, char *buf)
 		struct guest_msgs cmd;
 
 		cmd.msgtype = GUEST_ADD_VBUS;
-		cmd.add_vbus.bus_no = busNo;
+		cmd.add_vbus.bus_no = bus_no;
 		cmd.add_vbus.chanptr = bus->bus_channel;
-		cmd.add_vbus.dev_count = deviceCount;
+		cmd.add_vbus.dev_count = dev_count;
 		cmd.add_vbus.bus_uuid = msg->cmd.create_bus.bus_data_type_uuid;
 		cmd.add_vbus.instance_uuid = msg->cmd.create_bus.bus_inst_uuid;
 		if (!virt_control_chan_func) {
@@ -256,15 +251,15 @@ create_bus(struct controlvm_message *msg, char *buf)
 	}
 
 	/* add bus at the head of our list */
-	write_lock(&BusListLock);
-	if (!BusListHead)
-		BusListHead = bus;
-	else {
-		bus->next = BusListHead;
-		BusListHead = bus;
+	write_lock(&bus_list_lock);
+	if (!bus_list) {
+		bus_list = bus;
+	} else {
+		bus->next = bus_list;
+		bus_list = bus;
 	}
-	BusListCount++;
-	write_unlock(&BusListLock);
+	bus_list_count++;
+	write_unlock(&bus_list_lock);
 
 	POSTCODE_LINUX_3(BUS_CREATE_EXIT_PC, bus->bus_no,
 			 POSTCODE_SEVERITY_INFO);
@@ -277,15 +272,15 @@ destroy_bus(struct controlvm_message *msg, char *buf)
 	int i;
 	struct bus_info *bus, *prev = NULL;
 	struct guest_msgs cmd;
-	u32 busNo;
+	u32 bus_no;
 
-	busNo = msg->cmd.destroy_bus.bus_no;
+	bus_no = msg->cmd.destroy_bus.bus_no;
 
-	read_lock(&BusListLock);
+	read_lock(&bus_list_lock);
 
-	bus = BusListHead;
+	bus = bus_list;
 	while (bus) {
-		if (bus->bus_no == busNo)
+		if (bus->bus_no == bus_no)
 			break;
 		prev = bus;
 		bus = bus->next;
@@ -293,8 +288,8 @@ destroy_bus(struct controlvm_message *msg, char *buf)
 
 	if (!bus) {
 		LOGERR("CONTROLVM_BUS_DESTROY Failed: failed to find bus %d.\n",
-		       busNo);
-		read_unlock(&BusListLock);
+		       bus_no);
+		read_unlock(&bus_list_lock);
 		return CONTROLVM_RESP_ERROR_ALREADY_DONE;
 	}
 
@@ -302,12 +297,12 @@ destroy_bus(struct controlvm_message *msg, char *buf)
 	for (i = 0; i < bus->device_count; i++) {
 		if (bus->device[i] != NULL) {
 			LOGERR("CONTROLVM_BUS_DESTROY Failed: device %i attached to bus %d.",
-			     i, busNo);
-			read_unlock(&BusListLock);
+			       i, bus_no);
+			read_unlock(&bus_list_lock);
 			return CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED;
 		}
 	}
-	read_unlock(&BusListLock);
+	read_unlock(&bus_list_lock);
 
 	if (msg->hdr.flags.server)
 		goto remove;
@@ -315,7 +310,7 @@ destroy_bus(struct controlvm_message *msg, char *buf)
 	/* client messages require us to call the virtpci callback associated
 	   with this bus. */
 	cmd.msgtype = GUEST_DEL_VBUS;
-	cmd.del_vbus.bus_no = busNo;
+	cmd.del_vbus.bus_no = bus_no;
 	if (!virt_control_chan_func) {
 		LOGERR("CONTROLVM_BUS_DESTROY Failed: virtpci callback not registered.");
 		return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
@@ -327,13 +322,13 @@ destroy_bus(struct controlvm_message *msg, char *buf)
 
 	/* finally, remove the bus from the list */
 remove:
-	write_lock(&BusListLock);
+	write_lock(&bus_list_lock);
 	if (prev)	/* not at head */
 		prev->next = bus->next;
 	else
-		BusListHead = bus->next;
-	BusListCount--;
-	write_unlock(&BusListLock);
+		bus_list = bus->next;
+	bus_list_count--;
+	write_unlock(&bus_list_lock);
 
 	if (bus->bus_channel) {
 		uislib_iounmap(bus->bus_channel);
@@ -344,26 +339,26 @@ remove:
 	return CONTROLVM_RESP_SUCCESS;
 }
 
-static int
-create_device(struct controlvm_message *msg, char *buf)
+static int create_device(struct controlvm_message *msg, char *buf)
 {
 	struct device_info *dev;
 	struct bus_info *bus;
-	u32 busNo, devNo;
+	struct guest_msgs cmd;
+	u32 bus_no, dev_no;
 	int result = CONTROLVM_RESP_SUCCESS;
-	u64 minSize = MIN_IO_CHANNEL_SIZE;
-	struct req_handler_info *pReqHandler;
+	u64 min_size = MIN_IO_CHANNEL_SIZE;
+	struct req_handler_info *req_handler;
 
-	busNo = msg->cmd.create_device.bus_no;
-	devNo = msg->cmd.create_device.dev_no;
+	bus_no = msg->cmd.create_device.bus_no;
+	dev_no = msg->cmd.create_device.dev_no;
 
-	POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, devNo, busNo,
+	POSTCODE_LINUX_4(DEVICE_CREATE_ENTRY_PC, dev_no, bus_no,
 			 POSTCODE_SEVERITY_INFO);
 
-	dev = kzalloc(sizeof(struct device_info), GFP_ATOMIC);
+	dev = kzalloc(sizeof(*dev), GFP_ATOMIC);
 	if (!dev) {
 		LOGERR("CONTROLVM_DEVICE_CREATE Failed: kmalloc for dev failed.\n");
-		POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
+		POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
 				 POSTCODE_SEVERITY_ERR);
 		return CONTROLVM_RESP_ERROR_KMALLOC_FAILED;
 	}
@@ -371,169 +366,157 @@ create_device(struct controlvm_message *msg, char *buf)
 	dev->channel_uuid = msg->cmd.create_device.data_type_uuid;
 	dev->intr = msg->cmd.create_device.intr;
 	dev->channel_addr = msg->cmd.create_device.channel_addr;
-	dev->bus_no = busNo;
-	dev->dev_no = devNo;
+	dev->bus_no = bus_no;
+	dev->dev_no = dev_no;
 	sema_init(&dev->interrupt_callback_lock, 1);	/* unlocked */
-	sprintf(dev->devid, "vbus%u:dev%u", (unsigned) busNo, (unsigned) devNo);
+	sprintf(dev->devid, "vbus%u:dev%u", (unsigned)bus_no, (unsigned)dev_no);
 	/* map the channel memory for the device. */
-	if (msg->hdr.flags.test_message)
+	if (msg->hdr.flags.test_message) {
 		dev->chanptr = (void __iomem *)__va(dev->channel_addr);
-	else {
-		pReqHandler = req_handler_find(dev->channel_uuid);
-		if (pReqHandler)
+	} else {
+		req_handler = req_handler_find(dev->channel_uuid);
+		if (req_handler)
 			/* generic service handler registered for this
 			 * channel
 			 */
-			minSize = pReqHandler->min_channel_bytes;
-		if (minSize > msg->cmd.create_device.channel_bytes) {
+			min_size = req_handler->min_channel_bytes;
+		if (min_size > msg->cmd.create_device.channel_bytes) {
 			LOGERR("CONTROLVM_DEVICE_CREATE Failed: channel size is too small, channel size:0x%lx, required size:0x%lx",
-			     (ulong) msg->cmd.create_device.channel_bytes,
-			     (ulong) minSize);
-			POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
-					 POSTCODE_SEVERITY_ERR);
+			       (ulong)msg->cmd.create_device.channel_bytes,
+			       (ulong)min_size);
+			POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
+					 bus_no, POSTCODE_SEVERITY_ERR);
 			result = CONTROLVM_RESP_ERROR_CHANNEL_SIZE_TOO_SMALL;
-			goto Away;
+			goto cleanup;
 		}
 		dev->chanptr =
 		    uislib_ioremap_cache(dev->channel_addr,
 					 msg->cmd.create_device.channel_bytes);
 		if (!dev->chanptr) {
 			LOGERR("CONTROLVM_DEVICE_CREATE Failed: ioremap_cache of channelAddr:%Lx for channelBytes:%llu failed",
-			     dev->channel_addr,
-			     msg->cmd.create_device.channel_bytes);
+			       dev->channel_addr,
+			       msg->cmd.create_device.channel_bytes);
 			result = CONTROLVM_RESP_ERROR_IOREMAP_FAILED;
-			POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
-					 POSTCODE_SEVERITY_ERR);
-			goto Away;
+			POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
+					 bus_no, POSTCODE_SEVERITY_ERR);
+			goto cleanup;
 		}
 	}
 	dev->instance_uuid = msg->cmd.create_device.dev_inst_uuid;
 	dev->channel_bytes = msg->cmd.create_device.channel_bytes;
 
-	read_lock(&BusListLock);
-	for (bus = BusListHead; bus; bus = bus->next) {
-		if (bus->bus_no == busNo) {
-			/* make sure the device number is valid */
-			if (devNo >= bus->device_count) {
-				LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).",
-				     devNo, bus->device_count);
-				result = CONTROLVM_RESP_ERROR_MAX_DEVICES;
+	read_lock(&bus_list_lock);
+	for (bus = bus_list; bus; bus = bus->next) {
+		if (bus->bus_no != bus_no)
+			continue;
+		/* make sure the device number is valid */
+		if (dev_no >= bus->device_count) {
+			LOGERR("CONTROLVM_DEVICE_CREATE Failed: device (%d) >= deviceCount (%d).",
+			       dev_no, bus->device_count);
+			result = CONTROLVM_RESP_ERROR_MAX_DEVICES;
+			POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
+					 bus_no, POSTCODE_SEVERITY_ERR);
+			read_unlock(&bus_list_lock);
+			goto cleanup;
+		}
+		/* make sure this device is not already set */
+		if (bus->device[dev_no]) {
+			LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.",
+			       dev_no);
+			POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
+					 dev_no, bus_no,
+					 POSTCODE_SEVERITY_ERR);
+			result = CONTROLVM_RESP_ERROR_ALREADY_DONE;
+			read_unlock(&bus_list_lock);
+			goto cleanup;
+		}
+		read_unlock(&bus_list_lock);
+		/* the msg is bound for virtpci; send
+		 * guest_msgs struct to callback
+		 */
+		if (msg->hdr.flags.server) {
+			bus->device[dev_no] = dev;
+			POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, dev_no,
+					 bus_no, POSTCODE_SEVERITY_INFO);
+			return CONTROLVM_RESP_SUCCESS;
+		}
+		if (uuid_le_cmp(dev->channel_uuid,
+				spar_vhba_channel_protocol_uuid) == 0) {
+			wait_for_valid_guid(&((struct channel_header __iomem *)
+					    (dev->chanptr))->chtype);
+			if (!SPAR_VHBA_CHANNEL_OK_CLIENT(dev->chanptr)) {
+				LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
+				       dev_no);
 				POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
-						 devNo, busNo,
+						 dev_no, bus_no,
 						 POSTCODE_SEVERITY_ERR);
-				read_unlock(&BusListLock);
-				goto Away;
+				result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
+				goto cleanup;
 			}
-			/* make sure this device is not already set */
-			if (bus->device[devNo]) {
-				LOGERR("CONTROLVM_DEVICE_CREATE Failed: device %d is already exists.",
-				     devNo);
+			cmd.msgtype = GUEST_ADD_VHBA;
+			cmd.add_vhba.chanptr = dev->chanptr;
+			cmd.add_vhba.bus_no = bus_no;
+			cmd.add_vhba.device_no = dev_no;
+			cmd.add_vhba.instance_uuid = dev->instance_uuid;
+			cmd.add_vhba.intr = dev->intr;
+		} else if (uuid_le_cmp(dev->channel_uuid,
+				       spar_vnic_channel_protocol_uuid) == 0) {
+			wait_for_valid_guid(&((struct channel_header __iomem *)
+					    (dev->chanptr))->chtype);
+			if (!SPAR_VNIC_CHANNEL_OK_CLIENT(dev->chanptr)) {
+				LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
+				       dev_no);
 				POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC,
-						 devNo, busNo,
+						 dev_no, bus_no,
 						 POSTCODE_SEVERITY_ERR);
-				result = CONTROLVM_RESP_ERROR_ALREADY_DONE;
-				read_unlock(&BusListLock);
-				goto Away;
+				result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
+				goto cleanup;
 			}
-			read_unlock(&BusListLock);
-			/* the msg is bound for virtpci; send
-			 * guest_msgs struct to callback
-			 */
-			if (!msg->hdr.flags.server) {
-				struct guest_msgs cmd;
-
-				if (!uuid_le_cmp(dev->channel_uuid,
-				     spar_vhba_channel_protocol_uuid)) {
-					wait_for_valid_guid(&((
-						struct channel_header
-							__iomem *) (dev->
-								  chanptr))->
-							    chtype);
-					if (!SPAR_VHBA_CHANNEL_OK_CLIENT
-					    (dev->chanptr)) {
-						LOGERR("CONTROLVM_DEVICE_CREATE Failed:[CLIENT]VHBA dev %d chan invalid.",
-						     devNo);
-						POSTCODE_LINUX_4
-						    (DEVICE_CREATE_FAILURE_PC,
-						     devNo, busNo,
-						     POSTCODE_SEVERITY_ERR);
-						result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
-						goto Away;
-					}
-					cmd.msgtype = GUEST_ADD_VHBA;
-					cmd.add_vhba.chanptr = dev->chanptr;
-					cmd.add_vhba.bus_no = busNo;
-					cmd.add_vhba.device_no = devNo;
-					cmd.add_vhba.instance_uuid =
-					    dev->instance_uuid;
-					cmd.add_vhba.intr = dev->intr;
-				} else
-				    if (!uuid_le_cmp(dev->channel_uuid,
-					 spar_vnic_channel_protocol_uuid)) {
-					wait_for_valid_guid(&((
-						struct channel_header
-							__iomem *) (dev->
-								  chanptr))->
-							    chtype);
-					if (!SPAR_VNIC_CHANNEL_OK_CLIENT
-					    (dev->chanptr)) {
-						LOGERR("CONTROLVM_DEVICE_CREATE Failed: VNIC[CLIENT] dev %d chan invalid.",
-						     devNo);
-						POSTCODE_LINUX_4
-						    (DEVICE_CREATE_FAILURE_PC,
-						     devNo, busNo,
-						     POSTCODE_SEVERITY_ERR);
-						result = CONTROLVM_RESP_ERROR_CHANNEL_INVALID;
-						goto Away;
-					}
-					cmd.msgtype = GUEST_ADD_VNIC;
-					cmd.add_vnic.chanptr = dev->chanptr;
-					cmd.add_vnic.bus_no = busNo;
-					cmd.add_vnic.device_no = devNo;
-					cmd.add_vnic.instance_uuid =
-					    dev->instance_uuid;
-					cmd.add_vhba.intr = dev->intr;
-				} else {
-					LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
-					POSTCODE_LINUX_4
-					    (DEVICE_CREATE_FAILURE_PC, devNo,
-					     busNo, POSTCODE_SEVERITY_ERR);
-					result = CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
-					goto Away;
-				}
+			cmd.msgtype = GUEST_ADD_VNIC;
+			cmd.add_vnic.chanptr = dev->chanptr;
+			cmd.add_vnic.bus_no = bus_no;
+			cmd.add_vnic.device_no = dev_no;
+			cmd.add_vnic.instance_uuid = dev->instance_uuid;
+			cmd.add_vhba.intr = dev->intr;
+		} else {
+			LOGERR("CONTROLVM_DEVICE_CREATE Failed: unknown channelTypeGuid.\n");
+			POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
+					 bus_no, POSTCODE_SEVERITY_ERR);
+			result = CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
+			goto cleanup;
+		}
 
-				if (!virt_control_chan_func) {
-					LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered.");
-					POSTCODE_LINUX_4
-					    (DEVICE_CREATE_FAILURE_PC, devNo,
-					     busNo, POSTCODE_SEVERITY_ERR);
-					result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
-					goto Away;
-				}
+		if (!virt_control_chan_func) {
+			LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci callback not registered.");
+			POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
+					 bus_no, POSTCODE_SEVERITY_ERR);
+			result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
+			goto cleanup;
+		}
 
-				if (!virt_control_chan_func(&cmd)) {
-					LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error.");
-					POSTCODE_LINUX_4
-					    (DEVICE_CREATE_FAILURE_PC, devNo,
-					     busNo, POSTCODE_SEVERITY_ERR);
-					result = CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
-					goto Away;
-				}
-			}
-			bus->device[devNo] = dev;
-			POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, devNo, busNo,
-					 POSTCODE_SEVERITY_INFO);
-			return CONTROLVM_RESP_SUCCESS;
+		if (!virt_control_chan_func(&cmd)) {
+			LOGERR("CONTROLVM_DEVICE_CREATE Failed: virtpci GUEST_ADD_[VHBA||VNIC] returned error.");
+			POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no,
+					 bus_no, POSTCODE_SEVERITY_ERR);
+			result =
+			     CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
+			goto cleanup;
 		}
+
+		bus->device[dev_no] = dev;
+		POSTCODE_LINUX_4(DEVICE_CREATE_SUCCESS_PC, dev_no,
+				 bus_no, POSTCODE_SEVERITY_INFO);
+		return CONTROLVM_RESP_SUCCESS;
 	}
-	read_unlock(&BusListLock);
+	read_unlock(&bus_list_lock);
 
-	LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.", busNo);
-	POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, devNo, busNo,
+	LOGERR("CONTROLVM_DEVICE_CREATE Failed: failed to find bus %d.",
+	       bus_no);
+	POSTCODE_LINUX_4(DEVICE_CREATE_FAILURE_PC, dev_no, bus_no,
 			 POSTCODE_SEVERITY_ERR);
 	result = CONTROLVM_RESP_ERROR_BUS_INVALID;
 
-Away:
+cleanup:
 	if (!msg->hdr.flags.test_message) {
 		uislib_iounmap(dev->chanptr);
 		dev->chanptr = NULL;
@@ -543,32 +526,31 @@ Away:
 	return result;
 }
 
-static int
-pause_device(struct controlvm_message *msg)
+static int pause_device(struct controlvm_message *msg)
 {
-	u32 busNo, devNo;
+	u32 bus_no, dev_no;
 	struct bus_info *bus;
 	struct device_info *dev;
 	struct guest_msgs cmd;
 	int retval = CONTROLVM_RESP_SUCCESS;
 
-	busNo = msg->cmd.device_change_state.bus_no;
-	devNo = msg->cmd.device_change_state.dev_no;
+	bus_no = msg->cmd.device_change_state.bus_no;
+	dev_no = msg->cmd.device_change_state.dev_no;
 
-	read_lock(&BusListLock);
-	for (bus = BusListHead; bus; bus = bus->next) {
-		if (bus->bus_no == busNo) {
+	read_lock(&bus_list_lock);
+	for (bus = bus_list; bus; bus = bus->next) {
+		if (bus->bus_no == bus_no) {
 			/* make sure the device number is valid */
-			if (devNo >= bus->device_count) {
+			if (dev_no >= bus->device_count) {
 				LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device(%d) >= deviceCount(%d).",
-				     devNo, bus->device_count);
+				       dev_no, bus->device_count);
 				retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
 			} else {
 				/* make sure this device exists */
-				dev = bus->device[devNo];
+				dev = bus->device[dev_no];
 				if (!dev) {
 					LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: device %d does not exist.",
-					     devNo);
+					       dev_no);
 					retval =
 					  CONTROLVM_RESP_ERROR_ALREADY_DONE;
 				}
@@ -578,20 +560,20 @@ pause_device(struct controlvm_message *msg)
 	}
 	if (!bus) {
 		LOGERR("CONTROLVM_DEVICE_CHANGESTATE:pause Failed: bus %d does not exist",
-		     busNo);
+		       bus_no);
 		retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
 	}
-	read_unlock(&BusListLock);
+	read_unlock(&bus_list_lock);
 	if (retval == CONTROLVM_RESP_SUCCESS) {
 		/* the msg is bound for virtpci; send
 		 * guest_msgs struct to callback
 		 */
-		if (!uuid_le_cmp(dev->channel_uuid,
-				spar_vhba_channel_protocol_uuid)) {
+		if (uuid_le_cmp(dev->channel_uuid,
+				spar_vhba_channel_protocol_uuid) == 0) {
 			cmd.msgtype = GUEST_PAUSE_VHBA;
 			cmd.pause_vhba.chanptr = dev->chanptr;
-		} else if (!uuid_le_cmp(dev->channel_uuid,
-					spar_vnic_channel_protocol_uuid)) {
+		} else if (uuid_le_cmp(dev->channel_uuid,
+				       spar_vnic_channel_protocol_uuid) == 0) {
 			cmd.msgtype = GUEST_PAUSE_VNIC;
 			cmd.pause_vnic.chanptr = dev->chanptr;
 		} else {
@@ -611,32 +593,31 @@ pause_device(struct controlvm_message *msg)
 	return retval;
 }
 
-static int
-resume_device(struct controlvm_message *msg)
+static int resume_device(struct controlvm_message *msg)
 {
-	u32 busNo, devNo;
+	u32 bus_no, dev_no;
 	struct bus_info *bus;
 	struct device_info *dev;
 	struct guest_msgs cmd;
 	int retval = CONTROLVM_RESP_SUCCESS;
 
-	busNo = msg->cmd.device_change_state.bus_no;
-	devNo = msg->cmd.device_change_state.dev_no;
+	bus_no = msg->cmd.device_change_state.bus_no;
+	dev_no = msg->cmd.device_change_state.dev_no;
 
-	read_lock(&BusListLock);
-	for (bus = BusListHead; bus; bus = bus->next) {
-		if (bus->bus_no == busNo) {
+	read_lock(&bus_list_lock);
+	for (bus = bus_list; bus; bus = bus->next) {
+		if (bus->bus_no == bus_no) {
 			/* make sure the device number is valid */
-			if (devNo >= bus->device_count) {
+			if (dev_no >= bus->device_count) {
 				LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device(%d) >= deviceCount(%d).",
-				     devNo, bus->device_count);
+				       dev_no, bus->device_count);
 				retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
 			} else {
 				/* make sure this device exists */
-				dev = bus->device[devNo];
+				dev = bus->device[dev_no];
 				if (!dev) {
 					LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: device %d does not exist.",
-					     devNo);
+					       dev_no);
 					retval =
 					  CONTROLVM_RESP_ERROR_ALREADY_DONE;
 				}
@@ -647,20 +628,20 @@ resume_device(struct controlvm_message *msg)
 
 	if (!bus) {
 		LOGERR("CONTROLVM_DEVICE_CHANGESTATE:resume Failed: bus %d does not exist",
-		     busNo);
+		       bus_no);
 		retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
 	}
-	read_unlock(&BusListLock);
+	read_unlock(&bus_list_lock);
 	/* the msg is bound for virtpci; send
 	 * guest_msgs struct to callback
 	 */
 	if (retval == CONTROLVM_RESP_SUCCESS) {
-		if (!uuid_le_cmp(dev->channel_uuid,
-				 spar_vhba_channel_protocol_uuid)) {
+		if (uuid_le_cmp(dev->channel_uuid,
+				spar_vhba_channel_protocol_uuid) == 0) {
 			cmd.msgtype = GUEST_RESUME_VHBA;
 			cmd.resume_vhba.chanptr = dev->chanptr;
-		} else if (!uuid_le_cmp(dev->channel_uuid,
-					spar_vnic_channel_protocol_uuid)) {
+		} else if (uuid_le_cmp(dev->channel_uuid,
+				       spar_vnic_channel_protocol_uuid) == 0) {
 			cmd.msgtype = GUEST_RESUME_VNIC;
 			cmd.resume_vnic.chanptr = dev->chanptr;
 		} else {
@@ -680,33 +661,33 @@ resume_device(struct controlvm_message *msg)
 	return retval;
 }
 
-static int
-destroy_device(struct controlvm_message *msg, char *buf)
+static int destroy_device(struct controlvm_message *msg, char *buf)
 {
-	u32 busNo, devNo;
+	u32 bus_no, dev_no;
 	struct bus_info *bus;
 	struct device_info *dev;
 	struct guest_msgs cmd;
 	int retval = CONTROLVM_RESP_SUCCESS;
 
-	busNo = msg->cmd.destroy_device.bus_no;
-	devNo = msg->cmd.destroy_device.bus_no;
+	bus_no = msg->cmd.destroy_device.bus_no;
+	dev_no = msg->cmd.destroy_device.bus_no;
 
-	read_lock(&BusListLock);
-	LOGINF("destroy_device called for busNo=%u, devNo=%u", busNo, devNo);
-	for (bus = BusListHead; bus; bus = bus->next) {
-		if (bus->bus_no == busNo) {
+	read_lock(&bus_list_lock);
+	LOGINF("destroy_device called for bus_no=%u, dev_no=%u", bus_no,
+	       dev_no);
+	for (bus = bus_list; bus; bus = bus->next) {
+		if (bus->bus_no == bus_no) {
 			/* make sure the device number is valid */
-			if (devNo >= bus->device_count) {
-				LOGERR("CONTROLVM_DEVICE_DESTORY Failed: device(%d) >= deviceCount(%d).",
-				       devNo, bus->device_count);
+			if (dev_no >= bus->device_count) {
+				LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device(%d) >= device_count(%d).",
+				       dev_no, bus->device_count);
 				retval = CONTROLVM_RESP_ERROR_DEVICE_INVALID;
 			} else {
 				/* make sure this device exists */
-				dev = bus->device[devNo];
+				dev = bus->device[dev_no];
 				if (!dev) {
 					LOGERR("CONTROLVM_DEVICE_DESTROY Failed: device %d does not exist.",
-					       devNo);
+					       dev_no);
 					retval =
 					     CONTROLVM_RESP_ERROR_ALREADY_DONE;
 				}
@@ -717,20 +698,20 @@ destroy_device(struct controlvm_message *msg, char *buf)
 
 	if (!bus) {
 		LOGERR("CONTROLVM_DEVICE_DESTROY Failed: bus %d does not exist",
-		       busNo);
+		       bus_no);
 		retval = CONTROLVM_RESP_ERROR_BUS_INVALID;
 	}
-	read_unlock(&BusListLock);
+	read_unlock(&bus_list_lock);
 	if (retval == CONTROLVM_RESP_SUCCESS) {
 		/* the msg is bound for virtpci; send
 		 * guest_msgs struct to callback
 		 */
-		if (!uuid_le_cmp(dev->channel_uuid,
-				 spar_vhba_channel_protocol_uuid)) {
+		if (uuid_le_cmp(dev->channel_uuid,
+				spar_vhba_channel_protocol_uuid) == 0) {
 			cmd.msgtype = GUEST_DEL_VHBA;
 			cmd.del_vhba.chanptr = dev->chanptr;
-		} else if (!uuid_le_cmp(dev->channel_uuid,
-					spar_vnic_channel_protocol_uuid)) {
+		} else if (uuid_le_cmp(dev->channel_uuid,
+				       spar_vnic_channel_protocol_uuid) == 0) {
 			cmd.msgtype = GUEST_DEL_VNIC;
 			cmd.del_vnic.chanptr = dev->chanptr;
 		} else {
@@ -739,7 +720,7 @@ destroy_device(struct controlvm_message *msg, char *buf)
 			    CONTROLVM_RESP_ERROR_CHANNEL_TYPE_UNKNOWN;
 		}
 		if (!virt_control_chan_func) {
-			LOGERR("CONTROLVM_DEVICE_DESTORY Failed: virtpci callback not registered.");
+			LOGERR("CONTROLVM_DEVICE_DESTROY Failed: virtpci callback not registered.");
 			return
 			    CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
 		}
@@ -755,7 +736,7 @@ destroy_device(struct controlvm_message *msg, char *buf)
  */
 		if (dev->polling) {
 			LOGINF("calling uislib_disable_channel_interrupts");
-			uislib_disable_channel_interrupts(busNo, devNo);
+			uislib_disable_channel_interrupts(bus_no, dev_no);
 		}
 		/* unmap the channel memory for the device. */
 		if (!msg->hdr.flags.test_message) {
@@ -763,7 +744,7 @@ destroy_device(struct controlvm_message *msg, char *buf)
 			uislib_iounmap(dev->chanptr);
 		}
 		kfree(dev);
-		bus->device[devNo] = NULL;
+		bus->device[dev_no] = NULL;
 	}
 	return retval;
 }
@@ -773,9 +754,9 @@ init_chipset(struct controlvm_message *msg, char *buf)
 {
 	POSTCODE_LINUX_2(CHIPSET_INIT_ENTRY_PC, POSTCODE_SEVERITY_INFO);
 
-	MaxBusCount = msg->cmd.init_chipset.bus_count;
-	PlatformNumber = msg->cmd.init_chipset.platform_number;
-	PhysicalDataChan = 0;
+	max_bus_count = msg->cmd.init_chipset.bus_count;
+	platform_no = msg->cmd.init_chipset.platform_number;
+	phys_data_chan = 0;
 
 	/* We need to make sure we have our functions registered
 	* before processing messages.  If we are a test vehicle the
@@ -793,31 +774,29 @@ init_chipset(struct controlvm_message *msg, char *buf)
 	return CONTROLVM_RESP_SUCCESS;
 }
 
-static int
-delete_bus_glue(u32 busNo)
+static int delete_bus_glue(u32 bus_no)
 {
 	struct controlvm_message msg;
 
 	init_msg_header(&msg, CONTROLVM_BUS_DESTROY, 0, 0);
-	msg.cmd.destroy_bus.bus_no = busNo;
+	msg.cmd.destroy_bus.bus_no = bus_no;
 	if (destroy_bus(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
-		LOGERR("destroy_bus failed. busNo=0x%x\n", busNo);
+		LOGERR("destroy_bus failed. bus_no=0x%x\n", bus_no);
 		return 0;
 	}
 	return 1;
 }
 
-static int
-delete_device_glue(u32 busNo, u32 devNo)
+static int delete_device_glue(u32 bus_no, u32 dev_no)
 {
 	struct controlvm_message msg;
 
 	init_msg_header(&msg, CONTROLVM_DEVICE_DESTROY, 0, 0);
-	msg.cmd.destroy_device.bus_no = busNo;
-	msg.cmd.destroy_device.dev_no = devNo;
+	msg.cmd.destroy_device.bus_no = bus_no;
+	msg.cmd.destroy_device.dev_no = dev_no;
 	if (destroy_device(&msg, NULL) != CONTROLVM_RESP_SUCCESS) {
-		LOGERR("destroy_device failed. busNo=0x%x devNo=0x%x\n", busNo,
-		       devNo);
+		LOGERR("destroy_device failed. bus_no=0x%x dev_no=0x%x\n",
+		       bus_no, dev_no);
 		return 0;
 	}
 	return 1;
@@ -874,7 +853,6 @@ uislib_client_inject_add_bus(u32 bus_no, uuid_le inst_uuid,
 }
 EXPORT_SYMBOL_GPL(uislib_client_inject_add_bus);
 
-
 int
 uislib_client_inject_del_bus(u32 bus_no)
 {
@@ -919,7 +897,6 @@ uislib_client_inject_resume_vhba(u32 bus_no, u32 dev_no)
 		return rc;
 	}
 	return 0;
-
 }
 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vhba);
 
@@ -956,7 +933,7 @@ uislib_client_inject_add_vhba(u32 bus_no, u32 dev_no,
 	msg.cmd.create_device.channel_addr = phys_chan_addr;
 	if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
 		LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
-		     chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
+		       chan_bytes, (unsigned int)MIN_IO_CHANNEL_SIZE);
 		POSTCODE_LINUX_4(VHBA_CREATE_FAILURE_PC, chan_bytes,
 				 MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
 		return 0;
@@ -1015,7 +992,7 @@ uislib_client_inject_add_vnic(u32 bus_no, u32 dev_no,
 	msg.cmd.create_device.channel_addr = phys_chan_addr;
 	if (chan_bytes < MIN_IO_CHANNEL_SIZE) {
 		LOGERR("wrong channel size.chan_bytes = 0x%x IO_CHANNEL_SIZE= 0x%x\n",
-		     chan_bytes, (unsigned int) MIN_IO_CHANNEL_SIZE);
+		       chan_bytes, (unsigned int)MIN_IO_CHANNEL_SIZE);
 		POSTCODE_LINUX_4(VNIC_CREATE_FAILURE_PC, chan_bytes,
 				 MIN_IO_CHANNEL_SIZE, POSTCODE_SEVERITY_ERR);
 		return 0;
@@ -1072,7 +1049,6 @@ uislib_client_inject_resume_vnic(u32 bus_no, u32 dev_no)
 		return -1;
 	}
 	return 0;
-
 }
 EXPORT_SYMBOL_GPL(uislib_client_inject_resume_vnic);
 
@@ -1129,14 +1105,12 @@ info_debugfs_read_helper(char **buff, int *buff_len)
 	if (PLINE("\nBuses:\n") < 0)
 		goto err_done;
 
-	read_lock(&BusListLock);
-	for (bus = BusListHead; bus; bus = bus->next) {
-
+	read_lock(&bus_list_lock);
+	for (bus = bus_list; bus; bus = bus->next) {
 		if (PLINE("    bus=0x%p, busNo=%d, deviceCount=%d\n",
 			  bus, bus->bus_no, bus->device_count) < 0)
 			goto err_done_unlock;
 
-
 		if (PLINE("        Devices:\n") < 0)
 			goto err_done_unlock;
 
@@ -1156,7 +1130,7 @@ info_debugfs_read_helper(char **buff, int *buff_len)
 			}
 		}
 	}
-	read_unlock(&BusListLock);
+	read_unlock(&bus_list_lock);
 
 	if (PLINE("UisUtils_Registered_Services: %d\n",
 		  atomic_read(&uisutils_registered_services)) < 0)
@@ -1175,70 +1149,68 @@ info_debugfs_read_helper(char **buff, int *buff_len)
 	return tot;
 
 err_done_unlock:
-	read_unlock(&BusListLock);
+	read_unlock(&bus_list_lock);
 err_done:
 	return -1;
 }
 
-static ssize_t
-info_debugfs_read(struct file *file, char __user *buf,
-		size_t len, loff_t *offset)
+static ssize_t info_debugfs_read(struct file *file, char __user *buf,
+				 size_t len, loff_t *offset)
 {
 	char *temp;
-	int totalBytes = 0;
+	int total_bytes = 0;
 	int remaining_bytes = PROC_READ_BUFFER_SIZE;
 
 /* *start = buf; */
-	if (ProcReadBuffer == NULL) {
-		DBGINF("ProcReadBuffer == NULL; allocating buffer.\n.");
-		ProcReadBuffer = vmalloc(PROC_READ_BUFFER_SIZE);
+	if (debug_buf == NULL) {
+		DBGINF("debug_buf == NULL; allocating buffer.\n.");
+		debug_buf = vmalloc(PROC_READ_BUFFER_SIZE);
 
-		if (ProcReadBuffer == NULL) {
+		if (debug_buf == NULL) {
 			LOGERR("failed to allocate buffer to provide proc data.\n");
 			return -ENOMEM;
 		}
 	}
 
-	temp = ProcReadBuffer;
+	temp = debug_buf;
 
-	if ((*offset == 0) || (!ProcReadBufferValid)) {
+	if ((*offset == 0) || (!debug_buf_valid)) {
 		DBGINF("calling info_debugfs_read_helper.\n");
 		/* if the read fails, then -1 will be returned */
-		totalBytes = info_debugfs_read_helper(&temp, &remaining_bytes);
-		ProcReadBufferValid = 1;
-	} else
-		totalBytes = strlen(ProcReadBuffer);
+		total_bytes = info_debugfs_read_helper(&temp, &remaining_bytes);
+		debug_buf_valid = 1;
+	} else {
+		total_bytes = strlen(debug_buf);
+	}
 
 	return simple_read_from_buffer(buf, len, offset,
-				       ProcReadBuffer, totalBytes);
+				       debug_buf, total_bytes);
 }
 
-static struct device_info *
-find_dev(u32 busNo, u32 devNo)
+static struct device_info *find_dev(u32 bus_no, u32 dev_no)
 {
 	struct bus_info *bus;
 	struct device_info *dev = NULL;
 
-	read_lock(&BusListLock);
-	for (bus = BusListHead; bus; bus = bus->next) {
-		if (bus->bus_no == busNo) {
+	read_lock(&bus_list_lock);
+	for (bus = bus_list; bus; bus = bus->next) {
+		if (bus->bus_no == bus_no) {
 			/* make sure the device number is valid */
-			if (devNo >= bus->device_count) {
-				LOGERR("%s bad busNo, devNo=%d,%d",
+			if (dev_no >= bus->device_count) {
+				LOGERR("%s bad bus_no, dev_no=%d,%d",
 				       __func__,
-				       (int) (busNo), (int) (devNo));
-				goto Away;
+				       (int)bus_no, (int)dev_no);
+				break;
 			}
-			dev = bus->device[devNo];
+			dev = bus->device[dev_no];
 			if (!dev)
-				LOGERR("%s bad busNo, devNo=%d,%d",
+				LOGERR("%s bad bus_no, dev_no=%d,%d",
 				       __func__,
-				       (int) (busNo), (int) (devNo));
-			goto Away;
+				       (int)bus_no, (int)dev_no);
+			break;
 		}
 	}
-Away:
-	read_unlock(&BusListLock);
+	read_unlock(&bus_list_lock);
 	return dev;
 }
 
@@ -1262,8 +1234,7 @@ Away:
  *    less-busy ones.
  *
  */
-static int
-Process_Incoming(void *v)
+static int process_incoming(void *v)
 {
 	unsigned long long cur_cycles, old_cycles, idle_cycles, delta_cycles;
 	struct list_head *new_tail = NULL;
@@ -1272,7 +1243,7 @@ Process_Incoming(void *v)
 	UIS_DAEMONIZE("dev_incoming");
 	for (i = 0; i < 16; i++) {
 		old_cycles = get_cycles();
-		wait_event_timeout(Wakeup_Polling_Device_Channels,
+		wait_event_timeout(poll_dev_wake_q,
 				   0, POLLJIFFIES_NORMAL);
 		cur_cycles = get_cycles();
 		if (wait_cycles == 0) {
@@ -1285,15 +1256,15 @@ Process_Incoming(void *v)
 	LOGINF("wait_cycles=%llu", wait_cycles);
 	cycles_before_wait = wait_cycles;
 	idle_cycles = 0;
-	Go_Polling_Device_Channels = 0;
+	poll_dev_start = 0;
 	while (1) {
 		struct list_head *lelt, *tmp;
 		struct device_info *dev = NULL;
 
 		/* poll each channel for input */
-		down(&Lock_Polling_Device_Channels);
+		down(&poll_dev_lock);
 		new_tail = NULL;
-		list_for_each_safe(lelt, tmp, &List_Polling_Device_Channels) {
+		list_for_each_safe(lelt, tmp, &poll_dev_chan) {
 			int rc = 0;
 
 			dev = list_entry(lelt, struct device_info,
@@ -1315,22 +1286,22 @@ Process_Incoming(void *v)
 					if (!
 					    (list_is_last
 					     (lelt,
-					      &List_Polling_Device_Channels))) {
+					      &poll_dev_chan))) {
 						new_tail = lelt;
 						dev->moved_to_tail_cnt++;
-					} else
+					} else {
 						dev->last_on_list_cnt++;
+					}
 				}
-
 			}
-			if (Incoming_ThreadInfo.should_stop)
+			if (incoming_ti.should_stop)
 				break;
 		}
 		if (new_tail != NULL) {
 			tot_moved_to_tail_cnt++;
-			list_move_tail(new_tail, &List_Polling_Device_Channels);
+			list_move_tail(new_tail, &poll_dev_chan);
 		}
-		up(&Lock_Polling_Device_Channels);
+		up(&poll_dev_lock);
 		cur_cycles = get_cycles();
 		delta_cycles = cur_cycles - old_cycles;
 		old_cycles = cur_cycles;
@@ -1340,24 +1311,24 @@ Process_Incoming(void *v)
 		* - there is no input waiting on any of the channels
 		* - we have received a signal to stop this thread
 		*/
-		if (Incoming_ThreadInfo.should_stop)
+		if (incoming_ti.should_stop)
 			break;
 		if (en_smart_wakeup == 0xFF) {
 			LOGINF("en_smart_wakeup set to 0xff, to force exiting process_incoming");
 			break;
 		}
 		/* wait for POLLJIFFIES_NORMAL jiffies, or until
-		* someone wakes up Wakeup_Polling_Device_Channels,
+		* someone wakes up poll_dev_wake_q,
 		* whichever comes first only do a wait when we have
 		* been idle for cycles_before_wait cycles.
 		*/
 		if (idle_cycles > cycles_before_wait) {
-			Go_Polling_Device_Channels = 0;
+			poll_dev_start = 0;
 			tot_wait_cnt++;
-			wait_event_timeout(Wakeup_Polling_Device_Channels,
-					   Go_Polling_Device_Channels,
+			wait_event_timeout(poll_dev_wake_q,
+					   poll_dev_start,
 					   POLLJIFFIES_NORMAL);
-			Go_Polling_Device_Channels = 1;
+			poll_dev_start = 1;
 		} else {
 			tot_schedule_cnt++;
 			schedule();
@@ -1365,25 +1336,25 @@ Process_Incoming(void *v)
 		}
 	}
 	DBGINF("exiting.\n");
-	complete_and_exit(&Incoming_ThreadInfo.has_stopped, 0);
+	complete_and_exit(&incoming_ti.has_stopped, 0);
 }
 
 static BOOL
-Initialize_incoming_thread(void)
+initialize_incoming_thread(void)
 {
-	if (Incoming_Thread_Started)
+	if (incoming_started)
 		return TRUE;
-	if (!uisthread_start(&Incoming_ThreadInfo,
-			     &Process_Incoming, NULL, "dev_incoming")) {
-		LOGERR("uisthread_start Initialize_incoming_thread ****FAILED");
+	if (!uisthread_start(&incoming_ti,
+			     &process_incoming, NULL, "dev_incoming")) {
+		LOGERR("uisthread_start initialize_incoming_thread ****FAILED");
 		return FALSE;
 	}
-	Incoming_Thread_Started = TRUE;
+	incoming_started = TRUE;
 	return TRUE;
 }
 
 /*  Add a new device/channel to the list being processed by
- *  Process_Incoming().
+ *  process_incoming().
  *  <interrupt> - indicates the function to call periodically.
  *  <interrupt_context> - indicates the data to pass to the <interrupt>
  *                        function.
@@ -1397,23 +1368,23 @@ uislib_enable_channel_interrupts(u32 bus_no, u32 dev_no,
 
 	dev = find_dev(bus_no, dev_no);
 	if (!dev) {
-		LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (bus_no),
-		       (int) (dev_no));
+		LOGERR("%s busNo=%d, devNo=%d", __func__, (int)(bus_no),
+		       (int)(dev_no));
 		return;
 	}
-	down(&Lock_Polling_Device_Channels);
-	Initialize_incoming_thread();
+	down(&poll_dev_lock);
+	initialize_incoming_thread();
 	dev->interrupt = interrupt;
 	dev->interrupt_context = interrupt_context;
 	dev->polling = TRUE;
-	list_add_tail(&(dev->list_polling_device_channels),
-		      &List_Polling_Device_Channels);
-	up(&Lock_Polling_Device_Channels);
+	list_add_tail(&dev->list_polling_device_channels,
+		      &poll_dev_chan);
+	up(&poll_dev_lock);
 }
 EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts);
 
 /*  Remove a device/channel from the list being processed by
- *  Process_Incoming().
+ *  process_incoming().
  */
 void
 uislib_disable_channel_interrupts(u32 bus_no, u32 dev_no)
@@ -1422,31 +1393,31 @@ uislib_disable_channel_interrupts(u32 bus_no, u32 dev_no)
 
 	dev = find_dev(bus_no, dev_no);
 	if (!dev) {
-		LOGERR("%s busNo=%d, devNo=%d", __func__, (int) (bus_no),
-		       (int) (dev_no));
+		LOGERR("%s busNo=%d, devNo=%d", __func__, (int)(bus_no),
+		       (int)(dev_no));
 		return;
 	}
-	down(&Lock_Polling_Device_Channels);
+	down(&poll_dev_lock);
 	list_del(&dev->list_polling_device_channels);
 	dev->polling = FALSE;
 	dev->interrupt = NULL;
-	up(&Lock_Polling_Device_Channels);
+	up(&poll_dev_lock);
 }
 EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts);
 
 static void
 do_wakeup_polling_device_channels(struct work_struct *dummy)
 {
-	if (!Go_Polling_Device_Channels) {
-		Go_Polling_Device_Channels = 1;
-		wake_up(&Wakeup_Polling_Device_Channels);
+	if (!poll_dev_start) {
+		poll_dev_start = 1;
+		wake_up(&poll_dev_wake_q);
 	}
 }
 
-static DECLARE_WORK(Work_wakeup_polling_device_channels,
+static DECLARE_WORK(work_wakeup_polling_device_channels,
 		    do_wakeup_polling_device_channels);
 
-/*  Call this function when you want to send a hint to Process_Incoming() that
+/*  Call this function when you want to send a hint to process_incoming() that
  *  your device might have more requests.
  */
 void
@@ -1454,14 +1425,14 @@ uislib_force_channel_interrupt(u32 bus_no, u32 dev_no)
 {
 	if (en_smart_wakeup == 0)
 		return;
-	if (Go_Polling_Device_Channels)
+	if (poll_dev_start)
 		return;
 	/* The point of using schedule_work() instead of just doing
 	 * the work inline is to force a slight delay before waking up
-	 * the Process_Incoming() thread.
+	 * the process_incoming() thread.
 	 */
 	tot_wakeup_cnt++;
-	schedule_work(&Work_wakeup_polling_device_channels);
+	schedule_work(&work_wakeup_polling_device_channels);
 }
 EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt);
 
@@ -1472,35 +1443,35 @@ EXPORT_SYMBOL_GPL(uislib_force_channel_interrupt);
 static int __init
 uislib_mod_init(void)
 {
-
 	if (!unisys_spar_platform)
 		return -ENODEV;
 
 	LOGINF("MONITORAPIS");
 
 	LOGINF("sizeof(struct uiscmdrsp):%lu bytes\n",
-	       (ulong) sizeof(struct uiscmdrsp));
+	       (ulong)sizeof(struct uiscmdrsp));
 	LOGINF("sizeof(struct phys_info):%lu\n",
-	       (ulong) sizeof(struct phys_info));
+	       (ulong)sizeof(struct phys_info));
 	LOGINF("sizeof(uiscmdrsp_scsi):%lu\n",
-	       (ulong) sizeof(struct uiscmdrsp_scsi));
+	       (ulong)sizeof(struct uiscmdrsp_scsi));
 	LOGINF("sizeof(uiscmdrsp_net):%lu\n",
-	       (ulong) sizeof(struct uiscmdrsp_net));
+	       (ulong)sizeof(struct uiscmdrsp_net));
 	LOGINF("sizeof(CONTROLVM_MESSAGE):%lu bytes\n",
-	       (ulong) sizeof(struct controlvm_message));
+	       (ulong)sizeof(struct controlvm_message));
 	LOGINF("sizeof(struct spar_controlvm_channel_protocol):%lu bytes\n",
-	       (ulong) sizeof(struct spar_controlvm_channel_protocol));
+	       (ulong)sizeof(struct spar_controlvm_channel_protocol));
 	LOGINF("sizeof(CHANNEL_HEADER):%lu bytes\n",
-	       (ulong) sizeof(struct channel_header));
+	       (ulong)sizeof(struct channel_header));
 	LOGINF("sizeof(struct spar_io_channel_protocol):%lu bytes\n",
-	       (ulong) sizeof(struct spar_io_channel_protocol));
+	       (ulong)sizeof(struct spar_io_channel_protocol));
 	LOGINF("SIZEOF_CMDRSP:%lu bytes\n", SIZEOF_CMDRSP);
 	LOGINF("SIZEOF_PROTOCOL:%lu bytes\n", SIZEOF_PROTOCOL);
 
 	/* initialize global pointers to NULL */
-	BusListHead = NULL;
-	BusListCount = MaxBusCount = 0;
-	rwlock_init(&BusListLock);
+	bus_list = NULL;
+	bus_list_count = 0;
+	max_bus_count = 0;
+	rwlock_init(&bus_list_lock);
 	virt_control_chan_func = NULL;
 
 	/* Issue VMCALL_GET_CONTROLVM_ADDR to get CtrlChanPhysAddr and
@@ -1515,7 +1486,7 @@ uislib_mod_init(void)
 
 		platformnumber_debugfs_read = debugfs_create_u32(
 			PLATFORMNUMBER_DEBUGFS_ENTRY_FN, 0444, dir_debugfs,
-			&PlatformNumber);
+			&platform_no);
 
 		cycles_before_wait_debugfs_read = debugfs_create_u64(
 			CYCLES_BEFORE_WAIT_DEBUGFS_ENTRY_FN, 0666, dir_debugfs,
@@ -1533,9 +1504,9 @@ uislib_mod_init(void)
 static void __exit
 uislib_mod_exit(void)
 {
-	if (ProcReadBuffer) {
-		vfree(ProcReadBuffer);
-		ProcReadBuffer = NULL;
+	if (debug_buf) {
+		vfree(debug_buf);
+		debug_buf = NULL;
 	}
 
 	debugfs_remove(info_debugfs_entry);
diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c
index f9f8442d58c5..71bb7b608e9a 100644
--- a/drivers/staging/unisys/uislib/uisqueue.c
+++ b/drivers/staging/unisys/uislib/uisqueue.c
@@ -21,8 +21,6 @@
 
 #include "uisutils.h"
 
-#include "chanstub.h"
-
 /* this is shorter than using __FILE__ (full path name) in
  * debug/info/error messages */
 #define CURRENT_FILE_PC UISLIB_PC_uisqueue_c
@@ -33,9 +31,202 @@
 /*****************************************************/
 /* Exported functions                                */
 /*****************************************************/
+
+/*
+ * 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)
+{
+	void __iomem *psignal;
+	unsigned int head, tail, nof;
+
+	struct signal_queue_header __iomem *pqhdr =
+	    (struct signal_queue_header __iomem *)
+		((char __iomem *)ch + readq(&ch->ch_space_offset))
+		+ queue;
+
+	/* capture current head and tail */
+	head = readl(&pqhdr->head);
+	tail = readl(&pqhdr->tail);
+
+	/* queue is full if (head + 1) % n equals tail */
+	if (((head + 1) % readl(&pqhdr->max_slots)) == tail) {
+		nof = readq(&pqhdr->num_overflows) + 1;
+		writeq(nof, &pqhdr->num_overflows);
+		return 0;
+	}
+
+	/* increment the head index */
+	head = (head + 1) % readl(&pqhdr->max_slots);
+
+	/* copy signal to the head location from the area pointed to
+	 * by pSignal
+	 */
+	psignal = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) +
+		(head * readl(&pqhdr->signal_size));
+	memcpy_toio(psignal, sig, readl(&pqhdr->signal_size));
+
+	mb(); /* channel synch */
+	writel(head, &pqhdr->head);
+
+	writeq(readq(&pqhdr->num_sent) + 1, &pqhdr->num_sent);
+	return 1;
+}
+EXPORT_SYMBOL_GPL(spar_signal_insert);
+
+/*
+ * 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)
+{
+	void __iomem *psource;
+	unsigned int head, tail;
+	struct signal_queue_header __iomem *pqhdr =
+	    (struct signal_queue_header __iomem *)((char __iomem *)ch +
+				    readq(&ch->ch_space_offset)) + queue;
+
+	/* capture current head and tail */
+	head = readl(&pqhdr->head);
+	tail = readl(&pqhdr->tail);
+
+	/* queue is empty if the head index equals the tail index */
+	if (head == tail) {
+		writeq(readq(&pqhdr->num_empty) + 1, &pqhdr->num_empty);
+		return 0;
+	}
+
+	/* advance past the 'empty' front slot */
+	tail = (tail + 1) % readl(&pqhdr->max_slots);
+
+	/* copy signal from tail location to the area pointed to by pSignal */
+	psource = (char __iomem *)pqhdr + readq(&pqhdr->sig_base_offset) +
+		(tail * readl(&pqhdr->signal_size));
+	memcpy_fromio(sig, psource, readl(&pqhdr->signal_size));
+
+	mb(); /* channel synch */
+	writel(tail, &pqhdr->tail);
+
+	writeq(readq(&pqhdr->num_received) + 1,
+	       &pqhdr->num_received);
+	return 1;
+}
+EXPORT_SYMBOL_GPL(spar_signal_remove);
+
+/*
+ * 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)
+{
+	void *psource;
+	unsigned int head, tail, count = 0;
+	struct signal_queue_header *pqhdr =
+	    (struct signal_queue_header *)((char *)ch +
+				    ch->ch_space_offset) + queue;
+
+	/* capture current head and tail */
+	head = pqhdr->head;
+	tail = pqhdr->tail;
+
+	/* queue is empty if the head index equals the tail index */
+	if (head == tail)
+		return 0;
+
+	while (head != tail) {
+		/* advance past the 'empty' front slot */
+		tail = (tail + 1) % pqhdr->max_slots;
+
+		/* copy signal from tail location to the area pointed
+		 * to by pSignal
+		 */
+		psource =
+		    (char *)pqhdr + pqhdr->sig_base_offset +
+		    (tail * pqhdr->signal_size);
+		memcpy((char *)sig + (pqhdr->signal_size * count),
+		       psource, pqhdr->signal_size);
+
+		mb(); /* channel synch */
+		pqhdr->tail = tail;
+
+		count++;
+		pqhdr->num_received++;
+	}
+
+	return count;
+}
+
+/*
+ * 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)
+{
+	struct signal_queue_header __iomem *pqhdr =
+	    (struct signal_queue_header __iomem *)((char __iomem *)ch +
+				    readq(&ch->ch_space_offset)) + queue;
+	return readl(&pqhdr->head) == readl(&pqhdr->tail);
+}
+EXPORT_SYMBOL_GPL(spar_signalqueue_empty);
+
 unsigned long long
 uisqueue_interlocked_or(unsigned long long __iomem *tgt,
-		       unsigned long long set)
+			unsigned long long set)
 {
 	unsigned long long i;
 	unsigned long long j;
@@ -53,7 +244,7 @@ EXPORT_SYMBOL_GPL(uisqueue_interlocked_or);
 
 unsigned long long
 uisqueue_interlocked_and(unsigned long long __iomem *tgt,
-			unsigned long long set)
+			 unsigned long long set)
 {
 	unsigned long long i;
 	unsigned long long j;
@@ -72,22 +263,21 @@ EXPORT_SYMBOL_GPL(uisqueue_interlocked_and);
 static u8
 do_locked_client_insert(struct uisqueue_info *queueinfo,
 			unsigned int whichqueue,
-			void *pSignal,
+			void *signal,
 			spinlock_t *lock,
-			unsigned char issueInterruptIfEmpty,
-			u64 interruptHandle, u8 *channelId)
+			u8 *channel_id)
 {
 	unsigned long flags;
 	u8 rc = 0;
 
 	spin_lock_irqsave(lock, flags);
-	if (!spar_channel_client_acquire_os(queueinfo->chan, channelId))
+	if (!spar_channel_client_acquire_os(queueinfo->chan, channel_id))
 		goto unlock;
-	if (spar_signal_insert(queueinfo->chan, whichqueue, pSignal)) {
+	if (spar_signal_insert(queueinfo->chan, whichqueue, signal)) {
 		queueinfo->packets_sent++;
 		rc = 1;
 	}
-	spar_channel_client_release_os(queueinfo->chan, channelId);
+	spar_channel_client_release_os(queueinfo->chan, channel_id);
 unlock:
 	spin_unlock_irqrestore((spinlock_t *)lock, flags);
 	return rc;
@@ -103,9 +293,8 @@ uisqueue_put_cmdrsp_with_lock_client(struct uisqueue_info *queueinfo,
 				     char oktowait, u8 *channel_id)
 {
 	while (!do_locked_client_insert(queueinfo, whichqueue, cmdrsp,
-					(spinlock_t *) insertlock,
-					issue_irq_if_empty,
-					irq_handle, channel_id)) {
+					(spinlock_t *)insertlock,
+					channel_id)) {
 		if (oktowait != OK_TO_WAIT) {
 			LOGERR("****FAILED visor_signal_insert failed; cannot wait; insert aborted\n");
 			return 0;	/* failed to queue */
diff --git a/drivers/staging/unisys/uislib/uisthread.c b/drivers/staging/unisys/uislib/uisthread.c
index c0fc812f751e..25adf1a7307c 100644
--- a/drivers/staging/unisys/uislib/uisthread.c
+++ b/drivers/staging/unisys/uislib/uisthread.c
@@ -53,7 +53,6 @@ uisthread_start(struct uisthread_info *thrinfo,
 	wake_up_process(thrinfo->task);
 	LOGINF("started thread pid:%d\n", thrinfo->id);
 	return 1;
-
 }
 EXPORT_SYMBOL_GPL(uisthread_start);
 
diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c
index 4a5b86773927..31318d246252 100644
--- a/drivers/staging/unisys/uislib/uisutils.c
+++ b/drivers/staging/unisys/uislib/uisutils.c
@@ -42,14 +42,13 @@ atomic_t uisutils_registered_services = ATOMIC_INIT(0);
 					 * uisctrl_register_req_handler() or
 					 * uisctrl_register_req_handler_ex() */
 
-
 /*****************************************************/
 /* Utility functions                                 */
 /*****************************************************/
 
 int
 uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining,
-		      char *format, ...)
+			 char *format, ...)
 {
 	va_list args;
 	int len;
@@ -57,6 +56,7 @@ uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining,
 	DBGINF("buffer = 0x%p : *buffer = 0x%p.\n", buffer, *buffer);
 	va_start(args, format);
 	len = vsnprintf(*buffer, *buffer_remaining, format, args);
+	va_end(args);
 	if (len >= *buffer_remaining) {
 		*buffer += *buffer_remaining;
 		*total += *buffer_remaining;
@@ -96,7 +96,7 @@ uisctrl_register_req_handler(int type, void *fptr,
 	}
 	if (chipset_driver_info)
 		bus_device_info_init(chipset_driver_info, "chipset", "uislib",
-				   VERSION, NULL);
+				     VERSION, NULL);
 
 	return 1;
 }
@@ -113,66 +113,57 @@ uisctrl_register_req_handler_ex(uuid_le switch_uuid,
 						u32 client_str_len, u64 bytes),
 			struct ultra_vbus_deviceinfo *chipset_driver_info)
 {
-	struct req_handler_info *pReqHandlerInfo;
-	int rc = 0;		/* assume failure */
+	struct req_handler_info *req_handler;
 
 	LOGINF("type=%pUL, controlfunc=0x%p.\n",
 	       &switch_uuid, controlfunc);
 	if (!controlfunc) {
 		LOGERR("%pUL: controlfunc must be supplied\n", &switch_uuid);
-		goto Away;
+		return 0;
 	}
 	if (!server_channel_ok) {
 		LOGERR("%pUL: Server_Channel_Ok must be supplied\n",
 				&switch_uuid);
-		goto Away;
+		return 0;
 	}
 	if (!server_channel_init) {
 		LOGERR("%pUL: Server_Channel_Init must be supplied\n",
 				&switch_uuid);
-		goto Away;
+		return 0;
 	}
-	pReqHandlerInfo = req_handler_add(switch_uuid,
-					switch_type_name,
-					controlfunc,
-					min_channel_bytes,
-					server_channel_ok, server_channel_init);
-	if (!pReqHandlerInfo) {
+	req_handler = req_handler_add(switch_uuid,
+				      switch_type_name,
+				      controlfunc,
+				      min_channel_bytes,
+				      server_channel_ok, server_channel_init);
+	if (!req_handler) {
 		LOGERR("failed to add %pUL to server list\n", &switch_uuid);
-		goto Away;
+		return 0;
 	}
 
 	atomic_inc(&uisutils_registered_services);
-	rc = 1;			/* success */
-Away:
-	if (rc) {
-		if (chipset_driver_info)
-			bus_device_info_init(chipset_driver_info, "chipset",
-					   "uislib", VERSION, NULL);
-	} else
-		LOGERR("failed to register type %pUL.\n", &switch_uuid);
+	if (chipset_driver_info) {
+		bus_device_info_init(chipset_driver_info, "chipset",
+				     "uislib", VERSION, NULL);
+		return 1;
+	}
 
-	return rc;
+	LOGERR("failed to register type %pUL.\n", &switch_uuid);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(uisctrl_register_req_handler_ex);
 
 int
 uisctrl_unregister_req_handler_ex(uuid_le switch_uuid)
 {
-	int rc = 0;		/* assume failure */
-
 	LOGINF("type=%pUL.\n", &switch_uuid);
 	if (req_handler_del(switch_uuid) < 0) {
 		LOGERR("failed to remove %pUL from server list\n",
-				&switch_uuid);
-		goto Away;
+		       &switch_uuid);
+		return 0;
 	}
 	atomic_dec(&uisutils_registered_services);
-	rc = 1;			/* success */
-Away:
-	if (!rc)
-		LOGERR("failed to unregister type %pUL.\n", &switch_uuid);
-	return rc;
+	return 1;
 }
 EXPORT_SYMBOL_GPL(uisctrl_unregister_req_handler_ex);
 
@@ -214,10 +205,10 @@ uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx, void *skb_in,
 		frags[count].pi_pfn =
 		    page_to_pfn(virt_to_page(skb->data + offset));
 		frags[count].pi_off =
-		    (unsigned long) (skb->data + offset) & PI_PAGE_MASK;
+		    (unsigned long)(skb->data + offset) & PI_PAGE_MASK;
 		size =
 		    min(firstfraglen,
-			(unsigned int) (PI_PAGE_SIZE - frags[count].pi_off));
+			(unsigned int)(PI_PAGE_SIZE - frags[count].pi_off));
 		/* can take smallest of firstfraglen(what's left) OR
 		* bytes left in the page
 		*/
@@ -231,7 +222,7 @@ uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx, void *skb_in,
 
 	if ((count + numfrags) > frags_max) {
 		LOGERR("**** FAILED %s frags array too small: max:%d count+nr_frags:%d\n",
-		     calling_ctx, frags_max, count + numfrags);
+		       calling_ctx, frags_max, count + numfrags);
 		return -1;	/* failure */
 	}
 
@@ -255,7 +246,6 @@ dolist: if (skb_shinfo(skb)->frag_list) {
 
 		for (skbinlist = skb_shinfo(skb)->frag_list; skbinlist;
 		     skbinlist = skbinlist->next) {
-
 			c = uisutil_copy_fragsinfo_from_skb("recursive",
 				skbinlist,
 				skbinlist->len - skbinlist->data_len,
@@ -272,17 +262,18 @@ dolist: if (skb_shinfo(skb)->frag_list) {
 }
 EXPORT_SYMBOL_GPL(uisutil_copy_fragsinfo_from_skb);
 
-static LIST_HEAD(ReqHandlerInfo_list);	/* list of struct req_handler_info */
-static DEFINE_SPINLOCK(ReqHandlerInfo_list_lock);
+static LIST_HEAD(req_handler_info_list); /* list of struct req_handler_info */
+static DEFINE_SPINLOCK(req_handler_info_list_lock);
 
 struct req_handler_info *
 req_handler_add(uuid_le switch_uuid,
 	      const char *switch_type_name,
 	      int (*controlfunc)(struct io_msgs *),
 	      unsigned long min_channel_bytes,
-	      int (*Server_Channel_Ok)(unsigned long channelBytes),
-	      int (*Server_Channel_Init)
-	       (void *x, unsigned char *clientStr, u32 clientStrLen, u64 bytes))
+	      int (*server_channel_ok)(unsigned long channel_bytes),
+	      int (*server_channel_init)
+	       (void *x, unsigned char *clientstr, u32 clientstr_len,
+		u64 bytes))
 {
 	struct req_handler_info *rc = NULL;
 
@@ -292,14 +283,14 @@ req_handler_add(uuid_le switch_uuid,
 	rc->switch_uuid = switch_uuid;
 	rc->controlfunc = controlfunc;
 	rc->min_channel_bytes = min_channel_bytes;
-	rc->server_channel_ok = Server_Channel_Ok;
-	rc->server_channel_init = Server_Channel_Init;
+	rc->server_channel_ok = server_channel_ok;
+	rc->server_channel_init = server_channel_init;
 	if (switch_type_name)
 		strncpy(rc->switch_type_name, switch_type_name,
 			sizeof(rc->switch_type_name) - 1);
-	spin_lock(&ReqHandlerInfo_list_lock);
-	list_add_tail(&(rc->list_link), &ReqHandlerInfo_list);
-	spin_unlock(&ReqHandlerInfo_list_lock);
+	spin_lock(&req_handler_info_list_lock);
+	list_add_tail(&rc->list_link, &req_handler_info_list);
+	spin_unlock(&req_handler_info_list_lock);
 
 	return rc;
 }
@@ -310,15 +301,15 @@ req_handler_find(uuid_le switch_uuid)
 	struct list_head *lelt, *tmp;
 	struct req_handler_info *entry = NULL;
 
-	spin_lock(&ReqHandlerInfo_list_lock);
-	list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) {
+	spin_lock(&req_handler_info_list_lock);
+	list_for_each_safe(lelt, tmp, &req_handler_info_list) {
 		entry = list_entry(lelt, struct req_handler_info, list_link);
 		if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) {
-			spin_unlock(&ReqHandlerInfo_list_lock);
+			spin_unlock(&req_handler_info_list_lock);
 			return entry;
 		}
 	}
-	spin_unlock(&ReqHandlerInfo_list_lock);
+	spin_unlock(&req_handler_info_list_lock);
 	return NULL;
 }
 
@@ -329,8 +320,8 @@ req_handler_del(uuid_le switch_uuid)
 	struct req_handler_info *entry = NULL;
 	int rc = -1;
 
-	spin_lock(&ReqHandlerInfo_list_lock);
-	list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) {
+	spin_lock(&req_handler_info_list_lock);
+	list_for_each_safe(lelt, tmp, &req_handler_info_list) {
 		entry = list_entry(lelt, struct req_handler_info, list_link);
 		if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) {
 			list_del(lelt);
@@ -338,6 +329,6 @@ req_handler_del(uuid_le switch_uuid)
 			rc++;
 		}
 	}
-	spin_unlock(&ReqHandlerInfo_list_lock);
+	spin_unlock(&req_handler_info_list_lock);
 	return rc;
 }
diff --git a/drivers/staging/unisys/virthba/Kconfig b/drivers/staging/unisys/virthba/Kconfig
index c0d7986e78cb..9af98fc7acbc 100644
--- a/drivers/staging/unisys/virthba/Kconfig
+++ b/drivers/staging/unisys/virthba/Kconfig
@@ -4,7 +4,7 @@
 
 config UNISYS_VIRTHBA
 	tristate "Unisys virthba driver"
-	depends on UNISYSSPAR && UNISYS_VISORCHIPSET && UNISYS_CHANNELSTUB && UNISYS_UISLIB && UNISYS_VIRTPCI && SCSI
+	depends on UNISYSSPAR && UNISYS_VISORCHIPSET && UNISYS_UISLIB && UNISYS_VIRTPCI && SCSI
 	---help---
 	If you say Y here, you will enable the Unisys virthba driver.
 
diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c
index d7a629b5f111..e6ecea560495 100644
--- a/drivers/staging/unisys/virthba/virthba.c
+++ b/drivers/staging/unisys/virthba/virthba.c
@@ -85,7 +85,8 @@ static int virthba_host_reset_handler(struct scsi_cmnd *scsicmd);
 static const char *virthba_get_info(struct Scsi_Host *shp);
 static int virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
 static int virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
-				     void (*virthba_cmnd_done)(struct scsi_cmnd *));
+				     void (*virthba_cmnd_done)
+					   (struct scsi_cmnd *));
 
 static const struct x86_cpu_id unisys_spar_ids[] = {
 	{ X86_VENDOR_INTEL, 6, 62, X86_FEATURE_ANY },
@@ -107,19 +108,20 @@ static void virthba_slave_destroy(struct scsi_device *scsidev);
 static int process_incoming_rsps(void *);
 static int virthba_serverup(struct virtpci_dev *virtpcidev);
 static int virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state);
-static void doDiskAddRemove(struct work_struct *work);
+static void do_disk_add_remove(struct work_struct *work);
 static void virthba_serverdown_complete(struct work_struct *work);
 static ssize_t info_debugfs_read(struct file *file, char __user *buf,
-			size_t len, loff_t *offset);
+				 size_t len, loff_t *offset);
 static ssize_t enable_ints_write(struct file *file,
-			const char __user *buffer, size_t count, loff_t *ppos);
+				 const char __user *buffer, size_t count,
+				 loff_t *ppos);
 
 /*****************************************************/
 /* Globals                                           */
 /*****************************************************/
 
 static int rsltq_wait_usecs = 4000;	/* Default 4ms */
-static unsigned int MaxBuffLen;
+static unsigned int max_buff_len;
 
 /* Module options */
 static char *virthba_options = "NONE";
@@ -165,6 +167,7 @@ struct virtdisk_info {
 	atomic_t error_count;
 	struct virtdisk_info *next;
 };
+
 /* Each Scsi_Host has a host_data area that contains this struct. */
 struct virthba_info {
 	struct Scsi_Host *scsihost;
@@ -193,7 +196,7 @@ struct virthba_info {
 	struct virtdisk_info head;
 };
 
-/* Work Data for DARWorkQ */
+/* Work Data for dar_work_queue */
 struct diskaddremove {
 	u8 add;			/* 0-remove, 1-add */
 	struct Scsi_Host *shost; /* Scsi Host for this virthba instance */
@@ -244,7 +247,7 @@ static const struct file_operations debugfs_enable_ints_fops = {
 
 #define VIRTHBASOPENMAX 1
 /* array of open devices maintained by open() and close(); */
-static struct virthba_devices_open VirtHbasOpen[VIRTHBASOPENMAX];
+static struct virthba_devices_open virthbas_open[VIRTHBASOPENMAX];
 static struct dentry *virthba_debugfs_dir;
 
 /*****************************************************/
@@ -260,7 +263,7 @@ add_scsipending_entry(struct virthba_info *vhbainfo, char cmdtype, void *new)
 	insert_location = vhbainfo->nextinsert;
 	while (vhbainfo->pending[insert_location].sent != NULL) {
 		insert_location = (insert_location + 1) % MAX_PENDING_REQUESTS;
-		if (insert_location == (int) vhbainfo->nextinsert) {
+		if (insert_location == (int)vhbainfo->nextinsert) {
 			LOGERR("Queue should be full. insert_location<<%d>>  Unable to find open slot for pending commands.\n",
 			     insert_location);
 			spin_unlock_irqrestore(&vhbainfo->privlock, flags);
@@ -289,7 +292,7 @@ add_scsipending_entry_with_wait(struct virthba_info *vhbainfo, char cmdtype,
 		insert_location = add_scsipending_entry(vhbainfo, cmdtype, new);
 	}
 
-	return (unsigned int) insert_location;
+	return (unsigned int)insert_location;
 }
 
 static void *
@@ -300,13 +303,13 @@ del_scsipending_entry(struct virthba_info *vhbainfo, uintptr_t del)
 
 	if (del >= MAX_PENDING_REQUESTS) {
 		LOGERR("Invalid queue position <<%lu>> given to delete. MAX_PENDING_REQUESTS <<%d>>\n",
-		     (unsigned long) del, MAX_PENDING_REQUESTS);
+		     (unsigned long)del, MAX_PENDING_REQUESTS);
 	} else {
 		spin_lock_irqsave(&vhbainfo->privlock, flags);
 
 		if (vhbainfo->pending[del].sent == NULL)
 			LOGERR("Deleting already cleared queue entry at <<%lu>>.\n",
-			     (unsigned long) del);
+			     (unsigned long)del);
 
 		sent = vhbainfo->pending[del].sent;
 
@@ -318,30 +321,30 @@ del_scsipending_entry(struct virthba_info *vhbainfo, uintptr_t del)
 	return sent;
 }
 
-/* DARWorkQ (Disk Add/Remove) */
-static struct work_struct DARWorkQ;
-static struct diskaddremove *DARWorkQHead;
-static spinlock_t DARWorkQLock;
-static unsigned short DARWorkQSched;
+/* dar_work_queue (Disk Add/Remove) */
+static struct work_struct dar_work_queue;
+static struct diskaddremove *dar_work_queue_head;
+static spinlock_t dar_work_queue_lock;
+static unsigned short dar_work_queue_sched;
 #define QUEUE_DISKADDREMOVE(dar) { \
-	spin_lock_irqsave(&DARWorkQLock, flags); \
-	if (!DARWorkQHead) { \
-		DARWorkQHead = dar; \
+	spin_lock_irqsave(&dar_work_queue_lock, flags); \
+	if (!dar_work_queue_head) { \
+		dar_work_queue_head = dar; \
 		dar->next = NULL; \
 	} \
 	else { \
-		dar->next = DARWorkQHead; \
-		DARWorkQHead = dar; \
+		dar->next = dar_work_queue_head; \
+		dar_work_queue_head = dar; \
 	} \
-	if (!DARWorkQSched) { \
-		schedule_work(&DARWorkQ); \
-		DARWorkQSched = 1; \
+	if (!dar_work_queue_sched) { \
+		schedule_work(&dar_work_queue); \
+		dar_work_queue_sched = 1; \
 	} \
-	spin_unlock_irqrestore(&DARWorkQLock, flags); \
+	spin_unlock_irqrestore(&dar_work_queue_lock, flags); \
 }
 
 static inline void
-SendDiskAddRemove(struct diskaddremove *dar)
+send_disk_add_remove(struct diskaddremove *dar)
 {
 	struct scsi_device *sdev;
 	int error;
@@ -365,31 +368,31 @@ SendDiskAddRemove(struct diskaddremove *dar)
 }
 
 /*****************************************************/
-/* DARWorkQ Handler Thread                           */
+/* dar_work_queue Handler Thread                     */
 /*****************************************************/
 static void
-doDiskAddRemove(struct work_struct *work)
+do_disk_add_remove(struct work_struct *work)
 {
 	struct diskaddremove *dar;
 	struct diskaddremove *tmphead;
 	int i = 0;
 	unsigned long flags;
 
-	spin_lock_irqsave(&DARWorkQLock, flags);
-	tmphead = DARWorkQHead;
-	DARWorkQHead = NULL;
-	DARWorkQSched = 0;
-	spin_unlock_irqrestore(&DARWorkQLock, flags);
+	spin_lock_irqsave(&dar_work_queue_lock, flags);
+	tmphead = dar_work_queue_head;
+	dar_work_queue_head = NULL;
+	dar_work_queue_sched = 0;
+	spin_unlock_irqrestore(&dar_work_queue_lock, flags);
 	while (tmphead) {
 		dar = tmphead;
 		tmphead = dar->next;
-		SendDiskAddRemove(dar);
+		send_disk_add_remove(dar);
 		i++;
 	}
 }
 
 /*****************************************************/
-/* Routine to add entry to DARWorkQ                  */
+/* Routine to add entry to dar_work_queue            */
 /*****************************************************/
 static void
 process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp)
@@ -397,7 +400,7 @@ process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp)
 	struct diskaddremove *dar;
 	unsigned long flags;
 
-	dar = kzalloc(sizeof(struct diskaddremove), GFP_ATOMIC);
+	dar = kzalloc(sizeof(*dar), GFP_ATOMIC);
 	if (dar) {
 		dar->add = cmdrsp->disknotify.add;
 		dar->shost = shost;
@@ -416,10 +419,10 @@ process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp)
 /* Probe Remove Functions                            */
 /*****************************************************/
 static irqreturn_t
-virthba_ISR(int irq, void *dev_id)
+virthba_isr(int irq, void *dev_id)
 {
-	struct virthba_info *virthbainfo = (struct virthba_info *) dev_id;
-	struct channel_header __iomem *pChannelHeader;
+	struct virthba_info *virthbainfo = (struct virthba_info *)dev_id;
+	struct channel_header __iomem *channel_header;
 	struct signal_queue_header __iomem *pqhdr;
 	u64 mask;
 	unsigned long long rc1;
@@ -427,23 +430,23 @@ virthba_ISR(int irq, void *dev_id)
 	if (virthbainfo == NULL)
 		return IRQ_NONE;
 	virthbainfo->interrupts_rcvd++;
-	pChannelHeader = virthbainfo->chinfo.queueinfo->chan;
-	if (((readq(&pChannelHeader->features)
-	      & ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS) != 0)
-	    && ((readq(&pChannelHeader->features) &
+	channel_header = virthbainfo->chinfo.queueinfo->chan;
+	if (((readq(&channel_header->features)
+	      & ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS) != 0) &&
+	     ((readq(&channel_header->features) &
 		 ULTRA_IO_DRIVER_DISABLES_INTS) !=
 		0)) {
 		virthbainfo->interrupts_disabled++;
 		mask = ~ULTRA_CHANNEL_ENABLE_INTS;
 		rc1 = uisqueue_interlocked_and(virthbainfo->flags_addr, mask);
 	}
-	if (spar_signalqueue_empty(pChannelHeader, IOCHAN_FROM_IOPART)) {
+	if (spar_signalqueue_empty(channel_header, IOCHAN_FROM_IOPART)) {
 		virthbainfo->interrupts_notme++;
 		return IRQ_NONE;
 	}
 	pqhdr = (struct signal_queue_header __iomem *)
-		((char __iomem *) pChannelHeader +
-		 readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART;
+		((char __iomem *)channel_header +
+		 readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
 	writeq(readq(&pqhdr->num_irq_received) + 1,
 	       &pqhdr->num_irq_received);
 	atomic_set(&virthbainfo->interrupt_rcvd, 1);
@@ -459,8 +462,8 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
 	struct virthba_info *virthbainfo;
 	int rsp;
 	int i;
-	irq_handler_t handler = virthba_ISR;
-	struct channel_header __iomem *pChannelHeader;
+	irq_handler_t handler = virthba_isr;
+	struct channel_header __iomem *channel_header;
 	struct signal_queue_header __iomem *pqhdr;
 	u64 mask;
 
@@ -476,7 +479,7 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
 	 * instance - this virthba that has just been created is an
 	 * instance of a scsi host adapter. This scsi_host_alloc
 	 * function allocates a new Scsi_Host struct & performs basic
-	 * initializatoin.  The host is not published to the scsi
+	 * initialization.  The host is not published to the scsi
 	 * midlayer until scsi_add_host is called.
 	 */
 	DBGINF("calling scsi_host_alloc.\n");
@@ -501,19 +504,19 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
 	 * the max-channel value.
 	 */
 	LOGINF("virtpcidev->scsi.max.max_channel=%u, max_id=%u, max_lun=%u, cmd_per_lun=%u, max_io_size=%u\n",
-	     (unsigned) virtpcidev->scsi.max.max_channel - 1,
-	     (unsigned) virtpcidev->scsi.max.max_id,
-	     (unsigned) virtpcidev->scsi.max.max_lun,
-	     (unsigned) virtpcidev->scsi.max.cmd_per_lun,
-	     (unsigned) virtpcidev->scsi.max.max_io_size);
-	scsihost->max_channel = (unsigned) virtpcidev->scsi.max.max_channel;
-	scsihost->max_id = (unsigned) virtpcidev->scsi.max.max_id;
-	scsihost->max_lun = (unsigned) virtpcidev->scsi.max.max_lun;
-	scsihost->cmd_per_lun = (unsigned) virtpcidev->scsi.max.cmd_per_lun;
+	     (unsigned)virtpcidev->scsi.max.max_channel - 1,
+	     (unsigned)virtpcidev->scsi.max.max_id,
+	     (unsigned)virtpcidev->scsi.max.max_lun,
+	     (unsigned)virtpcidev->scsi.max.cmd_per_lun,
+	     (unsigned)virtpcidev->scsi.max.max_io_size);
+	scsihost->max_channel = (unsigned)virtpcidev->scsi.max.max_channel;
+	scsihost->max_id = (unsigned)virtpcidev->scsi.max.max_id;
+	scsihost->max_lun = (unsigned)virtpcidev->scsi.max.max_lun;
+	scsihost->cmd_per_lun = (unsigned)virtpcidev->scsi.max.cmd_per_lun;
 	scsihost->max_sectors =
-	    (unsigned short) (virtpcidev->scsi.max.max_io_size >> 9);
+	    (unsigned short)(virtpcidev->scsi.max.max_io_size >> 9);
 	scsihost->sg_tablesize =
-	    (unsigned short) (virtpcidev->scsi.max.max_io_size / PAGE_SIZE);
+	    (unsigned short)(virtpcidev->scsi.max.max_io_size / PAGE_SIZE);
 	if (scsihost->sg_tablesize > MAX_PHYS_INFO)
 		scsihost->sg_tablesize = MAX_PHYS_INFO;
 	LOGINF("scsihost->max_channel=%u, max_id=%u, max_lun=%llu, cmd_per_lun=%u, max_sectors=%hu, sg_tablesize=%hu\n",
@@ -544,11 +547,11 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
 		return -ENODEV;
 	}
 
-	virthbainfo = (struct virthba_info *) scsihost->hostdata;
+	virthbainfo = (struct virthba_info *)scsihost->hostdata;
 	memset(virthbainfo, 0, sizeof(struct virthba_info));
 	for (i = 0; i < VIRTHBASOPENMAX; i++) {
-		if (VirtHbasOpen[i].virthbainfo == NULL) {
-			VirtHbasOpen[i].virthbainfo = virthbainfo;
+		if (virthbas_open[i].virthbainfo == NULL) {
+			virthbas_open[i].virthbainfo = virthbainfo;
 			break;
 		}
 	}
@@ -584,10 +587,10 @@ virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
 	DBGINF("starting rsp thread -- queueinfo: 0x%p, threadinfo: 0x%p.\n",
 	       virthbainfo->chinfo.queueinfo, &virthbainfo->chinfo.threadinfo);
 
-	pChannelHeader = virthbainfo->chinfo.queueinfo->chan;
+	channel_header = virthbainfo->chinfo.queueinfo->chan;
 	pqhdr = (struct signal_queue_header __iomem *)
-		((char __iomem *)pChannelHeader +
-		 readq(&pChannelHeader->ch_space_offset)) + IOCHAN_FROM_IOPART;
+		((char __iomem *)channel_header +
+		 readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
 	virthbainfo->flags_addr = &pqhdr->features;
 
 	if (!uisthread_start(&virthbainfo->chinfo.threadinfo,
@@ -646,11 +649,11 @@ virthba_remove(struct virtpci_dev *virtpcidev)
 {
 	struct virthba_info *virthbainfo;
 	struct Scsi_Host *scsihost =
-	    (struct Scsi_Host *) virtpcidev->scsi.scsihost;
+	    (struct Scsi_Host *)virtpcidev->scsi.scsihost;
 
 	LOGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no,
 	       virtpcidev->device_no);
-	virthbainfo = (struct virthba_info *) scsihost->hostdata;
+	virthbainfo = (struct virthba_info *)scsihost->hostdata;
 	if (virthbainfo->interrupt_vector != -1)
 		free_irq(virthbainfo->interrupt_vector, virthbainfo);
 	LOGINF("Removing virtpcidev: 0x%p, virthbainfo: 0x%p\n", virtpcidev,
@@ -679,7 +682,7 @@ forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype,
 {
 	struct uiscmdrsp *cmdrsp;
 	struct virthba_info *virthbainfo =
-	    (struct virthba_info *) scsihost->hostdata;
+	    (struct virthba_info *)scsihost->hostdata;
 	int notifyresult = 0xffff;
 	wait_queue_head_t notifyevent;
 
@@ -706,8 +709,8 @@ forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype,
 	/* specify the event that has to be triggered when this cmd is
 	 * complete
 	 */
-	cmdrsp->vdiskmgmt.notify = (void *) &notifyevent;
-	cmdrsp->vdiskmgmt.notifyresult = (void *) &notifyresult;
+	cmdrsp->vdiskmgmt.notify = (void *)&notifyevent;
+	cmdrsp->vdiskmgmt.notifyresult = (void *)&notifyresult;
 
 	/* save destination */
 	cmdrsp->vdiskmgmt.vdisktype = vdiskcmdtype;
@@ -715,14 +718,14 @@ forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype,
 	cmdrsp->vdiskmgmt.vdest.id = vdest->id;
 	cmdrsp->vdiskmgmt.vdest.lun = vdest->lun;
 	cmdrsp->vdiskmgmt.scsicmd =
-	    (void *) (uintptr_t)
+	    (void *)(uintptr_t)
 		add_scsipending_entry_with_wait(virthbainfo, CMD_VDISKMGMT_TYPE,
-						(void *) cmdrsp);
+						(void *)cmdrsp);
 
 	uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
 					     cmdrsp, IOCHAN_TO_IOPART,
 					     &virthbainfo->chinfo.insertlock,
-					     DONT_ISSUE_INTERRUPT, (u64) NULL,
+					     DONT_ISSUE_INTERRUPT, (u64)NULL,
 					     OK_TO_WAIT, "vhba");
 	LOGINF("VdiskMgmt waiting on event notifyevent=0x%p\n",
 	       cmdrsp->scsitaskmgmt.notify);
@@ -742,7 +745,7 @@ forward_taskmgmt_command(enum task_mgmt_types tasktype,
 {
 	struct uiscmdrsp *cmdrsp;
 	struct virthba_info *virthbainfo =
-	    (struct virthba_info *) scsidev->host->hostdata;
+	    (struct virthba_info *)scsidev->host->hostdata;
 	int notifyresult = 0xffff;
 	wait_queue_head_t notifyevent;
 
@@ -767,8 +770,8 @@ forward_taskmgmt_command(enum task_mgmt_types tasktype,
 	cmdrsp->cmdtype = CMD_SCSITASKMGMT_TYPE;
 	/* specify the event that has to be triggered when this */
 	/* cmd is complete */
-	cmdrsp->scsitaskmgmt.notify = (void *) &notifyevent;
-	cmdrsp->scsitaskmgmt.notifyresult = (void *) &notifyresult;
+	cmdrsp->scsitaskmgmt.notify = (void *)&notifyevent;
+	cmdrsp->scsitaskmgmt.notifyresult = (void *)&notifyresult;
 
 	/* save destination */
 	cmdrsp->scsitaskmgmt.tasktype = tasktype;
@@ -776,15 +779,15 @@ forward_taskmgmt_command(enum task_mgmt_types tasktype,
 	cmdrsp->scsitaskmgmt.vdest.id = scsidev->id;
 	cmdrsp->scsitaskmgmt.vdest.lun = scsidev->lun;
 	cmdrsp->scsitaskmgmt.scsicmd =
-	    (void *) (uintptr_t)
+	    (void *)(uintptr_t)
 		add_scsipending_entry_with_wait(virthbainfo,
 						CMD_SCSITASKMGMT_TYPE,
-						(void *) cmdrsp);
+						(void *)cmdrsp);
 
 	uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
 					     cmdrsp, IOCHAN_TO_IOPART,
 					     &virthbainfo->chinfo.insertlock,
-					     DONT_ISSUE_INTERRUPT, (u64) NULL,
+					     DONT_ISSUE_INTERRUPT, (u64)NULL,
 					     OK_TO_WAIT, "vhba");
 	LOGINF("TaskMgmt waiting on event notifyevent=0x%p\n",
 	       cmdrsp->scsitaskmgmt.notify);
@@ -805,11 +808,11 @@ virthba_abort_handler(struct scsi_cmnd *scsicmd)
 	struct virtdisk_info *vdisk;
 
 	scsidev = scsicmd->device;
-	for (vdisk = &((struct virthba_info *) scsidev->host->hostdata)->head;
+	for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
 	     vdisk->next; vdisk = vdisk->next) {
-		if ((scsidev->channel == vdisk->channel)
-		    && (scsidev->id == vdisk->id)
-		    && (scsidev->lun == vdisk->lun)) {
+		if ((scsidev->channel == vdisk->channel) &&
+		    (scsidev->id == vdisk->id) &&
+		    (scsidev->lun == vdisk->lun)) {
 			if (atomic_read(&vdisk->error_count) <
 			    VIRTHBA_ERROR_COUNT) {
 				atomic_inc(&vdisk->error_count);
@@ -831,11 +834,11 @@ virthba_bus_reset_handler(struct scsi_cmnd *scsicmd)
 	struct virtdisk_info *vdisk;
 
 	scsidev = scsicmd->device;
-	for (vdisk = &((struct virthba_info *) scsidev->host->hostdata)->head;
+	for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
 	     vdisk->next; vdisk = vdisk->next) {
-		if ((scsidev->channel == vdisk->channel)
-		    && (scsidev->id == vdisk->id)
-		    && (scsidev->lun == vdisk->lun)) {
+		if ((scsidev->channel == vdisk->channel) &&
+		    (scsidev->id == vdisk->id) &&
+		    (scsidev->lun == vdisk->lun)) {
 			if (atomic_read(&vdisk->error_count) <
 			    VIRTHBA_ERROR_COUNT) {
 				atomic_inc(&vdisk->error_count);
@@ -857,11 +860,11 @@ virthba_device_reset_handler(struct scsi_cmnd *scsicmd)
 	struct virtdisk_info *vdisk;
 
 	scsidev = scsicmd->device;
-	for (vdisk = &((struct virthba_info *) scsidev->host->hostdata)->head;
+	for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
 	     vdisk->next; vdisk = vdisk->next) {
-		if ((scsidev->channel == vdisk->channel)
-		    && (scsidev->id == vdisk->id)
-		    && (scsidev->lun == vdisk->lun)) {
+		if ((scsidev->channel == vdisk->channel) &&
+		    (scsidev->id == vdisk->id) &&
+		    (scsidev->lun == vdisk->lun)) {
 			if (atomic_read(&vdisk->error_count) <
 			    VIRTHBA_ERROR_COUNT) {
 				atomic_inc(&vdisk->error_count);
@@ -915,7 +918,7 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
 	struct uiscmdrsp *cmdrsp;
 	unsigned int i;
 	struct virthba_info *virthbainfo =
-	    (struct virthba_info *) scsihost->hostdata;
+	    (struct virthba_info *)scsihost->hostdata;
 	struct scatterlist *sg = NULL;
 	struct scatterlist *sgl = NULL;
 	int sg_failed = 0;
@@ -940,9 +943,9 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
 	 * will return the scsicmd pointer for completion
 	 */
 	insert_location =
-	    add_scsipending_entry(virthbainfo, CMD_SCSI_TYPE, (void *) scsicmd);
+	    add_scsipending_entry(virthbainfo, CMD_SCSI_TYPE, (void *)scsicmd);
 	if (insert_location != -1) {
-		cmdrsp->scsi.scsicmd = (void *) (uintptr_t) insert_location;
+		cmdrsp->scsi.scsicmd = (void *)(uintptr_t)insert_location;
 	} else {
 		LOGERR("Queue is full. Returning busy.\n");
 		kfree(cmdrsp);
@@ -961,13 +964,13 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
 	cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd);
 
 	/* keep track of the max buffer length so far. */
-	if (cmdrsp->scsi.bufflen > MaxBuffLen)
-		MaxBuffLen = cmdrsp->scsi.bufflen;
+	if (cmdrsp->scsi.bufflen > max_buff_len)
+		max_buff_len = cmdrsp->scsi.bufflen;
 
 	if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO) {
 		LOGERR("scsicmd use_sg:%d greater than MAX:%d\n",
 		       scsi_sg_count(scsicmd), MAX_PHYS_INFO);
-		del_scsipending_entry(virthbainfo, (uintptr_t) insert_location);
+		del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
 		kfree(cmdrsp);
 		return 1;	/* reject the command */
 	}
@@ -989,22 +992,21 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
 		sgl = scsi_sglist(scsicmd);
 
 		for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) {
-
 			cmdrsp->scsi.gpi_list[i].address = sg_phys(sg);
 			cmdrsp->scsi.gpi_list[i].length = sg->length;
 			if ((i != 0) && (sg->offset != 0))
 				LOGINF("Offset on a sg_entry other than zero =<<%d>>.\n",
-				     sg->offset);
+				       sg->offset);
 		}
 
 		if (sg_failed) {
 			LOGERR("Start sg_list dump (entries %d, bufflen %d)...\n",
-			     scsi_sg_count(scsicmd), cmdrsp->scsi.bufflen);
+			       scsi_sg_count(scsicmd), cmdrsp->scsi.bufflen);
 			for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) {
 				LOGERR("   Entry(%d): page->[0x%p], phys->[0x%Lx], off(%d), len(%d)\n",
-				     i, sg_page(sg),
-				     (unsigned long long) sg_phys(sg),
-				     sg->offset, sg->length);
+				       i, sg_page(sg),
+				       (unsigned long long)sg_phys(sg),
+				       sg->offset, sg->length);
 			}
 			LOGERR("Done sg_list dump.\n");
 			/* BUG(); ***** For now, let it fail in uissd
@@ -1022,12 +1024,12 @@ virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
 						 &virthbainfo->chinfo.
 						 insertlock,
 						 DONT_ISSUE_INTERRUPT,
-						 (u64) NULL, DONT_WAIT, "vhba");
+						 (u64)NULL, DONT_WAIT, "vhba");
 	if (i == 0) {
 		/* queue must be full - and we said don't wait - return busy */
 		LOGERR("uisqueue_put_cmdrsp_with_lock ****FAILED\n");
 		kfree(cmdrsp);
-		del_scsipending_entry(virthbainfo, (uintptr_t) insert_location);
+		del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 
@@ -1047,9 +1049,9 @@ virthba_slave_alloc(struct scsi_device *scsidev)
 	struct virtdisk_info *vdisk;
 	struct virtdisk_info *tmpvdisk;
 	struct virthba_info *virthbainfo;
-	struct Scsi_Host *scsihost = (struct Scsi_Host *) scsidev->host;
+	struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
 
-	virthbainfo = (struct virthba_info *) scsihost->hostdata;
+	virthbainfo = (struct virthba_info *)scsihost->hostdata;
 	if (!virthbainfo) {
 		LOGERR("Could not find virthba_info for scsihost\n");
 		return 0;	/* even though we errored, treat as success */
@@ -1061,7 +1063,7 @@ virthba_slave_alloc(struct scsi_device *scsidev)
 		    (vdisk->next->lun == scsidev->lun))
 			return 0;
 	}
-	tmpvdisk = kzalloc(sizeof(struct virtdisk_info), GFP_ATOMIC);
+	tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
 	if (!tmpvdisk) {	/* error allocating */
 		LOGERR("Could not allocate memory for disk\n");
 		return 0;
@@ -1089,9 +1091,9 @@ virthba_slave_destroy(struct scsi_device *scsidev)
 	 */
 	struct virtdisk_info *vdisk, *delvdisk;
 	struct virthba_info *virthbainfo;
-	struct Scsi_Host *scsihost = (struct Scsi_Host *) scsidev->host;
+	struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
 
-	virthbainfo = (struct virthba_info *) scsihost->hostdata;
+	virthbainfo = (struct virthba_info *)scsihost->hostdata;
 	if (!virthbainfo)
 		LOGERR("Could not find virthba_info for scsihost\n");
 	for (vdisk = &virthbainfo->head; vdisk->next; vdisk = vdisk->next) {
@@ -1120,7 +1122,7 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
 
 	scsidev = scsicmd->device;
 	memcpy(scsicmd->sense_buffer, cmdrsp->scsi.sensebuf, MAX_SENSE_SIZE);
-	sd = (struct sense_data *) scsicmd->sense_buffer;
+	sd = (struct sense_data *)scsicmd->sense_buffer;
 
 	/* Do not log errors for disk-not-present inquiries */
 	if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
@@ -1129,11 +1131,11 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
 		return;
 
 	/* Okay see what our error_count is here.... */
-	for (vdisk = &((struct virthba_info *) scsidev->host->hostdata)->head;
+	for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
 	     vdisk->next; vdisk = vdisk->next) {
-		if ((scsidev->channel != vdisk->channel)
-		    || (scsidev->id != vdisk->id)
-		    || (scsidev->lun != vdisk->lun))
+		if ((scsidev->channel != vdisk->channel) ||
+		    (scsidev->id != vdisk->id) ||
+		    (scsidev->lun != vdisk->lun))
 			continue;
 
 		if (atomic_read(&vdisk->error_count) < VIRTHBA_ERROR_COUNT) {
@@ -1148,8 +1150,8 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
 			if (atomic_read(&vdisk->error_count) ==
 			    VIRTHBA_ERROR_COUNT) {
 				LOGERR("Throtling SCSICMD errors disk <%d:%d:%d:%llu>\n",
-				     scsidev->host->host_no, scsidev->id,
-				     scsidev->channel, scsidev->lun);
+				       scsidev->host->host_no, scsidev->id,
+				       scsidev->channel, scsidev->lun);
 			}
 			atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
 		}
@@ -1169,8 +1171,8 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
 	struct virtdisk_info *vdisk;
 
 	scsidev = scsicmd->device;
-	if ((cmdrsp->scsi.cmnd[0] == INQUIRY)
-	    && (cmdrsp->scsi.bufflen >= MIN_INQUIRY_RESULT_LEN)) {
+	if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
+	    (cmdrsp->scsi.bufflen >= MIN_INQUIRY_RESULT_LEN)) {
 		if (cmdrsp->scsi.no_disk_result == 0)
 			return;
 
@@ -1198,21 +1200,20 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
 		sg = scsi_sglist(scsicmd);
 		for (i = 0; i < scsi_sg_count(scsicmd); i++) {
 			DBGVER("copying OUT OF buf into 0x%p %d\n",
-			     sg_page(sg + i), sg[i].length);
+			       sg_page(sg + i), sg[i].length);
 			thispage_orig = kmap_atomic(sg_page(sg + i));
-			thispage = (void *) ((unsigned long)thispage_orig |
+			thispage = (void *)((unsigned long)thispage_orig |
 					     sg[i].offset);
 			memcpy(thispage, buf + bufind, sg[i].length);
 			kunmap_atomic(thispage_orig);
 			bufind += sg[i].length;
 		}
 	} else {
-
 		vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
 		for ( ; vdisk->next; vdisk = vdisk->next) {
-			if ((scsidev->channel != vdisk->channel)
-			    || (scsidev->id != vdisk->id)
-			    || (scsidev->lun != vdisk->lun))
+			if ((scsidev->channel != vdisk->channel) ||
+			    (scsidev->id != vdisk->id) ||
+			    (scsidev->lun != vdisk->lun))
 				continue;
 
 			if (atomic_read(&vdisk->ios_threshold) > 0) {
@@ -1249,8 +1250,8 @@ complete_vdiskmgmt_command(struct uiscmdrsp *cmdrsp)
 {
 	/* copy the result of the taskmgmt and */
 	/* wake up the error handler that is waiting for this */
-	*(int *) cmdrsp->vdiskmgmt.notifyresult = cmdrsp->vdiskmgmt.result;
-	wake_up_all((wait_queue_head_t *) cmdrsp->vdiskmgmt.notify);
+	*(int *)cmdrsp->vdiskmgmt.notifyresult = cmdrsp->vdiskmgmt.result;
+	wake_up_all((wait_queue_head_t *)cmdrsp->vdiskmgmt.notify);
 	LOGINF("set notify result to %d\n", cmdrsp->vdiskmgmt.result);
 }
 
@@ -1259,15 +1260,15 @@ complete_taskmgmt_command(struct uiscmdrsp *cmdrsp)
 {
 	/* copy the result of the taskmgmt and */
 	/* wake up the error handler that is waiting for this */
-	*(int *) cmdrsp->scsitaskmgmt.notifyresult =
+	*(int *)cmdrsp->scsitaskmgmt.notifyresult =
 	    cmdrsp->scsitaskmgmt.result;
-	wake_up_all((wait_queue_head_t *) cmdrsp->scsitaskmgmt.notify);
+	wake_up_all((wait_queue_head_t *)cmdrsp->scsitaskmgmt.notify);
 	LOGINF("set notify result to %d\n", cmdrsp->scsitaskmgmt.result);
 }
 
 static void
 drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
-		struct uiscmdrsp *cmdrsp)
+	    struct uiscmdrsp *cmdrsp)
 {
 	unsigned long flags;
 	int qrslt = 0;
@@ -1277,7 +1278,7 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
 	while (1) {
 		spin_lock_irqsave(&virthbainfo->chinfo.insertlock, flags);
 		if (!spar_channel_client_acquire_os(dc->queueinfo->chan,
-						     "vhba")) {
+						    "vhba")) {
 			spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock,
 					       flags);
 			virthbainfo->acquire_failed_cnt++;
@@ -1294,14 +1295,15 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
 			 * deletion
 			 */
 			scsicmd = del_scsipending_entry(virthbainfo,
-					(uintptr_t) cmdrsp->scsi.scsicmd);
+							(uintptr_t)
+							 cmdrsp->scsi.scsicmd);
 			if (!scsicmd)
 				break;
 			/* complete the orig cmd */
 			complete_scsi_command(cmdrsp, scsicmd);
 		} else if (cmdrsp->cmdtype == CMD_SCSITASKMGMT_TYPE) {
 			if (!del_scsipending_entry(virthbainfo,
-				   (uintptr_t) cmdrsp->scsitaskmgmt.scsicmd))
+				   (uintptr_t)cmdrsp->scsitaskmgmt.scsicmd))
 				break;
 			complete_taskmgmt_command(cmdrsp);
 		} else if (cmdrsp->cmdtype == CMD_NOTIFYGUEST_TYPE) {
@@ -1313,7 +1315,8 @@ drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
 			process_disk_notify(shost, cmdrsp);
 		} else if (cmdrsp->cmdtype == CMD_VDISKMGMT_TYPE) {
 			if (!del_scsipending_entry(virthbainfo,
-				   (uintptr_t) cmdrsp->vdiskmgmt.scsicmd))
+						   (uintptr_t)
+						    cmdrsp->vdiskmgmt.scsicmd))
 				break;
 			complete_vdiskmgmt_command(cmdrsp);
 		} else
@@ -1347,7 +1350,7 @@ process_incoming_rsps(void *v)
 	while (1) {
 		wait_event_interruptible_timeout(virthbainfo->rsp_queue,
 			 (atomic_read(&virthbainfo->interrupt_rcvd) == 1),
-					 usecs_to_jiffies(rsltq_wait_usecs));
+				      usecs_to_jiffies(rsltq_wait_usecs));
 		atomic_set(&virthbainfo->interrupt_rcvd, 0);
 		/* drain queue */
 		drain_queue(virthbainfo, dc, cmdrsp);
@@ -1367,7 +1370,7 @@ process_incoming_rsps(void *v)
 /*****************************************************/
 
 static ssize_t info_debugfs_read(struct file *file,
-			char __user *buf, size_t len, loff_t *offset)
+				 char __user *buf, size_t len, loff_t *offset)
 {
 	ssize_t bytes_read = 0;
 	int str_pos = 0;
@@ -1383,13 +1386,14 @@ static ssize_t info_debugfs_read(struct file *file,
 		return -ENOMEM;
 
 	for (i = 0; i < VIRTHBASOPENMAX; i++) {
-		if (VirtHbasOpen[i].virthbainfo == NULL)
+		if (virthbas_open[i].virthbainfo == NULL)
 			continue;
 
-		virthbainfo = VirtHbasOpen[i].virthbainfo;
+		virthbainfo = virthbas_open[i].virthbainfo;
 
 		str_pos += scnprintf(vbuf + str_pos,
-				len - str_pos, "MaxBuffLen:%u\n", MaxBuffLen);
+				len - str_pos, "max_buff_len:%u\n",
+				max_buff_len);
 
 		str_pos += scnprintf(vbuf + str_pos, len - str_pos,
 				"\nvirthba result queue poll wait:%d usecs.\n",
@@ -1418,14 +1422,14 @@ static ssize_t info_debugfs_read(struct file *file,
 	return bytes_read;
 }
 
-static ssize_t enable_ints_write(struct file *file,
-			const char __user *buffer, size_t count, loff_t *ppos)
+static ssize_t enable_ints_write(struct file *file, const char __user *buffer,
+				 size_t count, loff_t *ppos)
 {
 	char buf[4];
 	int i, new_value;
 	struct virthba_info *virthbainfo;
 
-	u64 __iomem *Features_addr;
+	u64 __iomem *features_addr;
 	u64 mask;
 
 	if (count >= ARRAY_SIZE(buf))
@@ -1434,37 +1438,37 @@ static ssize_t enable_ints_write(struct file *file,
 	buf[count] = '\0';
 	if (copy_from_user(buf, buffer, count)) {
 		LOGERR("copy_from_user failed. buf<<%.*s>> count<<%lu>>\n",
-		       (int) count, buf, count);
+		       (int)count, buf, count);
 		return -EFAULT;
 	}
 
-	i = kstrtoint(buf, 10 , &new_value);
+	i = kstrtoint(buf, 10, &new_value);
 
 	if (i != 0) {
 		LOGERR("Failed to scan value for enable_ints, buf<<%.*s>>",
-		       (int) count, buf);
+		       (int)count, buf);
 		return -EFAULT;
 	}
 
 	/* set all counts to new_value usually 0 */
 	for (i = 0; i < VIRTHBASOPENMAX; i++) {
-		if (VirtHbasOpen[i].virthbainfo != NULL) {
-			virthbainfo = VirtHbasOpen[i].virthbainfo;
-			Features_addr =
+		if (virthbas_open[i].virthbainfo != NULL) {
+			virthbainfo = virthbas_open[i].virthbainfo;
+			features_addr =
 				&virthbainfo->chinfo.queueinfo->chan->features;
 			if (new_value == 1) {
 				mask = ~(ULTRA_IO_CHANNEL_IS_POLLING |
 					 ULTRA_IO_DRIVER_DISABLES_INTS);
-				uisqueue_interlocked_and(Features_addr, mask);
+				uisqueue_interlocked_and(features_addr, mask);
 				mask = ULTRA_IO_DRIVER_ENABLES_INTS;
-				uisqueue_interlocked_or(Features_addr, mask);
+				uisqueue_interlocked_or(features_addr, mask);
 				rsltq_wait_usecs = 4000000;
 			} else {
 				mask = ~(ULTRA_IO_DRIVER_ENABLES_INTS |
 					 ULTRA_IO_DRIVER_DISABLES_INTS);
-				uisqueue_interlocked_and(Features_addr, mask);
+				uisqueue_interlocked_and(features_addr, mask);
 				mask = ULTRA_IO_CHANNEL_IS_POLLING;
-				uisqueue_interlocked_or(Features_addr, mask);
+				uisqueue_interlocked_or(features_addr, mask);
 				rsltq_wait_usecs = 4000;
 			}
 		}
@@ -1477,7 +1481,7 @@ static int
 virthba_serverup(struct virtpci_dev *virtpcidev)
 {
 	struct virthba_info *virthbainfo =
-	    (struct virthba_info *) ((struct Scsi_Host *) virtpcidev->scsi.
+	    (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
 				     scsihost)->hostdata;
 
 	DBGINF("virtpcidev bus_no<<%d>>devNo<<%d>>", virtpcidev->bus_no,
@@ -1535,26 +1539,26 @@ virthba_serverdown_complete(struct work_struct *work)
 	/* Fail Commands that weren't completed */
 	spin_lock_irqsave(&virthbainfo->privlock, flags);
 	for (i = 0; i < MAX_PENDING_REQUESTS; i++) {
-		pendingdel = &(virthbainfo->pending[i]);
+		pendingdel = &virthbainfo->pending[i];
 		switch (pendingdel->cmdtype) {
 		case CMD_SCSI_TYPE:
-			scsicmd = (struct scsi_cmnd *) pendingdel->sent;
+			scsicmd = (struct scsi_cmnd *)pendingdel->sent;
 			scsicmd->result = (DID_RESET << 16);
 			if (scsicmd->scsi_done)
 				scsicmd->scsi_done(scsicmd);
 			break;
 		case CMD_SCSITASKMGMT_TYPE:
-			cmdrsp = (struct uiscmdrsp *) pendingdel->sent;
+			cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
 			DBGINF("cmdrsp=0x%x, notify=0x%x\n", cmdrsp,
 			       cmdrsp->scsitaskmgmt.notify);
-			*(int *) cmdrsp->scsitaskmgmt.notifyresult =
+			*(int *)cmdrsp->scsitaskmgmt.notifyresult =
 			    TASK_MGMT_FAILED;
 			wake_up_all((wait_queue_head_t *)
 				    cmdrsp->scsitaskmgmt.notify);
 			break;
 		case CMD_VDISKMGMT_TYPE:
-			cmdrsp = (struct uiscmdrsp *) pendingdel->sent;
-			*(int *) cmdrsp->vdiskmgmt.notifyresult =
+			cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
+			*(int *)cmdrsp->vdiskmgmt.notifyresult =
 			    VDISK_MGMT_FAILED;
 			wake_up_all((wait_queue_head_t *)
 				    cmdrsp->vdiskmgmt.notify);
@@ -1584,8 +1588,10 @@ virthba_serverdown_complete(struct work_struct *work)
 static int
 virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state)
 {
+	int stat = 1;
+
 	struct virthba_info *virthbainfo =
-	    (struct virthba_info *) ((struct Scsi_Host *) virtpcidev->scsi.
+	    (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
 				     scsihost)->hostdata;
 
 	DBGINF("virthba_serverdown");
@@ -1598,11 +1604,12 @@ virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state)
 			   &virthbainfo->serverdown_completion);
 	} else if (virthbainfo->serverchangingstate) {
 		LOGERR("Server already processing change state message\n");
-		return 0;
-	} else
+		stat = 0;
+	} else {
 		LOGERR("Server already down, but another server down message received.");
+	}
 
-	return 1;
+	return stat;
 }
 
 /*****************************************************/
@@ -1655,23 +1662,22 @@ virthba_mod_init(void)
 		POSTCODE_LINUX_3(VHBA_CREATE_FAILURE_PC, error,
 				 POSTCODE_SEVERITY_ERR);
 	} else {
-
 		/* create the debugfs directories and entries */
 		virthba_debugfs_dir = debugfs_create_dir("virthba", NULL);
 		debugfs_create_file("info", S_IRUSR, virthba_debugfs_dir,
-				NULL, &debugfs_info_fops);
+				    NULL, &debugfs_info_fops);
 		debugfs_create_u32("rqwait_usecs", S_IRUSR | S_IWUSR,
-				virthba_debugfs_dir, &rsltq_wait_usecs);
+				   virthba_debugfs_dir, &rsltq_wait_usecs);
 		debugfs_create_file("enable_ints", S_IWUSR,
-				virthba_debugfs_dir, NULL,
-				&debugfs_enable_ints_fops);
-		/* Initialize DARWorkQ */
-		INIT_WORK(&DARWorkQ, doDiskAddRemove);
-		spin_lock_init(&DARWorkQLock);
+				    virthba_debugfs_dir, NULL,
+				    &debugfs_enable_ints_fops);
+		/* Initialize dar_work_queue */
+		INIT_WORK(&dar_work_queue, do_disk_add_remove);
+		spin_lock_init(&dar_work_queue_lock);
 
 		/* clear out array */
 		for (i = 0; i < VIRTHBASOPENMAX; i++)
-			VirtHbasOpen[i].virthbainfo = NULL;
+			virthbas_open[i].virthbainfo = NULL;
 		/* Initialize the serverdown workqueue */
 		virthba_serverdown_workqueue =
 		    create_singlethread_workqueue("virthba_serverdown");
@@ -1746,7 +1752,6 @@ virthba_mod_exit(void)
 
 	debugfs_remove_recursive(virthba_debugfs_dir);
 	LOGINF("Leaving virthba_mod_exit\n");
-
 }
 
 /* specify function to be run at module insertion time */
diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c
index 39b828dce503..8fdfd6f3605f 100644
--- a/drivers/staging/unisys/virtpci/virtpci.c
+++ b/drivers/staging/unisys/virtpci/virtpci.c
@@ -104,8 +104,6 @@ static ssize_t virtpci_driver_attr_store(struct kobject *kobj,
 					 const char *buf, size_t count);
 static int virtpci_bus_match(struct device *dev, struct device_driver *drv);
 static int virtpci_uevent(struct device *dev, struct kobj_uevent_env *env);
-static int virtpci_device_suspend(struct device *dev, pm_message_t state);
-static int virtpci_device_resume(struct device *dev);
 static int virtpci_device_probe(struct device *dev);
 static int virtpci_device_remove(struct device *dev);
 
@@ -128,8 +126,6 @@ static struct bus_type virtpci_bus_type = {
 	.name = "uisvirtpci",
 	.match = virtpci_bus_match,
 	.uevent = virtpci_uevent,
-	.suspend = virtpci_device_suspend,
-	.resume = virtpci_device_resume,
 };
 
 static struct device virtpci_rootbus_device = {
@@ -279,9 +275,9 @@ static int add_vbus(struct add_vbus_guestpart *addparams)
 		POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
 		return 0;
 	}
-	write_vbus_chp_info(vbus->platform_data /* chanptr */ ,
+	write_vbus_chp_info(vbus->platform_data /* chanptr */,
 			    &chipset_driver_info);
-	write_vbus_bus_info(vbus->platform_data /* chanptr */ ,
+	write_vbus_bus_info(vbus->platform_data /* chanptr */,
 			    &bus_driver_info);
 	LOGINF("Added vbus %d; device %s created successfully\n",
 	       addparams->bus_no, BUS_ID(vbus));
@@ -466,7 +462,7 @@ static int pause_vhba(struct pause_virt_guestpart *pauseparams)
 	GET_SCSIADAPINFO_FROM_CHANPTR(pauseparams->chanptr);
 
 	LOGINF("Pausing vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2);
-	i = virtpci_device_serverdown(NULL /*no parent bus */ , VIRTHBA_TYPE,
+	i = virtpci_device_serverdown(NULL /*no parent bus */, VIRTHBA_TYPE,
 				      &scsi.wwnn, NULL);
 	if (i)
 		LOGINF("Paused vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1,
@@ -487,7 +483,7 @@ static int pause_vnic(struct pause_virt_guestpart *pauseparams)
 	LOGINF("Pausing vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
 	       net.mac_addr[0], net.mac_addr[1], net.mac_addr[2],
 	       net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]);
-	i = virtpci_device_serverdown(NULL /*no parent bus */ , VIRTNIC_TYPE,
+	i = virtpci_device_serverdown(NULL /*no parent bus */, VIRTNIC_TYPE,
 				      NULL, net.mac_addr);
 	if (i) {
 		LOGINF(" Paused vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -508,7 +504,7 @@ static int resume_vhba(struct resume_virt_guestpart *resumeparams)
 	GET_SCSIADAPINFO_FROM_CHANPTR(resumeparams->chanptr);
 
 	LOGINF("Resuming vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2);
-	i = virtpci_device_serverup(NULL /*no parent bus */ , VIRTHBA_TYPE,
+	i = virtpci_device_serverup(NULL /*no parent bus */, VIRTHBA_TYPE,
 				    &scsi.wwnn, NULL);
 	if (i)
 		LOGINF("Resumed vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1,
@@ -530,7 +526,7 @@ resume_vnic(struct resume_virt_guestpart *resumeparams)
 	LOGINF("Resuming vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
 	       net.mac_addr[0], net.mac_addr[1], net.mac_addr[2],
 	       net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]);
-	i = virtpci_device_serverup(NULL /*no parent bus */ , VIRTNIC_TYPE,
+	i = virtpci_device_serverup(NULL /*no parent bus */, VIRTNIC_TYPE,
 				    NULL, net.mac_addr);
 	if (i) {
 		LOGINF(" Resumed vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -551,7 +547,7 @@ static int delete_vhba(struct del_virt_guestpart *delparams)
 	GET_SCSIADAPINFO_FROM_CHANPTR(delparams->chanptr);
 
 	LOGINF("Deleting vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1, scsi.wwnn.wwnn2);
-	i = virtpci_device_del(NULL /*no parent bus */ , VIRTHBA_TYPE,
+	i = virtpci_device_del(NULL /*no parent bus */, VIRTHBA_TYPE,
 			       &scsi.wwnn, NULL);
 	if (i) {
 		LOGINF("Deleted vhba wwnn:%x:%x\n", scsi.wwnn.wwnn1,
@@ -574,7 +570,7 @@ static int delete_vnic(struct del_virt_guestpart *delparams)
 	LOGINF("Deleting vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
 	       net.mac_addr[0], net.mac_addr[1], net.mac_addr[2],
 	       net.mac_addr[3], net.mac_addr[4], net.mac_addr[5]);
-	i = virtpci_device_del(NULL /*no parent bus */ , VIRTNIC_TYPE, NULL,
+	i = virtpci_device_del(NULL /*no parent bus */, VIRTNIC_TYPE, NULL,
 			       net.mac_addr);
 	if (i) {
 		LOGINF("Deleted vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -757,18 +753,6 @@ static int virtpci_uevent(struct device *dev, struct kobj_uevent_env *env)
 	return 0;
 }
 
-static int virtpci_device_suspend(struct device *dev, pm_message_t state)
-{
-	DBGINF("In virtpci_device_suspend -NYI ****\n");
-	return 0;
-}
-
-static int virtpci_device_resume(struct device *dev)
-{
-	DBGINF("In virtpci_device_resume -NYI ****\n");
-	return 0;
-}
-
 /* For a child device just created on a client bus, fill in
  * information about the driver that is controlling this device into
  * the appropriate slot within the vbus channel of the bus
@@ -1338,18 +1322,13 @@ static ssize_t virtpci_driver_attr_show(struct kobject *kobj,
 	ssize_t ret = 0;
 
 	struct driver_private *dprivate = to_driver(kobj);
-	struct device_driver *driver;
+	struct device_driver *driver = dprivate->driver;
 
-	if (dprivate != NULL)
-		driver = dprivate->driver;
-	else
-		driver = NULL;
+	DBGINF("In virtpci_driver_attr_show driver->name:%s\n",	driver->name);
+
+	if (dattr->show)
+		ret = dattr->show(driver, buf);
 
-	DBGINF("In virtpci_driver_attr_show driver->name:%s\n", driver->name);
-	if (driver) {
-		if (dattr->show)
-			ret = dattr->show(driver, buf);
-	}
 	return ret;
 }
 
@@ -1361,19 +1340,13 @@ static ssize_t virtpci_driver_attr_store(struct kobject *kobj,
 	ssize_t ret = 0;
 
 	struct driver_private *dprivate = to_driver(kobj);
-	struct device_driver *driver;
-
-	if (dprivate != NULL)
-		driver = dprivate->driver;
-	else
-		driver = NULL;
+	struct device_driver *driver = dprivate->driver;
 
 	DBGINF("In virtpci_driver_attr_store driver->name:%s\n", driver->name);
 
-	if (driver) {
-		if (dattr->store)
-			ret = dattr->store(driver, buf, count);
-	}
+	if (dattr->store)
+		ret = dattr->store(driver, buf, count);
+
 	return ret;
 }
 
diff --git a/drivers/staging/unisys/visorchannel/visorchannel.h b/drivers/staging/unisys/visorchannel/visorchannel.h
index 5061edff959a..63f1b9760373 100644
--- a/drivers/staging/unisys/visorchannel/visorchannel.h
+++ b/drivers/staging/unisys/visorchannel/visorchannel.h
@@ -29,49 +29,48 @@
 #define BOOL int
 #endif
 
-/* VISORCHANNEL is an opaque structure to users.
- * Fields are declared only in the implementation .c files.
- */
-typedef struct VISORCHANNEL_Tag VISORCHANNEL;
-
 /* Note that for visorchannel_create() and visorchannel_create_overlapped(),
- * <channelBytes> and <guid> arguments may be 0 if we are a channel CLIENT.
+ * <channel_bytes> and <guid> arguments may be 0 if we are a channel CLIENT.
  * In this case, the values can simply be read from the channel header.
  */
-VISORCHANNEL *visorchannel_create(HOSTADDRESS physaddr,
-				  ulong channelBytes, uuid_le guid);
-VISORCHANNEL *visorchannel_create_overlapped(ulong channelBytes,
-					     VISORCHANNEL *parent, ulong off,
-					     uuid_le guid);
-VISORCHANNEL *visorchannel_create_with_lock(HOSTADDRESS physaddr,
-					    ulong channelBytes, uuid_le guid);
-VISORCHANNEL *visorchannel_create_overlapped_with_lock(ulong channelBytes,
-						       VISORCHANNEL *parent,
-						       ulong off, uuid_le guid);
-void visorchannel_destroy(VISORCHANNEL *channel);
-int visorchannel_read(VISORCHANNEL *channel, ulong offset,
+struct visorchannel *visorchannel_create(HOSTADDRESS physaddr,
+					 ulong channel_bytes, uuid_le guid);
+struct visorchannel *visorchannel_create_overlapped(ulong channel_bytes,
+						    struct visorchannel *parent,
+						    ulong off, uuid_le guid);
+struct visorchannel *visorchannel_create_with_lock(HOSTADDRESS physaddr,
+						   ulong channel_bytes,
+						   uuid_le guid);
+struct visorchannel *visorchannel_create_overlapped_with_lock(
+				ulong channel_bytes,
+				struct visorchannel *parent,
+				ulong off, uuid_le guid);
+void visorchannel_destroy(struct visorchannel *channel);
+int visorchannel_read(struct visorchannel *channel, ulong offset,
 		      void *local, ulong nbytes);
-int visorchannel_write(VISORCHANNEL *channel, ulong offset,
+int visorchannel_write(struct visorchannel *channel, ulong offset,
 		       void *local, ulong nbytes);
-int visorchannel_clear(VISORCHANNEL *channel, ulong offset,
+int visorchannel_clear(struct visorchannel *channel, ulong offset,
 		       u8 ch, ulong nbytes);
-BOOL visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg);
-BOOL visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg);
-int visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue);
-int visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue);
-
-HOSTADDRESS visorchannel_get_physaddr(VISORCHANNEL *channel);
-ulong visorchannel_get_nbytes(VISORCHANNEL *channel);
-char *visorchannel_id(VISORCHANNEL *channel, char *s);
-char *visorchannel_zoneid(VISORCHANNEL *channel, char *s);
-u64 visorchannel_get_clientpartition(VISORCHANNEL *channel);
-uuid_le visorchannel_get_uuid(VISORCHANNEL *channel);
-struct memregion *visorchannel_get_memregion(VISORCHANNEL *channel);
+BOOL visorchannel_signalremove(struct visorchannel *channel, u32 queue,
+			       void *msg);
+BOOL visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
+			       void *msg);
+int visorchannel_signalqueue_slots_avail(struct visorchannel *channel,
+					 u32 queue);
+int visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue);
+HOSTADDRESS visorchannel_get_physaddr(struct visorchannel *channel);
+ulong visorchannel_get_nbytes(struct visorchannel *channel);
+char *visorchannel_id(struct visorchannel *channel, char *s);
+char *visorchannel_zoneid(struct visorchannel *channel, char *s);
+u64 visorchannel_get_clientpartition(struct visorchannel *channel);
+uuid_le visorchannel_get_uuid(struct visorchannel *channel);
+struct memregion *visorchannel_get_memregion(struct visorchannel *channel);
 char *visorchannel_uuid_id(uuid_le *guid, char *s);
-void visorchannel_debug(VISORCHANNEL *channel, int nQueues,
+void visorchannel_debug(struct visorchannel *channel, int num_queues,
 			struct seq_file *seq, u32 off);
-void visorchannel_dump_section(VISORCHANNEL *chan, char *s,
+void visorchannel_dump_section(struct visorchannel *chan, char *s,
 			       int off, int len, struct seq_file *seq);
-void __iomem *visorchannel_get_header(VISORCHANNEL *channel);
+void __iomem *visorchannel_get_header(struct visorchannel *channel);
 
 #endif
diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
index 36559d5fa673..0188ef866fdd 100644
--- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
+++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c
@@ -28,14 +28,15 @@
 
 #define MYDRVNAME "visorchannel"
 
-struct VISORCHANNEL_Tag {
+struct visorchannel {
 	struct memregion *memregion;	/* from visor_memregion_create() */
 	struct channel_header chan_hdr;
 	uuid_le guid;
 	ulong size;
-	BOOL needs_lock;
-	spinlock_t insert_lock;
-	spinlock_t remove_lock;
+	BOOL needs_lock;	/* channel creator knows if more than one
+				 * thread will be inserting or removing */
+	spinlock_t insert_lock; /* protect head writes in chan_hdr */
+	spinlock_t remove_lock;	/* protect tail writes in chan_hdr */
 
 	struct {
 		struct signal_queue_header req_queue;
@@ -45,18 +46,18 @@ struct VISORCHANNEL_Tag {
 	} safe_uis_queue;
 };
 
-/* Creates the VISORCHANNEL abstraction for a data area in memory, but does
- * NOT modify this data area.
+/* Creates the struct visorchannel abstraction for a data area in memory,
+ * but does NOT modify this data area.
  */
-static VISORCHANNEL *
-visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes,
-			 VISORCHANNEL *parent, ulong off, uuid_le guid,
+static struct visorchannel *
+visorchannel_create_guts(HOSTADDRESS physaddr, ulong channel_bytes,
+			 struct visorchannel *parent, ulong off, uuid_le guid,
 			 BOOL needs_lock)
 {
-	VISORCHANNEL *p = NULL;
+	struct visorchannel *p = NULL;
 	void *rc = NULL;
 
-	p = kmalloc(sizeof(VISORCHANNEL), GFP_KERNEL|__GFP_NORETRY);
+	p = kmalloc(sizeof(*p), GFP_KERNEL|__GFP_NORETRY);
 	if (p == NULL) {
 		ERRDRV("allocation failed: (status=0)\n");
 		rc = NULL;
@@ -87,18 +88,18 @@ visorchannel_create_guts(HOSTADDRESS physaddr, ulong channelBytes,
 		rc = NULL;
 		goto cleanup;
 	}
-	if (channelBytes == 0)
+	if (channel_bytes == 0)
 		/* we had better be a CLIENT of this channel */
-		channelBytes = (ulong)p->chan_hdr.size;
+		channel_bytes = (ulong)p->chan_hdr.size;
 	if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
 		/* we had better be a CLIENT of this channel */
 		guid = p->chan_hdr.chtype;
-	if (visor_memregion_resize(p->memregion, channelBytes) < 0) {
+	if (visor_memregion_resize(p->memregion, channel_bytes) < 0) {
 		ERRDRV("visor_memregion_resize failed: (status=0)\n");
 		rc = NULL;
 		goto cleanup;
 	}
-	p->size = channelBytes;
+	p->size = channel_bytes;
 	p->guid = guid;
 
 	rc = p;
@@ -113,44 +114,45 @@ cleanup:
 	return rc;
 }
 
-VISORCHANNEL *
-visorchannel_create(HOSTADDRESS physaddr, ulong channelBytes, uuid_le guid)
+struct visorchannel *
+visorchannel_create(HOSTADDRESS physaddr, ulong channel_bytes, uuid_le guid)
 {
-	return visorchannel_create_guts(physaddr, channelBytes, NULL, 0, guid,
+	return visorchannel_create_guts(physaddr, channel_bytes, NULL, 0, guid,
 					FALSE);
 }
 EXPORT_SYMBOL_GPL(visorchannel_create);
 
-VISORCHANNEL *
-visorchannel_create_with_lock(HOSTADDRESS physaddr, ulong channelBytes,
+struct visorchannel *
+visorchannel_create_with_lock(HOSTADDRESS physaddr, ulong channel_bytes,
 			      uuid_le guid)
 {
-	return visorchannel_create_guts(physaddr, channelBytes, NULL, 0, guid,
+	return visorchannel_create_guts(physaddr, channel_bytes, NULL, 0, guid,
 					TRUE);
 }
 EXPORT_SYMBOL_GPL(visorchannel_create_with_lock);
 
-VISORCHANNEL *
-visorchannel_create_overlapped(ulong channelBytes,
-			       VISORCHANNEL *parent, ulong off, uuid_le guid)
+struct visorchannel *
+visorchannel_create_overlapped(ulong channel_bytes,
+			       struct visorchannel *parent, ulong off,
+			       uuid_le guid)
 {
-	return visorchannel_create_guts(0, channelBytes, parent, off, guid,
+	return visorchannel_create_guts(0, channel_bytes, parent, off, guid,
 					FALSE);
 }
 EXPORT_SYMBOL_GPL(visorchannel_create_overlapped);
 
-VISORCHANNEL *
-visorchannel_create_overlapped_with_lock(ulong channelBytes,
-					 VISORCHANNEL *parent, ulong off,
+struct visorchannel *
+visorchannel_create_overlapped_with_lock(ulong channel_bytes,
+					 struct visorchannel *parent, ulong off,
 					 uuid_le guid)
 {
-	return visorchannel_create_guts(0, channelBytes, parent, off, guid,
+	return visorchannel_create_guts(0, channel_bytes, parent, off, guid,
 					TRUE);
 }
 EXPORT_SYMBOL_GPL(visorchannel_create_overlapped_with_lock);
 
 void
-visorchannel_destroy(VISORCHANNEL *channel)
+visorchannel_destroy(struct visorchannel *channel)
 {
 	if (channel == NULL)
 		return;
@@ -163,14 +165,14 @@ visorchannel_destroy(VISORCHANNEL *channel)
 EXPORT_SYMBOL_GPL(visorchannel_destroy);
 
 HOSTADDRESS
-visorchannel_get_physaddr(VISORCHANNEL *channel)
+visorchannel_get_physaddr(struct visorchannel *channel)
 {
 	return visor_memregion_get_physaddr(channel->memregion);
 }
 EXPORT_SYMBOL_GPL(visorchannel_get_physaddr);
 
 ulong
-visorchannel_get_nbytes(VISORCHANNEL *channel)
+visorchannel_get_nbytes(struct visorchannel *channel)
 {
 	return channel->size;
 }
@@ -185,42 +187,42 @@ visorchannel_uuid_id(uuid_le *guid, char *s)
 EXPORT_SYMBOL_GPL(visorchannel_uuid_id);
 
 char *
-visorchannel_id(VISORCHANNEL *channel, char *s)
+visorchannel_id(struct visorchannel *channel, char *s)
 {
 	return visorchannel_uuid_id(&channel->guid, s);
 }
 EXPORT_SYMBOL_GPL(visorchannel_id);
 
 char *
-visorchannel_zoneid(VISORCHANNEL *channel, char *s)
+visorchannel_zoneid(struct visorchannel *channel, char *s)
 {
 	return visorchannel_uuid_id(&channel->chan_hdr.zone_uuid, s);
 }
 EXPORT_SYMBOL_GPL(visorchannel_zoneid);
 
 HOSTADDRESS
-visorchannel_get_clientpartition(VISORCHANNEL *channel)
+visorchannel_get_clientpartition(struct visorchannel *channel)
 {
 	return channel->chan_hdr.partition_handle;
 }
 EXPORT_SYMBOL_GPL(visorchannel_get_clientpartition);
 
 uuid_le
-visorchannel_get_uuid(VISORCHANNEL *channel)
+visorchannel_get_uuid(struct visorchannel *channel)
 {
 	return channel->guid;
 }
 EXPORT_SYMBOL_GPL(visorchannel_get_uuid);
 
 struct memregion *
-visorchannel_get_memregion(VISORCHANNEL *channel)
+visorchannel_get_memregion(struct visorchannel *channel)
 {
 	return channel->memregion;
 }
 EXPORT_SYMBOL_GPL(visorchannel_get_memregion);
 
 int
-visorchannel_read(VISORCHANNEL *channel, ulong offset,
+visorchannel_read(struct visorchannel *channel, ulong offset,
 		  void *local, ulong nbytes)
 {
 	int rc = visor_memregion_read(channel->memregion, offset,
@@ -235,7 +237,7 @@ visorchannel_read(VISORCHANNEL *channel, ulong offset,
 EXPORT_SYMBOL_GPL(visorchannel_read);
 
 int
-visorchannel_write(VISORCHANNEL *channel, ulong offset,
+visorchannel_write(struct visorchannel *channel, ulong offset,
 		   void *local, ulong nbytes)
 {
 	if (offset == 0 && nbytes >= sizeof(struct channel_header))
@@ -246,7 +248,8 @@ visorchannel_write(VISORCHANNEL *channel, ulong offset,
 EXPORT_SYMBOL_GPL(visorchannel_write);
 
 int
-visorchannel_clear(VISORCHANNEL *channel, ulong offset, u8 ch, ulong nbytes)
+visorchannel_clear(struct visorchannel *channel, ulong offset, u8 ch,
+		   ulong nbytes)
 {
 	int rc = -1;
 	int bufsize = 65536;
@@ -285,7 +288,7 @@ cleanup:
 EXPORT_SYMBOL_GPL(visorchannel_clear);
 
 void __iomem  *
-visorchannel_get_header(VISORCHANNEL *channel)
+visorchannel_get_header(struct visorchannel *channel)
 {
 	return (void __iomem *)&channel->chan_hdr;
 }
@@ -316,7 +319,7 @@ EXPORT_SYMBOL_GPL(visorchannel_get_header);
 			       sizeof((sig_hdr)->FIELD)) >= 0)
 
 static BOOL
-sig_read_header(VISORCHANNEL *channel, u32 queue,
+sig_read_header(struct visorchannel *channel, u32 queue,
 		struct signal_queue_header *sig_hdr)
 {
 	BOOL rc = FALSE;
@@ -344,7 +347,7 @@ cleanup:
 }
 
 static BOOL
-sig_do_data(VISORCHANNEL *channel, u32 queue,
+sig_do_data(struct visorchannel *channel, u32 queue,
 	    struct signal_queue_header *sig_hdr, u32 slot, void *data,
 	    BOOL is_write)
 {
@@ -373,14 +376,14 @@ cleanup:
 }
 
 static inline BOOL
-sig_read_data(VISORCHANNEL *channel, u32 queue,
+sig_read_data(struct visorchannel *channel, u32 queue,
 	      struct signal_queue_header *sig_hdr, u32 slot, void *data)
 {
 	return sig_do_data(channel, queue, sig_hdr, slot, data, FALSE);
 }
 
 static inline BOOL
-sig_write_data(VISORCHANNEL *channel, u32 queue,
+sig_write_data(struct visorchannel *channel, u32 queue,
 	       struct signal_queue_header *sig_hdr, u32 slot, void *data)
 {
 	return sig_do_data(channel, queue, sig_hdr, slot, data, TRUE);
@@ -408,27 +411,21 @@ safe_sig_queue_validate(struct signal_queue_header *psafe_sqh,
 	return 1;
 }				/* end safe_sig_queue_validate */
 
-BOOL
-visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg)
+static BOOL
+signalremove_inner(struct visorchannel *channel, u32 queue, void *msg)
 {
-	BOOL rc = FALSE;
 	struct signal_queue_header sig_hdr;
 
-	if (channel->needs_lock)
-		spin_lock(&channel->remove_lock);
-
 	if (!sig_read_header(channel, queue, &sig_hdr)) {
-		rc = FALSE;
-		goto cleanup;
-	}
-	if (sig_hdr.head == sig_hdr.tail) {
-		rc = FALSE;	/* no signals to remove */
-		goto cleanup;
+		return FALSE;
 	}
+	if (sig_hdr.head == sig_hdr.tail)
+		return FALSE;	/* no signals to remove */
+
 	sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots;
 	if (!sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg)) {
-		ERRDRV("sig_read_data failed: (status=%d)\n", rc);
-		goto cleanup;
+		ERRDRV("sig_read_data failed\n");
+		return FALSE;
 	}
 	sig_hdr.num_received++;
 
@@ -437,53 +434,54 @@ visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg)
 	 */
 	mb(); /* required for channel synch */
 	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail)) {
-		ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n",
-		       rc);
-		goto cleanup;
+		ERRDRV("visor_memregion_write of Tail failed\n");
+		return FALSE;
 	}
 	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received)) {
-		ERRDRV("visor_memregion_write of NumSignalsReceived failed: (status=%d)\n",
-		       rc);
-		goto cleanup;
+		ERRDRV("visor_memregion_write of NumSignalsReceived failed\n");
+		return FALSE;
 	}
-	rc = TRUE;
-cleanup:
-	if (channel->needs_lock)
+	return TRUE;
+}
+
+BOOL
+visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
+{
+	BOOL rc;
+
+	if (channel->needs_lock) {
+		spin_lock(&channel->remove_lock);
+		rc = signalremove_inner(channel, queue, msg);
 		spin_unlock(&channel->remove_lock);
+	} else {
+		rc = signalremove_inner(channel, queue, msg);
+	}
 
 	return rc;
 }
 EXPORT_SYMBOL_GPL(visorchannel_signalremove);
 
-BOOL
-visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg)
+static BOOL
+signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
 {
-	BOOL rc = FALSE;
 	struct signal_queue_header sig_hdr;
 
-	if (channel->needs_lock)
-		spin_lock(&channel->insert_lock);
-
 	if (!sig_read_header(channel, queue, &sig_hdr)) {
-		rc = FALSE;
-		goto cleanup;
+		return FALSE;
 	}
 
 	sig_hdr.head = ((sig_hdr.head + 1) % sig_hdr.max_slots);
 	if (sig_hdr.head == sig_hdr.tail) {
 		sig_hdr.num_overflows++;
-		if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows)) {
-			ERRDRV("visor_memregion_write of NumOverflows failed: (status=%d)\n",
-			       rc);
-			goto cleanup;
-		}
-		rc = FALSE;
-		goto cleanup;
+		if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows))
+			ERRDRV("visor_memregion_write of NumOverflows failed\n");
+
+		return FALSE;
 	}
 
 	if (!sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg)) {
-		ERRDRV("sig_write_data failed: (status=%d)\n", rc);
-		goto cleanup;
+		ERRDRV("sig_write_data failed\n");
+		return FALSE;
 	}
 	sig_hdr.num_sent++;
 
@@ -492,26 +490,36 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg)
 	 */
 	mb(); /* required for channel synch */
 	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, head)) {
-		ERRDRV("visor_memregion_write of Head failed: (status=%d)\n",
-		       rc);
-		goto cleanup;
+		ERRDRV("visor_memregion_write of Head failed\n");
+		return FALSE;
 	}
 	if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent)) {
-		ERRDRV("visor_memregion_write of NumSignalsSent failed: (status=%d)\n",
-		       rc);
-		goto cleanup;
+		ERRDRV("visor_memregion_write of NumSignalsSent failed\n");
+		return FALSE;
 	}
-	rc = TRUE;
-cleanup:
-	if (channel->needs_lock)
+
+	return TRUE;
+}
+
+BOOL
+visorchannel_signalinsert(struct visorchannel *channel, u32 queue, void *msg)
+{
+	BOOL rc;
+
+	if (channel->needs_lock) {
+		spin_lock(&channel->insert_lock);
+		rc = signalinsert_inner(channel, queue, msg);
 		spin_unlock(&channel->insert_lock);
+	} else {
+		rc = signalinsert_inner(channel, queue, msg);
+	}
 
 	return rc;
 }
 EXPORT_SYMBOL_GPL(visorchannel_signalinsert);
 
 int
-visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue)
+visorchannel_signalqueue_slots_avail(struct visorchannel *channel, u32 queue)
 {
 	struct signal_queue_header sig_hdr;
 	u32 slots_avail, slots_used;
@@ -530,7 +538,7 @@ visorchannel_signalqueue_slots_avail(VISORCHANNEL *channel, u32 queue)
 EXPORT_SYMBOL_GPL(visorchannel_signalqueue_slots_avail);
 
 int
-visorchannel_signalqueue_max_slots(VISORCHANNEL *channel, u32 queue)
+visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue)
 {
 	struct signal_queue_header sig_hdr;
 
@@ -565,7 +573,7 @@ sigqueue_debug(struct signal_queue_header *q, int which, struct seq_file *seq)
 }
 
 void
-visorchannel_debug(VISORCHANNEL *channel, int nQueues,
+visorchannel_debug(struct visorchannel *channel, int num_queues,
 		   struct seq_file *seq, u32 off)
 {
 	HOSTADDRESS addr = 0;
@@ -625,7 +633,7 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues,
 	if ((phdr->ch_space_offset == 0) || (errcode < 0))
 		;
 	else
-		for (i = 0; i < nQueues; i++) {
+		for (i = 0; i < num_queues; i++) {
 			struct signal_queue_header q;
 
 			errcode = visorchannel_read(channel,
@@ -647,7 +655,7 @@ visorchannel_debug(VISORCHANNEL *channel, int nQueues,
 EXPORT_SYMBOL_GPL(visorchannel_debug);
 
 void
-visorchannel_dump_section(VISORCHANNEL *chan, char *s,
+visorchannel_dump_section(struct visorchannel *chan, char *s,
 			  int off, int len, struct seq_file *seq)
 {
 	char *buf, *tbuf, *fmtbuf;
diff --git a/drivers/staging/unisys/visorchipset/file.c b/drivers/staging/unisys/visorchipset/file.c
index 373fa36b7119..e51fd4e3fa2d 100644
--- a/drivers/staging/unisys/visorchipset/file.c
+++ b/drivers/staging/unisys/visorchipset/file.c
@@ -28,85 +28,75 @@
 
 #define CURRENT_FILE_PC VISOR_CHIPSET_PC_file_c
 
-static struct cdev Cdev;
-static VISORCHANNEL **PControlVm_channel;
-static dev_t MajorDev = -1; /**< indicates major num for device */
-static BOOL Registered = FALSE;
+static struct cdev file_cdev;
+static struct visorchannel **file_controlvm_channel;
+static dev_t majordev = -1; /**< indicates major num for device */
+static BOOL registered = FALSE;
 
 static int visorchipset_open(struct inode *inode, struct file *file);
 static int visorchipset_release(struct inode *inode, struct file *file);
 static int visorchipset_mmap(struct file *file, struct vm_area_struct *vma);
-#ifdef HAVE_UNLOCKED_IOCTL
 long visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-#else
-int visorchipset_ioctl(struct inode *inode, struct file *file,
-		       unsigned int cmd, unsigned long arg);
-#endif
 
 static const struct file_operations visorchipset_fops = {
 	.owner = THIS_MODULE,
 	.open = visorchipset_open,
 	.read = NULL,
 	.write = NULL,
-#ifdef HAVE_UNLOCKED_IOCTL
 	.unlocked_ioctl = visorchipset_ioctl,
-#else
-	.ioctl = visorchipset_ioctl,
-#endif
 	.release = visorchipset_release,
 	.mmap = visorchipset_mmap,
 };
 
 int
-visorchipset_file_init(dev_t majorDev, VISORCHANNEL **pControlVm_channel)
+visorchipset_file_init(dev_t major_dev, struct visorchannel **controlvm_channel)
 {
-	int rc = -1;
+	int rc = 0;
 
-	PControlVm_channel = pControlVm_channel;
-	MajorDev = majorDev;
-	cdev_init(&Cdev, &visorchipset_fops);
-	Cdev.owner = THIS_MODULE;
-	if (MAJOR(MajorDev) == 0) {
+	file_controlvm_channel = controlvm_channel;
+	majordev = major_dev;
+	cdev_init(&file_cdev, &visorchipset_fops);
+	file_cdev.owner = THIS_MODULE;
+	if (MAJOR(majordev) == 0) {
 		/* dynamic major device number registration required */
-		if (alloc_chrdev_region(&MajorDev, 0, 1, MYDRVNAME) < 0) {
+		if (alloc_chrdev_region(&majordev, 0, 1, MYDRVNAME) < 0) {
 			ERRDRV("Unable to allocate+register char device %s",
 			       MYDRVNAME);
-			goto Away;
+			return -1;
 		}
-		Registered = TRUE;
-		INFODRV("New major number %d registered\n", MAJOR(MajorDev));
+		registered = TRUE;
+		INFODRV("New major number %d registered\n", MAJOR(majordev));
 	} else {
 		/* static major device number registration required */
-		if (register_chrdev_region(MajorDev, 1, MYDRVNAME) < 0) {
+		if (register_chrdev_region(majordev, 1, MYDRVNAME) < 0) {
 			ERRDRV("Unable to register char device %s", MYDRVNAME);
-			goto Away;
+			return -1;
 		}
-		Registered = TRUE;
-		INFODRV("Static major number %d registered\n", MAJOR(MajorDev));
+		registered = TRUE;
+		INFODRV("Static major number %d registered\n", MAJOR(majordev));
 	}
-	if (cdev_add(&Cdev, MKDEV(MAJOR(MajorDev), 0), 1) < 0) {
+	rc = cdev_add(&file_cdev, MKDEV(MAJOR(majordev), 0), 1);
+	if (rc  < 0) {
 		ERRDRV("failed to create char device: (status=%d)\n", rc);
-		goto Away;
+		return -1;
 	}
 	INFODRV("Registered char device for %s (major=%d)",
-		MYDRVNAME, MAJOR(MajorDev));
-	rc = 0;
-Away:
-	return rc;
+		MYDRVNAME, MAJOR(majordev));
+	return 0;
 }
 
 void
 visorchipset_file_cleanup(void)
 {
-	if (Cdev.ops != NULL)
-		cdev_del(&Cdev);
-	Cdev.ops = NULL;
-	if (Registered) {
-		if (MAJOR(MajorDev) >= 0) {
-			unregister_chrdev_region(MajorDev, 1);
-			MajorDev = MKDEV(0, 0);
+	if (file_cdev.ops != NULL)
+		cdev_del(&file_cdev);
+	file_cdev.ops = NULL;
+	if (registered) {
+		if (MAJOR(majordev) >= 0) {
+			unregister_chrdev_region(majordev, 1);
+			majordev = MKDEV(0, 0);
 		}
-		Registered = FALSE;
+		registered = FALSE;
 	}
 }
 
@@ -114,17 +104,12 @@ static int
 visorchipset_open(struct inode *inode, struct file *file)
 {
 	unsigned minor_number = iminor(inode);
-	int rc = -ENODEV;
 
 	DEBUGDRV("%s", __func__);
 	if (minor_number != 0)
-		goto Away;
+		return -ENODEV;
 	file->private_data = NULL;
-	rc = 0;
-Away:
-	if (rc < 0)
-		ERRDRV("%s minor=%d failed", __func__, minor_number);
-	return rc;
+	return 0;
 }
 
 static int
@@ -137,7 +122,7 @@ visorchipset_release(struct inode *inode, struct file *file)
 static int
 visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	ulong physAddr = 0;
+	ulong physaddr = 0;
 	ulong offset = vma->vm_pgoff << PAGE_SHIFT;
 	GUEST_PHYSICAL_ADDRESS addr = 0;
 
@@ -150,11 +135,11 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
 	switch (offset) {
 	case VISORCHIPSET_MMAP_CONTROLCHANOFFSET:
 		vma->vm_flags |= VM_IO;
-		if (*PControlVm_channel == NULL) {
+		if (*file_controlvm_channel == NULL) {
 			ERRDRV("%s no controlvm channel yet", __func__);
 			return -ENXIO;
 		}
-		visorchannel_read(*PControlVm_channel,
+		visorchannel_read(*file_controlvm_channel,
 			offsetof(struct spar_controlvm_channel_protocol,
 				 gp_control_channel),
 			&addr, sizeof(addr));
@@ -162,10 +147,10 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
 			ERRDRV("%s control channel address is 0", __func__);
 			return -ENXIO;
 		}
-		physAddr = (ulong) (addr);
-		DEBUGDRV("mapping physical address = 0x%lx", physAddr);
+		physaddr = (ulong)addr;
+		DEBUGDRV("mapping physical address = 0x%lx", physaddr);
 		if (remap_pfn_range(vma, vma->vm_start,
-				    physAddr >> PAGE_SHIFT,
+				    physaddr >> PAGE_SHIFT,
 				    vma->vm_end - vma->vm_start,
 				    /*pgprot_noncached */
 				    (vma->vm_page_prot))) {
@@ -180,16 +165,8 @@ visorchipset_mmap(struct file *file, struct vm_area_struct *vma)
 	return 0;
 }
 
-#ifdef HAVE_UNLOCKED_IOCTL
-long
-visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-#else
-int
-visorchipset_ioctl(struct inode *inode, struct file *file,
-		   unsigned int cmd, unsigned long arg)
-#endif
+long visorchipset_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	int rc = SUCCESS;
 	s64 adjustment;
 	s64 vrtc_offset;
 
@@ -200,28 +177,21 @@ visorchipset_ioctl(struct inode *inode, struct file *file,
 		vrtc_offset = issue_vmcall_query_guest_virtual_time_offset();
 		if (copy_to_user
 		    ((void __user *)arg, &vrtc_offset, sizeof(vrtc_offset))) {
-			rc = -EFAULT;
-			goto Away;
+			return -EFAULT;
 		}
 		DBGINF("insde visorchipset_ioctl, cmd=%d, vrtc_offset=%lld",
 		       cmd, vrtc_offset);
-		break;
+		return SUCCESS;
 	case VMCALL_UPDATE_PHYSICAL_TIME:
 		if (copy_from_user
 		    (&adjustment, (void __user *)arg, sizeof(adjustment))) {
-			rc = -EFAULT;
-			goto Away;
+			return -EFAULT;
 		}
 		DBGINF("insde visorchipset_ioctl, cmd=%d, adjustment=%lld", cmd,
 		       adjustment);
-		rc = issue_vmcall_update_physical_time(adjustment);
-		break;
+		return issue_vmcall_update_physical_time(adjustment);
 	default:
 		LOGERR("visorchipset_ioctl received invalid command");
-		rc = -EFAULT;
-		break;
+		return -EFAULT;
 	}
-Away:
-	DBGINF("exiting %d!", rc);
-	return rc;
 }
diff --git a/drivers/staging/unisys/visorchipset/file.h b/drivers/staging/unisys/visorchipset/file.h
index 21bb906242e1..dc7a19556b3f 100644
--- a/drivers/staging/unisys/visorchipset/file.h
+++ b/drivers/staging/unisys/visorchipset/file.h
@@ -20,7 +20,8 @@
 
 #include "globals.h"
 
-int visorchipset_file_init(dev_t majorDev, VISORCHANNEL **pControlVm_channel);
+int visorchipset_file_init(dev_t majorDev,
+			   struct visorchannel **pControlVm_channel);
 void visorchipset_file_cleanup(void);
 
 #endif
diff --git a/drivers/staging/unisys/visorchipset/globals.h b/drivers/staging/unisys/visorchipset/globals.h
index 0fe14599f185..a1d35d4bef2e 100644
--- a/drivers/staging/unisys/visorchipset/globals.h
+++ b/drivers/staging/unisys/visorchipset/globals.h
@@ -15,7 +15,6 @@
  * details.
  */
 
-
 #ifndef __VISORCHIPSET_GLOBALS_H__
 #define __VISORCHIPSET_GLOBALS_H__
 
@@ -28,7 +27,6 @@
 
 #define MYDRVNAME "visorchipset"
 
-
 /* module parameters */
 
 extern int visorchipset_testvnic;
diff --git a/drivers/staging/unisys/visorchipset/testing.h b/drivers/staging/unisys/visorchipset/testing.h
deleted file mode 100644
index 573aa8b5ba6a..000000000000
--- a/drivers/staging/unisys/visorchipset/testing.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* testing.h
- *
- * Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- */
-
-#ifndef __VISORCHIPSET_TESTING_H__
-#define __VISORCHIPSET_TESTING_H__
-
-#define VISORCHIPSET_TEST_PROC
-#include <linux/uuid.h>
-#include "globals.h"
-#include "controlvmchannel.h"
-
-void test_produce_test_message(struct controlvm_message *msg,
-			       int isLocalTestAddr);
-BOOL test_consume_test_message(struct controlvm_message *msg);
-void test_manufacture_vnic_client_add(void *p);
-void test_manufacture_vnic_client_add_phys(HOSTADDRESS addr);
-void test_manufacture_preamble_messages(void);
-void test_manufacture_device_attach(ulong busNo, ulong devNo);
-void test_manufacture_device_add(ulong busNo, ulong devNo, uuid_le dataTypeGuid,
-				 void *pChannel);
-void test_manufacture_add_bus(ulong busNo, ulong maxDevices,
-			      uuid_le id, u8 *name, BOOL isServer);
-void test_manufacture_device_destroy(ulong busNo, ulong devNo);
-void test_manufacture_bus_destroy(ulong busNo);
-void test_manufacture_detach_externalPort(ulong switchNo, ulong externalPortNo);
-void test_manufacture_detach_internalPort(ulong switchNo, ulong internalPortNo);
-void test_cleanup(void);
-
-#endif
diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h
index 46dad63fa2c8..98f3ba4c13ac 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset.h
+++ b/drivers/staging/unisys/visorchipset/visorchipset.h
@@ -158,61 +158,6 @@ findbus(struct list_head *list, u32 bus_no)
 	return NULL;
 }
 
-/** Attributes for a particular Supervisor switch.
- */
-struct visorchipset_switch_info {
-	u32 switch_no;
-	struct visorchipset_state state;
-	uuid_le switch_type_uuid;
-	u8 *authservice1;
-	u8 *authservice2;
-	u8 *authservice3;
-	u8 *security_context;
-	u64 reserved;
-	u32 reserved2;		/* control_vm_id */
-	struct device dev;
-	BOOL dev_exists;
-	struct controlvm_message_header pending_msg_hdr;
-};
-
-/** Attributes for a particular Supervisor external port, which is connected
- *  to a specific switch.
- */
-struct visorchipset_externalport_info {
-	u32 switch_no;
-	u32 external_port_no;
-	struct visorchipset_state state;
-	uuid_le network_zone_uuid;
-	int pd_port;
-	u8 *ip;
-	u8 *ip_netmask;
-	u8 *ip_broadcast;
-	u8 *ip_network;
-	u8 *ip_gateway;
-	u8 *ip_dns;
-	u64 reserved1;
-	u32 reserved2;		/* control_vm_id */
-	struct device dev;
-	BOOL dev_exists;
-	struct controlvm_message_header pending_msg_hdr;
-};
-
-/** Attributes for a particular Supervisor internal port, which is how a
- *  device connects to a particular switch.
- */
-struct visorchipset_internalport_info {
-	u32 switch_no;
-	u32 internal_port_no;
-	struct visorchipset_state state;
-	u32 bus_no;		/* valid only when state.attached == 1 */
-	u32 dev_no;		/* valid only when state.attached == 1 */
-	u64 reserved1;
-	u32 reserved2;		/* CONTROLVM_ID */
-	struct controlvm_message_header pending_msg_hdr;
-	MYPROCOBJECT *proc_object;
-
-};
-
 /*  These functions will be called from within visorchipset when certain
  *  events happen.  (The implementation of these functions is outside of
  *  visorchipset.)
diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c
index 7e6be32cf7bb..f606ee9e0de9 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset_main.c
+++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c
@@ -20,7 +20,6 @@
 #include "procobjecttree.h"
 #include "visorchannel.h"
 #include "periodic_work.h"
-#include "testing.h"
 #include "file.h"
 #include "parser.h"
 #include "uniklog.h"
@@ -102,7 +101,7 @@ static struct controlvm_message_packet g_DeviceChangeStatePacket;
 static LIST_HEAD(BusInfoList);
 static LIST_HEAD(DevInfoList);
 
-static VISORCHANNEL *ControlVm_channel;
+static struct visorchannel *ControlVm_channel;
 
 typedef struct {
 	u8 __iomem *ptr;	/* pointer to base address of payload pool */
@@ -1595,7 +1594,7 @@ parahotplug_next_id(void)
 static unsigned long
 parahotplug_next_expiration(void)
 {
-	return jiffies + PARAHOTPLUG_TIMEOUT_MS * HZ / 1000;
+	return jiffies + msecs_to_jiffies(PARAHOTPLUG_TIMEOUT_MS);
 }
 
 /*
diff --git a/drivers/staging/unisys/visorchipset/visorchipset_umode.h b/drivers/staging/unisys/visorchipset/visorchipset_umode.h
index 06ba5b7e4254..6cf6eccb3f4a 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset_umode.h
+++ b/drivers/staging/unisys/visorchipset/visorchipset_umode.h
@@ -26,8 +26,6 @@
 #ifndef __VISORCHIPSET_UMODE_H
 #define __VISORCHIPSET_UMODE_H
 
-
-
 /** The user-mode program can access the control channel buffer directly
  *  via this memory map.
  */
diff --git a/drivers/staging/unisys/visorutil/charqueue.c b/drivers/staging/unisys/visorutil/charqueue.c
index 1ce7003c3a90..ac7acb7c5b79 100644
--- a/drivers/staging/unisys/visorutil/charqueue.c
+++ b/drivers/staging/unisys/visorutil/charqueue.c
@@ -28,7 +28,7 @@
 struct charqueue {
 	int alloc_size;
 	int nslots;
-	spinlock_t lock;
+	spinlock_t lock; /* read/write lock for this structure */
 	int head, tail;
 	unsigned char buf[0];
 };
diff --git a/drivers/staging/unisys/visorutil/procobjecttree.c b/drivers/staging/unisys/visorutil/procobjecttree.c
index 195772d22c9e..82279ca5fbe1 100644
--- a/drivers/staging/unisys/visorutil/procobjecttree.c
+++ b/drivers/staging/unisys/visorutil/procobjecttree.c
@@ -25,12 +25,12 @@
  *  need in order to call the callback function that supplies the /proc read
  *  info for that file.
  */
-typedef struct {
+struct proc_dir_entry_context {
 	void (*show_property)(struct seq_file *, void *, int);
 	MYPROCOBJECT *procObject;
 	int propertyIndex;
 
-} PROCDIRENTRYCONTEXT;
+};
 
 /** This describes the attributes of a tree rooted at
  *  <procDirRoot>/<name[0]>/<name[1]>/...
@@ -86,7 +86,7 @@ struct MYPROCOBJECT_Tag {
 
 	/** this is a holding area for the context information that is needed
 	 *  to run the /proc callback function */
-	PROCDIRENTRYCONTEXT *procDirPropertyContexts;
+	struct proc_dir_entry_context *procDirPropertyContexts;
 };
 
 
@@ -254,15 +254,16 @@ MYPROCOBJECT *visor_proc_CreateObject(MYPROCTYPE *type,
 			goto Away;
 	}
 	obj->procDirPropertyContexts =
-		kzalloc((type->nProperties + 1) * sizeof(PROCDIRENTRYCONTEXT),
+		kzalloc((type->nProperties + 1) *
+			sizeof(struct proc_dir_entry_context),
 			GFP_KERNEL | __GFP_NORETRY);
 	if (obj->procDirPropertyContexts == NULL) {
 		ERRDRV("out of memory\n");
 		goto Away;
 	}
-	obj->procDirProperties =
-		kzalloc((type->nProperties + 1) * sizeof(struct proc_dir_entry *),
-			GFP_KERNEL | __GFP_NORETRY);
+	obj->procDirProperties = kzalloc((type->nProperties + 1) *
+					 sizeof(struct proc_dir_entry *),
+					 GFP_KERNEL | __GFP_NORETRY);
 	if (obj->procDirProperties == NULL) {
 		ERRDRV("out of memory\n");
 		goto Away;
@@ -276,8 +277,8 @@ MYPROCOBJECT *visor_proc_CreateObject(MYPROCTYPE *type,
 			/* only create properties that have names */
 			obj->procDirProperties[i] =
 				createProcFile(type->propertyNames[i],
-					       obj->procDir, &proc_fops,
-					       &obj->procDirPropertyContexts[i]);
+					obj->procDir, &proc_fops,
+					&obj->procDirPropertyContexts[i]);
 			if (obj->procDirProperties[i] == NULL) {
 				rc = NULL;
 				goto Away;
@@ -340,7 +341,7 @@ EXPORT_SYMBOL_GPL(visor_proc_DestroyObject);
 
 static int seq_show(struct seq_file *seq, void *offset)
 {
-	PROCDIRENTRYCONTEXT *ctx = (PROCDIRENTRYCONTEXT *)(seq->private);
+	struct proc_dir_entry_context *ctx = seq->private;
 
 	if (ctx == NULL) {
 		ERRDRV("I don't have a freakin' clue...");
diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c
index f8c5fc371c4c..565ba189afb2 100644
--- a/drivers/staging/vt6655/baseband.c
+++ b/drivers/staging/vt6655/baseband.c
@@ -27,7 +27,8 @@
  *
  * Functions:
  *      BBuGetFrameTime        - Calculate data frame transmitting time
- *      BBvCaculateParameter   - Caculate PhyLength, PhyService and Phy Signal parameter for baseband Tx
+ *      BBvCaculateParameter   - Caculate PhyLength, PhyService and Phy Signal
+ *                               parameter for baseband Tx
  *      BBbReadEmbedded         - Embedded read baseband register via MAC
  *      BBbWriteEmbedded        - Embedded write baseband register via MAC
  *      BBbVT3253Init          - VIA VT3253 baseband chip init code
@@ -1698,46 +1699,6 @@ static const unsigned short awcFrameTime[MAX_RATE] = {
 		10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216
 };
 
-/*---------------------  Static Functions  --------------------------*/
-
-static
-unsigned long
-s_ulGetRatio(struct vnt_private *priv);
-
-static
-void
-s_vChangeAntenna(
-	struct vnt_private *priv
-);
-
-static
-void
-s_vChangeAntenna(
-	struct vnt_private *priv
-)
-{
-	if (priv->dwRxAntennaSel == 0) {
-		priv->dwRxAntennaSel = 1;
-		if (priv->bTxRxAntInv == true)
-			BBvSetRxAntennaMode(priv, ANT_A);
-		else
-			BBvSetRxAntennaMode(priv, ANT_B);
-	} else {
-		priv->dwRxAntennaSel = 0;
-		if (priv->bTxRxAntInv == true)
-			BBvSetRxAntennaMode(priv, ANT_B);
-		else
-			BBvSetRxAntennaMode(priv, ANT_A);
-	}
-	if (priv->dwTxAntennaSel == 0) {
-		priv->dwTxAntennaSel = 1;
-		BBvSetTxAntennaMode(priv, ANT_B);
-	} else {
-		priv->dwTxAntennaSel = 0;
-		BBvSetTxAntennaMode(priv, ANT_A);
-	}
-}
-
 /*---------------------  Export Variables  --------------------------*/
 /*
  * Description: Calculate data frame transmitting time
@@ -2412,303 +2373,3 @@ BBvExitDeepSleep(struct vnt_private *priv, unsigned char byLocalID)
 	BBbWriteEmbedded(priv, 0x0C, 0x00); /* CR12 */
 	BBbWriteEmbedded(priv, 0x0D, 0x01); /* CR13 */
 }
-
-static
-unsigned long
-s_ulGetRatio(struct vnt_private *priv)
-{
-	unsigned long ulRatio = 0;
-	unsigned long ulMaxPacket;
-	unsigned long ulPacketNum;
-
-	/* This is a thousand-ratio */
-	ulMaxPacket = priv->uNumSQ3[RATE_54M];
-	if (priv->uNumSQ3[RATE_54M] != 0) {
-		ulPacketNum = priv->uNumSQ3[RATE_54M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_54M;
-	}
-	if (priv->uNumSQ3[RATE_48M] > ulMaxPacket) {
-		ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_48M;
-		ulMaxPacket = priv->uNumSQ3[RATE_48M];
-	}
-	if (priv->uNumSQ3[RATE_36M] > ulMaxPacket) {
-		ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] +
-			priv->uNumSQ3[RATE_36M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_36M;
-		ulMaxPacket = priv->uNumSQ3[RATE_36M];
-	}
-	if (priv->uNumSQ3[RATE_24M] > ulMaxPacket) {
-		ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] +
-			priv->uNumSQ3[RATE_36M] + priv->uNumSQ3[RATE_24M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_24M;
-		ulMaxPacket = priv->uNumSQ3[RATE_24M];
-	}
-	if (priv->uNumSQ3[RATE_18M] > ulMaxPacket) {
-		ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] +
-			priv->uNumSQ3[RATE_36M] + priv->uNumSQ3[RATE_24M] +
-			priv->uNumSQ3[RATE_18M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_18M;
-		ulMaxPacket = priv->uNumSQ3[RATE_18M];
-	}
-	if (priv->uNumSQ3[RATE_12M] > ulMaxPacket) {
-		ulPacketNum = priv->uNumSQ3[RATE_54M] + priv->uNumSQ3[RATE_48M] +
-			priv->uNumSQ3[RATE_36M] + priv->uNumSQ3[RATE_24M] +
-			priv->uNumSQ3[RATE_18M] + priv->uNumSQ3[RATE_12M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_12M;
-		ulMaxPacket = priv->uNumSQ3[RATE_12M];
-	}
-	if (priv->uNumSQ3[RATE_11M] > ulMaxPacket) {
-		ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] -
-			priv->uNumSQ3[RATE_2M] - priv->uNumSQ3[RATE_5M] -
-			priv->uNumSQ3[RATE_6M] - priv->uNumSQ3[RATE_9M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_11M;
-		ulMaxPacket = priv->uNumSQ3[RATE_11M];
-	}
-	if (priv->uNumSQ3[RATE_9M] > ulMaxPacket) {
-		ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] -
-			priv->uNumSQ3[RATE_2M] - priv->uNumSQ3[RATE_5M] -
-			priv->uNumSQ3[RATE_6M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_9M;
-		ulMaxPacket = priv->uNumSQ3[RATE_9M];
-	}
-	if (priv->uNumSQ3[RATE_6M] > ulMaxPacket) {
-		ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] -
-			priv->uNumSQ3[RATE_2M] - priv->uNumSQ3[RATE_5M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_6M;
-		ulMaxPacket = priv->uNumSQ3[RATE_6M];
-	}
-	if (priv->uNumSQ3[RATE_5M] > ulMaxPacket) {
-		ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M] -
-			priv->uNumSQ3[RATE_2M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_55M;
-		ulMaxPacket = priv->uNumSQ3[RATE_5M];
-	}
-	if (priv->uNumSQ3[RATE_2M] > ulMaxPacket) {
-		ulPacketNum = priv->uDiversityCnt - priv->uNumSQ3[RATE_1M];
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_2M;
-		ulMaxPacket = priv->uNumSQ3[RATE_2M];
-	}
-	if (priv->uNumSQ3[RATE_1M] > ulMaxPacket) {
-		ulPacketNum = priv->uDiversityCnt;
-		ulRatio = (ulPacketNum * 1000 / priv->uDiversityCnt);
-		ulRatio += TOP_RATE_1M;
-	}
-
-	return ulRatio;
-}
-
-void
-BBvClearAntDivSQ3Value(struct vnt_private *priv)
-{
-	unsigned int ii;
-
-	priv->uDiversityCnt = 0;
-	for (ii = 0; ii < MAX_RATE; ii++)
-		priv->uNumSQ3[ii] = 0;
-}
-
-/*
- * Description: Antenna Diversity
- *
- * Parameters:
- *  In:
- *      priv          - Device Structure
- *      byRSR            - RSR from received packet
- *      bySQ3            - SQ3 value from received packet
- *  Out:
- *      none
- *
- * Return Value: none
- *
- */
-
-void BBvAntennaDiversity(struct vnt_private *priv,
-			 unsigned char byRxRate, unsigned char bySQ3)
-{
-	if ((byRxRate >= MAX_RATE) || (priv->wAntDiversityMaxRate >= MAX_RATE))
-		return;
-
-	priv->uDiversityCnt++;
-
-	priv->uNumSQ3[byRxRate]++;
-
-	if (priv->byAntennaState == 0) {
-		if (priv->uDiversityCnt > priv->ulDiversityNValue) {
-			pr_debug("ulDiversityNValue=[%d],54M-[%d]\n",
-				 (int)priv->ulDiversityNValue,
-				 (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate]);
-
-			if (priv->uNumSQ3[priv->wAntDiversityMaxRate] < priv->uDiversityCnt/2) {
-				priv->ulRatio_State0 = s_ulGetRatio(priv);
-				pr_debug("SQ3_State0, rate = [%08x]\n",
-					 (int)priv->ulRatio_State0);
-
-				if (priv->byTMax == 0)
-					return;
-				pr_debug("1.[%08x], uNumSQ3[%d]=%d, %d\n",
-					 (int)priv->ulRatio_State0,
-					 (int)priv->wAntDiversityMaxRate,
-					 (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate],
-					 (int)priv->uDiversityCnt);
-
-				s_vChangeAntenna(priv);
-				priv->byAntennaState = 1;
-				del_timer(&priv->TimerSQ3Tmax3);
-				del_timer(&priv->TimerSQ3Tmax2);
-				priv->TimerSQ3Tmax1.expires =  RUN_AT(priv->byTMax * HZ);
-				add_timer(&priv->TimerSQ3Tmax1);
-
-			} else {
-				priv->TimerSQ3Tmax3.expires =  RUN_AT(priv->byTMax3 * HZ);
-				add_timer(&priv->TimerSQ3Tmax3);
-			}
-			BBvClearAntDivSQ3Value(priv);
-
-		}
-	} else { /* byAntennaState == 1 */
-
-		if (priv->uDiversityCnt > priv->ulDiversityMValue) {
-			del_timer(&priv->TimerSQ3Tmax1);
-
-			priv->ulRatio_State1 = s_ulGetRatio(priv);
-			pr_debug("RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n",
-				 (int)priv->ulRatio_State0,
-				 (int)priv->ulRatio_State1);
-
-			if (priv->ulRatio_State1 < priv->ulRatio_State0) {
-				pr_debug("2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
-					 (int)priv->ulRatio_State0,
-					 (int)priv->ulRatio_State1,
-					 (int)priv->wAntDiversityMaxRate,
-					 (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate],
-					 (int)priv->uDiversityCnt);
-
-				s_vChangeAntenna(priv);
-				priv->TimerSQ3Tmax3.expires =  RUN_AT(priv->byTMax3 * HZ);
-				priv->TimerSQ3Tmax2.expires =  RUN_AT(priv->byTMax2 * HZ);
-				add_timer(&priv->TimerSQ3Tmax3);
-				add_timer(&priv->TimerSQ3Tmax2);
-			}
-			priv->byAntennaState = 0;
-			BBvClearAntDivSQ3Value(priv);
-		}
-	} /* byAntennaState */
-}
-
-/*+
- *
- * Description:
- *  Timer for SQ3 antenna diversity
- *
- * Parameters:
- *  In:
- *  Out:
- *      none
- *
- * Return Value: none
- *
- -*/
-
-void
-TimerSQ3CallBack(
-	unsigned long data
-)
-{
-	struct vnt_private *priv = (struct vnt_private *)data;
-	unsigned long flags;
-
-	pr_debug("TimerSQ3CallBack...\n");
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	pr_debug("3.[%08x][%08x], %d\n",
-		 (int)priv->ulRatio_State0, (int)priv->ulRatio_State1,
-		 (int)priv->uDiversityCnt);
-
-	s_vChangeAntenna(priv);
-	priv->byAntennaState = 0;
-	BBvClearAntDivSQ3Value(priv);
-
-	priv->TimerSQ3Tmax3.expires =  RUN_AT(priv->byTMax3 * HZ);
-	priv->TimerSQ3Tmax2.expires =  RUN_AT(priv->byTMax2 * HZ);
-	add_timer(&priv->TimerSQ3Tmax3);
-	add_timer(&priv->TimerSQ3Tmax2);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-/*+
- *
- * Description:
- *  Timer for SQ3 antenna diversity
- *
- * Parameters:
- *  In:
- *      pvSysSpec1
- *      hDeviceContext - Pointer to the adapter
- *      pvSysSpec2
- *      pvSysSpec3
- *  Out:
- *      none
- *
- * Return Value: none
- *
- -*/
-
-void
-TimerState1CallBack(
-	unsigned long data
-)
-{
-	struct vnt_private *priv = (struct vnt_private *)data;
-	unsigned long flags;
-
-	pr_debug("TimerState1CallBack...\n");
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	if (priv->uDiversityCnt < priv->ulDiversityMValue/100) {
-		s_vChangeAntenna(priv);
-		priv->TimerSQ3Tmax3.expires =  RUN_AT(priv->byTMax3 * HZ);
-		priv->TimerSQ3Tmax2.expires =  RUN_AT(priv->byTMax2 * HZ);
-		add_timer(&priv->TimerSQ3Tmax3);
-		add_timer(&priv->TimerSQ3Tmax2);
-	} else {
-		priv->ulRatio_State1 = s_ulGetRatio(priv);
-		pr_debug("SQ3_State1, rate0 = %08x,rate1 = %08x\n",
-			 (int)priv->ulRatio_State0,
-			 (int)priv->ulRatio_State1);
-
-		if (priv->ulRatio_State1 < priv->ulRatio_State0) {
-			pr_debug("2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
-				 (int)priv->ulRatio_State0,
-				 (int)priv->ulRatio_State1,
-				 (int)priv->wAntDiversityMaxRate,
-				 (int)priv->uNumSQ3[(int)priv->wAntDiversityMaxRate],
-				 (int)priv->uDiversityCnt);
-
-			s_vChangeAntenna(priv);
-
-			priv->TimerSQ3Tmax3.expires =  RUN_AT(priv->byTMax3 * HZ);
-			priv->TimerSQ3Tmax2.expires =  RUN_AT(priv->byTMax2 * HZ);
-			add_timer(&priv->TimerSQ3Tmax3);
-			add_timer(&priv->TimerSQ3Tmax2);
-		}
-	}
-	priv->byAntennaState = 0;
-	BBvClearAntDivSQ3Value(priv);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-}
diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h
index d9f6d63e4ab7..43a4fb1f3570 100644
--- a/drivers/staging/vt6655/baseband.h
+++ b/drivers/staging/vt6655/baseband.h
@@ -93,21 +93,4 @@ void BBvSetRxAntennaMode(struct vnt_private *, unsigned char byAntennaMode);
 void BBvSetDeepSleep(struct vnt_private *, unsigned char byLocalID);
 void BBvExitDeepSleep(struct vnt_private *, unsigned char byLocalID);
 
-/* timer for antenna diversity */
-
-void
-TimerSQ3CallBack(
-	unsigned long
-);
-
-void
-TimerState1CallBack(
-	unsigned long
-);
-
-void BBvAntennaDiversity(struct vnt_private *,
-			 unsigned char byRxRate, unsigned char bySQ3);
-void
-BBvClearAntDivSQ3Value(struct vnt_private *);
-
 #endif /* __BASEBAND_H__ */
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index a0796405c308..1cdcf49b2445 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -68,8 +68,8 @@
 
 /*---------------------  Static Variables  --------------------------*/
 
-static const unsigned short cwRXBCNTSFOff[MAX_RATE] =
-{17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
+static const unsigned short cwRXBCNTSFOff[MAX_RATE] = {
+	17, 17, 17, 17, 34, 23, 17, 11, 8, 5, 4, 3};
 
 /*---------------------  Static Functions  --------------------------*/
 
@@ -670,6 +670,9 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, u8 bb_type)
 {
 	union vnt_phy_field_swap phy;
 	unsigned char byTxRate, byRsvTime;      /* For OFDM */
+	unsigned long flags;
+
+	spin_lock_irqsave(&pDevice->lock, flags);
 
 	/* Set to Page1 */
 	MACvSelectPage1(pDevice->PortOffset);
@@ -767,6 +770,8 @@ void CARDvSetRSPINF(struct vnt_private *pDevice, u8 bb_type)
 	VNSvOutPortW(pDevice->PortOffset + MAC_REG_RSPINF_A_72, MAKEWORD(byTxRate, byRsvTime));
 	/* Set to Page0 */
 	MACvSelectPage0(pDevice->PortOffset);
+
+	spin_unlock_irqrestore(&pDevice->lock, flags);
 }
 
 void CARDvUpdateBasicTopRate(struct vnt_private *pDevice)
diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c
index 70f870541f92..3c17725d5910 100644
--- a/drivers/staging/vt6655/channel.c
+++ b/drivers/staging/vt6655/channel.c
@@ -174,12 +174,12 @@ void vnt_init_bands(struct vnt_private *priv)
  * Return Value: true if succeeded; false if failed.
  *
  */
-bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel)
+bool set_channel(void *pDeviceHandler, struct ieee80211_channel *ch)
 {
 	struct vnt_private *pDevice = pDeviceHandler;
 	bool bResult = true;
 
-	if (pDevice->byCurrentCh == uConnectionChannel)
+	if (pDevice->byCurrentCh == ch->hw_value)
 		return bResult;
 
 	/* Set VGA to max sensitivity */
@@ -197,19 +197,23 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel)
 
 	if (pDevice->byRFType == RF_AIROHA7230)
 		RFbAL7230SelectChannelPostProcess(pDevice, pDevice->byCurrentCh,
-						  (unsigned char)uConnectionChannel);
+						  ch->hw_value);
 
-	pDevice->byCurrentCh = (unsigned char)uConnectionChannel;
+	pDevice->byCurrentCh = ch->hw_value;
 	bResult &= RFbSelectChannel(pDevice, pDevice->byRFType,
-				    (unsigned char)uConnectionChannel);
+				    ch->hw_value);
 
 	/* Init Synthesizer Table */
 	if (pDevice->bEnablePSMode)
-		RFvWriteWakeProgSyn(pDevice, pDevice->byRFType, uConnectionChannel);
+		RFvWriteWakeProgSyn(pDevice, pDevice->byRFType, ch->hw_value);
 
 	BBvSoftwareReset(pDevice);
 
 	if (pDevice->byLocalID > REV_ID_VT3253_B1) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&pDevice->lock, flags);
+
 		/* set HW default power register */
 		MACvSelectPage1(pDevice->PortOffset);
 		RFbSetPower(pDevice, RATE_1M, pDevice->byCurrentCh);
@@ -217,6 +221,8 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel)
 		RFbSetPower(pDevice, RATE_6M, pDevice->byCurrentCh);
 		VNSvOutPortB(pDevice->PortOffset + MAC_REG_PWROFDM, pDevice->byCurPwr);
 		MACvSelectPage0(pDevice->PortOffset);
+
+		spin_unlock_irqrestore(&pDevice->lock, flags);
 	}
 
 	if (pDevice->byBBType == BB_TYPE_11B)
diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h
index 4f4264e23462..e2be6fca5f26 100644
--- a/drivers/staging/vt6655/channel.h
+++ b/drivers/staging/vt6655/channel.h
@@ -27,6 +27,6 @@
 
 void vnt_init_bands(struct vnt_private *);
 
-bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel);
+bool set_channel(void *pDeviceHandler, struct ieee80211_channel *);
 
 #endif /* _CHANNEL_H_ */
diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h
index 83efbfb57c79..440537e47121 100644
--- a/drivers/staging/vt6655/device.h
+++ b/drivers/staging/vt6655/device.h
@@ -367,7 +367,7 @@ struct vnt_private {
 	bool bIsBeaconBufReadySet;
 	unsigned int	cbBeaconBufReadySetCnt;
 	bool bFixRate;
-	unsigned char byCurrentCh;
+	u16 byCurrentCh;
 
 	bool bAES;
 
@@ -407,29 +407,6 @@ struct vnt_private {
 	unsigned char byBBCR88;
 	unsigned char byBBCR09;
 
-	bool bDiversityRegCtlON;
-	bool bDiversityEnable;
-	unsigned long ulDiversityNValue;
-	unsigned long ulDiversityMValue;
-	unsigned char byTMax;
-	unsigned char byTMax2;
-	unsigned char byTMax3;
-	unsigned long ulSQ3TH;
-
-	/* ANT diversity */
-	unsigned long uDiversityCnt;
-	unsigned char byAntennaState;
-	unsigned long ulRatio_State0;
-	unsigned long ulRatio_State1;
-
-	/* SQ3 functions for antenna diversity */
-	struct timer_list           TimerSQ3Tmax1;
-	struct timer_list           TimerSQ3Tmax2;
-	struct timer_list           TimerSQ3Tmax3;
-
-	unsigned long uNumSQ3[MAX_RATE];
-	unsigned short wAntDiversityMaxRate;
-
 	unsigned char abyEEPROM[EEP_MAX_CONTEXT_SIZE]; /* unsigned long alignment */
 
 	unsigned short wBeaconInterval;
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index cd1a277d853b..4324282afe49 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -126,10 +126,6 @@ DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
 
 DEVICE_PARAM(BasebandType, "baseband type");
 
-#define DIVERSITY_ANT_DEF     0
-
-DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode");
-
 //
 // Static vars definitions
 //
@@ -152,7 +148,6 @@ static void vt6655_init_info(struct pci_dev *pcid,
 static void device_free_info(struct vnt_private *pDevice);
 static bool device_get_pci_info(struct vnt_private *, struct pci_dev *pcid);
 static void device_print_info(struct vnt_private *pDevice);
-static void device_init_diversity_timer(struct vnt_private *pDevice);
 static  irqreturn_t  device_intr(int irq,  void *dev_instance);
 
 #ifdef CONFIG_PM
@@ -216,7 +211,6 @@ static void device_get_options(struct vnt_private *pDevice)
 	pOpts->short_retry = SHORT_RETRY_DEF;
 	pOpts->long_retry = LONG_RETRY_DEF;
 	pOpts->bbp_type = BBP_TYPE_DEF;
-	pOpts->flags |= DEVICE_FLAGS_DiversityANT;
 }
 
 static void
@@ -224,7 +218,6 @@ device_set_options(struct vnt_private *pDevice)
 {
 	pDevice->byShortRetryLimit = pDevice->sOpts.short_retry;
 	pDevice->byLongRetryLimit = pDevice->sOpts.long_retry;
-	pDevice->bDiversityRegCtlON = (pDevice->sOpts.flags & DEVICE_FLAGS_DiversityANT) ? 1 : 0;
 	pDevice->byBBType = pDevice->sOpts.bbp_type;
 	pDevice->byPacketType = pDevice->byBBType;
 	pDevice->byAutoFBCtrl = AUTO_FB_0;
@@ -236,8 +229,6 @@ device_set_options(struct vnt_private *pDevice)
 	pr_debug(" byPreambleType= %d\n", (int)pDevice->byPreambleType);
 	pr_debug(" byShortPreamble= %d\n", (int)pDevice->byShortPreamble);
 	pr_debug(" byBBType= %d\n", (int)pDevice->byBBType);
-	pr_debug(" pDevice->bDiversityRegCtlON= %d\n",
-		 (int)pDevice->bDiversityRegCtlON);
 }
 
 //
@@ -249,7 +240,6 @@ static void device_init_registers(struct vnt_private *pDevice)
 	unsigned long flags;
 	unsigned int ii;
 	unsigned char byValue;
-	unsigned char byValue1;
 	unsigned char byCCKPwrdBm = 0;
 	unsigned char byOFDMPwrdBm = 0;
 
@@ -301,13 +291,6 @@ static void device_init_registers(struct vnt_private *pDevice)
 	if (byValue == 0)
 		byValue = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
 
-	pDevice->ulDiversityNValue = 100*260;
-	pDevice->ulDiversityMValue = 100*16;
-	pDevice->byTMax = 1;
-	pDevice->byTMax2 = 4;
-	pDevice->ulSQ3TH = 0;
-	pDevice->byTMax3 = 64;
-
 	if (byValue == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
 		pDevice->byAntennaCount = 2;
 		pDevice->byTxAntennaMode = ANT_B;
@@ -318,16 +301,7 @@ static void device_init_registers(struct vnt_private *pDevice)
 			pDevice->byRxAntennaMode = ANT_A;
 		else
 			pDevice->byRxAntennaMode = ANT_B;
-
-		byValue1 = SROMbyReadEmbedded(pDevice->PortOffset,
-					      EEP_OFS_ANTENNA);
-
-		if ((byValue1 & 0x08) == 0)
-			pDevice->bDiversityEnable = false;
-		else
-			pDevice->bDiversityEnable = true;
 	} else  {
-		pDevice->bDiversityEnable = false;
 		pDevice->byAntennaCount = 1;
 		pDevice->dwTxAntennaSel = 0;
 		pDevice->dwRxAntennaSel = 0;
@@ -349,10 +323,9 @@ static void device_init_registers(struct vnt_private *pDevice)
 		}
 	}
 
-	pr_debug("bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
-		 pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue,
-		 (int)pDevice->ulDiversityMValue, pDevice->byTMax,
-		 pDevice->byTMax2);
+	/* Set initial antenna mode */
+	BBvSetTxAntennaMode(pDevice, pDevice->byTxAntennaMode);
+	BBvSetRxAntennaMode(pDevice, pDevice->byRxAntennaMode);
 
 	/* zonetype initial */
 	pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
@@ -493,24 +466,6 @@ static void device_init_registers(struct vnt_private *pDevice)
 	MACvStart(pDevice->PortOffset);
 }
 
-static void device_init_diversity_timer(struct vnt_private *pDevice)
-{
-	init_timer(&pDevice->TimerSQ3Tmax1);
-	pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice;
-	pDevice->TimerSQ3Tmax1.function = TimerSQ3CallBack;
-	pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
-
-	init_timer(&pDevice->TimerSQ3Tmax2);
-	pDevice->TimerSQ3Tmax2.data = (unsigned long) pDevice;
-	pDevice->TimerSQ3Tmax2.function = TimerSQ3CallBack;
-	pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
-
-	init_timer(&pDevice->TimerSQ3Tmax3);
-	pDevice->TimerSQ3Tmax3.data = (unsigned long) pDevice;
-	pDevice->TimerSQ3Tmax3.function = TimerState1CallBack;
-	pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
-}
-
 static void device_print_info(struct vnt_private *pDevice)
 {
 	dev_info(&pDevice->pcid->dev, "%s\n", get_chip_name(pDevice->chip_id));
@@ -1053,6 +1008,58 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc)
 	pTDInfo->byFlags = 0;
 }
 
+static void vnt_check_bb_vga(struct vnt_private *priv)
+{
+	long dbm;
+	int i;
+
+	if (!priv->bUpdateBBVGA)
+		return;
+
+	if (priv->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+		return;
+
+	if (!(priv->vif->bss_conf.assoc && priv->uCurrRSSI))
+		return;
+
+	RFvRSSITodBm(priv, (u8)priv->uCurrRSSI, &dbm);
+
+	for (i = 0; i < BB_VGA_LEVEL; i++) {
+		if (dbm < priv->ldBmThreshold[i]) {
+			priv->byBBVGANew = priv->abyBBVGA[i];
+			break;
+		}
+	}
+
+	if (priv->byBBVGANew == priv->byBBVGACurrent) {
+		priv->uBBVGADiffCount = 1;
+		return;
+	}
+
+	priv->uBBVGADiffCount++;
+
+	if (priv->uBBVGADiffCount == 1) {
+		/* first VGA diff gain */
+		BBvSetVGAGainOffset(priv, priv->byBBVGANew);
+
+		dev_dbg(&priv->pcid->dev,
+			"First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
+			(int)dbm, priv->byBBVGANew,
+			priv->byBBVGACurrent,
+			(int)priv->uBBVGADiffCount);
+	}
+
+	if (priv->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
+		dev_dbg(&priv->pcid->dev,
+			"RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
+			(int)dbm, priv->byBBVGANew,
+			priv->byBBVGACurrent,
+			(int)priv->uBBVGADiffCount);
+
+		BBvSetVGAGainOffset(priv, priv->byBBVGANew);
+	}
+}
+
 static  irqreturn_t  device_intr(int irq,  void *dev_instance)
 {
 	struct vnt_private *pDevice = dev_instance;
@@ -1060,7 +1067,6 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance)
 	unsigned long dwMIBCounter = 0;
 	unsigned char byOrgPageSel = 0;
 	int             handled = 0;
-	int             ii = 0;
 	unsigned long flags;
 
 	MACvReadISR(pDevice->PortOffset, &pDevice->dwIsr);
@@ -1090,7 +1096,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance)
 	// Must do this after doing rx/tx, cause ISR bit is slow
 	// than RD/TD write back
 	// update ISR counter
-	STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic , dwMIBCounter);
+	STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, dwMIBCounter);
 	while (pDevice->dwIsr != 0) {
 		STAvUpdateIsrStatCounter(&pDevice->scStatistic, pDevice->dwIsr);
 		MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);
@@ -1104,44 +1110,8 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance)
 
 		if (pDevice->dwIsr & ISR_TBTT) {
 			if (pDevice->vif &&
-			    pDevice->op_mode != NL80211_IFTYPE_ADHOC) {
-				if (pDevice->bUpdateBBVGA &&
-				    !(pDevice->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
-				    pDevice->vif->bss_conf.assoc &&
-				    pDevice->uCurrRSSI) {
-					long            ldBm;
-
-					RFvRSSITodBm(pDevice, (unsigned char) pDevice->uCurrRSSI, &ldBm);
-					for (ii = 0; ii < BB_VGA_LEVEL; ii++) {
-						if (ldBm < pDevice->ldBmThreshold[ii]) {
-							pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
-							break;
-						}
-					}
-					if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
-						pDevice->uBBVGADiffCount++;
-						if (pDevice->uBBVGADiffCount == 1) {
-							// first VGA diff gain
-							BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
-							pr_debug("First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
-								 (int)ldBm,
-								 pDevice->byBBVGANew,
-								 pDevice->byBBVGACurrent,
-								 (int)pDevice->uBBVGADiffCount);
-						}
-						if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
-							pr_debug("RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
-								 (int)ldBm,
-								 pDevice->byBBVGANew,
-								 pDevice->byBBVGACurrent,
-								 (int)pDevice->uBBVGADiffCount);
-							BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
-						}
-					} else {
-						pDevice->uBBVGADiffCount = 1;
-					}
-				}
-			}
+			    pDevice->op_mode != NL80211_IFTYPE_ADHOC)
+				vnt_check_bb_vga(pDevice);
 
 			pDevice->bBeaconSent = false;
 			if (pDevice->bEnablePSMode)
@@ -1262,12 +1232,15 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 	head_td->m_td1TD1.wReqCount =
 			cpu_to_le16((u16)head_td->pTDInfo->dwReqCount);
 
-	head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;
+	head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma);
+
+	if (dma_idx == TYPE_AC0DMA) {
+		head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;
 
-	if (dma_idx == TYPE_AC0DMA)
 		MACvTransmitAC0(priv->PortOffset);
-	else
+	} else {
 		MACvTransmit0(priv->PortOffset);
+	}
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -1348,8 +1321,6 @@ static int vnt_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 
 	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
-		if (priv->bDiversityRegCtlON)
-			device_init_diversity_timer(priv);
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		MACvRegBitsOff(priv->PortOffset, MAC_REG_RCR, RCR_UNICAST);
@@ -1379,11 +1350,6 @@ static void vnt_remove_interface(struct ieee80211_hw *hw,
 
 	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
-		if (priv->bDiversityRegCtlON) {
-			del_timer(&priv->TimerSQ3Tmax1);
-			del_timer(&priv->TimerSQ3Tmax2);
-			del_timer(&priv->TimerSQ3Tmax3);
-		}
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		MACvRegBitsOff(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
@@ -1420,7 +1386,7 @@ static int vnt_config(struct ieee80211_hw *hw, u32 changed)
 
 	if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) ||
 	    (conf->flags & IEEE80211_CONF_OFFCHANNEL)) {
-		set_channel(priv, conf->chandef.chan->hw_value);
+		set_channel(priv, conf->chandef.chan);
 
 		if (conf->chandef.chan->band == IEEE80211_BAND_5GHZ)
 			bb_type = BB_TYPE_11A;
@@ -1572,6 +1538,10 @@ static void vnt_configure(struct ieee80211_hw *hw,
 
 	if (changed_flags & FIF_ALLMULTI) {
 		if (*total_flags & FIF_ALLMULTI) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&priv->lock, flags);
+
 			if (priv->mc_list_count > 2) {
 				MACvSelectPage1(priv->PortOffset);
 
@@ -1593,6 +1563,8 @@ static void vnt_configure(struct ieee80211_hw *hw,
 				MACvSelectPage0(priv->PortOffset);
 			}
 
+			spin_unlock_irqrestore(&priv->lock, flags);
+
 			rx_mode |= RCR_MULTICAST | RCR_BROADCAST;
 		} else {
 			rx_mode &= ~(RCR_MULTICAST | RCR_BROADCAST);
@@ -1676,7 +1648,7 @@ static const struct ieee80211_ops vnt_mac_ops = {
 	.reset_tsf		= vnt_reset_tsf,
 };
 
-int vnt_init(struct vnt_private *priv)
+static int vnt_init(struct vnt_private *priv)
 {
 	SET_IEEE80211_PERM_ADDR(priv->hw, priv->abyCurrentNetAddr);
 
diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c
index 977683cb7391..3c5b87ffdcac 100644
--- a/drivers/staging/vt6655/dpc.c
+++ b/drivers/staging/vt6655/dpc.c
@@ -91,6 +91,8 @@ static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb,
 	new_rsr = skb_data + bytes_received - 3;
 	rssi = skb_data + bytes_received - 2;
 	rsr = skb_data + bytes_received - 1;
+	if (*rsr & (RSR_IVLDTYP | RSR_IVLDLEN))
+		return false;
 
 	RFvRSSITodBm(priv, *rssi, &rx_dbm);
 
@@ -106,6 +108,9 @@ static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb,
 	rx_status.flag = 0;
 	rx_status.freq = hw->conf.chandef.chan->center_freq;
 
+	if (!(*rsr & RSR_CRCOK))
+		rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+
 	hdr = (struct ieee80211_hdr *)(skb->data);
 	fc = hdr->frame_control;
 
@@ -113,13 +118,11 @@ static bool vnt_rx_data(struct vnt_private *priv, struct sk_buff *skb,
 
 	if (ieee80211_has_protected(fc)) {
 		if (priv->byLocalID > REV_ID_VT3253_A1)
-			rx_status.flag = RX_FLAG_DECRYPTED;
-	}
+			rx_status.flag |= RX_FLAG_DECRYPTED;
 
-	if (priv->vif && priv->bDiversityEnable) {
-		if (ieee80211_is_data(fc) &&
-		    (frame_size > 50) && priv->vif->bss_conf.assoc)
-			BBvAntennaDiversity(priv, priv->rx_rate, 0);
+		/* Drop packet */
+		if (!(*new_rsr & NEWRSR_DECRYPTOK))
+			return false;
 	}
 
 	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c
index 8f0d652fea7c..3653a2bd1e36 100644
--- a/drivers/staging/vt6655/mac.c
+++ b/drivers/staging/vt6655/mac.c
@@ -30,7 +30,6 @@
  *      MACbIsRegBitsOff - Test if All test Bits Off
  *      MACbIsIntDisable - Test if MAC interrupt disable
  *      MACvSetShortRetryLimit - Set 802.11 Short Retry limit
- *      MACvGetShortRetryLimit - Get 802.11 Short Retry limit
  *      MACvSetLongRetryLimit - Set 802.11 Long Retry limit
  *      MACvSetLoopbackMode - Set MAC Loopback Mode
  *      MACvSaveContext - Save Context of MAC Registers
@@ -146,24 +145,6 @@ void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit)
 	VNSvOutPortB(dwIoBase + MAC_REG_SRT, byRetryLimit);
 }
 
-/*
- * Description:
- *      Get 802.11 Short Retry Limit
- *
- * Parameters:
- *  In:
- *      dwIoBase        - Base Address for MAC
- *  Out:
- *      pbyRetryLimit   - Retry Limit Get
- *
- * Return Value: none
- *
- */
-void MACvGetShortRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit)
-{
-	// get SRT
-	VNSvInPortB(dwIoBase + MAC_REG_SRT, pbyRetryLimit);
-}
 
 /*
  * Description:
@@ -356,7 +337,7 @@ bool MACbSafeSoftwareReset(void __iomem *dwIoBase)
 
 /*
  * Description:
- *      Trun Off MAC Rx
+ *      Turn Off MAC Rx
  *
  * Parameters:
  *  In:
@@ -417,7 +398,7 @@ bool MACbSafeRxOff(void __iomem *dwIoBase)
 
 /*
  * Description:
- *      Trun Off MAC Tx
+ *      Turn Off MAC Tx
  *
  * Parameters:
  *  In:
@@ -808,7 +789,7 @@ bool MACbPSWakeup(void __iomem *dwIoBase)
 
 	// Check if SyncFlushOK
 	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
-		VNSvInPortB(dwIoBase + MAC_REG_PSCTL , &byOrgValue);
+		VNSvInPortB(dwIoBase + MAC_REG_PSCTL, &byOrgValue);
 		if (byOrgValue & PSCTL_WAKEDONE)
 			break;
 	}
diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h
index e1e7e10435f6..8e0200a78b19 100644
--- a/drivers/staging/vt6655/mac.h
+++ b/drivers/staging/vt6655/mac.h
@@ -38,13 +38,11 @@
 #include "upc.h"
 
 /*---------------------  Export Definitions -------------------------*/
-//
-// Registers in the MAC
-//
+/* Registers in the MAC */
 #define MAC_MAX_CONTEXT_SIZE_PAGE0  256
 #define MAC_MAX_CONTEXT_SIZE_PAGE1  128
 
-// Registers not related to 802.11b
+/* Registers not related to 802.11b */
 #define MAC_REG_BCFG0       0x00
 #define MAC_REG_BCFG1       0x01
 #define MAC_REG_FCR0        0x02
@@ -69,15 +67,16 @@
 #define MAC_REG_TMCTL0      0x18
 #define MAC_REG_TMCTL1      0x19
 #define MAC_REG_TMDATA0     0x1C
-// MAC Parameter related
-#define MAC_REG_LRT         0x20        //
-#define MAC_REG_SRT         0x21        //
-#define MAC_REG_SIFS        0x22        //
-#define MAC_REG_DIFS        0x23        //
-#define MAC_REG_EIFS        0x24        //
-#define MAC_REG_SLOT        0x25        //
-#define MAC_REG_BI          0x26        //
-#define MAC_REG_CWMAXMIN0   0x28        //
+
+/* MAC Parameter related */
+#define MAC_REG_LRT         0x20
+#define MAC_REG_SRT         0x21
+#define MAC_REG_SIFS        0x22
+#define MAC_REG_DIFS        0x23
+#define MAC_REG_EIFS        0x24
+#define MAC_REG_SLOT        0x25
+#define MAC_REG_BI          0x26
+#define MAC_REG_CWMAXMIN0   0x28
 #define MAC_REG_LINKOFFTOTM 0x2A
 #define MAC_REG_SWTMOT      0x2B
 #define MAC_REG_MIBCNTR     0x2C
@@ -85,26 +84,29 @@
 #define MAC_REG_RTSFAILCNT  0x2D
 #define MAC_REG_ACKFAILCNT  0x2E
 #define MAC_REG_FCSERRCNT   0x2F
-// TSF Related
-#define MAC_REG_TSFCNTR     0x30        //
-#define MAC_REG_NEXTTBTT    0x38        //
-#define MAC_REG_TSFOFST     0x40        //
-#define MAC_REG_TFTCTL      0x48        //
-// WMAC Control/Status Related
-#define MAC_REG_ENCFG       0x4C        //
-#define MAC_REG_PAGE1SEL    0x4F        //
-#define MAC_REG_CFG         0x50        //
-#define MAC_REG_TEST        0x52        //
-#define MAC_REG_HOSTCR      0x54        //
-#define MAC_REG_MACCR       0x55        //
-#define MAC_REG_RCR         0x56        //
-#define MAC_REG_TCR         0x57        //
-#define MAC_REG_IMR         0x58        //
+
+/* TSF Related */
+#define MAC_REG_TSFCNTR     0x30
+#define MAC_REG_NEXTTBTT    0x38
+#define MAC_REG_TSFOFST     0x40
+#define MAC_REG_TFTCTL      0x48
+
+/* WMAC Control/Status Related */
+#define MAC_REG_ENCFG       0x4C
+#define MAC_REG_PAGE1SEL    0x4F
+#define MAC_REG_CFG         0x50
+#define MAC_REG_TEST        0x52
+#define MAC_REG_HOSTCR      0x54
+#define MAC_REG_MACCR       0x55
+#define MAC_REG_RCR         0x56
+#define MAC_REG_TCR         0x57
+#define MAC_REG_IMR         0x58
 #define MAC_REG_ISR         0x5C
-// Power Saving Related
-#define MAC_REG_PSCFG       0x60        //
-#define MAC_REG_PSCTL       0x61        //
-#define MAC_REG_PSPWRSIG    0x62        //
+
+/* Power Saving Related */
+#define MAC_REG_PSCFG       0x60
+#define MAC_REG_PSCTL       0x61
+#define MAC_REG_PSPWRSIG    0x62
 #define MAC_REG_BBCR13      0x63
 #define MAC_REG_AIDATIM     0x64
 #define MAC_REG_PWBT        0x66
@@ -112,41 +114,45 @@
 #define MAC_REG_CALTMR      0x69
 #define MAC_REG_SYNSPACCNT  0x6A
 #define MAC_REG_WAKSYNOPT   0x6B
-// Baseband/IF Control Group
-#define MAC_REG_BBREGCTL    0x6C        //
+
+/* Baseband/IF Control Group */
+#define MAC_REG_BBREGCTL    0x6C
 #define MAC_REG_CHANNEL     0x6D
 #define MAC_REG_BBREGADR    0x6E
 #define MAC_REG_BBREGDATA   0x6F
-#define MAC_REG_IFREGCTL    0x70        //
-#define MAC_REG_IFDATA      0x71        //
-#define MAC_REG_ITRTMSET    0x74        //
+#define MAC_REG_IFREGCTL    0x70
+#define MAC_REG_IFDATA      0x71
+#define MAC_REG_ITRTMSET    0x74
 #define MAC_REG_PAPEDELAY   0x77
-#define MAC_REG_SOFTPWRCTL  0x78        //
-#define MAC_REG_GPIOCTL0    0x7A        //
-#define MAC_REG_GPIOCTL1    0x7B        //
-
-// MAC DMA Related Group
-#define MAC_REG_TXDMACTL0   0x7C        //
-#define MAC_REG_TXDMAPTR0   0x80        //
-#define MAC_REG_AC0DMACTL   0x84        //
-#define MAC_REG_AC0DMAPTR   0x88        //
-#define MAC_REG_BCNDMACTL   0x8C        //
-#define MAC_REG_BCNDMAPTR   0x90        //
-#define MAC_REG_RXDMACTL0   0x94        //
-#define MAC_REG_RXDMAPTR0   0x98        //
-#define MAC_REG_RXDMACTL1   0x9C        //
-#define MAC_REG_RXDMAPTR1   0xA0        //
-#define MAC_REG_SYNCDMACTL  0xA4        //
+#define MAC_REG_SOFTPWRCTL  0x78
+#define MAC_REG_GPIOCTL0    0x7A
+#define MAC_REG_GPIOCTL1    0x7B
+
+/* MAC DMA Related Group */
+#define MAC_REG_TXDMACTL0   0x7C
+#define MAC_REG_TXDMAPTR0   0x80
+#define MAC_REG_AC0DMACTL   0x84
+#define MAC_REG_AC0DMAPTR   0x88
+#define MAC_REG_BCNDMACTL   0x8C
+#define MAC_REG_BCNDMAPTR   0x90
+#define MAC_REG_RXDMACTL0   0x94
+#define MAC_REG_RXDMAPTR0   0x98
+#define MAC_REG_RXDMACTL1   0x9C
+#define MAC_REG_RXDMAPTR1   0xA0
+#define MAC_REG_SYNCDMACTL  0xA4
 #define MAC_REG_SYNCDMAPTR  0xA8
 #define MAC_REG_ATIMDMACTL  0xAC
 #define MAC_REG_ATIMDMAPTR  0xB0
-// MiscFF PIO related
+
+/* MiscFF PIO related */
 #define MAC_REG_MISCFFNDEX  0xB4
 #define MAC_REG_MISCFFCTL   0xB6
 #define MAC_REG_MISCFFDATA  0xB8
-// Extend SW Timer
+
+/* Extend SW Timer */
 #define MAC_REG_TMDATA1     0xBC
-// WOW Related Group
+
+/* WOW Related Group */
 #define MAC_REG_WAKEUPEN0   0xC0
 #define MAC_REG_WAKEUPEN1   0xC1
 #define MAC_REG_WAKEUPSR0   0xC2
@@ -156,19 +162,21 @@
 #define MAC_REG_WAKE128_2   0xE4
 #define MAC_REG_WAKE128_3   0xF4
 
-/////////////// Page 1 ///////////////////
+/************** Page 1 ******************/
 #define MAC_REG_CRC_128_0   0x04
 #define MAC_REG_CRC_128_1   0x06
 #define MAC_REG_CRC_128_2   0x08
 #define MAC_REG_CRC_128_3   0x0A
-// MAC Configuration Group
+
+/* MAC Configuration Group */
 #define MAC_REG_PAR0        0x0C
 #define MAC_REG_PAR4        0x10
 #define MAC_REG_BSSID0      0x14
 #define MAC_REG_BSSID4      0x18
 #define MAC_REG_MAR0        0x1C
 #define MAC_REG_MAR4        0x20
-// MAC RSPPKT INFO Group
+
+/* MAC RSPPKT INFO Group */
 #define MAC_REG_RSPINF_B_1  0x24
 #define MAC_REG_RSPINF_B_2  0x28
 #define MAC_REG_RSPINF_B_5  0x2C
@@ -183,7 +191,7 @@
 #define MAC_REG_RSPINF_A_54 0x42
 #define MAC_REG_RSPINF_A_72 0x44
 
-// 802.11h relative
+/* 802.11h relative */
 #define MAC_REG_QUIETINIT   0x60
 #define MAC_REG_QUIETGAP    0x62
 #define MAC_REG_QUIETDUR    0x64
@@ -195,9 +203,7 @@
 #define MAC_REG_PWRCCK      0x73
 #define MAC_REG_PWROFDM     0x7C
 
-//
-// Bits in the BCFG0 register
-//
+/* Bits in the BCFG0 register */
 #define BCFG0_PERROFF       0x40
 #define BCFG0_MRDMDIS       0x20
 #define BCFG0_MRDLDIS       0x10
@@ -205,9 +211,7 @@
 #define BCFG0_VSERREN       0x02
 #define BCFG0_LATMEN        0x01
 
-//
-// Bits in the BCFG1 register
-//
+/* Bits in the BCFG1 register */
 #define BCFG1_CFUNOPT       0x80
 #define BCFG1_CREQOPT       0x40
 #define BCFG1_DMA8          0x10
@@ -216,25 +220,23 @@
 #define BCFG1_MIOEN         0x02
 #define BCFG1_CISDLYEN      0x01
 
-// Bits in RAMBIST registers
-#define BISTCMD_TSTPAT5     0x00        //
-#define BISTCMD_TSTPATA     0x80        //
-#define BISTCMD_TSTERR      0x20        //
-#define BISTCMD_TSTPATF     0x18        //
-#define BISTCMD_TSTPAT0     0x10        //
-#define BISTCMD_TSTMODE     0x04        //
-#define BISTCMD_TSTITTX     0x03        //
-#define BISTCMD_TSTATRX     0x02        //
-#define BISTCMD_TSTATTX     0x01        //
-#define BISTCMD_TSTRX       0x00        //
-#define BISTSR0_BISTGO      0x01        //
-#define BISTSR1_TSTSR       0x01        //
-#define BISTSR2_CMDPRTEN    0x02        //
-#define BISTSR2_RAMTSTEN    0x01        //
-
-//
-// Bits in the I2MCFG EEPROM register
-//
+/* Bits in RAMBIST registers */
+#define BISTCMD_TSTPAT5     0x00
+#define BISTCMD_TSTPATA     0x80
+#define BISTCMD_TSTERR      0x20
+#define BISTCMD_TSTPATF     0x18
+#define BISTCMD_TSTPAT0     0x10
+#define BISTCMD_TSTMODE     0x04
+#define BISTCMD_TSTITTX     0x03
+#define BISTCMD_TSTATRX     0x02
+#define BISTCMD_TSTATTX     0x01
+#define BISTCMD_TSTRX       0x00
+#define BISTSR0_BISTGO      0x01
+#define BISTSR1_TSTSR       0x01
+#define BISTSR2_CMDPRTEN    0x02
+#define BISTSR2_RAMTSTEN    0x01
+
+/* Bits in the I2MCFG EEPROM register */
 #define I2MCFG_BOUNDCTL     0x80
 #define I2MCFG_WAITCTL      0x20
 #define I2MCFG_SCLOECTL     0x10
@@ -243,50 +245,38 @@
 #define I2MCFG_I2MLDSEQ     0x02
 #define I2MCFG_I2CMFAST     0x01
 
-//
-// Bits in the I2MCSR EEPROM register
-//
+/* Bits in the I2MCSR EEPROM register */
 #define I2MCSR_EEMW         0x80
 #define I2MCSR_EEMR         0x40
 #define I2MCSR_AUTOLD       0x08
 #define I2MCSR_NACK         0x02
 #define I2MCSR_DONE         0x01
 
-//
-// Bits in the PMC1 register
-//
+/* Bits in the PMC1 register */
 #define SPS_RST             0x80
 #define PCISTIKY            0x40
 #define PME_OVR             0x02
 
-//
-// Bits in the STICKYHW register
-//
+/* Bits in the STICKYHW register */
 #define STICKHW_DS1_SHADOW  0x02
 #define STICKHW_DS0_SHADOW  0x01
 
-//
-// Bits in the TMCTL register
-//
+/* Bits in the TMCTL register */
 #define TMCTL_TSUSP         0x04
 #define TMCTL_TMD           0x02
 #define TMCTL_TE            0x01
 
-//
-// Bits in the TFTCTL register
-//
-#define TFTCTL_HWUTSF       0x80        //
+/* Bits in the TFTCTL register */
+#define TFTCTL_HWUTSF       0x80
 #define TFTCTL_TBTTSYNC     0x40
 #define TFTCTL_HWUTSFEN     0x20
-#define TFTCTL_TSFCNTRRD    0x10        //
-#define TFTCTL_TBTTSYNCEN   0x08        //
-#define TFTCTL_TSFSYNCEN    0x04        //
-#define TFTCTL_TSFCNTRST    0x02        //
-#define TFTCTL_TSFCNTREN    0x01        //
-
-//
-// Bits in the EnhanceCFG register
-//
+#define TFTCTL_TSFCNTRRD    0x10
+#define TFTCTL_TBTTSYNCEN   0x08
+#define TFTCTL_TSFSYNCEN    0x04
+#define TFTCTL_TSFCNTRST    0x02
+#define TFTCTL_TSFCNTREN    0x01
+
+/* Bits in the EnhanceCFG register */
 #define EnCFG_BarkerPream   0x00020000
 #define EnCFG_NXTBTTCFPSTR  0x00010000
 #define EnCFG_BcnSusClr     0x00000200
@@ -300,14 +290,10 @@
 #define EnCFG_BBType_b      0x00000001
 #define EnCFG_BBType_a      0x00000000
 
-//
-// Bits in the Page1Sel register
-//
+/* Bits in the Page1Sel register */
 #define PAGE1_SEL           0x01
 
-//
-// Bits in the CFG register
-//
+/* Bits in the CFG register */
 #define CFG_TKIPOPT         0x80
 #define CFG_RXDMAOPT        0x40
 #define CFG_TMOT_SW         0x20
@@ -318,242 +304,196 @@
 #define CFG_NOTXTIMEOUT     0x02
 #define CFG_NOBUFOPT        0x01
 
-//
-// Bits in the TEST register
-//
-#define TEST_LBEXT          0x80        //
-#define TEST_LBINT          0x40        //
-#define TEST_LBNONE         0x00        //
-#define TEST_SOFTINT        0x20        //
-#define TEST_CONTTX         0x10        //
-#define TEST_TXPE           0x08        //
-#define TEST_NAVDIS         0x04        //
-#define TEST_NOCTS          0x02        //
-#define TEST_NOACK          0x01        //
-
-//
-// Bits in the HOSTCR register
-//
-#define HOSTCR_TXONST       0x80        //
-#define HOSTCR_RXONST       0x40        //
-#define HOSTCR_ADHOC        0x20        // Network Type 1 = Ad-hoc
-#define HOSTCR_AP           0x10        // Port Type 1 = AP
-#define HOSTCR_TXON         0x08        //0000 1000
-#define HOSTCR_RXON         0x04        //0000 0100
-#define HOSTCR_MACEN        0x02        //0000 0010
-#define HOSTCR_SOFTRST      0x01        //0000 0001
-
-//
-// Bits in the MACCR register
-//
-#define MACCR_SYNCFLUSHOK   0x04        //
-#define MACCR_SYNCFLUSH     0x02        //
-#define MACCR_CLRNAV        0x01        //
-
-// Bits in the MAC_REG_GPIOCTL0 register
-//
-#define LED_ACTSET           0x01        //
-#define LED_RFOFF            0x02        //
-#define LED_NOCONNECT        0x04        //
-//
-// Bits in the RCR register
-//
+/* Bits in the TEST register */
+#define TEST_LBEXT          0x80
+#define TEST_LBINT          0x40
+#define TEST_LBNONE         0x00
+#define TEST_SOFTINT        0x20
+#define TEST_CONTTX         0x10
+#define TEST_TXPE           0x08
+#define TEST_NAVDIS         0x04
+#define TEST_NOCTS          0x02
+#define TEST_NOACK          0x01
+
+/* Bits in the HOSTCR register */
+#define HOSTCR_TXONST       0x80
+#define HOSTCR_RXONST       0x40
+#define HOSTCR_ADHOC        0x20 /* Network Type 1 = Ad-hoc */
+#define HOSTCR_AP           0x10 /* Port Type 1 = AP */
+#define HOSTCR_TXON         0x08 /* 0000 1000 */
+#define HOSTCR_RXON         0x04 /* 0000 0100 */
+#define HOSTCR_MACEN        0x02 /* 0000 0010 */
+#define HOSTCR_SOFTRST      0x01 /* 0000 0001 */
+
+/* Bits in the MACCR register */
+#define MACCR_SYNCFLUSHOK   0x04
+#define MACCR_SYNCFLUSH     0x02
+#define MACCR_CLRNAV        0x01
+
+/* Bits in the MAC_REG_GPIOCTL0 register */
+#define LED_ACTSET           0x01
+#define LED_RFOFF            0x02
+#define LED_NOCONNECT        0x04
+
+/* Bits in the RCR register */
 #define RCR_SSID            0x80
-#define RCR_RXALLTYPE       0x40        //
-#define RCR_UNICAST         0x20        //
-#define RCR_BROADCAST       0x10        //
-#define RCR_MULTICAST       0x08        //
-#define RCR_WPAERR          0x04        //
-#define RCR_ERRCRC          0x02        //
-#define RCR_BSSID           0x01        //
-
-//
-// Bits in the TCR register
-//
-#define TCR_SYNCDCFOPT      0x02        //
-#define TCR_AUTOBCNTX       0x01        // Beacon automatically transmit enable
-
-//
-// Bits in the IMR register
-//
-#define IMR_MEASURESTART    0x80000000      //
-#define IMR_QUIETSTART      0x20000000      //
-#define IMR_RADARDETECT     0x10000000      //
-#define IMR_MEASUREEND      0x08000000      //
-#define IMR_SOFTTIMER1      0x00200000      //
-#define IMR_RXDMA1          0x00001000      //0000 0000 0001 0000 0000 0000
-#define IMR_RXNOBUF         0x00000800      //
-#define IMR_MIBNEARFULL     0x00000400      //
-#define IMR_SOFTINT         0x00000200      //
-#define IMR_FETALERR        0x00000100      //
-#define IMR_WATCHDOG        0x00000080      //
-#define IMR_SOFTTIMER       0x00000040      //
-#define IMR_GPIO            0x00000020      //
-#define IMR_TBTT            0x00000010      //
-#define IMR_RXDMA0          0x00000008      //
-#define IMR_BNTX            0x00000004      //
-#define IMR_AC0DMA          0x00000002      //
-#define IMR_TXDMA0          0x00000001      //
-
-//
-// Bits in the ISR register
-//
-
-#define ISR_MEASURESTART    0x80000000      //
-#define ISR_QUIETSTART      0x20000000      //
-#define ISR_RADARDETECT     0x10000000      //
-#define ISR_MEASUREEND      0x08000000      //
-#define ISR_SOFTTIMER1      0x00200000      //
-#define ISR_RXDMA1          0x00001000      //0000 0000 0001 0000 0000 0000
-#define ISR_RXNOBUF         0x00000800      //0000 0000 0000 1000 0000 0000
-#define ISR_MIBNEARFULL     0x00000400      //0000 0000 0000 0100 0000 0000
-#define ISR_SOFTINT         0x00000200      //
-#define ISR_FETALERR        0x00000100      //
-#define ISR_WATCHDOG        0x00000080      //
-#define ISR_SOFTTIMER       0x00000040      //
-#define ISR_GPIO            0x00000020      //
-#define ISR_TBTT            0x00000010      //
-#define ISR_RXDMA0          0x00000008      //
-#define ISR_BNTX            0x00000004      //
-#define ISR_AC0DMA          0x00000002      //
-#define ISR_TXDMA0          0x00000001      //
-
-//
-// Bits in the PSCFG register
-//
-#define PSCFG_PHILIPMD      0x40        //
-#define PSCFG_WAKECALEN     0x20        //
-#define PSCFG_WAKETMREN     0x10        //
-#define PSCFG_BBPSPROG      0x08        //
-#define PSCFG_WAKESYN       0x04        //
-#define PSCFG_SLEEPSYN      0x02        //
-#define PSCFG_AUTOSLEEP     0x01        //
-
-//
-// Bits in the PSCTL register
-//
-#define PSCTL_WAKEDONE      0x20        //
-#define PSCTL_PS            0x10        //
-#define PSCTL_GO2DOZE       0x08        //
-#define PSCTL_LNBCN         0x04        //
-#define PSCTL_ALBCN         0x02        //
-#define PSCTL_PSEN          0x01        //
-
-//
-// Bits in the PSPWSIG register
-//
-#define PSSIG_WPE3          0x80        //
-#define PSSIG_WPE2          0x40        //
-#define PSSIG_WPE1          0x20        //
-#define PSSIG_WRADIOPE      0x10        //
-#define PSSIG_SPE3          0x08        //
-#define PSSIG_SPE2          0x04        //
-#define PSSIG_SPE1          0x02        //
-#define PSSIG_SRADIOPE      0x01        //
-
-//
-// Bits in the BBREGCTL register
-//
-#define BBREGCTL_DONE       0x04        //
-#define BBREGCTL_REGR       0x02        //
-#define BBREGCTL_REGW       0x01        //
-
-//
-// Bits in the IFREGCTL register
-//
-#define IFREGCTL_DONE       0x04        //
-#define IFREGCTL_IFRF       0x02        //
-#define IFREGCTL_REGW       0x01        //
-
-//
-// Bits in the SOFTPWRCTL register
-//
-#define SOFTPWRCTL_RFLEOPT      0x0800  //
-#define SOFTPWRCTL_TXPEINV      0x0200  //
-#define SOFTPWRCTL_SWPECTI      0x0100  //
-#define SOFTPWRCTL_SWPAPE       0x0020  //
-#define SOFTPWRCTL_SWCALEN      0x0010  //
-#define SOFTPWRCTL_SWRADIO_PE   0x0008  //
-#define SOFTPWRCTL_SWPE2        0x0004  //
-#define SOFTPWRCTL_SWPE1        0x0002  //
-#define SOFTPWRCTL_SWPE3        0x0001  //
-
-//
-// Bits in the GPIOCTL1 register
-//
-#define GPIO1_DATA1             0x20    //
-#define GPIO1_MD1               0x10    //
-#define GPIO1_DATA0             0x02    //
-#define GPIO1_MD0               0x01    //
-
-//
-// Bits in the DMACTL register
-//
-#define DMACTL_CLRRUN       0x00080000  //
-#define DMACTL_RUN          0x00000008  //
-#define DMACTL_WAKE         0x00000004  //
-#define DMACTL_DEAD         0x00000002  //
-#define DMACTL_ACTIVE       0x00000001  //
-//
-// Bits in the RXDMACTL0 register
-//
-#define RX_PERPKT           0x00000100  //
-#define RX_PERPKTCLR        0x01000000  //
-//
-// Bits in the BCNDMACTL register
-//
-#define BEACON_READY        0x01        //
-//
-// Bits in the MISCFFCTL register
-//
-#define MISCFFCTL_WRITE     0x0001      //
-
-//
-// Bits in WAKEUPEN0
-//
+#define RCR_RXALLTYPE       0x40
+#define RCR_UNICAST         0x20
+#define RCR_BROADCAST       0x10
+#define RCR_MULTICAST       0x08
+#define RCR_WPAERR          0x04
+#define RCR_ERRCRC          0x02
+#define RCR_BSSID           0x01
+
+/* Bits in the TCR register */
+#define TCR_SYNCDCFOPT      0x02
+#define TCR_AUTOBCNTX       0x01 /* Beacon automatically transmit enable */
+
+/* Bits in the IMR register */
+#define IMR_MEASURESTART    0x80000000
+#define IMR_QUIETSTART      0x20000000
+#define IMR_RADARDETECT     0x10000000
+#define IMR_MEASUREEND      0x08000000
+#define IMR_SOFTTIMER1      0x00200000
+#define IMR_RXDMA1          0x00001000 /* 0000 0000 0001 0000 0000 0000 */
+#define IMR_RXNOBUF         0x00000800
+#define IMR_MIBNEARFULL     0x00000400
+#define IMR_SOFTINT         0x00000200
+#define IMR_FETALERR        0x00000100
+#define IMR_WATCHDOG        0x00000080
+#define IMR_SOFTTIMER       0x00000040
+#define IMR_GPIO            0x00000020
+#define IMR_TBTT            0x00000010
+#define IMR_RXDMA0          0x00000008
+#define IMR_BNTX            0x00000004
+#define IMR_AC0DMA          0x00000002
+#define IMR_TXDMA0          0x00000001
+
+/* Bits in the ISR register */
+#define ISR_MEASURESTART    0x80000000
+#define ISR_QUIETSTART      0x20000000
+#define ISR_RADARDETECT     0x10000000
+#define ISR_MEASUREEND      0x08000000
+#define ISR_SOFTTIMER1      0x00200000
+#define ISR_RXDMA1          0x00001000 /* 0000 0000 0001 0000 0000 0000 */
+#define ISR_RXNOBUF         0x00000800 /* 0000 0000 0000 1000 0000 0000 */
+#define ISR_MIBNEARFULL     0x00000400 /* 0000 0000 0000 0100 0000 0000 */
+#define ISR_SOFTINT         0x00000200
+#define ISR_FETALERR        0x00000100
+#define ISR_WATCHDOG        0x00000080
+#define ISR_SOFTTIMER       0x00000040
+#define ISR_GPIO            0x00000020
+#define ISR_TBTT            0x00000010
+#define ISR_RXDMA0          0x00000008
+#define ISR_BNTX            0x00000004
+#define ISR_AC0DMA          0x00000002
+#define ISR_TXDMA0          0x00000001
+
+/* Bits in the PSCFG register */
+#define PSCFG_PHILIPMD      0x40
+#define PSCFG_WAKECALEN     0x20
+#define PSCFG_WAKETMREN     0x10
+#define PSCFG_BBPSPROG      0x08
+#define PSCFG_WAKESYN       0x04
+#define PSCFG_SLEEPSYN      0x02
+#define PSCFG_AUTOSLEEP     0x01
+
+/* Bits in the PSCTL register */
+#define PSCTL_WAKEDONE      0x20
+#define PSCTL_PS            0x10
+#define PSCTL_GO2DOZE       0x08
+#define PSCTL_LNBCN         0x04
+#define PSCTL_ALBCN         0x02
+#define PSCTL_PSEN          0x01
+
+/* Bits in the PSPWSIG register */
+#define PSSIG_WPE3          0x80
+#define PSSIG_WPE2          0x40
+#define PSSIG_WPE1          0x20
+#define PSSIG_WRADIOPE      0x10
+#define PSSIG_SPE3          0x08
+#define PSSIG_SPE2          0x04
+#define PSSIG_SPE1          0x02
+#define PSSIG_SRADIOPE      0x01
+
+/* Bits in the BBREGCTL register */
+#define BBREGCTL_DONE       0x04
+#define BBREGCTL_REGR       0x02
+#define BBREGCTL_REGW       0x01
+
+/* Bits in the IFREGCTL register */
+#define IFREGCTL_DONE       0x04
+#define IFREGCTL_IFRF       0x02
+#define IFREGCTL_REGW       0x01
+
+/* Bits in the SOFTPWRCTL register */
+#define SOFTPWRCTL_RFLEOPT      0x0800
+#define SOFTPWRCTL_TXPEINV      0x0200
+#define SOFTPWRCTL_SWPECTI      0x0100
+#define SOFTPWRCTL_SWPAPE       0x0020
+#define SOFTPWRCTL_SWCALEN      0x0010
+#define SOFTPWRCTL_SWRADIO_PE   0x0008
+#define SOFTPWRCTL_SWPE2        0x0004
+#define SOFTPWRCTL_SWPE1        0x0002
+#define SOFTPWRCTL_SWPE3        0x0001
+
+/* Bits in the GPIOCTL1 register */
+#define GPIO1_DATA1             0x20
+#define GPIO1_MD1               0x10
+#define GPIO1_DATA0             0x02
+#define GPIO1_MD0               0x01
+
+/* Bits in the DMACTL register */
+#define DMACTL_CLRRUN       0x00080000
+#define DMACTL_RUN          0x00000008
+#define DMACTL_WAKE         0x00000004
+#define DMACTL_DEAD         0x00000002
+#define DMACTL_ACTIVE       0x00000001
+
+/* Bits in the RXDMACTL0 register */
+#define RX_PERPKT           0x00000100
+#define RX_PERPKTCLR        0x01000000
+
+/* Bits in the BCNDMACTL register */
+#define BEACON_READY        0x01
+
+/* Bits in the MISCFFCTL register */
+#define MISCFFCTL_WRITE     0x0001
+
+/* Bits in WAKEUPEN0 */
 #define WAKEUPEN0_DIRPKT    0x10
 #define WAKEUPEN0_LINKOFF   0x08
 #define WAKEUPEN0_ATIMEN    0x04
 #define WAKEUPEN0_TIMEN     0x02
 #define WAKEUPEN0_MAGICEN   0x01
 
-//
-// Bits in WAKEUPEN1
-//
+/* Bits in WAKEUPEN1 */
 #define WAKEUPEN1_128_3     0x08
 #define WAKEUPEN1_128_2     0x04
 #define WAKEUPEN1_128_1     0x02
 #define WAKEUPEN1_128_0     0x01
 
-//
-// Bits in WAKEUPSR0
-//
+/* Bits in WAKEUPSR0 */
 #define WAKEUPSR0_DIRPKT    0x10
 #define WAKEUPSR0_LINKOFF   0x08
 #define WAKEUPSR0_ATIMEN    0x04
 #define WAKEUPSR0_TIMEN     0x02
 #define WAKEUPSR0_MAGICEN   0x01
 
-//
-// Bits in WAKEUPSR1
-//
+/* Bits in WAKEUPSR1 */
 #define WAKEUPSR1_128_3     0x08
 #define WAKEUPSR1_128_2     0x04
 #define WAKEUPSR1_128_1     0x02
 #define WAKEUPSR1_128_0     0x01
 
-//
-// Bits in the MAC_REG_GPIOCTL register
-//
-#define GPIO0_MD            0x01        //
-#define GPIO0_DATA          0x02        //
-#define GPIO0_INTMD         0x04        //
-#define GPIO1_MD            0x10        //
-#define GPIO1_DATA          0x20        //
-
-//
-// Bits in the MSRCTL register
-//
+/* Bits in the MAC_REG_GPIOCTL register */
+#define GPIO0_MD            0x01
+#define GPIO0_DATA          0x02
+#define GPIO0_INTMD         0x04
+#define GPIO1_MD            0x10
+#define GPIO1_DATA          0x20
+
+/* Bits in the MSRCTL register */
 #define MSRCTL_FINISH       0x80
 #define MSRCTL_READY        0x40
 #define MSRCTL_RADARDETECT  0x20
@@ -562,28 +502,27 @@
 #define MSRCTL_QUIETRPT     0x04
 #define MSRCTL_QUIETINT     0x02
 #define MSRCTL_QUIETEN      0x01
-//
-// Bits in the MSRCTL1 register
-//
+
+/* Bits in the MSRCTL1 register */
 #define MSRCTL1_TXPWR       0x08
 #define MSRCTL1_CSAPAREN    0x04
 #define MSRCTL1_TXPAUSE     0x01
 
-// Loopback mode
-#define MAC_LB_EXT          0x02        //
-#define MAC_LB_INTERNAL     0x01        //
-#define MAC_LB_NONE         0x00        //
+/* Loopback mode */
+#define MAC_LB_EXT          0x02
+#define MAC_LB_INTERNAL     0x01
+#define MAC_LB_NONE         0x00
 
 #define Default_BI              0x200
 
-// MiscFIFO Offset
+/* MiscFIFO Offset */
 #define MISCFIFO_KEYETRY0       32
 #define MISCFIFO_KEYENTRYSIZE   22
 #define MISCFIFO_SYNINFO_IDX    10
 #define MISCFIFO_SYNDATA_IDX    11
 #define MISCFIFO_SYNDATASIZE    21
 
-// enabled mask value of irq
+/* enabled mask value of irq */
 #define IMR_MASK_VALUE     (IMR_SOFTTIMER1 |	\
 			    IMR_RXDMA1 |	\
 			    IMR_RXNOBUF |	\
@@ -599,15 +538,13 @@
 			    IMR_AC0DMA |	\
 			    IMR_TXDMA0)
 
-// max time out delay time
-#define W_MAX_TIMEOUT       0xFFF0U     //
+/* max time out delay time */
+#define W_MAX_TIMEOUT       0xFFF0U
 
-// wait time within loop
-#define CB_DELAY_LOOP_WAIT  10          // 10ms
+/* wait time within loop */
+#define CB_DELAY_LOOP_WAIT  10 /* 10ms */
 
-//
-// revision id
-//
+/* revision id */
 #define REV_ID_VT3253_A0    0x00
 #define REV_ID_VT3253_A1    0x01
 #define REV_ID_VT3253_B0    0x08
@@ -691,12 +628,12 @@ do {									\
 	VNSvInPortD(dwIoBase + MAC_REG_ATIMDMAPTR,		\
 		    (unsigned long *)pdwCurrDescAddr)
 
-// set the chip with current BCN tx descriptor address
+/* set the chip with current BCN tx descriptor address */
 #define MACvSetCurrBCNTxDescAddr(dwIoBase, dwCurrDescAddr)	\
 	VNSvOutPortD(dwIoBase + MAC_REG_BCNDMAPTR,		\
 		     dwCurrDescAddr)
 
-// set the chip with current BCN length
+/* set the chip with current BCN length */
 #define MACvSetCurrBCNLength(dwIoBase, wCurrBCNLength)		\
 	VNSvOutPortW(dwIoBase + MAC_REG_BCNDMACTL+2,		\
 		     wCurrBCNLength)
@@ -888,7 +825,7 @@ do {									\
 	VNSvOutPortB(dwIoBase + MAC_REG_PAGE1SEL, 1)
 
 #define MACvReadMIBCounter(dwIoBase, pdwCounter)			\
-	VNSvInPortD(dwIoBase + MAC_REG_MIBCNTR , pdwCounter)
+	VNSvInPortD(dwIoBase + MAC_REG_MIBCNTR, pdwCounter)
 
 #define MACvPwrEvntDisable(dwIoBase)					\
 	VNSvOutPortW(dwIoBase + MAC_REG_WAKEUPEN0, 0x0000)
@@ -896,7 +833,7 @@ do {									\
 #define MACvEnableProtectMD(dwIoBase)					\
 do {									\
 	unsigned long dwOrgValue;					\
-	VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);		\
+	VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue);		\
 	dwOrgValue = dwOrgValue | EnCFG_ProtectMd;			\
 	VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);		\
 } while (0)
@@ -904,7 +841,7 @@ do {									\
 #define MACvDisableProtectMD(dwIoBase)					\
 do {									\
 	unsigned long dwOrgValue;					\
-	VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);		\
+	VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue);		\
 	dwOrgValue = dwOrgValue & ~EnCFG_ProtectMd;			\
 	VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);		\
 } while (0)
@@ -912,7 +849,7 @@ do {									\
 #define MACvEnableBarkerPreambleMd(dwIoBase)				\
 do {									\
 	unsigned long dwOrgValue;					\
-	VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);		\
+	VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue);		\
 	dwOrgValue = dwOrgValue | EnCFG_BarkerPream;			\
 	VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);		\
 } while (0)
@@ -920,7 +857,7 @@ do {									\
 #define MACvDisableBarkerPreambleMd(dwIoBase)				\
 do {									\
 	unsigned long dwOrgValue;					\
-	VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);		\
+	VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue);		\
 	dwOrgValue = dwOrgValue & ~EnCFG_BarkerPream;			\
 	VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);		\
 } while (0)
@@ -928,7 +865,7 @@ do {									\
 #define MACvSetBBType(dwIoBase, byTyp)					\
 do {									\
 	unsigned long dwOrgValue;					\
-	VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);		\
+	VNSvInPortD(dwIoBase + MAC_REG_ENCFG, &dwOrgValue);		\
 	dwOrgValue = dwOrgValue & ~EnCFG_BBType_MASK;			\
 	dwOrgValue = dwOrgValue | (unsigned long)byTyp;			\
 	VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);		\
@@ -953,15 +890,18 @@ do {								\
 #define MACvSetRFLE_LatchBase(dwIoBase)                                 \
 	MACvWordRegBitsOn(dwIoBase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_RFLEOPT)
 
-bool MACbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits);
-bool MACbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byRegOfs, unsigned char byTestBits);
+bool MACbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byRegOfs,
+		     unsigned char byTestBits);
+bool MACbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byRegOfs,
+		      unsigned char byTestBits);
 
 bool MACbIsIntDisable(void __iomem *dwIoBase);
 
 void MACvSetShortRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit);
 
 void MACvSetLongRetryLimit(void __iomem *dwIoBase, unsigned char byRetryLimit);
-void MACvGetLongRetryLimit(void __iomem *dwIoBase, unsigned char *pbyRetryLimit);
+void MACvGetLongRetryLimit(void __iomem *dwIoBase,
+			   unsigned char *pbyRetryLimit);
 
 void MACvSetLoopbackMode(void __iomem *dwIoBase, unsigned char byLoopbackMode);
 
@@ -975,22 +915,32 @@ bool MACbSafeTxOff(void __iomem *dwIoBase);
 bool MACbSafeStop(void __iomem *dwIoBase);
 bool MACbShutdown(void __iomem *dwIoBase);
 void MACvInitialize(void __iomem *dwIoBase);
-void MACvSetCurrRx0DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrRx1DescAddr(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrTXDescAddr(int iTxType, void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrTx0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrSyncDescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
-void MACvSetCurrATIMDescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAddr);
+void MACvSetCurrRx0DescAddr(void __iomem *dwIoBase,
+			    unsigned long dwCurrDescAddr);
+void MACvSetCurrRx1DescAddr(void __iomem *dwIoBase,
+			    unsigned long dwCurrDescAddr);
+void MACvSetCurrTXDescAddr(int iTxType, void __iomem *dwIoBase,
+			   unsigned long dwCurrDescAddr);
+void MACvSetCurrTx0DescAddrEx(void __iomem *dwIoBase,
+			      unsigned long dwCurrDescAddr);
+void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase,
+			      unsigned long dwCurrDescAddr);
+void MACvSetCurrSyncDescAddrEx(void __iomem *dwIoBase,
+			       unsigned long dwCurrDescAddr);
+void MACvSetCurrATIMDescAddrEx(void __iomem *dwIoBase,
+			       unsigned long dwCurrDescAddr);
 void MACvTimer0MicroSDelay(void __iomem *dwIoBase, unsigned int uDelay);
 void MACvOneShotTimer1MicroSec(void __iomem *dwIoBase, unsigned int uDelayTime);
 
-void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset, unsigned long dwData);
+void MACvSetMISCFifo(void __iomem *dwIoBase, unsigned short wOffset,
+		     unsigned long dwData);
 
 bool MACbPSWakeup(void __iomem *dwIoBase);
 
-void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned int uEntryIdx,
-		     unsigned int uKeyIdx, unsigned char *pbyAddr, u32 *pdwKey, unsigned char byLocalID);
+void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl,
+		     unsigned int uEntryIdx, unsigned int uKeyIdx,
+		     unsigned char *pbyAddr, u32 *pdwKey,
+		     unsigned char byLocalID);
 void MACvDisableKeyEntry(void __iomem *dwIoBase, unsigned int uEntryIdx);
 
-#endif // __MAC_H__
+#endif /* __MAC_H__ */
diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c
index e826f07e91c0..be3c4e949b6a 100644
--- a/drivers/staging/vt6655/power.c
+++ b/drivers/staging/vt6655/power.c
@@ -71,33 +71,33 @@ PSvEnablePowerSaving(
 	struct vnt_private *pDevice = hDeviceContext;
 	u16 wAID = pDevice->current_aid | BIT(14) | BIT(15);
 
-	// set period of power up before TBTT
+	/* set period of power up before TBTT */
 	VNSvOutPortW(pDevice->PortOffset + MAC_REG_PWBT, C_PWBT);
 	if (pDevice->op_mode != NL80211_IFTYPE_ADHOC) {
-		// set AID
+		/* set AID */
 		VNSvOutPortW(pDevice->PortOffset + MAC_REG_AIDATIM, wAID);
 	} else {
-		// set ATIM Window
+		/* set ATIM Window */
 #if 0 /* TODO atim window */
 		MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
 #endif
 	}
-	// Set AutoSleep
+	/* Set AutoSleep */
 	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
-	// Set HWUTSF
+	/* Set HWUTSF */
 	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
 
 	if (wListenInterval >= 2) {
-		// clear always listen beacon
+		/* clear always listen beacon */
 		MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
-		// first time set listen next beacon
+		/* first time set listen next beacon */
 		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_LNBCN);
 	} else {
-		// always listen beacon
+		/* always listen beacon */
 		MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
 	}
 
-	// enable power saving hw function
+	/* enable power saving hw function */
 	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PSEN);
 	pDevice->bEnablePSMode = true;
 
@@ -122,13 +122,13 @@ PSvDisablePowerSaving(
 {
 	struct vnt_private *pDevice = hDeviceContext;
 
-	// disable power saving hw function
+	/* disable power saving hw function */
 	MACbPSWakeup(pDevice->PortOffset);
-	//clear AutoSleep
+	/* clear AutoSleep */
 	MACvRegBitsOff(pDevice->PortOffset, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
-	//clear HWUTSF
+	/* clear HWUTSF */
 	MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TFTCTL, TFTCTL_HWUTSF);
-	// set always listen beacon
+	/* set always listen beacon */
 	MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_ALBCN);
 
 	pDevice->bEnablePSMode = false;
diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c
index 32ef99341e20..941b2adca95a 100644
--- a/drivers/staging/vt6655/rf.c
+++ b/drivers/staging/vt6655/rf.c
@@ -651,7 +651,8 @@ bool RFbInit(
  * Return Value: true if succeeded; false if failed.
  *
  */
-bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType, unsigned char byChannel)
+bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType,
+		      u16 byChannel)
 {
 	bool bResult = true;
 
@@ -687,7 +688,8 @@ bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType, unsigned
  * Return Value: None.
  *
  */
-bool RFvWriteWakeProgSyn(struct vnt_private *priv, unsigned char byRFType, unsigned int uChannel)
+bool RFvWriteWakeProgSyn(struct vnt_private *priv, unsigned char byRFType,
+			 u16 uChannel)
 {
 	void __iomem *dwIoBase = priv->PortOffset;
 	int   ii;
@@ -767,13 +769,12 @@ bool RFvWriteWakeProgSyn(struct vnt_private *priv, unsigned char byRFType, unsig
 bool RFbSetPower(
 	struct vnt_private *priv,
 	unsigned int uRATE,
-	unsigned int uCH
+	u16 uCH
 )
 {
 	bool bResult = true;
 	unsigned char byPwr = 0;
 	unsigned char byDec = 0;
-	unsigned char byPwrdBm = 0;
 
 	if (priv->dwDiagRefCount != 0)
 		return true;
@@ -786,8 +787,10 @@ bool RFbSetPower(
 	case RATE_2M:
 	case RATE_5M:
 	case RATE_11M:
+		if (uCH > CB_MAX_CHANNEL_24G)
+			return false;
+
 		byPwr = priv->abyCCKPwrTbl[uCH];
-		byPwrdBm = priv->abyCCKDefaultPwr[uCH];
 		break;
 	case RATE_6M:
 	case RATE_9M:
@@ -801,15 +804,6 @@ bool RFbSetPower(
 		if (byDec >= priv->byMaxPwrLevel)
 			byDec = priv->byMaxPwrLevel-1;
 
-		if (priv->byRFType == RF_UW2452) {
-			byPwrdBm = byDec - byPwr;
-			byPwrdBm /= 3;
-		} else {
-			byPwrdBm = byDec - byPwr;
-			byPwrdBm >>= 1;
-		}
-
-		byPwrdBm += priv->abyOFDMDefaultPwr[uCH];
 		byPwr = byDec;
 		break;
 	case RATE_24M:
@@ -817,7 +811,6 @@ bool RFbSetPower(
 	case RATE_48M:
 	case RATE_54M:
 		byPwr = priv->abyOFDMPwrTbl[uCH];
-		byPwrdBm = priv->abyOFDMDefaultPwr[uCH];
 		break;
 	}
 
@@ -937,8 +930,8 @@ RFvRSSITodBm(
 /* Post processing for the 11b/g and 11a.
  * for save time on changing Reg2,3,5,7,10,12,15 */
 bool RFbAL7230SelectChannelPostProcess(struct vnt_private *priv,
-				       unsigned char byOldChannel,
-				       unsigned char byNewChannel)
+				       u16 byOldChannel,
+				       u16 byNewChannel)
 {
 	bool bResult;
 
diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h
index 8a6e2cfedaa5..2ea21e2b00f2 100644
--- a/drivers/staging/vt6655/rf.h
+++ b/drivers/staging/vt6655/rf.h
@@ -74,12 +74,12 @@
 /*---------------------  Export Functions  --------------------------*/
 
 bool IFRFbWriteEmbedded(struct vnt_private *, unsigned long dwData);
-bool RFbSelectChannel(struct vnt_private *, unsigned char byRFType, unsigned char byChannel);
+bool RFbSelectChannel(struct vnt_private *, unsigned char byRFType, u16);
 bool RFbInit(
 	struct vnt_private *
 );
-bool RFvWriteWakeProgSyn(struct vnt_private *, unsigned char byRFType, unsigned int uChannel);
-bool RFbSetPower(struct vnt_private *, unsigned int uRATE, unsigned int uCH);
+bool RFvWriteWakeProgSyn(struct vnt_private *, unsigned char byRFType, u16);
+bool RFbSetPower(struct vnt_private *, unsigned int uRATE, u16);
 bool RFbRawSetPower(
 	struct vnt_private *,
 	unsigned char byPwr,
@@ -94,7 +94,7 @@ RFvRSSITodBm(
 );
 
 //{{ RobertYu: 20050104
-bool RFbAL7230SelectChannelPostProcess(struct vnt_private *, unsigned char byOldChannel, unsigned char byNewChannel);
+bool RFbAL7230SelectChannelPostProcess(struct vnt_private *, u16, u16);
 //}} RobertYu
 
 #endif // __RF_H__
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
index b5b0155961f2..07ce3fd88e70 100644
--- a/drivers/staging/vt6655/rxtx.c
+++ b/drivers/staging/vt6655/rxtx.c
@@ -205,7 +205,7 @@ s_uGetRTSCTSRsvTime(
 	unsigned short wCurrentRate
 )
 {
-	unsigned int uRrvTime  , uRTSTime, uCTSTime, uAckTime, uDataTime;
+	unsigned int uRrvTime, uRTSTime, uCTSTime, uAckTime, uDataTime;
 
 	uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
 
@@ -1207,7 +1207,6 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType,
 	ptdCurr->pTDInfo->dwReqCount = cbReqCount;
 	ptdCurr->pTDInfo->dwHeaderLength = cbHeaderLength;
 	ptdCurr->pTDInfo->skb_dma = ptdCurr->pTDInfo->buf_dma;
-	ptdCurr->buff_addr = cpu_to_le32(ptdCurr->pTDInfo->skb_dma);
 
 	return cbHeaderLength;
 }
diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h
index c53703a772f5..cc63dc8d47f7 100644
--- a/drivers/staging/vt6655/upc.h
+++ b/drivers/staging/vt6655/upc.h
@@ -33,9 +33,9 @@
 
 /*---------------------  Export Definitions -------------------------*/
 
-//
-//  For memory mapped IO
-//
+
+/* For memory mapped IO */
+
 
 #define VNSvInPortB(dwIOAddress, pbyData)				\
 do {									\
@@ -86,4 +86,4 @@ do {								\
 
 /*---------------------  Export Functions  --------------------------*/
 
-#endif // __UPC_H__
+#endif /* __UPC_H__ */
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
index 9340f1508cff..67ff13f4f731 100644
--- a/drivers/staging/vt6656/card.c
+++ b/drivers/staging/vt6656/card.c
@@ -78,7 +78,7 @@ void vnt_set_channel(struct vnt_private *priv, u32 connection_channel)
 	/* Set Channel[7] = 0 to tell H/W channel is changing now. */
 	vnt_mac_reg_bits_off(priv, MAC_REG_CHANNEL, 0xb0);
 
-	vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNLE,
+	vnt_control_out(priv, MESSAGE_TYPE_SELECT_CHANNEL,
 					connection_channel, 0, 0, NULL);
 
 	vnt_control_out_u8(priv, MESSAGE_REQUEST_MACREG, MAC_REG_CHANNEL,
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
index 5a7ca527106e..f71d59fa3b21 100644
--- a/drivers/staging/vt6656/device.h
+++ b/drivers/staging/vt6656/device.h
@@ -160,7 +160,7 @@
 #define MESSAGE_TYPE_CLRKEYENTRY	0x9
 #define MESSAGE_TYPE_WRITE_MISCFF	0xa
 #define MESSAGE_TYPE_SET_ANTMD		0xb
-#define MESSAGE_TYPE_SELECT_CHANNLE	0xc
+#define MESSAGE_TYPE_SELECT_CHANNEL	0xc
 #define MESSAGE_TYPE_SET_TSFTBTT	0xd
 #define MESSAGE_TYPE_SET_SSTIFS		0xe
 #define MESSAGE_TYPE_CHANGE_BBTYPE	0xf
@@ -307,8 +307,8 @@ struct vnt_private {
 
 	struct vnt_cmd_card_init init_command;
 	struct vnt_rsp_card_init init_response;
-	u8 current_net_addr[ETH_ALEN];
-	u8 permanent_net_addr[ETH_ALEN];
+	u8 current_net_addr[ETH_ALEN] __aligned(2);
+	u8 permanent_net_addr[ETH_ALEN] __aligned(2);
 
 	u8 exist_sw_net_addr;
 
diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h
index fab195f8c3f5..95e0e83a487e 100644
--- a/drivers/staging/vt6656/dpc.h
+++ b/drivers/staging/vt6656/dpc.h
@@ -32,6 +32,6 @@
 #include "device.h"
 
 int vnt_rx_data(struct vnt_private *, struct vnt_rcb *,
-	unsigned long bytes_recieved);
+	unsigned long bytes_received);
 
 #endif /* __RXTX_H__ */
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
index b95d5b1efcc7..71adc1f61838 100644
--- a/drivers/staging/vt6656/main_usb.c
+++ b/drivers/staging/vt6656/main_usb.c
@@ -34,6 +34,7 @@
  */
 #undef __NO_VERSION__
 
+#include <linux/etherdevice.h>
 #include <linux/file.h>
 #include "device.h"
 #include "card.h"
@@ -319,7 +320,7 @@ static int vnt_init_registers(struct vnt_private *priv)
 
 	/* get permanent network address */
 	memcpy(priv->permanent_net_addr, init_rsp->net_addr, 6);
-	memcpy(priv->current_net_addr, priv->permanent_net_addr, ETH_ALEN);
+	ether_addr_copy(priv->current_net_addr, priv->permanent_net_addr);
 
 	/* if exist SW network address, use it */
 	dev_dbg(&priv->usb->dev, "Network address = %pM\n",
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
index ea5140ab2b41..33baf26de4b5 100644
--- a/drivers/staging/vt6656/rxtx.c
+++ b/drivers/staging/vt6656/rxtx.c
@@ -36,6 +36,7 @@
  *
  */
 
+#include <linux/etherdevice.h>
 #include "device.h"
 #include "rxtx.h"
 #include "card.h"
@@ -55,7 +56,7 @@ static const u16 vnt_fb_opt0[2][5] = {
 
 static const u16 vnt_fb_opt1[2][5] = {
 	{RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, /* fallback_rate0 */
-	{RATE_6M , RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
+	{RATE_6M,  RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, /* fallback_rate1 */
 };
 
 #define RTSDUR_BB       0
@@ -392,8 +393,8 @@ static int vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context,
 	rts->frame_control =
 		cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
 
-	memcpy(rts->ra, hdr->addr1, ETH_ALEN);
-	memcpy(rts->ta, hdr->addr2, ETH_ALEN);
+	ether_addr_copy(rts->ra, hdr->addr1);
+	ether_addr_copy(rts->ta, hdr->addr2);
 
 	return 0;
 }
@@ -517,65 +518,66 @@ static u16 vnt_rxtx_rts_a_fb_head(struct vnt_usb_send_context *tx_context,
 	return vnt_rxtx_datahead_a_fb(tx_context, &buf->data_head);
 }
 
-static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context,
-	union vnt_tx_data_head *head)
+static u16 vnt_fill_cts_fb_head(struct vnt_usb_send_context *tx_context,
+				union vnt_tx_data_head *head)
 {
 	struct vnt_private *priv = tx_context->priv;
+	struct vnt_cts_fb *buf = &head->cts_g_fb;
 	u32 cts_frame_len = 14;
 	u16 current_rate = tx_context->tx_rate;
 
-	if (!head)
-		return 0;
+	/* Get SignalField,ServiceField,Length */
+	vnt_get_phy_field(priv, cts_frame_len, priv->top_cck_basic_rate,
+			  PK_TYPE_11B, &buf->b);
 
-	if (tx_context->fb_option) {
-		/* Auto Fall back */
-		struct vnt_cts_fb *buf = &head->cts_g_fb;
-		/* Get SignalField,ServiceField,Length */
-		vnt_get_phy_field(priv, cts_frame_len,
-			priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b);
-		buf->duration_ba =
-			vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA,
-						   tx_context->pkt_type,
-						   current_rate);
-		/* Get CTSDuration_ba_f0 */
-		buf->cts_duration_ba_f0 =
-			vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F0,
-						   tx_context->pkt_type,
-						   priv->tx_rate_fb0);
-		/* Get CTSDuration_ba_f1 */
-		buf->cts_duration_ba_f1 =
-			vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F1,
-						   tx_context->pkt_type,
-						   priv->tx_rate_fb1);
-		/* Get CTS Frame body */
-		buf->data.duration = buf->duration_ba;
-		buf->data.frame_control =
-			cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
+	buf->duration_ba =
+		vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA,
+					   tx_context->pkt_type,
+					   current_rate);
+	/* Get CTSDuration_ba_f0 */
+	buf->cts_duration_ba_f0 =
+		vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F0,
+					   tx_context->pkt_type,
+					   priv->tx_rate_fb0);
+	/* Get CTSDuration_ba_f1 */
+	buf->cts_duration_ba_f1 =
+		vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA_F1,
+					   tx_context->pkt_type,
+					   priv->tx_rate_fb1);
+	/* Get CTS Frame body */
+	buf->data.duration = buf->duration_ba;
+	buf->data.frame_control =
+		cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
 
-		memcpy(buf->data.ra, priv->current_net_addr, ETH_ALEN);
+	ether_addr_copy(buf->data.ra, priv->current_net_addr);
 
-		return vnt_rxtx_datahead_g_fb(tx_context, &buf->data_head);
-	} else {
-		struct vnt_cts *buf = &head->cts_g;
-		/* Get SignalField,ServiceField,Length */
-		vnt_get_phy_field(priv, cts_frame_len,
-			priv->top_cck_basic_rate, PK_TYPE_11B, &buf->b);
-		/* Get CTSDuration_ba */
-		buf->duration_ba =
-			vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA,
-						   tx_context->pkt_type,
-						   current_rate);
-		/*Get CTS Frame body*/
-		buf->data.duration = buf->duration_ba;
-		buf->data.frame_control =
-			cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
+	return vnt_rxtx_datahead_g_fb(tx_context, &buf->data_head);
+}
+
+static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context,
+			     union vnt_tx_data_head *head)
+{
+	struct vnt_private *priv = tx_context->priv;
+	struct vnt_cts *buf = &head->cts_g;
+	u32 cts_frame_len = 14;
+	u16 current_rate = tx_context->tx_rate;
 
-		memcpy(buf->data.ra, priv->current_net_addr, ETH_ALEN);
+	/* Get SignalField,ServiceField,Length */
+	vnt_get_phy_field(priv, cts_frame_len, priv->top_cck_basic_rate,
+			  PK_TYPE_11B, &buf->b);
+	/* Get CTSDuration_ba */
+	buf->duration_ba =
+		vnt_get_rtscts_duration_le(tx_context, CTSDUR_BA,
+					   tx_context->pkt_type,
+					   current_rate);
+	/*Get CTS Frame body*/
+	buf->data.duration = buf->duration_ba;
+	buf->data.frame_control =
+		cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
 
-		return vnt_rxtx_datahead_g(tx_context, &buf->data_head);
-	}
+	ether_addr_copy(buf->data.ra, priv->current_net_addr);
 
-	return 0;
+	return vnt_rxtx_datahead_g(tx_context, &buf->data_head);
 }
 
 static u16 vnt_rxtx_rts(struct vnt_usb_send_context *tx_context,
@@ -632,6 +634,9 @@ static u16 vnt_rxtx_cts(struct vnt_usb_send_context *tx_context,
 		head = &tx_head->tx_cts.tx.mic.head;
 
 	/* Fill CTS */
+	if (tx_context->fb_option)
+		return vnt_fill_cts_fb_head(tx_context, head);
+
 	return vnt_fill_cts_head(tx_context, head);
 }
 
@@ -739,7 +744,7 @@ static void vnt_fill_txkey(struct vnt_usb_send_context *tx_context,
 
 		mic_hdr->id = 0x59;
 		mic_hdr->payload_len = cpu_to_be16(payload_len);
-		memcpy(mic_hdr->mic_addr2, hdr->addr2, ETH_ALEN);
+		ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2);
 
 		ieee80211_get_key_tx_seq(tx_key, &seq);
 
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index 20d146b61ba7..8f2091070491 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -879,7 +879,7 @@ typedef struct hfa384x_usb_error {
 /* Unions for packaging all the known packet types together */
 
 typedef union hfa384x_usbout {
-	u16 type;
+	__le16 type;
 	hfa384x_usb_txfrm_t txfrm;
 	hfa384x_usb_cmdreq_t cmdreq;
 	hfa384x_usb_wridreq_t wridreq;
@@ -889,7 +889,7 @@ typedef union hfa384x_usbout {
 } __packed hfa384x_usbout_t;
 
 typedef union hfa384x_usbin {
-	u16 type;
+	__le16 type;
 	hfa384x_usb_rxfrm_t rxfrm;
 	hfa384x_usb_txfrm_t txfrm;
 	hfa384x_usb_infofrm_t infofrm;
@@ -1268,7 +1268,7 @@ typedef struct hfa384x {
 	hfa384x_downloadbuffer_t bufinfo;
 	u16 dltimeout;
 
-	int scanflag;		/* to signal scan comlete */
+	int scanflag;		/* to signal scan complete */
 	int join_ap;		/* are we joined to a specific ap */
 	int join_retries;	/* number of join retries till we fail */
 	hfa384x_JoinRequest_data_t joinreq;	/* join request saved data */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 55d2f563e308..28cd1c4c02c8 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -382,7 +382,7 @@ done:
 *
 * Arguments:
 *	hw		device struct
-*	tx_urb		URB of data for tranmission
+*	tx_urb		URB of data for transmission
 *	memflags	memory allocation flags
 *
 * Returns:
@@ -2391,7 +2391,7 @@ int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
 *	0		success
 *	>0		f/w reported error - f/w status code
 *	<0		driver reported error
-*	-ETIMEDOUT	timout waiting for the cmd regs to become
+*	-ETIMEDOUT	timeout waiting for the cmd regs to become
 *			available, or waiting for the control reg
 *			to indicate the Aux port is enabled.
 *	-ENODATA	the buffer does NOT contain a valid PDA.
@@ -3346,7 +3346,7 @@ retry:
 		if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
 			run_queue = 1;
 	} else {
-		const u16 intype = (usbin->type & ~cpu_to_le16(0x8000));
+		const __le16 intype = (usbin->type & ~cpu_to_le16(0x8000));
 
 		/*
 		 * Check that our message is what we're expecting ...
@@ -4123,12 +4123,11 @@ static int hfa384x_isgood_pdrcode(u16 pdrcode)
 			pr_debug("Encountered unknown PDR#=0x%04x, assuming it's ok.\n",
 				 pdrcode);
 			return 1;
-		} else {
-			/* bad code */
-			pr_debug("Encountered unknown PDR#=0x%04x, (>=0x1000), assuming it's bad.\n",
-				 pdrcode);
-			return 0;
 		}
+		break;
 	}
-	return 0;		/* avoid compiler warnings */
+	/* bad code */
+	pr_debug("Encountered unknown PDR#=0x%04x, (>=0x1000), assuming it's bad.\n",
+		 pdrcode);
+	return 0;
 }
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index 7eaaf9a63503..bd69e8cf200f 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -511,7 +511,7 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
 * protocol.
 *
 * Arguments:
-*	proto	protocl number (in host order) to search for.
+*	proto	protocol number (in host order) to search for.
 *
 * Returns:
 *	1 - if the table is empty or a match is found.
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
index 7221379c9742..4b84b568f6ca 100644
--- a/drivers/staging/wlan-ng/p80211req.c
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -80,7 +80,7 @@ static void p80211req_mibset_mibget(wlandevice_t *wlandev,
 /*----------------------------------------------------------------
 * p80211req_dorequest
 *
-* Handles an MLME reqest/confirm message.
+* Handles an MLME request/confirm message.
 *
 * Arguments:
 *	wlandev		WLAN device struct
diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h
index b62fdcba94e6..16f123959104 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.h
+++ b/drivers/staging/wlan-ng/prism2mgmt.h
@@ -45,7 +45,7 @@
 * --------------------------------------------------------------------
 *
 * This file contains the constants and data structures for interaction
-* with the hfa384x Wireless LAN (WLAN) Media Access Contoller (MAC).
+* with the hfa384x Wireless LAN (WLAN) Media Access Controller (MAC).
 * The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset.
 *
 * [Implementation and usage notes]
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index df577dfe7ffb..10ad24a89ddd 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -199,7 +199,7 @@ static int prism2sta_close(wlandevice_t *wlandev)
 /*----------------------------------------------------------------
 * prism2sta_reset
 *
-* Not currently implented.
+* Currently not implemented.
 *
 * Arguments:
 *	wlandev		wlan device structure
@@ -662,7 +662,7 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
 		       "ident:  ap f/w: id=0x%02x %d.%d.%d\n",
 		       hw->ident_sta_fw.id, hw->ident_sta_fw.major,
 		       hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
-		netdev_err(wlandev->netdev, "Unsupported Tertiary AP firmeare loaded!\n");
+		netdev_err(wlandev->netdev, "Unsupported Tertiary AP firmware loaded!\n");
 		goto failed;
 	}
 
diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c
index 709d49e7f3c9..935c714f592a 100644
--- a/drivers/staging/xgifb/XGI_main_26.c
+++ b/drivers/staging/xgifb/XGI_main_26.c
@@ -930,7 +930,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 			+ var->hsync_len;
 	unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
 			+ var->vsync_len;
-#if defined(__powerpc__)
+#if defined(__BIG_ENDIAN)
 	u8 cr_data;
 #endif
 	unsigned int drate = 0, hrate = 0;
@@ -952,7 +952,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 	} pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n",
 			var->pixclock, htotal, vtotal);
 
-	if (var->pixclock && htotal && vtotal) {
+	if (var->pixclock) {
 		drate = 1000000000 / var->pixclock;
 		hrate = (drate * 1000) / htotal;
 		xgifb_info->refresh_rate = (unsigned int) (hrate * 2
@@ -1044,7 +1044,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 			xgifb_info->DstColor = 0x0000;
 			xgifb_info->XGI310_AccelDepth = 0x00000000;
 			xgifb_info->video_cmap_len = 256;
-#if defined(__powerpc__)
+#if defined(__BIG_ENDIAN)
 			cr_data = xgifb_reg_get(XGICR, 0x4D);
 			xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
 #endif
@@ -1052,7 +1052,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 		case 16:
 			xgifb_info->DstColor = 0x8000;
 			xgifb_info->XGI310_AccelDepth = 0x00010000;
-#if defined(__powerpc__)
+#if defined(__BIG_ENDIAN)
 			cr_data = xgifb_reg_get(XGICR, 0x4D);
 			xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
 #endif
@@ -1062,7 +1062,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 			xgifb_info->DstColor = 0xC000;
 			xgifb_info->XGI310_AccelDepth = 0x00020000;
 			xgifb_info->video_cmap_len = 16;
-#if defined(__powerpc__)
+#if defined(__BIG_ENDIAN)
 			cr_data = xgifb_reg_get(XGICR, 0x4D);
 			xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
 #endif
diff --git a/include/dt-bindings/iio/qcom,spmi-vadc.h b/include/dt-bindings/iio/qcom,spmi-vadc.h
new file mode 100644
index 000000000000..42121fa238fa
--- /dev/null
+++ b/include/dt-bindings/iio/qcom,spmi-vadc.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _DT_BINDINGS_QCOM_SPMI_VADC_H
+#define _DT_BINDINGS_QCOM_SPMI_VADC_H
+
+/* Voltage ADC channels */
+#define VADC_USBIN				0x00
+#define VADC_DCIN				0x01
+#define VADC_VCHG_SNS				0x02
+#define VADC_SPARE1_03				0x03
+#define VADC_USB_ID_MV				0x04
+#define VADC_VCOIN				0x05
+#define VADC_VBAT_SNS				0x06
+#define VADC_VSYS				0x07
+#define VADC_DIE_TEMP				0x08
+#define VADC_REF_625MV				0x09
+#define VADC_REF_1250MV				0x0a
+#define VADC_CHG_TEMP				0x0b
+#define VADC_SPARE1				0x0c
+#define VADC_SPARE2				0x0d
+#define VADC_GND_REF				0x0e
+#define VADC_VDD_VADC				0x0f
+
+#define VADC_P_MUX1_1_1				0x10
+#define VADC_P_MUX2_1_1				0x11
+#define VADC_P_MUX3_1_1				0x12
+#define VADC_P_MUX4_1_1				0x13
+#define VADC_P_MUX5_1_1				0x14
+#define VADC_P_MUX6_1_1				0x15
+#define VADC_P_MUX7_1_1				0x16
+#define VADC_P_MUX8_1_1				0x17
+#define VADC_P_MUX9_1_1				0x18
+#define VADC_P_MUX10_1_1			0x19
+#define VADC_P_MUX11_1_1			0x1a
+#define VADC_P_MUX12_1_1			0x1b
+#define VADC_P_MUX13_1_1			0x1c
+#define VADC_P_MUX14_1_1			0x1d
+#define VADC_P_MUX15_1_1			0x1e
+#define VADC_P_MUX16_1_1			0x1f
+
+#define VADC_P_MUX1_1_3				0x20
+#define VADC_P_MUX2_1_3				0x21
+#define VADC_P_MUX3_1_3				0x22
+#define VADC_P_MUX4_1_3				0x23
+#define VADC_P_MUX5_1_3				0x24
+#define VADC_P_MUX6_1_3				0x25
+#define VADC_P_MUX7_1_3				0x26
+#define VADC_P_MUX8_1_3				0x27
+#define VADC_P_MUX9_1_3				0x28
+#define VADC_P_MUX10_1_3			0x29
+#define VADC_P_MUX11_1_3			0x2a
+#define VADC_P_MUX12_1_3			0x2b
+#define VADC_P_MUX13_1_3			0x2c
+#define VADC_P_MUX14_1_3			0x2d
+#define VADC_P_MUX15_1_3			0x2e
+#define VADC_P_MUX16_1_3			0x2f
+
+#define VADC_LR_MUX1_BAT_THERM			0x30
+#define VADC_LR_MUX2_BAT_ID			0x31
+#define VADC_LR_MUX3_XO_THERM			0x32
+#define VADC_LR_MUX4_AMUX_THM1			0x33
+#define VADC_LR_MUX5_AMUX_THM2			0x34
+#define VADC_LR_MUX6_AMUX_THM3			0x35
+#define VADC_LR_MUX7_HW_ID			0x36
+#define VADC_LR_MUX8_AMUX_THM4			0x37
+#define VADC_LR_MUX9_AMUX_THM5			0x38
+#define VADC_LR_MUX10_USB_ID			0x39
+#define VADC_AMUX_PU1				0x3a
+#define VADC_AMUX_PU2				0x3b
+#define VADC_LR_MUX3_BUF_XO_THERM		0x3c
+
+#define VADC_LR_MUX1_PU1_BAT_THERM		0x70
+#define VADC_LR_MUX2_PU1_BAT_ID			0x71
+#define VADC_LR_MUX3_PU1_XO_THERM		0x72
+#define VADC_LR_MUX4_PU1_AMUX_THM1		0x73
+#define VADC_LR_MUX5_PU1_AMUX_THM2		0x74
+#define VADC_LR_MUX6_PU1_AMUX_THM3		0x75
+#define VADC_LR_MUX7_PU1_AMUX_HW_ID		0x76
+#define VADC_LR_MUX8_PU1_AMUX_THM4		0x77
+#define VADC_LR_MUX9_PU1_AMUX_THM5		0x78
+#define VADC_LR_MUX10_PU1_AMUX_USB_ID		0x79
+#define VADC_LR_MUX3_BUF_PU1_XO_THERM		0x7c
+
+#define VADC_LR_MUX1_PU2_BAT_THERM		0xb0
+#define VADC_LR_MUX2_PU2_BAT_ID			0xb1
+#define VADC_LR_MUX3_PU2_XO_THERM		0xb2
+#define VADC_LR_MUX4_PU2_AMUX_THM1		0xb3
+#define VADC_LR_MUX5_PU2_AMUX_THM2		0xb4
+#define VADC_LR_MUX6_PU2_AMUX_THM3		0xb5
+#define VADC_LR_MUX7_PU2_AMUX_HW_ID		0xb6
+#define VADC_LR_MUX8_PU2_AMUX_THM4		0xb7
+#define VADC_LR_MUX9_PU2_AMUX_THM5		0xb8
+#define VADC_LR_MUX10_PU2_AMUX_USB_ID		0xb9
+#define VADC_LR_MUX3_BUF_PU2_XO_THERM		0xbc
+
+#define VADC_LR_MUX1_PU1_PU2_BAT_THERM		0xf0
+#define VADC_LR_MUX2_PU1_PU2_BAT_ID		0xf1
+#define VADC_LR_MUX3_PU1_PU2_XO_THERM		0xf2
+#define VADC_LR_MUX4_PU1_PU2_AMUX_THM1		0xf3
+#define VADC_LR_MUX5_PU1_PU2_AMUX_THM2		0xf4
+#define VADC_LR_MUX6_PU1_PU2_AMUX_THM3		0xf5
+#define VADC_LR_MUX7_PU1_PU2_AMUX_HW_ID		0xf6
+#define VADC_LR_MUX8_PU1_PU2_AMUX_THM4		0xf7
+#define VADC_LR_MUX9_PU1_PU2_AMUX_THM5		0xf8
+#define VADC_LR_MUX10_PU1_PU2_AMUX_USB_ID	0xf9
+#define VADC_LR_MUX3_BUF_PU1_PU2_XO_THERM	0xfc
+
+#endif /* _DT_BINDINGS_QCOM_SPMI_VADC_H */
diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h
index 519392763393..b65850a41127 100644
--- a/include/linux/iio/buffer.h
+++ b/include/linux/iio/buffer.h
@@ -25,9 +25,7 @@ struct iio_buffer;
  *			available.
  * @request_update:	if a parameter change has been marked, update underlying
  *			storage.
- * @get_bytes_per_datum:get current bytes per datum
  * @set_bytes_per_datum:set number of bytes per datum
- * @get_length:		get number of datums in buffer
  * @set_length:		set number of datums in buffer
  * @release:		called when the last reference to the buffer is dropped,
  *			should free all resources allocated by the buffer.
@@ -49,9 +47,7 @@ struct iio_buffer_access_funcs {
 
 	int (*request_update)(struct iio_buffer *buffer);
 
-	int (*get_bytes_per_datum)(struct iio_buffer *buffer);
 	int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
-	int (*get_length)(struct iio_buffer *buffer);
 	int (*set_length)(struct iio_buffer *buffer, int length);
 
 	void (*release)(struct iio_buffer *buffer);
@@ -85,10 +81,11 @@ struct iio_buffer {
 	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_group *attrs;
+	const struct attribute			**attrs;
 	struct list_head			demux_list;
 	void					*demux_bounce;
 	struct list_head			buffer_list;
@@ -117,15 +114,6 @@ int iio_scan_mask_query(struct iio_dev *indio_dev,
 			struct iio_buffer *buffer, int bit);
 
 /**
- * iio_scan_mask_set() - set particular bit in the scan mask
- * @indio_dev		IIO device structure
- * @buffer:		the buffer whose scan mask we are interested in
- * @bit:		the bit to be set.
- **/
-int iio_scan_mask_set(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.
@@ -159,56 +147,6 @@ static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev,
 
 int iio_update_demux(struct iio_dev *indio_dev);
 
-/**
- * iio_buffer_register() - register the buffer with IIO core
- * @indio_dev:		device with the buffer to be registered
- * @channels:		the channel descriptions used to construct buffer
- * @num_channels:	the number of channels
- **/
-int iio_buffer_register(struct iio_dev *indio_dev,
-			const struct iio_chan_spec *channels,
-			int num_channels);
-
-/**
- * iio_buffer_unregister() - unregister the buffer from IIO core
- * @indio_dev:		the device with the buffer to be unregistered
- **/
-void iio_buffer_unregister(struct iio_dev *indio_dev);
-
-/**
- * iio_buffer_read_length() - attr func to get number of datums in the buffer
- **/
-ssize_t iio_buffer_read_length(struct device *dev,
-			       struct device_attribute *attr,
-			       char *buf);
-/**
- * iio_buffer_write_length() - attr func to set number of datums in the buffer
- **/
-ssize_t iio_buffer_write_length(struct device *dev,
-			      struct device_attribute *attr,
-			      const char *buf,
-			      size_t len);
-/**
- * iio_buffer_store_enable() - attr to turn the buffer on
- **/
-ssize_t iio_buffer_store_enable(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf,
-				size_t len);
-/**
- * iio_buffer_show_enable() - attr to see if the buffer is on
- **/
-ssize_t iio_buffer_show_enable(struct device *dev,
-			       struct device_attribute *attr,
-			       char *buf);
-#define IIO_BUFFER_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR,	\
-					   iio_buffer_read_length,	\
-					   iio_buffer_write_length)
-
-#define IIO_BUFFER_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,	\
-					   iio_buffer_show_enable,	\
-					   iio_buffer_store_enable)
-
 bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
 	const unsigned long *mask);
 
@@ -232,16 +170,6 @@ static inline void iio_device_attach_buffer(struct iio_dev *indio_dev,
 
 #else /* CONFIG_IIO_BUFFER */
 
-static inline int iio_buffer_register(struct iio_dev *indio_dev,
-					   const struct iio_chan_spec *channels,
-					   int num_channels)
-{
-	return 0;
-}
-
-static inline void iio_buffer_unregister(struct iio_dev *indio_dev)
-{}
-
 static inline void iio_buffer_get(struct iio_buffer *buffer) {}
 static inline void iio_buffer_put(struct iio_buffer *buffer) {}
 
diff --git a/include/linux/iio/common/ssp_sensors.h b/include/linux/iio/common/ssp_sensors.h
new file mode 100644
index 000000000000..f4d1b0edb432
--- /dev/null
+++ b/include/linux/iio/common/ssp_sensors.h
@@ -0,0 +1,82 @@
+/*
+ *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ */
+#ifndef _SSP_SENSORS_H_
+#define _SSP_SENSORS_H_
+
+#include <linux/iio/iio.h>
+
+#define SSP_TIME_SIZE				4
+#define SSP_ACCELEROMETER_SIZE			6
+#define SSP_GYROSCOPE_SIZE			6
+#define SSP_BIO_HRM_RAW_SIZE			8
+#define SSP_BIO_HRM_RAW_FAC_SIZE		36
+#define SSP_BIO_HRM_LIB_SIZE			8
+
+/**
+ * enum ssp_sensor_type - SSP sensor type
+ */
+enum ssp_sensor_type {
+	SSP_ACCELEROMETER_SENSOR = 0,
+	SSP_GYROSCOPE_SENSOR,
+	SSP_GEOMAGNETIC_UNCALIB_SENSOR,
+	SSP_GEOMAGNETIC_RAW,
+	SSP_GEOMAGNETIC_SENSOR,
+	SSP_PRESSURE_SENSOR,
+	SSP_GESTURE_SENSOR,
+	SSP_PROXIMITY_SENSOR,
+	SSP_TEMPERATURE_HUMIDITY_SENSOR,
+	SSP_LIGHT_SENSOR,
+	SSP_PROXIMITY_RAW,
+	SSP_ORIENTATION_SENSOR,
+	SSP_STEP_DETECTOR,
+	SSP_SIG_MOTION_SENSOR,
+	SSP_GYRO_UNCALIB_SENSOR,
+	SSP_GAME_ROTATION_VECTOR,
+	SSP_ROTATION_VECTOR,
+	SSP_STEP_COUNTER,
+	SSP_BIO_HRM_RAW,
+	SSP_BIO_HRM_RAW_FAC,
+	SSP_BIO_HRM_LIB,
+	SSP_SENSOR_MAX,
+};
+
+struct ssp_data;
+
+/**
+ * struct ssp_sensor_data - Sensor object
+ * @process_data:	Callback to feed sensor data.
+ * @type:		Used sensor type.
+ * @buffer:		Received data buffer.
+ */
+struct ssp_sensor_data {
+	int (*process_data)(struct iio_dev *indio_dev, void *buf,
+			    int64_t timestamp);
+	enum ssp_sensor_type type;
+	u8 *buffer;
+};
+
+void ssp_register_consumer(struct iio_dev *indio_dev,
+			   enum ssp_sensor_type type);
+
+int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type,
+		      u32 delay);
+
+int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type);
+
+u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type);
+
+int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type,
+		     u32 delay);
+#endif /* _SSP_SENSORS_H_ */
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 651f9a0e2765..26fb8f6342bb 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -151,6 +151,16 @@ int iio_read_channel_average_raw(struct iio_channel *chan, int *val);
 int iio_read_channel_processed(struct iio_channel *chan, int *val);
 
 /**
+ * iio_write_channel_raw() - write to a given channel
+ * @chan:		The channel being queried.
+ * @val:		Value being written.
+ *
+ * Note raw writes to iio channels are in dac counts and hence
+ * scale will need to be applied if standard units required.
+ */
+int iio_write_channel_raw(struct iio_channel *chan, int val);
+
+/**
  * iio_get_channel_type() - get the type of a channel
  * @channel:		The channel being queried.
  * @type:		The type of the channel.
@@ -191,7 +201,7 @@ int iio_read_channel_scale(struct iio_channel *chan, int *val,
  * The scale factor allows to increase the precession of the returned value. For
  * a scale factor of 1 the function will return the result in the normal IIO
  * unit for the channel type. E.g. millivolt for voltage channels, if you want
- * nanovolts instead pass 1000 as the scale factor.
+ * nanovolts instead pass 1000000 as the scale factor.
  */
 int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
 	int *processed, unsigned int scale);
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 3642ce7ef512..80d855061064 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -38,6 +38,11 @@ enum iio_chan_info_enum {
 	IIO_CHAN_INFO_HARDWAREGAIN,
 	IIO_CHAN_INFO_HYSTERESIS,
 	IIO_CHAN_INFO_INT_TIME,
+	IIO_CHAN_INFO_ENABLE,
+	IIO_CHAN_INFO_CALIBHEIGHT,
+	IIO_CHAN_INFO_CALIBWEIGHT,
+	IIO_CHAN_INFO_DEBOUNCE_COUNT,
+	IIO_CHAN_INFO_DEBOUNCE_TIME,
 };
 
 enum iio_shared_by {
@@ -284,10 +289,11 @@ static inline s64 iio_get_time_ns(void)
 /* Device operating modes */
 #define INDIO_DIRECT_MODE		0x01
 #define INDIO_BUFFER_TRIGGERED		0x02
+#define INDIO_BUFFER_SOFTWARE		0x04
 #define INDIO_BUFFER_HARDWARE		0x08
 
 #define INDIO_ALL_BUFFER_MODES					\
-	(INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE)
+	(INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE | INDIO_BUFFER_SOFTWARE)
 
 #define INDIO_MAX_RAW_ELEMENTS		4
 
@@ -591,7 +597,8 @@ void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig);
 static inline bool iio_buffer_enabled(struct iio_dev *indio_dev)
 {
 	return indio_dev->currentmode
-		& (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE);
+		& (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE |
+		   INDIO_BUFFER_SOFTWARE);
 }
 
 /**
diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h
index 25eeac762e84..1683bc710d14 100644
--- a/include/linux/iio/kfifo_buf.h
+++ b/include/linux/iio/kfifo_buf.h
@@ -5,7 +5,10 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/buffer.h>
 
-struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev);
+struct iio_buffer *iio_kfifo_allocate(void);
 void iio_kfifo_free(struct iio_buffer *r);
 
+struct iio_buffer *devm_iio_kfifo_allocate(struct device *dev);
+void devm_iio_kfifo_free(struct device *dev, struct iio_buffer *r);
+
 #endif
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 4a2af8adf874..580ed5bdb3fa 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -30,6 +30,11 @@ enum iio_chan_type {
 	IIO_CCT,
 	IIO_PRESSURE,
 	IIO_HUMIDITYRELATIVE,
+	IIO_ACTIVITY,
+	IIO_STEPS,
+	IIO_ENERGY,
+	IIO_DISTANCE,
+	IIO_VELOCITY,
 };
 
 enum iio_modifier {
@@ -59,7 +64,12 @@ enum iio_modifier {
 	IIO_MOD_NORTH_MAGN,
 	IIO_MOD_NORTH_TRUE,
 	IIO_MOD_NORTH_MAGN_TILT_COMP,
-	IIO_MOD_NORTH_TRUE_TILT_COMP
+	IIO_MOD_NORTH_TRUE_TILT_COMP,
+	IIO_MOD_RUNNING,
+	IIO_MOD_JOGGING,
+	IIO_MOD_WALKING,
+	IIO_MOD_STILL,
+	IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z,
 };
 
 enum iio_event_type {
@@ -68,6 +78,7 @@ enum iio_event_type {
 	IIO_EV_TYPE_ROC,
 	IIO_EV_TYPE_THRESH_ADAPTIVE,
 	IIO_EV_TYPE_MAG_ADAPTIVE,
+	IIO_EV_TYPE_CHANGE,
 };
 
 enum iio_event_info {
@@ -81,6 +92,7 @@ enum iio_event_direction {
 	IIO_EV_DIR_EITHER,
 	IIO_EV_DIR_RISING,
 	IIO_EV_DIR_FALLING,
+	IIO_EV_DIR_NONE,
 };
 
 #define IIO_VAL_INT 1