summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/drivers/misc')
-rw-r--r--ANDROID_3.4.5/drivers/misc/Kconfig549
-rw-r--r--ANDROID_3.4.5/drivers/misc/Makefile62
-rw-r--r--ANDROID_3.4.5/drivers/misc/ab8500-pwm.c169
-rw-r--r--ANDROID_3.4.5/drivers/misc/ad525x_dpot-i2c.c121
-rw-r--r--ANDROID_3.4.5/drivers/misc/ad525x_dpot-spi.c143
-rw-r--r--ANDROID_3.4.5/drivers/misc/ad525x_dpot.c771
-rw-r--r--ANDROID_3.4.5/drivers/misc/ad525x_dpot.h215
-rw-r--r--ANDROID_3.4.5/drivers/misc/akm8975.c732
-rw-r--r--ANDROID_3.4.5/drivers/misc/altera-stapl/Kconfig8
-rw-r--r--ANDROID_3.4.5/drivers/misc/altera-stapl/Makefile3
-rw-r--r--ANDROID_3.4.5/drivers/misc/altera-stapl/altera-comp.c142
-rw-r--r--ANDROID_3.4.5/drivers/misc/altera-stapl/altera-exprt.h33
-rw-r--r--ANDROID_3.4.5/drivers/misc/altera-stapl/altera-jtag.c1021
-rw-r--r--ANDROID_3.4.5/drivers/misc/altera-stapl/altera-jtag.h113
-rw-r--r--ANDROID_3.4.5/drivers/misc/altera-stapl/altera-lpt.c70
-rw-r--r--ANDROID_3.4.5/drivers/misc/altera-stapl/altera.c2537
-rw-r--r--ANDROID_3.4.5/drivers/misc/apds9802als.c339
-rw-r--r--ANDROID_3.4.5/drivers/misc/apds990x.c1286
-rw-r--r--ANDROID_3.4.5/drivers/misc/arm-charlcd.c396
-rw-r--r--ANDROID_3.4.5/drivers/misc/atmel-ssc.c177
-rw-r--r--ANDROID_3.4.5/drivers/misc/atmel_pwm.c410
-rw-r--r--ANDROID_3.4.5/drivers/misc/atmel_tclib.c207
-rw-r--r--ANDROID_3.4.5/drivers/misc/bcm2079x-i2c.c736
-rw-r--r--ANDROID_3.4.5/drivers/misc/bh1770glc.c1406
-rw-r--r--ANDROID_3.4.5/drivers/misc/bh1780gli.c263
-rw-r--r--ANDROID_3.4.5/drivers/misc/bmp085.c472
-rw-r--r--ANDROID_3.4.5/drivers/misc/c2port/Kconfig35
-rw-r--r--ANDROID_3.4.5/drivers/misc/c2port/Makefile3
-rw-r--r--ANDROID_3.4.5/drivers/misc/c2port/c2port-duramar2150.c159
-rw-r--r--ANDROID_3.4.5/drivers/misc/c2port/core.c1006
-rw-r--r--ANDROID_3.4.5/drivers/misc/carma/Kconfig17
-rw-r--r--ANDROID_3.4.5/drivers/misc/carma/Makefile2
-rw-r--r--ANDROID_3.4.5/drivers/misc/carma/carma-fpga-program.c1140
-rw-r--r--ANDROID_3.4.5/drivers/misc/carma/carma-fpga.c1447
-rw-r--r--ANDROID_3.4.5/drivers/misc/cb710/Kconfig25
-rw-r--r--ANDROID_3.4.5/drivers/misc/cb710/Makefile6
-rw-r--r--ANDROID_3.4.5/drivers/misc/cb710/core.c359
-rw-r--r--ANDROID_3.4.5/drivers/misc/cb710/debug.c118
-rw-r--r--ANDROID_3.4.5/drivers/misc/cb710/sgbuf2.c146
-rw-r--r--ANDROID_3.4.5/drivers/misc/cs5535-mfgpt.c351
-rw-r--r--ANDROID_3.4.5/drivers/misc/ds1682.c257
-rw-r--r--ANDROID_3.4.5/drivers/misc/eeprom/Kconfig98
-rw-r--r--ANDROID_3.4.5/drivers/misc/eeprom/Makefile7
-rw-r--r--ANDROID_3.4.5/drivers/misc/eeprom/at24.c707
-rw-r--r--ANDROID_3.4.5/drivers/misc/eeprom/at25.c413
-rw-r--r--ANDROID_3.4.5/drivers/misc/eeprom/digsy_mtc_eeprom.c85
-rw-r--r--ANDROID_3.4.5/drivers/misc/eeprom/eeprom.c238
-rw-r--r--ANDROID_3.4.5/drivers/misc/eeprom/eeprom_93cx6.c321
-rw-r--r--ANDROID_3.4.5/drivers/misc/eeprom/eeprom_93xx46.c400
-rw-r--r--ANDROID_3.4.5/drivers/misc/eeprom/max6875.c215
-rw-r--r--ANDROID_3.4.5/drivers/misc/enclosure.c570
-rw-r--r--ANDROID_3.4.5/drivers/misc/ep93xx_pwm.c385
-rw-r--r--ANDROID_3.4.5/drivers/misc/fsa9480.c546
-rw-r--r--ANDROID_3.4.5/drivers/misc/hmc6352.c155
-rw-r--r--ANDROID_3.4.5/drivers/misc/hpilo.c889
-rw-r--r--ANDROID_3.4.5/drivers/misc/hpilo.h212
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/Makefile15
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/command.c187
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/dot_command.c152
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/dot_command.h78
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/event.c177
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/heartbeat.c101
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/i2o.h77
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/ibmasm.h220
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/ibmasmfs.c630
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/lowlevel.c85
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/lowlevel.h137
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/module.c237
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/r_heartbeat.c99
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/remote.c282
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/remote.h270
-rw-r--r--ANDROID_3.4.5/drivers/misc/ibmasm/uart.c72
-rw-r--r--ANDROID_3.4.5/drivers/misc/ics932s401.c495
-rw-r--r--ANDROID_3.4.5/drivers/misc/ioc4.c502
-rw-r--r--ANDROID_3.4.5/drivers/misc/isl29003.c463
-rw-r--r--ANDROID_3.4.5/drivers/misc/isl29020.c237
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/Kconfig20
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/Makefile29
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/debugfs.c137
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/debugfs.h58
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/fw-download.c358
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/fw-msg.h113
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/iwmc3200top.h205
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/log.c348
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/log.h171
-rw-r--r--ANDROID_3.4.5/drivers/misc/iwmc3200top/main.c662
-rw-r--r--ANDROID_3.4.5/drivers/misc/kgdbts.c1187
-rw-r--r--ANDROID_3.4.5/drivers/misc/lis3lv02d/Kconfig37
-rw-r--r--ANDROID_3.4.5/drivers/misc/lis3lv02d/Makefile7
-rw-r--r--ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d.c1054
-rw-r--r--ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d.h294
-rw-r--r--ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d_i2c.c263
-rw-r--r--ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d_spi.c134
-rw-r--r--ANDROID_3.4.5/drivers/misc/lkdtm.c695
-rw-r--r--ANDROID_3.4.5/drivers/misc/max8997-muic.c495
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/Kconfig9
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/Makefile3
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/Kconfig35
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/Makefile39
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/bt/Makefile41
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/bt/uhid/Makefile46
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/fm/Makefile72
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/fm/private/Makefile44
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/gps/Makefile50
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/wmt/Makefile78
-rwxr-xr-xANDROID_3.4.5/drivers/misc/mediatek/dummy.c0
-rw-r--r--ANDROID_3.4.5/drivers/misc/pch_phub.c914
-rw-r--r--ANDROID_3.4.5/drivers/misc/phantom.c571
-rwxr-xr-xANDROID_3.4.5/drivers/misc/pn547.c1180
-rw-r--r--ANDROID_3.4.5/drivers/misc/pti.c996
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/Kconfig6
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/Makefile8
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/asn1.h244
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/base64.h87
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/bignum.c2132
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/bignum.h763
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/dhm.h153
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/pem.h100
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/rsa.h373
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/rsa_verify.c572
-rwxr-xr-xANDROID_3.4.5/drivers/misc/rsa/x509.h726
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/Makefile5
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/gru.h78
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/gru_instructions.h736
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/grufault.c902
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/grufile.c618
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/gruhandles.c216
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/gruhandles.h531
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/grukdump.c235
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/grukservices.c1162
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/grukservices.h214
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/grulib.h153
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/grumain.c973
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/gruprocfs.c381
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/grutables.h678
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-gru/grutlbpurge.c378
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/Makefile19
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xp.h358
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xp_main.c286
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xp_nofault.S35
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xp_sn2.c190
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xp_uv.c171
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xpc.h1004
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_channel.c1011
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_main.c1344
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_partition.c541
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_sn2.c2462
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_uv.c1767
-rw-r--r--ANDROID_3.4.5/drivers/misc/sgi-xp/xpnet.c607
-rw-r--r--ANDROID_3.4.5/drivers/misc/spear13xx_pcie_gadget.c898
-rw-r--r--ANDROID_3.4.5/drivers/misc/ti-st/Kconfig17
-rw-r--r--ANDROID_3.4.5/drivers/misc/ti-st/Makefile6
-rw-r--r--ANDROID_3.4.5/drivers/misc/ti-st/st_core.c890
-rw-r--r--ANDROID_3.4.5/drivers/misc/ti-st/st_kim.c844
-rw-r--r--ANDROID_3.4.5/drivers/misc/ti-st/st_ll.c169
-rw-r--r--ANDROID_3.4.5/drivers/misc/ti_dac7512.c90
-rw-r--r--ANDROID_3.4.5/drivers/misc/tifm_7xx1.c454
-rw-r--r--ANDROID_3.4.5/drivers/misc/tifm_core.c368
-rw-r--r--ANDROID_3.4.5/drivers/misc/tsl2550.c462
-rw-r--r--ANDROID_3.4.5/drivers/misc/uid_stat.c156
-rwxr-xr-xANDROID_3.4.5/drivers/misc/viatel/Kconfig14
-rwxr-xr-xANDROID_3.4.5/drivers/misc/viatel/Makefile3
-rwxr-xr-xANDROID_3.4.5/drivers/misc/viatel/core.c49
-rwxr-xr-xANDROID_3.4.5/drivers/misc/viatel/core.h21
-rwxr-xr-xANDROID_3.4.5/drivers/misc/viatel/oem.c752
-rwxr-xr-xANDROID_3.4.5/drivers/misc/viatel/power.c340
-rwxr-xr-xANDROID_3.4.5/drivers/misc/viatel/sync.c2445
-rw-r--r--ANDROID_3.4.5/drivers/misc/vmw_balloon.c838
-rw-r--r--ANDROID_3.4.5/drivers/misc/wl127x-rfkill.c121
169 files changed, 0 insertions, 68710 deletions
diff --git a/ANDROID_3.4.5/drivers/misc/Kconfig b/ANDROID_3.4.5/drivers/misc/Kconfig
deleted file mode 100644
index cdd400f4..00000000
--- a/ANDROID_3.4.5/drivers/misc/Kconfig
+++ /dev/null
@@ -1,549 +0,0 @@
-#
-# Misc strange devices
-#
-
-menu "Misc devices"
-
-config SENSORS_LIS3LV02D
- tristate
- depends on INPUT
- select INPUT_POLLDEV
- default n
-
-config AD525X_DPOT
- tristate "Analog Devices Digital Potentiometers"
- depends on (I2C || SPI) && SYSFS
- help
- If you say yes here, you get support for the Analog Devices
- AD5258, AD5259, AD5251, AD5252, AD5253, AD5254, AD5255
- AD5160, AD5161, AD5162, AD5165, AD5200, AD5201, AD5203,
- AD5204, AD5206, AD5207, AD5231, AD5232, AD5233, AD5235,
- AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293,
- AD7376, AD8400, AD8402, AD8403, ADN2850, AD5241, AD5242,
- AD5243, AD5245, AD5246, AD5247, AD5248, AD5280, AD5282,
- ADN2860, AD5273, AD5171, AD5170, AD5172, AD5173, AD5270,
- AD5271, AD5272, AD5274
- digital potentiometer chips.
-
- See Documentation/misc-devices/ad525x_dpot.txt for the
- userspace interface.
-
- This driver can also be built as a module. If so, the module
- will be called ad525x_dpot.
-
-config AD525X_DPOT_I2C
- tristate "support I2C bus connection"
- depends on AD525X_DPOT && I2C
- help
- Say Y here if you have a digital potentiometers hooked to an I2C bus.
-
- To compile this driver as a module, choose M here: the
- module will be called ad525x_dpot-i2c.
-
-config AD525X_DPOT_SPI
- tristate "support SPI bus connection"
- depends on AD525X_DPOT && SPI_MASTER
- help
- Say Y here if you have a digital potentiometers hooked to an SPI bus.
-
- If unsure, say N (but it's safe to say "Y").
-
- To compile this driver as a module, choose M here: the
- module will be called ad525x_dpot-spi.
-
-config ATMEL_PWM
- tristate "Atmel AT32/AT91 PWM support"
- depends on HAVE_CLK
- help
- This option enables device driver support for the PWM channels
- on certain Atmel processors. Pulse Width Modulation is used for
- purposes including software controlled power-efficient backlights
- on LCD displays, motor control, and waveform generation.
-
-config BCM2079X_NFC
- tristate "bcm2079x NFC driver"
- default m
- ---help---
- Say yes if you want bcm2079x Near Field Communication driver.
- This is for i2c connected version. If unsure, say N here.
-
-config AB8500_PWM
- bool "AB8500 PWM support"
- depends on AB8500_CORE && ARCH_U8500
- select HAVE_PWM
- help
- This driver exports functions to enable/disble/config/free Pulse
- Width Modulation in the Analog Baseband Chip AB8500.
- It is used by led and backlight driver to control the intensity.
-
-config ATMEL_TCLIB
- bool "Atmel AT32/AT91 Timer/Counter Library"
- depends on (AVR32 || ARCH_AT91)
- help
- Select this if you want a library to allocate the Timer/Counter
- blocks found on many Atmel processors. This facilitates using
- these blocks by different drivers despite processor differences.
-
-config ATMEL_TCB_CLKSRC
- bool "TC Block Clocksource"
- depends on ATMEL_TCLIB
- default y
- help
- Select this to get a high precision clocksource based on a
- TC block with a 5+ MHz base clock rate. Two timer channels
- are combined to make a single 32-bit timer.
-
- When GENERIC_CLOCKEVENTS is defined, the third timer channel
- may be used as a clock event device supporting oneshot mode
- (delays of up to two seconds) based on the 32 KiHz clock.
-
-config ATMEL_TCB_CLKSRC_BLOCK
- int
- depends on ATMEL_TCB_CLKSRC
- prompt "TC Block" if ARCH_AT91RM9200 || ARCH_AT91SAM9260 || CPU_AT32AP700X
- default 0
- range 0 1
- help
- Some chips provide more than one TC block, so you have the
- choice of which one to use for the clock framework. The other
- TC can be used for other purposes, such as PWM generation and
- interval timing.
-
-config IBM_ASM
- tristate "Device driver for IBM RSA service processor"
- depends on X86 && PCI && INPUT && EXPERIMENTAL
- ---help---
- This option enables device driver support for in-band access to the
- IBM RSA (Condor) service processor in eServer xSeries systems.
- The ibmasm device driver allows user space application to access
- ASM (Advanced Systems Management) functions on the service
- processor. The driver is meant to be used in conjunction with
- a user space API.
- The ibmasm driver also enables the OS to use the UART on the
- service processor board as a regular serial port. To make use of
- this feature serial driver support (CONFIG_SERIAL_8250) must be
- enabled.
-
- WARNING: This software may not be supported or function
- correctly on your IBM server. Please consult the IBM ServerProven
- website <http://www-03.ibm.com/systems/info/x86servers/serverproven/compat/us/>
- for information on the specific driver level and support statement
- for your IBM server.
-
-config PHANTOM
- tristate "Sensable PHANToM (PCI)"
- depends on PCI
- help
- Say Y here if you want to build a driver for Sensable PHANToM device.
-
- This driver is only for PCI PHANToMs.
-
- If you choose to build module, its name will be phantom. If unsure,
- say N here.
-
-config INTEL_MID_PTI
- tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
- depends on PCI
- default n
- help
- The PTI (Parallel Trace Interface) driver directs
- trace data routed from various parts in the system out
- through an Intel Penwell PTI port and out of the mobile
- device for analysis with a debugging tool (Lauterbach or Fido).
-
- You should select this driver if the target kernel is meant for
- an Intel Atom (non-netbook) mobile device containing a MIPI
- P1149.7 standard implementation.
-
-config SGI_IOC4
- tristate "SGI IOC4 Base IO support"
- depends on PCI
- ---help---
- This option enables basic support for the IOC4 chip on certain
- SGI IO controller cards (IO9, IO10, and PCI-RT). This option
- does not enable any specific functions on such a card, but provides
- necessary infrastructure for other drivers to utilize.
-
- If you have an SGI Altix with an IOC4-based card say Y.
- Otherwise say N.
-
-config TIFM_CORE
- tristate "TI Flash Media interface support (EXPERIMENTAL)"
- depends on EXPERIMENTAL && PCI
- help
- If you want support for Texas Instruments(R) Flash Media adapters
- you should select this option and then also choose an appropriate
- host adapter, such as 'TI Flash Media PCI74xx/PCI76xx host adapter
- support', if you have a TI PCI74xx compatible card reader, for
- example.
- You will also have to select some flash card format drivers. MMC/SD
- cards are supported via 'MMC/SD Card support: TI Flash Media MMC/SD
- Interface support (MMC_TIFM_SD)'.
-
- To compile this driver as a module, choose M here: the module will
- be called tifm_core.
-
-config TIFM_7XX1
- tristate "TI Flash Media PCI74xx/PCI76xx host adapter support (EXPERIMENTAL)"
- depends on PCI && TIFM_CORE && EXPERIMENTAL
- default TIFM_CORE
- help
- This option enables support for Texas Instruments(R) PCI74xx and
- PCI76xx families of Flash Media adapters, found in many laptops.
- To make actual use of the device, you will have to select some
- flash card format drivers, as outlined in the TIFM_CORE Help.
-
- To compile this driver as a module, choose M here: the module will
- be called tifm_7xx1.
-
-config ICS932S401
- tristate "Integrated Circuits ICS932S401"
- depends on I2C && EXPERIMENTAL
- help
- If you say yes here you get support for the Integrated Circuits
- ICS932S401 clock control chips.
-
- This driver can also be built as a module. If so, the module
- will be called ics932s401.
-
-config ATMEL_SSC
- tristate "Device driver for Atmel SSC peripheral"
- depends on AVR32 || ARCH_AT91
- ---help---
- This option enables device driver support for Atmel Synchronized
- Serial Communication peripheral (SSC).
-
- The SSC peripheral supports a wide variety of serial frame based
- communications, i.e. I2S, SPI, etc.
-
- If unsure, say N.
-
-config ENCLOSURE_SERVICES
- tristate "Enclosure Services"
- default n
- help
- Provides support for intelligent enclosures (bays which
- contain storage devices). You also need either a host
- driver (SCSI/ATA) which supports enclosures
- or a SCSI enclosure device (SES) to use these services.
-
-config SGI_XP
- tristate "Support communication between SGI SSIs"
- depends on NET
- depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_UV) && SMP
- select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
- select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
- select SGI_GRU if X86_64 && SMP
- ---help---
- An SGI machine can be divided into multiple Single System
- Images which act independently of each other and have
- hardware based memory protection from the others. Enabling
- this feature will allow for direct communication between SSIs
- based on a network adapter and DMA messaging.
-
-config CS5535_MFGPT
- tristate "CS5535/CS5536 Geode Multi-Function General Purpose Timer (MFGPT) support"
- depends on PCI && X86 && MFD_CS5535
- default n
- help
- This driver provides access to MFGPT functionality for other
- drivers that need timers. MFGPTs are available in the CS5535 and
- CS5536 companion chips that are found in AMD Geode and several
- other platforms. They have a better resolution and max interval
- than the generic PIT, and are suitable for use as high-res timers.
- You probably don't want to enable this manually; other drivers that
- make use of it should enable it.
-
-config CS5535_MFGPT_DEFAULT_IRQ
- int
- depends on CS5535_MFGPT
- default 7
- help
- MFGPTs on the CS5535 require an interrupt. The selected IRQ
- can be overridden as a module option as well as by driver that
- use the cs5535_mfgpt_ API; however, different architectures might
- want to use a different IRQ by default. This is here for
- architectures to set as necessary.
-
-config CS5535_CLOCK_EVENT_SRC
- tristate "CS5535/CS5536 high-res timer (MFGPT) events"
- depends on GENERIC_CLOCKEVENTS && CS5535_MFGPT
- help
- This driver provides a clock event source based on the MFGPT
- timer(s) in the CS5535 and CS5536 companion chips.
- MFGPTs have a better resolution and max interval than the
- generic PIT, and are suitable for use as high-res timers.
-
-config HP_ILO
- tristate "Channel interface driver for the HP iLO processor"
- depends on PCI
- default n
- help
- The channel interface driver allows applications to communicate
- with iLO management processors present on HP ProLiant servers.
- Upon loading, the driver creates /dev/hpilo/dXccbN files, which
- can be used to gather data from the management processor, via
- read and write system calls.
-
- To compile this driver as a module, choose M here: the
- module will be called hpilo.
-
-config SGI_GRU
- tristate "SGI GRU driver"
- depends on X86_UV && SMP
- default n
- select MMU_NOTIFIER
- ---help---
- The GRU is a hardware resource located in the system chipset. The GRU
- contains memory that can be mmapped into the user address space. This memory is
- used to communicate with the GRU to perform functions such as load/store,
- scatter/gather, bcopy, AMOs, etc. The GRU is directly accessed by user
- instructions using user virtual addresses. GRU instructions (ex., bcopy) use
- user virtual addresses for operands.
-
- If you are not running on a SGI UV system, say N.
-
-config SGI_GRU_DEBUG
- bool "SGI GRU driver debug"
- depends on SGI_GRU
- default n
- ---help---
- This option enables addition debugging code for the SGI GRU driver. If
- you are unsure, say N.
-
-config APDS9802ALS
- tristate "Medfield Avago APDS9802 ALS Sensor module"
- depends on I2C
- help
- If you say yes here you get support for the ALS APDS9802 ambient
- light sensor.
-
- This driver can also be built as a module. If so, the module
- will be called apds9802als.
-
-config ISL29003
- tristate "Intersil ISL29003 ambient light sensor"
- depends on I2C && SYSFS
- help
- If you say yes here you get support for the Intersil ISL29003
- ambient light sensor.
-
- This driver can also be built as a module. If so, the module
- will be called isl29003.
-
-config ISL29020
- tristate "Intersil ISL29020 ambient light sensor"
- depends on I2C
- help
- If you say yes here you get support for the Intersil ISL29020
- ambient light sensor.
-
- This driver can also be built as a module. If so, the module
- will be called isl29020.
-
-config SENSORS_TSL2550
- tristate "Taos TSL2550 ambient light sensor"
- depends on I2C && SYSFS
- help
- If you say yes here you get support for the Taos TSL2550
- ambient light sensor.
-
- This driver can also be built as a module. If so, the module
- will be called tsl2550.
-
-config SENSORS_BH1780
- tristate "ROHM BH1780GLI ambient light sensor"
- depends on I2C && SYSFS
- help
- If you say yes here you get support for the ROHM BH1780GLI
- ambient light sensor.
-
- This driver can also be built as a module. If so, the module
- will be called bh1780gli.
-
-config SENSORS_BH1770
- tristate "BH1770GLC / SFH7770 combined ALS - Proximity sensor"
- depends on I2C
- ---help---
- Say Y here if you want to build a driver for BH1770GLC (ROHM) or
- SFH7770 (Osram) combined ambient light and proximity sensor chip.
-
- To compile this driver as a module, choose M here: the
- module will be called bh1770glc. If unsure, say N here.
-
-config SENSORS_APDS990X
- tristate "APDS990X combined als and proximity sensors"
- depends on I2C
- default n
- ---help---
- Say Y here if you want to build a driver for Avago APDS990x
- combined ambient light and proximity sensor chip.
-
- To compile this driver as a module, choose M here: the
- module will be called apds990x. If unsure, say N here.
-
-config HMC6352
- tristate "Honeywell HMC6352 compass"
- depends on I2C
- help
- This driver provides support for the Honeywell HMC6352 compass,
- providing configuration and heading data via sysfs.
-
-config SENSORS_AK8975
- tristate "AK8975 compass support"
- default n
- depends on I2C
- help
- If you say yes here you get support for Asahi Kasei's
- orientation sensor AK8975.
-
-config EP93XX_PWM
- tristate "EP93xx PWM support"
- depends on ARCH_EP93XX
- help
- This option enables device driver support for the PWM channels
- on the Cirrus EP93xx processors. The EP9307 chip only has one
- PWM channel all the others have two, the second channel is an
- alternate function of the EGPIO14 pin. A sysfs interface is
- provided to control the PWM channels.
-
- To compile this driver as a module, choose M here: the module will
- be called ep93xx_pwm.
-
-config DS1682
- tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
- depends on I2C && EXPERIMENTAL
- help
- If you say yes here you get support for Dallas Semiconductor
- DS1682 Total Elapsed Time Recorder.
-
- This driver can also be built as a module. If so, the module
- will be called ds1682.
-
-config SPEAR13XX_PCIE_GADGET
- bool "PCIe gadget support for SPEAr13XX platform"
- depends on ARCH_SPEAR13XX
- default n
- help
- This option enables gadget support for PCIe controller. If
- board file defines any controller as PCIe endpoint then a sysfs
- entry will be created for that controller. User can use these
- sysfs node to configure PCIe EP as per his requirements.
-
-config TI_DAC7512
- tristate "Texas Instruments DAC7512"
- depends on SPI && SYSFS
- help
- If you say yes here you get support for the Texas Instruments
- DAC7512 16-bit digital-to-analog converter.
-
- This driver can also be built as a module. If so, the module
- will be called ti_dac7512.
-
-config UID_STAT
- bool "UID based statistics tracking exported to /proc/uid_stat"
- default n
-
-config VMWARE_BALLOON
- tristate "VMware Balloon Driver"
- depends on X86
- help
- This is VMware physical memory management driver which acts
- like a "balloon" that can be inflated to reclaim physical pages
- by reserving them in the guest and invalidating them in the
- monitor, freeing up the underlying machine pages so they can
- be allocated to other guests. The balloon can also be deflated
- to allow the guest to use more physical memory.
-
- If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called vmw_balloon.
-
-config ARM_CHARLCD
- bool "ARM Ltd. Character LCD Driver"
- depends on PLAT_VERSATILE
- help
- This is a driver for the character LCD found on the ARM Ltd.
- Versatile and RealView Platform Baseboards. It doesn't do
- very much more than display the text "ARM Linux" on the first
- line and the Linux version on the second line, but that's
- still useful.
-
-config BMP085
- tristate "BMP085 digital pressure sensor"
- depends on I2C && SYSFS
- help
- If you say yes here you get support for the Bosch Sensortec
- BMP085 digital pressure sensor.
-
- To compile this driver as a module, choose M here: the
- module will be called bmp085.
-
-config PCH_PHUB
- tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"
- depends on PCI
- help
- This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
- Intel Topcliff which is an IOH(Input/Output Hub) for x86 embedded
- processor. The Topcliff has MAC address and Option ROM data in SROM.
- This driver can access MAC address and Option ROM data in SROM.
-
- This driver also can be used for LAPIS Semiconductor's IOH,
- ML7213/ML7223/ML7831.
- ML7213 which is for IVI(In-Vehicle Infotainment) use.
- ML7223 IOH is for MP(Media Phone) use.
- ML7831 IOH is for general purpose use.
- ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
- ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
-
- To compile this driver as a module, choose M here: the module will
- be called pch_phub.
-
-config USB_SWITCH_FSA9480
- tristate "FSA9480 USB Switch"
- depends on I2C
- help
- The FSA9480 is a USB port accessory detector and switch.
- The FSA9480 is fully controlled using I2C and enables USB data,
- stereo and mono audio, video, microphone and UART data to use
- a common connector port.
-
-config MAX8997_MUIC
- tristate "MAX8997 MUIC Support"
- depends on MFD_MAX8997
- help
- If you say yes here you get support for the MUIC device of
- Maxim MAX8997 PMIC.
- The MAX8997 MUIC is a USB port accessory detector and switch.
-
-config WL127X_RFKILL
- tristate "Bluetooth power control driver for TI wl127x"
- depends on RFKILL
- default n
- ---help---
- Creates an rfkill entry in sysfs for power control of Bluetooth
- TI wl127x chips.
-
-config PN547_NFC
- tristate "PN547 NFC driver"
- depends on I2C
- select CRC_CCITT
- default n
- ---help---
- Say yes if you want PN547 Near Field Communication driver.
- This is for i2c connected version. If unsure, say N here.
-
- To compile this driver as a module, choose m here. The module will
- be called pn547.
-
-
-source "drivers/misc/c2port/Kconfig"
-source "drivers/misc/eeprom/Kconfig"
-source "drivers/misc/cb710/Kconfig"
-source "drivers/misc/iwmc3200top/Kconfig"
-source "drivers/misc/ti-st/Kconfig"
-source "drivers/misc/lis3lv02d/Kconfig"
-source "drivers/misc/carma/Kconfig"
-source "drivers/misc/altera-stapl/Kconfig"
-endmenu
diff --git a/ANDROID_3.4.5/drivers/misc/Makefile b/ANDROID_3.4.5/drivers/misc/Makefile
deleted file mode 100644
index f2e3c9ef..00000000
--- a/ANDROID_3.4.5/drivers/misc/Makefile
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Makefile for misc devices that really don't fit anywhere else.
-#
-
-obj-$(CONFIG_IBM_ASM) += ibmasm/
-obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o
-obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o
-obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
-obj-$(CONFIG_INTEL_MID_PTI) += pti.o
-obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
-obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
-obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
-obj-$(CONFIG_BMP085) += bmp085.o
-obj-$(CONFIG_ICS932S401) += ics932s401.o
-obj-$(CONFIG_LKDTM) += lkdtm.o
-obj-$(CONFIG_TIFM_CORE) += tifm_core.o
-obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
-obj-$(CONFIG_PHANTOM) += phantom.o
-obj-$(CONFIG_SENSORS_BH1780) += bh1780gli.o
-obj-$(CONFIG_SENSORS_BH1770) += bh1770glc.o
-obj-$(CONFIG_SENSORS_APDS990X) += apds990x.o
-obj-$(CONFIG_SGI_IOC4) += ioc4.o
-obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
-obj-$(CONFIG_KGDB_TESTS) += kgdbts.o
-obj-$(CONFIG_SGI_XP) += sgi-xp/
-obj-$(CONFIG_SGI_GRU) += sgi-gru/
-obj-$(CONFIG_CS5535_MFGPT) += cs5535-mfgpt.o
-obj-$(CONFIG_HP_ILO) += hpilo.o
-obj-$(CONFIG_APDS9802ALS) += apds9802als.o
-obj-$(CONFIG_ISL29003) += isl29003.o
-obj-$(CONFIG_ISL29020) += isl29020.o
-obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
-obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
-obj-$(CONFIG_DS1682) += ds1682.o
-obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o
-obj-$(CONFIG_UID_STAT) += uid_stat.o
-obj-$(CONFIG_C2PORT) += c2port/
-obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/
-obj-$(CONFIG_HMC6352) += hmc6352.o
-obj-y += eeprom/
-obj-y += cb710/
-obj-$(CONFIG_SPEAR13XX_PCIE_GADGET) += spear13xx_pcie_gadget.o
-obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o
-obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
-obj-$(CONFIG_PCH_PHUB) += pch_phub.o
-obj-y += ti-st/
-obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o
-obj-y += lis3lv02d/
-obj-y += carma/
-obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
-obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
-obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o
-obj-$(CONFIG_WL127X_RFKILL) += wl127x-rfkill.o
-obj-$(CONFIG_SENSORS_AK8975) += akm8975.o
-obj-y += rsa/
-obj-y += viatel/
-obj-y += mediatek/
-wmt_pn547-objs += pn547.o
-obj-$(CONFIG_PN547_NFC) += wmt_pn547.o
-
-s_wmt_nfc_bcm2079x-objs += bcm2079x-i2c.o
-obj-$(CONFIG_BCM2079X_NFC) += s_wmt_nfc_bcm2079x.o \ No newline at end of file
diff --git a/ANDROID_3.4.5/drivers/misc/ab8500-pwm.c b/ANDROID_3.4.5/drivers/misc/ab8500-pwm.c
deleted file mode 100644
index d7a9aa14..00000000
--- a/ANDROID_3.4.5/drivers/misc/ab8500-pwm.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Arun R Murthy <arun.murthy@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/pwm.h>
-#include <linux/mfd/abx500.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include <linux/module.h>
-
-/*
- * PWM Out generators
- * Bank: 0x10
- */
-#define AB8500_PWM_OUT_CTRL1_REG 0x60
-#define AB8500_PWM_OUT_CTRL2_REG 0x61
-#define AB8500_PWM_OUT_CTRL7_REG 0x66
-
-/* backlight driver constants */
-#define ENABLE_PWM 1
-#define DISABLE_PWM 0
-
-struct pwm_device {
- struct device *dev;
- struct list_head node;
- const char *label;
- unsigned int pwm_id;
-};
-
-static LIST_HEAD(pwm_list);
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- int ret = 0;
- unsigned int higher_val, lower_val;
- u8 reg;
-
- /*
- * get the first 8 bits that are be written to
- * AB8500_PWM_OUT_CTRL1_REG[0:7]
- */
- lower_val = duty_ns & 0x00FF;
- /*
- * get bits [9:10] that are to be written to
- * AB8500_PWM_OUT_CTRL2_REG[0:1]
- */
- higher_val = ((duty_ns & 0x0300) >> 8);
-
- reg = AB8500_PWM_OUT_CTRL1_REG + ((pwm->pwm_id - 1) * 2);
-
- ret = abx500_set_register_interruptible(pwm->dev, AB8500_MISC,
- reg, (u8)lower_val);
- if (ret < 0)
- return ret;
- ret = abx500_set_register_interruptible(pwm->dev, AB8500_MISC,
- (reg + 1), (u8)higher_val);
-
- return ret;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
- int ret;
-
- ret = abx500_mask_and_set_register_interruptible(pwm->dev,
- AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
- 1 << (pwm->pwm_id-1), ENABLE_PWM);
- if (ret < 0)
- dev_err(pwm->dev, "%s: Failed to disable PWM, Error %d\n",
- pwm->label, ret);
- return ret;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
- int ret;
-
- ret = abx500_mask_and_set_register_interruptible(pwm->dev,
- AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
- 1 << (pwm->pwm_id-1), DISABLE_PWM);
- if (ret < 0)
- dev_err(pwm->dev, "%s: Failed to disable PWM, Error %d\n",
- pwm->label, ret);
- return;
-}
-EXPORT_SYMBOL(pwm_disable);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
- struct pwm_device *pwm;
-
- list_for_each_entry(pwm, &pwm_list, node) {
- if (pwm->pwm_id == pwm_id) {
- pwm->label = label;
- pwm->pwm_id = pwm_id;
- return pwm;
- }
- }
-
- return ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
- pwm_disable(pwm);
-}
-EXPORT_SYMBOL(pwm_free);
-
-static int __devinit ab8500_pwm_probe(struct platform_device *pdev)
-{
- struct pwm_device *pwm;
- /*
- * Nothing to be done in probe, this is required to get the
- * device which is required for ab8500 read and write
- */
- pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
- if (pwm == NULL) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
- return -ENOMEM;
- }
- pwm->dev = &pdev->dev;
- pwm->pwm_id = pdev->id;
- list_add_tail(&pwm->node, &pwm_list);
- platform_set_drvdata(pdev, pwm);
- dev_dbg(pwm->dev, "pwm probe successful\n");
- return 0;
-}
-
-static int __devexit ab8500_pwm_remove(struct platform_device *pdev)
-{
- struct pwm_device *pwm = platform_get_drvdata(pdev);
- list_del(&pwm->node);
- dev_dbg(&pdev->dev, "pwm driver removed\n");
- kfree(pwm);
- return 0;
-}
-
-static struct platform_driver ab8500_pwm_driver = {
- .driver = {
- .name = "ab8500-pwm",
- .owner = THIS_MODULE,
- },
- .probe = ab8500_pwm_probe,
- .remove = __devexit_p(ab8500_pwm_remove),
-};
-
-static int __init ab8500_pwm_init(void)
-{
- return platform_driver_register(&ab8500_pwm_driver);
-}
-
-static void __exit ab8500_pwm_exit(void)
-{
- platform_driver_unregister(&ab8500_pwm_driver);
-}
-
-subsys_initcall(ab8500_pwm_init);
-module_exit(ab8500_pwm_exit);
-MODULE_AUTHOR("Arun MURTHY <arun.murthy@stericsson.com>");
-MODULE_DESCRIPTION("AB8500 Pulse Width Modulation Driver");
-MODULE_ALIAS("platform:ab8500-pwm");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/misc/ad525x_dpot-i2c.c b/ANDROID_3.4.5/drivers/misc/ad525x_dpot-i2c.c
deleted file mode 100644
index 82082627..00000000
--- a/ANDROID_3.4.5/drivers/misc/ad525x_dpot-i2c.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Driver for the Analog Devices digital potentiometers (I2C bus)
- *
- * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/i2c.h>
-#include <linux/module.h>
-
-#include "ad525x_dpot.h"
-
-/* I2C bus functions */
-static int write_d8(void *client, u8 val)
-{
- return i2c_smbus_write_byte(client, val);
-}
-
-static int write_r8d8(void *client, u8 reg, u8 val)
-{
- return i2c_smbus_write_byte_data(client, reg, val);
-}
-
-static int write_r8d16(void *client, u8 reg, u16 val)
-{
- return i2c_smbus_write_word_data(client, reg, val);
-}
-
-static int read_d8(void *client)
-{
- return i2c_smbus_read_byte(client);
-}
-
-static int read_r8d8(void *client, u8 reg)
-{
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int read_r8d16(void *client, u8 reg)
-{
- return i2c_smbus_read_word_data(client, reg);
-}
-
-static const struct ad_dpot_bus_ops bops = {
- .read_d8 = read_d8,
- .read_r8d8 = read_r8d8,
- .read_r8d16 = read_r8d16,
- .write_d8 = write_d8,
- .write_r8d8 = write_r8d8,
- .write_r8d16 = write_r8d16,
-};
-
-static int __devinit ad_dpot_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct ad_dpot_bus_data bdata = {
- .client = client,
- .bops = &bops,
- };
-
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_WORD_DATA)) {
- dev_err(&client->dev, "SMBUS Word Data not Supported\n");
- return -EIO;
- }
-
- return ad_dpot_probe(&client->dev, &bdata, id->driver_data, id->name);
-}
-
-static int __devexit ad_dpot_i2c_remove(struct i2c_client *client)
-{
- return ad_dpot_remove(&client->dev);
-}
-
-static const struct i2c_device_id ad_dpot_id[] = {
- {"ad5258", AD5258_ID},
- {"ad5259", AD5259_ID},
- {"ad5251", AD5251_ID},
- {"ad5252", AD5252_ID},
- {"ad5253", AD5253_ID},
- {"ad5254", AD5254_ID},
- {"ad5255", AD5255_ID},
- {"ad5241", AD5241_ID},
- {"ad5242", AD5242_ID},
- {"ad5243", AD5243_ID},
- {"ad5245", AD5245_ID},
- {"ad5246", AD5246_ID},
- {"ad5247", AD5247_ID},
- {"ad5248", AD5248_ID},
- {"ad5280", AD5280_ID},
- {"ad5282", AD5282_ID},
- {"adn2860", ADN2860_ID},
- {"ad5273", AD5273_ID},
- {"ad5161", AD5161_ID},
- {"ad5171", AD5171_ID},
- {"ad5170", AD5170_ID},
- {"ad5172", AD5172_ID},
- {"ad5173", AD5173_ID},
- {"ad5272", AD5272_ID},
- {"ad5274", AD5274_ID},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, ad_dpot_id);
-
-static struct i2c_driver ad_dpot_i2c_driver = {
- .driver = {
- .name = "ad_dpot",
- .owner = THIS_MODULE,
- },
- .probe = ad_dpot_i2c_probe,
- .remove = __devexit_p(ad_dpot_i2c_remove),
- .id_table = ad_dpot_id,
-};
-
-module_i2c_driver(ad_dpot_i2c_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("digital potentiometer I2C bus driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("i2c:ad_dpot");
diff --git a/ANDROID_3.4.5/drivers/misc/ad525x_dpot-spi.c b/ANDROID_3.4.5/drivers/misc/ad525x_dpot-spi.c
deleted file mode 100644
index f6231754..00000000
--- a/ANDROID_3.4.5/drivers/misc/ad525x_dpot-spi.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Driver for the Analog Devices digital potentiometers (SPI bus)
- *
- * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/spi/spi.h>
-#include <linux/module.h>
-
-#include "ad525x_dpot.h"
-
-/* SPI bus functions */
-static int write8(void *client, u8 val)
-{
- u8 data = val;
- return spi_write(client, &data, 1);
-}
-
-static int write16(void *client, u8 reg, u8 val)
-{
- u8 data[2] = {reg, val};
- return spi_write(client, data, 2);
-}
-
-static int write24(void *client, u8 reg, u16 val)
-{
- u8 data[3] = {reg, val >> 8, val};
- return spi_write(client, data, 3);
-}
-
-static int read8(void *client)
-{
- int ret;
- u8 data;
- ret = spi_read(client, &data, 1);
- if (ret < 0)
- return ret;
-
- return data;
-}
-
-static int read16(void *client, u8 reg)
-{
- int ret;
- u8 buf_rx[2];
-
- write16(client, reg, 0);
- ret = spi_read(client, buf_rx, 2);
- if (ret < 0)
- return ret;
-
- return (buf_rx[0] << 8) | buf_rx[1];
-}
-
-static int read24(void *client, u8 reg)
-{
- int ret;
- u8 buf_rx[3];
-
- write24(client, reg, 0);
- ret = spi_read(client, buf_rx, 3);
- if (ret < 0)
- return ret;
-
- return (buf_rx[1] << 8) | buf_rx[2];
-}
-
-static const struct ad_dpot_bus_ops bops = {
- .read_d8 = read8,
- .read_r8d8 = read16,
- .read_r8d16 = read24,
- .write_d8 = write8,
- .write_r8d8 = write16,
- .write_r8d16 = write24,
-};
-static int __devinit ad_dpot_spi_probe(struct spi_device *spi)
-{
- struct ad_dpot_bus_data bdata = {
- .client = spi,
- .bops = &bops,
- };
-
- return ad_dpot_probe(&spi->dev, &bdata,
- spi_get_device_id(spi)->driver_data,
- spi_get_device_id(spi)->name);
-}
-
-static int __devexit ad_dpot_spi_remove(struct spi_device *spi)
-{
- return ad_dpot_remove(&spi->dev);
-}
-
-static const struct spi_device_id ad_dpot_spi_id[] = {
- {"ad5160", AD5160_ID},
- {"ad5161", AD5161_ID},
- {"ad5162", AD5162_ID},
- {"ad5165", AD5165_ID},
- {"ad5200", AD5200_ID},
- {"ad5201", AD5201_ID},
- {"ad5203", AD5203_ID},
- {"ad5204", AD5204_ID},
- {"ad5206", AD5206_ID},
- {"ad5207", AD5207_ID},
- {"ad5231", AD5231_ID},
- {"ad5232", AD5232_ID},
- {"ad5233", AD5233_ID},
- {"ad5235", AD5235_ID},
- {"ad5260", AD5260_ID},
- {"ad5262", AD5262_ID},
- {"ad5263", AD5263_ID},
- {"ad5290", AD5290_ID},
- {"ad5291", AD5291_ID},
- {"ad5292", AD5292_ID},
- {"ad5293", AD5293_ID},
- {"ad7376", AD7376_ID},
- {"ad8400", AD8400_ID},
- {"ad8402", AD8402_ID},
- {"ad8403", AD8403_ID},
- {"adn2850", ADN2850_ID},
- {"ad5270", AD5270_ID},
- {"ad5271", AD5271_ID},
- {}
-};
-MODULE_DEVICE_TABLE(spi, ad_dpot_spi_id);
-
-static struct spi_driver ad_dpot_spi_driver = {
- .driver = {
- .name = "ad_dpot",
- .owner = THIS_MODULE,
- },
- .probe = ad_dpot_spi_probe,
- .remove = __devexit_p(ad_dpot_spi_remove),
- .id_table = ad_dpot_spi_id,
-};
-
-module_spi_driver(ad_dpot_spi_driver);
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("digital potentiometer SPI bus driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("spi:ad_dpot");
diff --git a/ANDROID_3.4.5/drivers/misc/ad525x_dpot.c b/ANDROID_3.4.5/drivers/misc/ad525x_dpot.c
deleted file mode 100644
index 1d1d4261..00000000
--- a/ANDROID_3.4.5/drivers/misc/ad525x_dpot.c
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
- * ad525x_dpot: Driver for the Analog Devices digital potentiometers
- * Copyright (c) 2009-2010 Analog Devices, Inc.
- * Author: Michael Hennerich <hennerich@blackfin.uclinux.org>
- *
- * DEVID #Wipers #Positions Resistor Options (kOhm)
- * AD5258 1 64 1, 10, 50, 100
- * AD5259 1 256 5, 10, 50, 100
- * AD5251 2 64 1, 10, 50, 100
- * AD5252 2 256 1, 10, 50, 100
- * AD5255 3 512 25, 250
- * AD5253 4 64 1, 10, 50, 100
- * AD5254 4 256 1, 10, 50, 100
- * AD5160 1 256 5, 10, 50, 100
- * AD5161 1 256 5, 10, 50, 100
- * AD5162 2 256 2.5, 10, 50, 100
- * AD5165 1 256 100
- * AD5200 1 256 10, 50
- * AD5201 1 33 10, 50
- * AD5203 4 64 10, 100
- * AD5204 4 256 10, 50, 100
- * AD5206 6 256 10, 50, 100
- * AD5207 2 256 10, 50, 100
- * AD5231 1 1024 10, 50, 100
- * AD5232 2 256 10, 50, 100
- * AD5233 4 64 10, 50, 100
- * AD5235 2 1024 25, 250
- * AD5260 1 256 20, 50, 200
- * AD5262 2 256 20, 50, 200
- * AD5263 4 256 20, 50, 200
- * AD5290 1 256 10, 50, 100
- * AD5291 1 256 20, 50, 100 (20-TP)
- * AD5292 1 1024 20, 50, 100 (20-TP)
- * AD5293 1 1024 20, 50, 100
- * AD7376 1 128 10, 50, 100, 1M
- * AD8400 1 256 1, 10, 50, 100
- * AD8402 2 256 1, 10, 50, 100
- * AD8403 4 256 1, 10, 50, 100
- * ADN2850 3 512 25, 250
- * AD5241 1 256 10, 100, 1M
- * AD5246 1 128 5, 10, 50, 100
- * AD5247 1 128 5, 10, 50, 100
- * AD5245 1 256 5, 10, 50, 100
- * AD5243 2 256 2.5, 10, 50, 100
- * AD5248 2 256 2.5, 10, 50, 100
- * AD5242 2 256 20, 50, 200
- * AD5280 1 256 20, 50, 200
- * AD5282 2 256 20, 50, 200
- * ADN2860 3 512 25, 250
- * AD5273 1 64 1, 10, 50, 100 (OTP)
- * AD5171 1 64 5, 10, 50, 100 (OTP)
- * AD5170 1 256 2.5, 10, 50, 100 (OTP)
- * AD5172 2 256 2.5, 10, 50, 100 (OTP)
- * AD5173 2 256 2.5, 10, 50, 100 (OTP)
- * AD5270 1 1024 20, 50, 100 (50-TP)
- * AD5271 1 256 20, 50, 100 (50-TP)
- * AD5272 1 1024 20, 50, 100 (50-TP)
- * AD5274 1 256 20, 50, 100 (50-TP)
- *
- * See Documentation/misc-devices/ad525x_dpot.txt for more info.
- *
- * derived from ad5258.c
- * Copyright (c) 2009 Cyber Switching, Inc.
- * Author: Chris Verges <chrisv@cyberswitching.com>
- *
- * derived from ad5252.c
- * Copyright (c) 2006-2011 Michael Hennerich <hennerich@blackfin.uclinux.org>
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-
-#include "ad525x_dpot.h"
-
-/*
- * Client data (each client gets its own)
- */
-
-struct dpot_data {
- struct ad_dpot_bus_data bdata;
- struct mutex update_lock;
- unsigned rdac_mask;
- unsigned max_pos;
- unsigned long devid;
- unsigned uid;
- unsigned feat;
- unsigned wipers;
- u16 rdac_cache[MAX_RDACS];
- DECLARE_BITMAP(otp_en_mask, MAX_RDACS);
-};
-
-static inline int dpot_read_d8(struct dpot_data *dpot)
-{
- return dpot->bdata.bops->read_d8(dpot->bdata.client);
-}
-
-static inline int dpot_read_r8d8(struct dpot_data *dpot, u8 reg)
-{
- return dpot->bdata.bops->read_r8d8(dpot->bdata.client, reg);
-}
-
-static inline int dpot_read_r8d16(struct dpot_data *dpot, u8 reg)
-{
- return dpot->bdata.bops->read_r8d16(dpot->bdata.client, reg);
-}
-
-static inline int dpot_write_d8(struct dpot_data *dpot, u8 val)
-{
- return dpot->bdata.bops->write_d8(dpot->bdata.client, val);
-}
-
-static inline int dpot_write_r8d8(struct dpot_data *dpot, u8 reg, u16 val)
-{
- return dpot->bdata.bops->write_r8d8(dpot->bdata.client, reg, val);
-}
-
-static inline int dpot_write_r8d16(struct dpot_data *dpot, u8 reg, u16 val)
-{
- return dpot->bdata.bops->write_r8d16(dpot->bdata.client, reg, val);
-}
-
-static s32 dpot_read_spi(struct dpot_data *dpot, u8 reg)
-{
- unsigned ctrl = 0;
- int value;
-
- if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD))) {
-
- if (dpot->feat & F_RDACS_WONLY)
- return dpot->rdac_cache[reg & DPOT_RDAC_MASK];
- if (dpot->uid == DPOT_UID(AD5291_ID) ||
- dpot->uid == DPOT_UID(AD5292_ID) ||
- dpot->uid == DPOT_UID(AD5293_ID)) {
-
- value = dpot_read_r8d8(dpot,
- DPOT_AD5291_READ_RDAC << 2);
-
- if (dpot->uid == DPOT_UID(AD5291_ID))
- value = value >> 2;
-
- return value;
- } else if (dpot->uid == DPOT_UID(AD5270_ID) ||
- dpot->uid == DPOT_UID(AD5271_ID)) {
-
- value = dpot_read_r8d8(dpot,
- DPOT_AD5270_1_2_4_READ_RDAC << 2);
-
- if (value < 0)
- return value;
-
- if (dpot->uid == DPOT_UID(AD5271_ID))
- value = value >> 2;
-
- return value;
- }
-
- ctrl = DPOT_SPI_READ_RDAC;
- } else if (reg & DPOT_ADDR_EEPROM) {
- ctrl = DPOT_SPI_READ_EEPROM;
- }
-
- if (dpot->feat & F_SPI_16BIT)
- return dpot_read_r8d8(dpot, ctrl);
- else if (dpot->feat & F_SPI_24BIT)
- return dpot_read_r8d16(dpot, ctrl);
-
- return -EFAULT;
-}
-
-static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
-{
- int value;
- unsigned ctrl = 0;
- switch (dpot->uid) {
- case DPOT_UID(AD5246_ID):
- case DPOT_UID(AD5247_ID):
- return dpot_read_d8(dpot);
- case DPOT_UID(AD5245_ID):
- case DPOT_UID(AD5241_ID):
- case DPOT_UID(AD5242_ID):
- case DPOT_UID(AD5243_ID):
- case DPOT_UID(AD5248_ID):
- case DPOT_UID(AD5280_ID):
- case DPOT_UID(AD5282_ID):
- ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
- 0 : DPOT_AD5282_RDAC_AB;
- return dpot_read_r8d8(dpot, ctrl);
- case DPOT_UID(AD5170_ID):
- case DPOT_UID(AD5171_ID):
- case DPOT_UID(AD5273_ID):
- return dpot_read_d8(dpot);
- case DPOT_UID(AD5172_ID):
- case DPOT_UID(AD5173_ID):
- ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
- 0 : DPOT_AD5172_3_A0;
- return dpot_read_r8d8(dpot, ctrl);
- case DPOT_UID(AD5272_ID):
- case DPOT_UID(AD5274_ID):
- dpot_write_r8d8(dpot,
- (DPOT_AD5270_1_2_4_READ_RDAC << 2), 0);
-
- value = dpot_read_r8d16(dpot,
- DPOT_AD5270_1_2_4_RDAC << 2);
-
- if (value < 0)
- return value;
- /*
- * AD5272/AD5274 returns high byte first, however
- * underling smbus expects low byte first.
- */
- value = swab16(value);
-
- if (dpot->uid == DPOT_UID(AD5271_ID))
- value = value >> 2;
- return value;
- default:
- if ((reg & DPOT_REG_TOL) || (dpot->max_pos > 256))
- return dpot_read_r8d16(dpot, (reg & 0xF8) |
- ((reg & 0x7) << 1));
- else
- return dpot_read_r8d8(dpot, reg);
- }
-}
-
-static s32 dpot_read(struct dpot_data *dpot, u8 reg)
-{
- if (dpot->feat & F_SPI)
- return dpot_read_spi(dpot, reg);
- else
- return dpot_read_i2c(dpot, reg);
-}
-
-static s32 dpot_write_spi(struct dpot_data *dpot, u8 reg, u16 value)
-{
- unsigned val = 0;
-
- if (!(reg & (DPOT_ADDR_EEPROM | DPOT_ADDR_CMD | DPOT_ADDR_OTP))) {
- if (dpot->feat & F_RDACS_WONLY)
- dpot->rdac_cache[reg & DPOT_RDAC_MASK] = value;
-
- if (dpot->feat & F_AD_APPDATA) {
- if (dpot->feat & F_SPI_8BIT) {
- val = ((reg & DPOT_RDAC_MASK) <<
- DPOT_MAX_POS(dpot->devid)) |
- value;
- return dpot_write_d8(dpot, val);
- } else if (dpot->feat & F_SPI_16BIT) {
- val = ((reg & DPOT_RDAC_MASK) <<
- DPOT_MAX_POS(dpot->devid)) |
- value;
- return dpot_write_r8d8(dpot, val >> 8,
- val & 0xFF);
- } else
- BUG();
- } else {
- if (dpot->uid == DPOT_UID(AD5291_ID) ||
- dpot->uid == DPOT_UID(AD5292_ID) ||
- dpot->uid == DPOT_UID(AD5293_ID)) {
-
- dpot_write_r8d8(dpot, DPOT_AD5291_CTRLREG << 2,
- DPOT_AD5291_UNLOCK_CMD);
-
- if (dpot->uid == DPOT_UID(AD5291_ID))
- value = value << 2;
-
- return dpot_write_r8d8(dpot,
- (DPOT_AD5291_RDAC << 2) |
- (value >> 8), value & 0xFF);
- } else if (dpot->uid == DPOT_UID(AD5270_ID) ||
- dpot->uid == DPOT_UID(AD5271_ID)) {
- dpot_write_r8d8(dpot,
- DPOT_AD5270_1_2_4_CTRLREG << 2,
- DPOT_AD5270_1_2_4_UNLOCK_CMD);
-
- if (dpot->uid == DPOT_UID(AD5271_ID))
- value = value << 2;
-
- return dpot_write_r8d8(dpot,
- (DPOT_AD5270_1_2_4_RDAC << 2) |
- (value >> 8), value & 0xFF);
- }
- val = DPOT_SPI_RDAC | (reg & DPOT_RDAC_MASK);
- }
- } else if (reg & DPOT_ADDR_EEPROM) {
- val = DPOT_SPI_EEPROM | (reg & DPOT_RDAC_MASK);
- } else if (reg & DPOT_ADDR_CMD) {
- switch (reg) {
- case DPOT_DEC_ALL_6DB:
- val = DPOT_SPI_DEC_ALL_6DB;
- break;
- case DPOT_INC_ALL_6DB:
- val = DPOT_SPI_INC_ALL_6DB;
- break;
- case DPOT_DEC_ALL:
- val = DPOT_SPI_DEC_ALL;
- break;
- case DPOT_INC_ALL:
- val = DPOT_SPI_INC_ALL;
- break;
- }
- } else if (reg & DPOT_ADDR_OTP) {
- if (dpot->uid == DPOT_UID(AD5291_ID) ||
- dpot->uid == DPOT_UID(AD5292_ID)) {
- return dpot_write_r8d8(dpot,
- DPOT_AD5291_STORE_XTPM << 2, 0);
- } else if (dpot->uid == DPOT_UID(AD5270_ID) ||
- dpot->uid == DPOT_UID(AD5271_ID)) {
- return dpot_write_r8d8(dpot,
- DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0);
- }
- } else
- BUG();
-
- if (dpot->feat & F_SPI_16BIT)
- return dpot_write_r8d8(dpot, val, value);
- else if (dpot->feat & F_SPI_24BIT)
- return dpot_write_r8d16(dpot, val, value);
-
- return -EFAULT;
-}
-
-static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
-{
- /* Only write the instruction byte for certain commands */
- unsigned tmp = 0, ctrl = 0;
-
- switch (dpot->uid) {
- case DPOT_UID(AD5246_ID):
- case DPOT_UID(AD5247_ID):
- return dpot_write_d8(dpot, value);
- break;
-
- case DPOT_UID(AD5245_ID):
- case DPOT_UID(AD5241_ID):
- case DPOT_UID(AD5242_ID):
- case DPOT_UID(AD5243_ID):
- case DPOT_UID(AD5248_ID):
- case DPOT_UID(AD5280_ID):
- case DPOT_UID(AD5282_ID):
- ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
- 0 : DPOT_AD5282_RDAC_AB;
- return dpot_write_r8d8(dpot, ctrl, value);
- break;
- case DPOT_UID(AD5171_ID):
- case DPOT_UID(AD5273_ID):
- if (reg & DPOT_ADDR_OTP) {
- tmp = dpot_read_d8(dpot);
- if (tmp >> 6) /* Ready to Program? */
- return -EFAULT;
- ctrl = DPOT_AD5273_FUSE;
- }
- return dpot_write_r8d8(dpot, ctrl, value);
- break;
- case DPOT_UID(AD5172_ID):
- case DPOT_UID(AD5173_ID):
- ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
- 0 : DPOT_AD5172_3_A0;
- if (reg & DPOT_ADDR_OTP) {
- tmp = dpot_read_r8d16(dpot, ctrl);
- if (tmp >> 14) /* Ready to Program? */
- return -EFAULT;
- ctrl |= DPOT_AD5170_2_3_FUSE;
- }
- return dpot_write_r8d8(dpot, ctrl, value);
- break;
- case DPOT_UID(AD5170_ID):
- if (reg & DPOT_ADDR_OTP) {
- tmp = dpot_read_r8d16(dpot, tmp);
- if (tmp >> 14) /* Ready to Program? */
- return -EFAULT;
- ctrl = DPOT_AD5170_2_3_FUSE;
- }
- return dpot_write_r8d8(dpot, ctrl, value);
- break;
- case DPOT_UID(AD5272_ID):
- case DPOT_UID(AD5274_ID):
- dpot_write_r8d8(dpot, DPOT_AD5270_1_2_4_CTRLREG << 2,
- DPOT_AD5270_1_2_4_UNLOCK_CMD);
-
- if (reg & DPOT_ADDR_OTP)
- return dpot_write_r8d8(dpot,
- DPOT_AD5270_1_2_4_STORE_XTPM << 2, 0);
-
- if (dpot->uid == DPOT_UID(AD5274_ID))
- value = value << 2;
-
- return dpot_write_r8d8(dpot, (DPOT_AD5270_1_2_4_RDAC << 2) |
- (value >> 8), value & 0xFF);
- break;
- default:
- if (reg & DPOT_ADDR_CMD)
- return dpot_write_d8(dpot, reg);
-
- if (dpot->max_pos > 256)
- return dpot_write_r8d16(dpot, (reg & 0xF8) |
- ((reg & 0x7) << 1), value);
- else
- /* All other registers require instruction + data bytes */
- return dpot_write_r8d8(dpot, reg, value);
- }
-}
-
-static s32 dpot_write(struct dpot_data *dpot, u8 reg, u16 value)
-{
- if (dpot->feat & F_SPI)
- return dpot_write_spi(dpot, reg, value);
- else
- return dpot_write_i2c(dpot, reg, value);
-}
-
-/* sysfs functions */
-
-static ssize_t sysfs_show_reg(struct device *dev,
- struct device_attribute *attr,
- char *buf, u32 reg)
-{
- struct dpot_data *data = dev_get_drvdata(dev);
- s32 value;
-
- if (reg & DPOT_ADDR_OTP_EN)
- return sprintf(buf, "%s\n",
- test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask) ?
- "enabled" : "disabled");
-
-
- mutex_lock(&data->update_lock);
- value = dpot_read(data, reg);
- mutex_unlock(&data->update_lock);
-
- if (value < 0)
- return -EINVAL;
- /*
- * Let someone else deal with converting this ...
- * the tolerance is a two-byte value where the MSB
- * is a sign + integer value, and the LSB is a
- * decimal value. See page 18 of the AD5258
- * datasheet (Rev. A) for more details.
- */
-
- if (reg & DPOT_REG_TOL)
- return sprintf(buf, "0x%04x\n", value & 0xFFFF);
- else
- return sprintf(buf, "%u\n", value & data->rdac_mask);
-}
-
-static ssize_t sysfs_set_reg(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count, u32 reg)
-{
- struct dpot_data *data = dev_get_drvdata(dev);
- unsigned long value;
- int err;
-
- if (reg & DPOT_ADDR_OTP_EN) {
- if (!strncmp(buf, "enabled", sizeof("enabled")))
- set_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
- else
- clear_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask);
-
- return count;
- }
-
- if ((reg & DPOT_ADDR_OTP) &&
- !test_bit(DPOT_RDAC_MASK & reg, data->otp_en_mask))
- return -EPERM;
-
- err = strict_strtoul(buf, 10, &value);
- if (err)
- return err;
-
- if (value > data->rdac_mask)
- value = data->rdac_mask;
-
- mutex_lock(&data->update_lock);
- dpot_write(data, reg, value);
- if (reg & DPOT_ADDR_EEPROM)
- msleep(26); /* Sleep while the EEPROM updates */
- else if (reg & DPOT_ADDR_OTP)
- msleep(400); /* Sleep while the OTP updates */
- mutex_unlock(&data->update_lock);
-
- return count;
-}
-
-static ssize_t sysfs_do_cmd(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count, u32 reg)
-{
- struct dpot_data *data = dev_get_drvdata(dev);
-
- mutex_lock(&data->update_lock);
- dpot_write(data, reg, 0);
- mutex_unlock(&data->update_lock);
-
- return count;
-}
-
-/* ------------------------------------------------------------------------- */
-
-#define DPOT_DEVICE_SHOW(_name, _reg) static ssize_t \
-show_##_name(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- return sysfs_show_reg(dev, attr, buf, _reg); \
-}
-
-#define DPOT_DEVICE_SET(_name, _reg) static ssize_t \
-set_##_name(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return sysfs_set_reg(dev, attr, buf, count, _reg); \
-}
-
-#define DPOT_DEVICE_SHOW_SET(name, reg) \
-DPOT_DEVICE_SHOW(name, reg) \
-DPOT_DEVICE_SET(name, reg) \
-static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, set_##name);
-
-#define DPOT_DEVICE_SHOW_ONLY(name, reg) \
-DPOT_DEVICE_SHOW(name, reg) \
-static DEVICE_ATTR(name, S_IWUSR | S_IRUGO, show_##name, NULL);
-
-DPOT_DEVICE_SHOW_SET(rdac0, DPOT_ADDR_RDAC | DPOT_RDAC0);
-DPOT_DEVICE_SHOW_SET(eeprom0, DPOT_ADDR_EEPROM | DPOT_RDAC0);
-DPOT_DEVICE_SHOW_ONLY(tolerance0, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC0);
-DPOT_DEVICE_SHOW_SET(otp0, DPOT_ADDR_OTP | DPOT_RDAC0);
-DPOT_DEVICE_SHOW_SET(otp0en, DPOT_ADDR_OTP_EN | DPOT_RDAC0);
-
-DPOT_DEVICE_SHOW_SET(rdac1, DPOT_ADDR_RDAC | DPOT_RDAC1);
-DPOT_DEVICE_SHOW_SET(eeprom1, DPOT_ADDR_EEPROM | DPOT_RDAC1);
-DPOT_DEVICE_SHOW_ONLY(tolerance1, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC1);
-DPOT_DEVICE_SHOW_SET(otp1, DPOT_ADDR_OTP | DPOT_RDAC1);
-DPOT_DEVICE_SHOW_SET(otp1en, DPOT_ADDR_OTP_EN | DPOT_RDAC1);
-
-DPOT_DEVICE_SHOW_SET(rdac2, DPOT_ADDR_RDAC | DPOT_RDAC2);
-DPOT_DEVICE_SHOW_SET(eeprom2, DPOT_ADDR_EEPROM | DPOT_RDAC2);
-DPOT_DEVICE_SHOW_ONLY(tolerance2, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC2);
-DPOT_DEVICE_SHOW_SET(otp2, DPOT_ADDR_OTP | DPOT_RDAC2);
-DPOT_DEVICE_SHOW_SET(otp2en, DPOT_ADDR_OTP_EN | DPOT_RDAC2);
-
-DPOT_DEVICE_SHOW_SET(rdac3, DPOT_ADDR_RDAC | DPOT_RDAC3);
-DPOT_DEVICE_SHOW_SET(eeprom3, DPOT_ADDR_EEPROM | DPOT_RDAC3);
-DPOT_DEVICE_SHOW_ONLY(tolerance3, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC3);
-DPOT_DEVICE_SHOW_SET(otp3, DPOT_ADDR_OTP | DPOT_RDAC3);
-DPOT_DEVICE_SHOW_SET(otp3en, DPOT_ADDR_OTP_EN | DPOT_RDAC3);
-
-DPOT_DEVICE_SHOW_SET(rdac4, DPOT_ADDR_RDAC | DPOT_RDAC4);
-DPOT_DEVICE_SHOW_SET(eeprom4, DPOT_ADDR_EEPROM | DPOT_RDAC4);
-DPOT_DEVICE_SHOW_ONLY(tolerance4, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC4);
-DPOT_DEVICE_SHOW_SET(otp4, DPOT_ADDR_OTP | DPOT_RDAC4);
-DPOT_DEVICE_SHOW_SET(otp4en, DPOT_ADDR_OTP_EN | DPOT_RDAC4);
-
-DPOT_DEVICE_SHOW_SET(rdac5, DPOT_ADDR_RDAC | DPOT_RDAC5);
-DPOT_DEVICE_SHOW_SET(eeprom5, DPOT_ADDR_EEPROM | DPOT_RDAC5);
-DPOT_DEVICE_SHOW_ONLY(tolerance5, DPOT_ADDR_EEPROM | DPOT_TOL_RDAC5);
-DPOT_DEVICE_SHOW_SET(otp5, DPOT_ADDR_OTP | DPOT_RDAC5);
-DPOT_DEVICE_SHOW_SET(otp5en, DPOT_ADDR_OTP_EN | DPOT_RDAC5);
-
-static const struct attribute *dpot_attrib_wipers[] = {
- &dev_attr_rdac0.attr,
- &dev_attr_rdac1.attr,
- &dev_attr_rdac2.attr,
- &dev_attr_rdac3.attr,
- &dev_attr_rdac4.attr,
- &dev_attr_rdac5.attr,
- NULL
-};
-
-static const struct attribute *dpot_attrib_eeprom[] = {
- &dev_attr_eeprom0.attr,
- &dev_attr_eeprom1.attr,
- &dev_attr_eeprom2.attr,
- &dev_attr_eeprom3.attr,
- &dev_attr_eeprom4.attr,
- &dev_attr_eeprom5.attr,
- NULL
-};
-
-static const struct attribute *dpot_attrib_otp[] = {
- &dev_attr_otp0.attr,
- &dev_attr_otp1.attr,
- &dev_attr_otp2.attr,
- &dev_attr_otp3.attr,
- &dev_attr_otp4.attr,
- &dev_attr_otp5.attr,
- NULL
-};
-
-static const struct attribute *dpot_attrib_otp_en[] = {
- &dev_attr_otp0en.attr,
- &dev_attr_otp1en.attr,
- &dev_attr_otp2en.attr,
- &dev_attr_otp3en.attr,
- &dev_attr_otp4en.attr,
- &dev_attr_otp5en.attr,
- NULL
-};
-
-static const struct attribute *dpot_attrib_tolerance[] = {
- &dev_attr_tolerance0.attr,
- &dev_attr_tolerance1.attr,
- &dev_attr_tolerance2.attr,
- &dev_attr_tolerance3.attr,
- &dev_attr_tolerance4.attr,
- &dev_attr_tolerance5.attr,
- NULL
-};
-
-/* ------------------------------------------------------------------------- */
-
-#define DPOT_DEVICE_DO_CMD(_name, _cmd) static ssize_t \
-set_##_name(struct device *dev, \
- struct device_attribute *attr, \
- const char *buf, size_t count) \
-{ \
- return sysfs_do_cmd(dev, attr, buf, count, _cmd); \
-} \
-static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, NULL, set_##_name);
-
-DPOT_DEVICE_DO_CMD(inc_all, DPOT_INC_ALL);
-DPOT_DEVICE_DO_CMD(dec_all, DPOT_DEC_ALL);
-DPOT_DEVICE_DO_CMD(inc_all_6db, DPOT_INC_ALL_6DB);
-DPOT_DEVICE_DO_CMD(dec_all_6db, DPOT_DEC_ALL_6DB);
-
-static struct attribute *ad525x_attributes_commands[] = {
- &dev_attr_inc_all.attr,
- &dev_attr_dec_all.attr,
- &dev_attr_inc_all_6db.attr,
- &dev_attr_dec_all_6db.attr,
- NULL
-};
-
-static const struct attribute_group ad525x_group_commands = {
- .attrs = ad525x_attributes_commands,
-};
-
-__devinit int ad_dpot_add_files(struct device *dev,
- unsigned features, unsigned rdac)
-{
- int err = sysfs_create_file(&dev->kobj,
- dpot_attrib_wipers[rdac]);
- if (features & F_CMD_EEP)
- err |= sysfs_create_file(&dev->kobj,
- dpot_attrib_eeprom[rdac]);
- if (features & F_CMD_TOL)
- err |= sysfs_create_file(&dev->kobj,
- dpot_attrib_tolerance[rdac]);
- if (features & F_CMD_OTP) {
- err |= sysfs_create_file(&dev->kobj,
- dpot_attrib_otp_en[rdac]);
- err |= sysfs_create_file(&dev->kobj,
- dpot_attrib_otp[rdac]);
- }
-
- if (err)
- dev_err(dev, "failed to register sysfs hooks for RDAC%d\n",
- rdac);
-
- return err;
-}
-
-inline void ad_dpot_remove_files(struct device *dev,
- unsigned features, unsigned rdac)
-{
- sysfs_remove_file(&dev->kobj,
- dpot_attrib_wipers[rdac]);
- if (features & F_CMD_EEP)
- sysfs_remove_file(&dev->kobj,
- dpot_attrib_eeprom[rdac]);
- if (features & F_CMD_TOL)
- sysfs_remove_file(&dev->kobj,
- dpot_attrib_tolerance[rdac]);
- if (features & F_CMD_OTP) {
- sysfs_remove_file(&dev->kobj,
- dpot_attrib_otp_en[rdac]);
- sysfs_remove_file(&dev->kobj,
- dpot_attrib_otp[rdac]);
- }
-}
-
-int __devinit ad_dpot_probe(struct device *dev,
- struct ad_dpot_bus_data *bdata, unsigned long devid,
- const char *name)
-{
-
- struct dpot_data *data;
- int i, err = 0;
-
- data = kzalloc(sizeof(struct dpot_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
-
- dev_set_drvdata(dev, data);
- mutex_init(&data->update_lock);
-
- data->bdata = *bdata;
- data->devid = devid;
-
- data->max_pos = 1 << DPOT_MAX_POS(devid);
- data->rdac_mask = data->max_pos - 1;
- data->feat = DPOT_FEAT(devid);
- data->uid = DPOT_UID(devid);
- data->wipers = DPOT_WIPERS(devid);
-
- for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
- if (data->wipers & (1 << i)) {
- err = ad_dpot_add_files(dev, data->feat, i);
- if (err)
- goto exit_remove_files;
- /* power-up midscale */
- if (data->feat & F_RDACS_WONLY)
- data->rdac_cache[i] = data->max_pos / 2;
- }
-
- if (data->feat & F_CMD_INC)
- err = sysfs_create_group(&dev->kobj, &ad525x_group_commands);
-
- if (err) {
- dev_err(dev, "failed to register sysfs hooks\n");
- goto exit_free;
- }
-
- dev_info(dev, "%s %d-Position Digital Potentiometer registered\n",
- name, data->max_pos);
-
- return 0;
-
-exit_remove_files:
- for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
- if (data->wipers & (1 << i))
- ad_dpot_remove_files(dev, data->feat, i);
-
-exit_free:
- kfree(data);
- dev_set_drvdata(dev, NULL);
-exit:
- dev_err(dev, "failed to create client for %s ID 0x%lX\n",
- name, devid);
- return err;
-}
-EXPORT_SYMBOL(ad_dpot_probe);
-
-__devexit int ad_dpot_remove(struct device *dev)
-{
- struct dpot_data *data = dev_get_drvdata(dev);
- int i;
-
- for (i = DPOT_RDAC0; i < MAX_RDACS; i++)
- if (data->wipers & (1 << i))
- ad_dpot_remove_files(dev, data->feat, i);
-
- kfree(data);
-
- return 0;
-}
-EXPORT_SYMBOL(ad_dpot_remove);
-
-
-MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, "
- "Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Digital potentiometer driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/ad525x_dpot.h b/ANDROID_3.4.5/drivers/misc/ad525x_dpot.h
deleted file mode 100644
index 6bd1eba2..00000000
--- a/ANDROID_3.4.5/drivers/misc/ad525x_dpot.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Driver for the Analog Devices digital potentiometers
- *
- * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#ifndef _AD_DPOT_H_
-#define _AD_DPOT_H_
-
-#include <linux/types.h>
-
-#define DPOT_CONF(features, wipers, max_pos, uid) \
- (((features) << 18) | (((wipers) & 0xFF) << 10) | \
- ((max_pos & 0xF) << 6) | (uid & 0x3F))
-
-#define DPOT_UID(conf) (conf & 0x3F)
-#define DPOT_MAX_POS(conf) ((conf >> 6) & 0xF)
-#define DPOT_WIPERS(conf) ((conf >> 10) & 0xFF)
-#define DPOT_FEAT(conf) (conf >> 18)
-
-#define BRDAC0 (1 << 0)
-#define BRDAC1 (1 << 1)
-#define BRDAC2 (1 << 2)
-#define BRDAC3 (1 << 3)
-#define BRDAC4 (1 << 4)
-#define BRDAC5 (1 << 5)
-#define MAX_RDACS 6
-
-#define F_CMD_INC (1 << 0) /* Features INC/DEC ALL, 6dB */
-#define F_CMD_EEP (1 << 1) /* Features EEPROM */
-#define F_CMD_OTP (1 << 2) /* Features OTP */
-#define F_CMD_TOL (1 << 3) /* RDACS feature Tolerance REG */
-#define F_RDACS_RW (1 << 4) /* RDACS are Read/Write */
-#define F_RDACS_WONLY (1 << 5) /* RDACS are Write only */
-#define F_AD_APPDATA (1 << 6) /* RDAC Address append to data */
-#define F_SPI_8BIT (1 << 7) /* All SPI XFERS are 8-bit */
-#define F_SPI_16BIT (1 << 8) /* All SPI XFERS are 16-bit */
-#define F_SPI_24BIT (1 << 9) /* All SPI XFERS are 24-bit */
-
-#define F_RDACS_RW_TOL (F_RDACS_RW | F_CMD_EEP | F_CMD_TOL)
-#define F_RDACS_RW_EEP (F_RDACS_RW | F_CMD_EEP)
-#define F_SPI (F_SPI_8BIT | F_SPI_16BIT | F_SPI_24BIT)
-
-enum dpot_devid {
- AD5258_ID = DPOT_CONF(F_RDACS_RW_TOL, BRDAC0, 6, 0), /* I2C */
- AD5259_ID = DPOT_CONF(F_RDACS_RW_TOL, BRDAC0, 8, 1),
- AD5251_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC,
- BRDAC1 | BRDAC3, 6, 2),
- AD5252_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC,
- BRDAC1 | BRDAC3, 8, 3),
- AD5253_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC,
- BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 6, 4),
- AD5254_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC,
- BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 8, 5),
- AD5255_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC,
- BRDAC0 | BRDAC1 | BRDAC2, 9, 6),
- AD5160_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
- BRDAC0, 8, 7), /* SPI */
- AD5161_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
- BRDAC0, 8, 8),
- AD5162_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
- BRDAC0 | BRDAC1, 8, 9),
- AD5165_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
- BRDAC0, 8, 10),
- AD5200_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
- BRDAC0, 8, 11),
- AD5201_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
- BRDAC0, 5, 12),
- AD5203_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
- BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 6, 13),
- AD5204_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
- BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 8, 14),
- AD5206_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
- BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3 | BRDAC4 | BRDAC5,
- 8, 15),
- AD5207_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
- BRDAC0 | BRDAC1, 8, 16),
- AD5231_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_24BIT,
- BRDAC0, 10, 17),
- AD5232_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_16BIT,
- BRDAC0 | BRDAC1, 8, 18),
- AD5233_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_16BIT,
- BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 6, 19),
- AD5235_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_24BIT,
- BRDAC0 | BRDAC1, 10, 20),
- AD5260_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
- BRDAC0, 8, 21),
- AD5262_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
- BRDAC0 | BRDAC1, 8, 22),
- AD5263_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
- BRDAC0 | BRDAC1 | BRDAC2 | BRDAC3, 8, 23),
- AD5290_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
- BRDAC0, 8, 24),
- AD5291_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT | F_CMD_OTP,
- BRDAC0, 8, 25),
- AD5292_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT | F_CMD_OTP,
- BRDAC0, 10, 26),
- AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27),
- AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT,
- BRDAC0, 7, 28),
- AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
- BRDAC0, 8, 29),
- AD8402_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
- BRDAC0 | BRDAC1, 8, 30),
- AD8403_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT,
- BRDAC0 | BRDAC1 | BRDAC2, 8, 31),
- ADN2850_ID = DPOT_CONF(F_RDACS_RW_EEP | F_CMD_INC | F_SPI_24BIT,
- BRDAC0 | BRDAC1, 10, 32),
- AD5241_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 8, 33),
- AD5242_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 34),
- AD5243_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 35),
- AD5245_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 8, 36),
- AD5246_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 7, 37),
- AD5247_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 7, 38),
- AD5248_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 39),
- AD5280_ID = DPOT_CONF(F_RDACS_RW, BRDAC0, 8, 40),
- AD5282_ID = DPOT_CONF(F_RDACS_RW, BRDAC0 | BRDAC1, 8, 41),
- ADN2860_ID = DPOT_CONF(F_RDACS_RW_TOL | F_CMD_INC,
- BRDAC0 | BRDAC1 | BRDAC2, 9, 42),
- AD5273_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 6, 43),
- AD5171_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 6, 44),
- AD5170_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 8, 45),
- AD5172_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 46),
- AD5173_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0 | BRDAC1, 8, 47),
- AD5270_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP | F_SPI_16BIT,
- BRDAC0, 10, 48),
- AD5271_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP | F_SPI_16BIT,
- BRDAC0, 8, 49),
- AD5272_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 10, 50),
- AD5274_ID = DPOT_CONF(F_RDACS_RW | F_CMD_OTP, BRDAC0, 8, 51),
-};
-
-#define DPOT_RDAC0 0
-#define DPOT_RDAC1 1
-#define DPOT_RDAC2 2
-#define DPOT_RDAC3 3
-#define DPOT_RDAC4 4
-#define DPOT_RDAC5 5
-
-#define DPOT_RDAC_MASK 0x1F
-
-#define DPOT_REG_TOL 0x18
-#define DPOT_TOL_RDAC0 (DPOT_REG_TOL | DPOT_RDAC0)
-#define DPOT_TOL_RDAC1 (DPOT_REG_TOL | DPOT_RDAC1)
-#define DPOT_TOL_RDAC2 (DPOT_REG_TOL | DPOT_RDAC2)
-#define DPOT_TOL_RDAC3 (DPOT_REG_TOL | DPOT_RDAC3)
-#define DPOT_TOL_RDAC4 (DPOT_REG_TOL | DPOT_RDAC4)
-#define DPOT_TOL_RDAC5 (DPOT_REG_TOL | DPOT_RDAC5)
-
-/* RDAC-to-EEPROM Interface Commands */
-#define DPOT_ADDR_RDAC (0x0 << 5)
-#define DPOT_ADDR_EEPROM (0x1 << 5)
-#define DPOT_ADDR_OTP (0x1 << 6)
-#define DPOT_ADDR_CMD (0x1 << 7)
-#define DPOT_ADDR_OTP_EN (0x1 << 9)
-
-#define DPOT_DEC_ALL_6DB (DPOT_ADDR_CMD | (0x4 << 3))
-#define DPOT_INC_ALL_6DB (DPOT_ADDR_CMD | (0x9 << 3))
-#define DPOT_DEC_ALL (DPOT_ADDR_CMD | (0x6 << 3))
-#define DPOT_INC_ALL (DPOT_ADDR_CMD | (0xB << 3))
-
-#define DPOT_SPI_RDAC 0xB0
-#define DPOT_SPI_EEPROM 0x30
-#define DPOT_SPI_READ_RDAC 0xA0
-#define DPOT_SPI_READ_EEPROM 0x90
-#define DPOT_SPI_DEC_ALL_6DB 0x50
-#define DPOT_SPI_INC_ALL_6DB 0xD0
-#define DPOT_SPI_DEC_ALL 0x70
-#define DPOT_SPI_INC_ALL 0xF0
-
-/* AD5291/2/3 use special commands */
-#define DPOT_AD5291_RDAC 0x01
-#define DPOT_AD5291_READ_RDAC 0x02
-#define DPOT_AD5291_STORE_XTPM 0x03
-#define DPOT_AD5291_CTRLREG 0x06
-#define DPOT_AD5291_UNLOCK_CMD 0x03
-
-/* AD5270/1/2/4 use special commands */
-#define DPOT_AD5270_1_2_4_RDAC 0x01
-#define DPOT_AD5270_1_2_4_READ_RDAC 0x02
-#define DPOT_AD5270_1_2_4_STORE_XTPM 0x03
-#define DPOT_AD5270_1_2_4_CTRLREG 0x07
-#define DPOT_AD5270_1_2_4_UNLOCK_CMD 0x03
-
-#define DPOT_AD5282_RDAC_AB 0x80
-
-#define DPOT_AD5273_FUSE 0x80
-#define DPOT_AD5170_2_3_FUSE 0x20
-#define DPOT_AD5170_2_3_OW 0x08
-#define DPOT_AD5172_3_A0 0x08
-#define DPOT_AD5170_2FUSE 0x80
-
-struct dpot_data;
-
-struct ad_dpot_bus_ops {
- int (*read_d8) (void *client);
- int (*read_r8d8) (void *client, u8 reg);
- int (*read_r8d16) (void *client, u8 reg);
- int (*write_d8) (void *client, u8 val);
- int (*write_r8d8) (void *client, u8 reg, u8 val);
- int (*write_r8d16) (void *client, u8 reg, u16 val);
-};
-
-struct ad_dpot_bus_data {
- void *client;
- const struct ad_dpot_bus_ops *bops;
-};
-
-int ad_dpot_probe(struct device *dev, struct ad_dpot_bus_data *bdata,
- unsigned long devid, const char *name);
-int ad_dpot_remove(struct device *dev);
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/misc/akm8975.c b/ANDROID_3.4.5/drivers/misc/akm8975.c
deleted file mode 100644
index 830d2897..00000000
--- a/ANDROID_3.4.5/drivers/misc/akm8975.c
+++ /dev/null
@@ -1,732 +0,0 @@
-/* drivers/misc/akm8975.c - akm8975 compass driver
- *
- * Copyright (C) 2007-2008 HTC Corporation.
- * Author: Hou-Kun Chen <houkun.chen@gmail.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.
- *
- */
-
-/*
- * Revised by AKM 2009/04/02
- * Revised by Motorola 2010/05/27
- *
- */
-
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-#include <linux/miscdevice.h>
-#include <linux/gpio.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-#include <linux/input.h>
-#include <linux/workqueue.h>
-#include <linux/freezer.h>
-#include <linux/akm8975.h>
-#include <linux/earlysuspend.h>
-
-#define AK8975DRV_CALL_DBG 0
-#if AK8975DRV_CALL_DBG
-#define FUNCDBG(msg) pr_err("%s:%s\n", __func__, msg);
-#else
-#define FUNCDBG(msg)
-#endif
-
-#define AK8975DRV_DATA_DBG 0
-#define MAX_FAILURE_COUNT 10
-
-struct akm8975_data {
- struct i2c_client *this_client;
- struct akm8975_platform_data *pdata;
- struct input_dev *input_dev;
- struct work_struct work;
- struct mutex flags_lock;
-#ifdef CONFIG_HAS_EARLYSUSPEND
- struct early_suspend early_suspend;
-#endif
-};
-
-/*
-* Because misc devices can not carry a pointer from driver register to
-* open, we keep this global. This limits the driver to a single instance.
-*/
-struct akm8975_data *akmd_data;
-
-static DECLARE_WAIT_QUEUE_HEAD(open_wq);
-
-static atomic_t open_flag;
-
-static short m_flag;
-static short a_flag;
-static short t_flag;
-static short mv_flag;
-
-static short akmd_delay;
-
-static ssize_t akm8975_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- return sprintf(buf, "%u\n", i2c_smbus_read_byte_data(client,
- AK8975_REG_CNTL));
-}
-static ssize_t akm8975_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- unsigned long val;
- strict_strtoul(buf, 10, &val);
- if (val > 0xff)
- return -EINVAL;
- i2c_smbus_write_byte_data(client, AK8975_REG_CNTL, val);
- return count;
-}
-static DEVICE_ATTR(akm_ms1, S_IWUSR | S_IRUGO, akm8975_show, akm8975_store);
-
-static int akm8975_i2c_rxdata(struct akm8975_data *akm, char *buf, int length)
-{
- struct i2c_msg msgs[] = {
- {
- .addr = akm->this_client->addr,
- .flags = 0,
- .len = 1,
- .buf = buf,
- },
- {
- .addr = akm->this_client->addr,
- .flags = I2C_M_RD,
- .len = length,
- .buf = buf,
- },
- };
-
- FUNCDBG("called");
-
- if (i2c_transfer(akm->this_client->adapter, msgs, 2) < 0) {
- pr_err("akm8975_i2c_rxdata: transfer error\n");
- return EIO;
- } else
- return 0;
-}
-
-static int akm8975_i2c_txdata(struct akm8975_data *akm, char *buf, int length)
-{
- struct i2c_msg msgs[] = {
- {
- .addr = akm->this_client->addr,
- .flags = 0,
- .len = length,
- .buf = buf,
- },
- };
-
- FUNCDBG("called");
-
- if (i2c_transfer(akm->this_client->adapter, msgs, 1) < 0) {
- pr_err("akm8975_i2c_txdata: transfer error\n");
- return -EIO;
- } else
- return 0;
-}
-
-static void akm8975_ecs_report_value(struct akm8975_data *akm, short *rbuf)
-{
- struct akm8975_data *data = i2c_get_clientdata(akm->this_client);
-
- FUNCDBG("called");
-
-#if AK8975DRV_DATA_DBG
- pr_info("akm8975_ecs_report_value: yaw = %d, pitch = %d, roll = %d\n",
- rbuf[0], rbuf[1], rbuf[2]);
- pr_info("tmp = %d, m_stat= %d, g_stat=%d\n", rbuf[3], rbuf[4], rbuf[5]);
- pr_info("Acceleration: x = %d LSB, y = %d LSB, z = %d LSB\n",
- rbuf[6], rbuf[7], rbuf[8]);
- pr_info("Magnetic: x = %d LSB, y = %d LSB, z = %d LSB\n\n",
- rbuf[9], rbuf[10], rbuf[11]);
-#endif
- mutex_lock(&akm->flags_lock);
- /* Report magnetic sensor information */
- if (m_flag) {
- input_report_abs(data->input_dev, ABS_RX, rbuf[0]);
- input_report_abs(data->input_dev, ABS_RY, rbuf[1]);
- input_report_abs(data->input_dev, ABS_RZ, rbuf[2]);
- input_report_abs(data->input_dev, ABS_RUDDER, rbuf[4]);
- }
-
- /* Report acceleration sensor information */
- if (a_flag) {
- input_report_abs(data->input_dev, ABS_X, rbuf[6]);
- input_report_abs(data->input_dev, ABS_Y, rbuf[7]);
- input_report_abs(data->input_dev, ABS_Z, rbuf[8]);
- input_report_abs(data->input_dev, ABS_WHEEL, rbuf[5]);
- }
-
- /* Report temperature information */
- if (t_flag)
- input_report_abs(data->input_dev, ABS_THROTTLE, rbuf[3]);
-
- if (mv_flag) {
- input_report_abs(data->input_dev, ABS_HAT0X, rbuf[9]);
- input_report_abs(data->input_dev, ABS_HAT0Y, rbuf[10]);
- input_report_abs(data->input_dev, ABS_BRAKE, rbuf[11]);
- }
- mutex_unlock(&akm->flags_lock);
-
- input_sync(data->input_dev);
-}
-
-static void akm8975_ecs_close_done(struct akm8975_data *akm)
-{
- FUNCDBG("called");
- mutex_lock(&akm->flags_lock);
- m_flag = 1;
- a_flag = 1;
- t_flag = 1;
- mv_flag = 1;
- mutex_unlock(&akm->flags_lock);
-}
-
-static int akm_aot_open(struct inode *inode, struct file *file)
-{
- int ret = -1;
-
- FUNCDBG("called");
- if (atomic_cmpxchg(&open_flag, 0, 1) == 0) {
- wake_up(&open_wq);
- ret = 0;
- }
-
- ret = nonseekable_open(inode, file);
- if (ret)
- return ret;
-
- file->private_data = akmd_data;
-
- return ret;
-}
-
-static int akm_aot_release(struct inode *inode, struct file *file)
-{
- FUNCDBG("called");
- atomic_set(&open_flag, 0);
- wake_up(&open_wq);
- return 0;
-}
-
-static int akm_aot_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- void __user *argp = (void __user *) arg;
- short flag;
- struct akm8975_data *akm = file->private_data;
-
- FUNCDBG("called");
-
- switch (cmd) {
- case ECS_IOCTL_APP_SET_MFLAG:
- case ECS_IOCTL_APP_SET_AFLAG:
- case ECS_IOCTL_APP_SET_MVFLAG:
- if (copy_from_user(&flag, argp, sizeof(flag)))
- return -EFAULT;
- if (flag < 0 || flag > 1)
- return -EINVAL;
- break;
- case ECS_IOCTL_APP_SET_DELAY:
- if (copy_from_user(&flag, argp, sizeof(flag)))
- return -EFAULT;
- break;
- default:
- break;
- }
-
- mutex_lock(&akm->flags_lock);
- switch (cmd) {
- case ECS_IOCTL_APP_SET_MFLAG:
- m_flag = flag;
- break;
- case ECS_IOCTL_APP_GET_MFLAG:
- flag = m_flag;
- break;
- case ECS_IOCTL_APP_SET_AFLAG:
- a_flag = flag;
- break;
- case ECS_IOCTL_APP_GET_AFLAG:
- flag = a_flag;
- break;
- case ECS_IOCTL_APP_SET_MVFLAG:
- mv_flag = flag;
- break;
- case ECS_IOCTL_APP_GET_MVFLAG:
- flag = mv_flag;
- break;
- case ECS_IOCTL_APP_SET_DELAY:
- akmd_delay = flag;
- break;
- case ECS_IOCTL_APP_GET_DELAY:
- flag = akmd_delay;
- break;
- default:
- return -ENOTTY;
- }
- mutex_unlock(&akm->flags_lock);
-
- switch (cmd) {
- case ECS_IOCTL_APP_GET_MFLAG:
- case ECS_IOCTL_APP_GET_AFLAG:
- case ECS_IOCTL_APP_GET_MVFLAG:
- case ECS_IOCTL_APP_GET_DELAY:
- if (copy_to_user(argp, &flag, sizeof(flag)))
- return -EFAULT;
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int akmd_open(struct inode *inode, struct file *file)
-{
- int err = 0;
-
- FUNCDBG("called");
- err = nonseekable_open(inode, file);
- if (err)
- return err;
-
- file->private_data = akmd_data;
- return 0;
-}
-
-static int akmd_release(struct inode *inode, struct file *file)
-{
- struct akm8975_data *akm = file->private_data;
-
- FUNCDBG("called");
- akm8975_ecs_close_done(akm);
- return 0;
-}
-
-static int akmd_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- void __user *argp = (void __user *) arg;
-
- char rwbuf[16];
- int ret = -1;
- int status;
- short value[12];
- short delay;
- struct akm8975_data *akm = file->private_data;
-
- FUNCDBG("called");
-
- switch (cmd) {
- case ECS_IOCTL_READ:
- case ECS_IOCTL_WRITE:
- if (copy_from_user(&rwbuf, argp, sizeof(rwbuf)))
- return -EFAULT;
- break;
-
- case ECS_IOCTL_SET_YPR:
- if (copy_from_user(&value, argp, sizeof(value)))
- return -EFAULT;
- break;
-
- default:
- break;
- }
-
- switch (cmd) {
- case ECS_IOCTL_READ:
- if (rwbuf[0] < 1)
- return -EINVAL;
-
- ret = akm8975_i2c_rxdata(akm, &rwbuf[1], rwbuf[0]);
- if (ret < 0)
- return ret;
- break;
-
- case ECS_IOCTL_WRITE:
- if (rwbuf[0] < 2)
- return -EINVAL;
-
- ret = akm8975_i2c_txdata(akm, &rwbuf[1], rwbuf[0]);
- if (ret < 0)
- return ret;
- break;
- case ECS_IOCTL_SET_YPR:
- akm8975_ecs_report_value(akm, value);
- break;
-
- case ECS_IOCTL_GET_OPEN_STATUS:
- wait_event_interruptible(open_wq,
- (atomic_read(&open_flag) != 0));
- status = atomic_read(&open_flag);
- break;
- case ECS_IOCTL_GET_CLOSE_STATUS:
- wait_event_interruptible(open_wq,
- (atomic_read(&open_flag) == 0));
- status = atomic_read(&open_flag);
- break;
-
- case ECS_IOCTL_GET_DELAY:
- delay = akmd_delay;
- break;
-
- default:
- FUNCDBG("Unknown cmd\n");
- return -ENOTTY;
- }
-
- switch (cmd) {
- case ECS_IOCTL_READ:
- if (copy_to_user(argp, &rwbuf, sizeof(rwbuf)))
- return -EFAULT;
- break;
- case ECS_IOCTL_GET_OPEN_STATUS:
- case ECS_IOCTL_GET_CLOSE_STATUS:
- if (copy_to_user(argp, &status, sizeof(status)))
- return -EFAULT;
- break;
- case ECS_IOCTL_GET_DELAY:
- if (copy_to_user(argp, &delay, sizeof(delay)))
- return -EFAULT;
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-/* needed to clear the int. pin */
-static void akm_work_func(struct work_struct *work)
-{
- struct akm8975_data *akm =
- container_of(work, struct akm8975_data, work);
-
- FUNCDBG("called");
- enable_irq(akm->this_client->irq);
-}
-
-static irqreturn_t akm8975_interrupt(int irq, void *dev_id)
-{
- struct akm8975_data *akm = dev_id;
- FUNCDBG("called");
-
- disable_irq_nosync(akm->this_client->irq);
- schedule_work(&akm->work);
- return IRQ_HANDLED;
-}
-
-static int akm8975_power_off(struct akm8975_data *akm)
-{
-#if AK8975DRV_CALL_DBG
- pr_info("%s\n", __func__);
-#endif
- if (akm->pdata->power_off)
- akm->pdata->power_off();
-
- return 0;
-}
-
-static int akm8975_power_on(struct akm8975_data *akm)
-{
- int err;
-
-#if AK8975DRV_CALL_DBG
- pr_info("%s\n", __func__);
-#endif
- if (akm->pdata->power_on) {
- err = akm->pdata->power_on();
- if (err < 0)
- return err;
- }
- return 0;
-}
-
-static int akm8975_suspend(struct i2c_client *client, pm_message_t mesg)
-{
- struct akm8975_data *akm = i2c_get_clientdata(client);
-
-#if AK8975DRV_CALL_DBG
- pr_info("%s\n", __func__);
-#endif
- /* TO DO: might need more work after power mgmt
- is enabled */
- return akm8975_power_off(akm);
-}
-
-static int akm8975_resume(struct i2c_client *client)
-{
- struct akm8975_data *akm = i2c_get_clientdata(client);
-
-#if AK8975DRV_CALL_DBG
- pr_info("%s\n", __func__);
-#endif
- /* TO DO: might need more work after power mgmt
- is enabled */
- return akm8975_power_on(akm);
-}
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void akm8975_early_suspend(struct early_suspend *handler)
-{
- struct akm8975_data *akm;
- akm = container_of(handler, struct akm8975_data, early_suspend);
-
-#if AK8975DRV_CALL_DBG
- pr_info("%s\n", __func__);
-#endif
- akm8975_suspend(akm->this_client, PMSG_SUSPEND);
-}
-
-static void akm8975_early_resume(struct early_suspend *handler)
-{
- struct akm8975_data *akm;
- akm = container_of(handler, struct akm8975_data, early_suspend);
-
-#if AK8975DRV_CALL_DBG
- pr_info("%s\n", __func__);
-#endif
- akm8975_resume(akm->this_client);
-}
-#endif
-
-
-static int akm8975_init_client(struct i2c_client *client)
-{
- struct akm8975_data *data;
- int ret;
-
- data = i2c_get_clientdata(client);
-
- ret = request_irq(client->irq, akm8975_interrupt, IRQF_TRIGGER_RISING,
- "akm8975", data);
-
- if (ret < 0) {
- pr_err("akm8975_init_client: request irq failed\n");
- goto err;
- }
-
- init_waitqueue_head(&open_wq);
-
- mutex_lock(&data->flags_lock);
- m_flag = 1;
- a_flag = 1;
- t_flag = 1;
- mv_flag = 1;
- mutex_unlock(&data->flags_lock);
-
- return 0;
-err:
- return ret;
-}
-
-static const struct file_operations akmd_fops = {
- .owner = THIS_MODULE,
- .open = akmd_open,
- .release = akmd_release,
- .ioctl = akmd_ioctl,
-};
-
-static const struct file_operations akm_aot_fops = {
- .owner = THIS_MODULE,
- .open = akm_aot_open,
- .release = akm_aot_release,
- .ioctl = akm_aot_ioctl,
-};
-
-static struct miscdevice akm_aot_device = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "akm8975_aot",
- .fops = &akm_aot_fops,
-};
-
-static struct miscdevice akmd_device = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "akm8975_dev",
- .fops = &akmd_fops,
-};
-
-int akm8975_probe(struct i2c_client *client,
- const struct i2c_device_id *devid)
-{
- struct akm8975_data *akm;
- int err;
- FUNCDBG("called");
-
- if (client->dev.platform_data == NULL) {
- dev_err(&client->dev, "platform data is NULL. exiting.\n");
- err = -ENODEV;
- goto exit_platform_data_null;
- }
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- dev_err(&client->dev, "platform data is NULL. exiting.\n");
- err = -ENODEV;
- goto exit_check_functionality_failed;
- }
-
- akm = kzalloc(sizeof(struct akm8975_data), GFP_KERNEL);
- if (!akm) {
- dev_err(&client->dev,
- "failed to allocate memory for module data\n");
- err = -ENOMEM;
- goto exit_alloc_data_failed;
- }
-
- akm->pdata = client->dev.platform_data;
-
- mutex_init(&akm->flags_lock);
- INIT_WORK(&akm->work, akm_work_func);
- i2c_set_clientdata(client, akm);
-
- err = akm8975_power_on(akm);
- if (err < 0)
- goto exit_power_on_failed;
-
- akm8975_init_client(client);
- akm->this_client = client;
- akmd_data = akm;
-
- akm->input_dev = input_allocate_device();
- if (!akm->input_dev) {
- err = -ENOMEM;
- dev_err(&akm->this_client->dev,
- "input device allocate failed\n");
- goto exit_input_dev_alloc_failed;
- }
-
- set_bit(EV_ABS, akm->input_dev->evbit);
-
- /* yaw */
- input_set_abs_params(akm->input_dev, ABS_RX, 0, 23040, 0, 0);
- /* pitch */
- input_set_abs_params(akm->input_dev, ABS_RY, -11520, 11520, 0, 0);
- /* roll */
- input_set_abs_params(akm->input_dev, ABS_RZ, -5760, 5760, 0, 0);
- /* x-axis acceleration */
- input_set_abs_params(akm->input_dev, ABS_X, -5760, 5760, 0, 0);
- /* y-axis acceleration */
- input_set_abs_params(akm->input_dev, ABS_Y, -5760, 5760, 0, 0);
- /* z-axis acceleration */
- input_set_abs_params(akm->input_dev, ABS_Z, -5760, 5760, 0, 0);
- /* temparature */
- input_set_abs_params(akm->input_dev, ABS_THROTTLE, -30, 85, 0, 0);
- /* status of magnetic sensor */
- input_set_abs_params(akm->input_dev, ABS_RUDDER, 0, 3, 0, 0);
- /* status of acceleration sensor */
- input_set_abs_params(akm->input_dev, ABS_WHEEL, 0, 3, 0, 0);
- /* x-axis of raw magnetic vector */
- input_set_abs_params(akm->input_dev, ABS_HAT0X, -20480, 20479, 0, 0);
- /* y-axis of raw magnetic vector */
- input_set_abs_params(akm->input_dev, ABS_HAT0Y, -20480, 20479, 0, 0);
- /* z-axis of raw magnetic vector */
- input_set_abs_params(akm->input_dev, ABS_BRAKE, -20480, 20479, 0, 0);
-
- akm->input_dev->name = "compass";
-
- err = input_register_device(akm->input_dev);
- if (err) {
- pr_err("akm8975_probe: Unable to register input device: %s\n",
- akm->input_dev->name);
- goto exit_input_register_device_failed;
- }
-
- err = misc_register(&akmd_device);
- if (err) {
- pr_err("akm8975_probe: akmd_device register failed\n");
- goto exit_misc_device_register_failed;
- }
-
- err = misc_register(&akm_aot_device);
- if (err) {
- pr_err("akm8975_probe: akm_aot_device register failed\n");
- goto exit_misc_device_register_failed;
- }
-
- err = device_create_file(&client->dev, &dev_attr_akm_ms1);
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
- akm->early_suspend.suspend = akm8975_early_suspend;
- akm->early_suspend.resume = akm8975_early_resume;
- register_early_suspend(&akm->early_suspend);
-#endif
- return 0;
-
-exit_misc_device_register_failed:
-exit_input_register_device_failed:
- input_free_device(akm->input_dev);
-exit_input_dev_alloc_failed:
- akm8975_power_off(akm);
-exit_power_on_failed:
- kfree(akm);
-exit_alloc_data_failed:
-exit_check_functionality_failed:
-exit_platform_data_null:
- return err;
-}
-
-static int __devexit akm8975_remove(struct i2c_client *client)
-{
- struct akm8975_data *akm = i2c_get_clientdata(client);
- FUNCDBG("called");
- free_irq(client->irq, NULL);
- input_unregister_device(akm->input_dev);
- misc_deregister(&akmd_device);
- misc_deregister(&akm_aot_device);
- akm8975_power_off(akm);
- kfree(akm);
- return 0;
-}
-
-static const struct i2c_device_id akm8975_id[] = {
- { "akm8975", 0 },
- { }
-};
-
-MODULE_DEVICE_TABLE(i2c, akm8975_id);
-
-static struct i2c_driver akm8975_driver = {
- .probe = akm8975_probe,
- .remove = akm8975_remove,
-#ifndef CONFIG_HAS_EARLYSUSPEND
- .resume = akm8975_resume,
- .suspend = akm8975_suspend,
-#endif
- .id_table = akm8975_id,
- .driver = {
- .name = "akm8975",
- },
-};
-
-static int __init akm8975_init(void)
-{
- pr_info("AK8975 compass driver: init\n");
- FUNCDBG("AK8975 compass driver: init\n");
- return i2c_add_driver(&akm8975_driver);
-}
-
-static void __exit akm8975_exit(void)
-{
- FUNCDBG("AK8975 compass driver: exit\n");
- i2c_del_driver(&akm8975_driver);
-}
-
-module_init(akm8975_init);
-module_exit(akm8975_exit);
-
-MODULE_AUTHOR("Hou-Kun Chen <hk_chen@htc.com>");
-MODULE_DESCRIPTION("AK8975 compass driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/altera-stapl/Kconfig b/ANDROID_3.4.5/drivers/misc/altera-stapl/Kconfig
deleted file mode 100644
index 7f01d8e9..00000000
--- a/ANDROID_3.4.5/drivers/misc/altera-stapl/Kconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-comment "Altera FPGA firmware download module"
-
-config ALTERA_STAPL
- tristate "Altera FPGA firmware download module"
- depends on I2C
- default n
- help
- An Altera FPGA module. Say Y when you want to support this tool.
diff --git a/ANDROID_3.4.5/drivers/misc/altera-stapl/Makefile b/ANDROID_3.4.5/drivers/misc/altera-stapl/Makefile
deleted file mode 100644
index 055f61ee..00000000
--- a/ANDROID_3.4.5/drivers/misc/altera-stapl/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-altera-stapl-objs = altera-lpt.o altera-jtag.o altera-comp.o altera.o
-
-obj-$(CONFIG_ALTERA_STAPL) += altera-stapl.o
diff --git a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-comp.c b/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-comp.c
deleted file mode 100644
index 49b103be..00000000
--- a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-comp.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * altera-comp.c
- *
- * altera FPGA driver
- *
- * Copyright (C) Altera Corporation 1998-2001
- * Copyright (C) 2010 NetUP Inc.
- * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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/kernel.h>
-#include "altera-exprt.h"
-
-#define SHORT_BITS 16
-#define CHAR_BITS 8
-#define DATA_BLOB_LENGTH 3
-#define MATCH_DATA_LENGTH 8192
-#define ALTERA_REQUEST_SIZE 1024
-#define ALTERA_BUFFER_SIZE (MATCH_DATA_LENGTH + ALTERA_REQUEST_SIZE)
-
-static u32 altera_bits_req(u32 n)
-{
- u32 result = SHORT_BITS;
-
- if (n == 0)
- result = 1;
- else {
- /* Look for the highest non-zero bit position */
- while ((n & (1 << (SHORT_BITS - 1))) == 0) {
- n <<= 1;
- --result;
- }
- }
-
- return result;
-}
-
-static u32 altera_read_packed(u8 *buffer, u32 bits, u32 *bits_avail,
- u32 *in_index)
-{
- u32 result = 0;
- u32 shift = 0;
- u32 databyte = 0;
-
- while (bits > 0) {
- databyte = buffer[*in_index];
- result |= (((databyte >> (CHAR_BITS - *bits_avail))
- & (0xff >> (CHAR_BITS - *bits_avail))) << shift);
-
- if (bits <= *bits_avail) {
- result &= (0xffff >> (SHORT_BITS - (bits + shift)));
- *bits_avail -= bits;
- bits = 0;
- } else {
- ++(*in_index);
- shift += *bits_avail;
- bits -= *bits_avail;
- *bits_avail = CHAR_BITS;
- }
- }
-
- return result;
-}
-
-u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version)
-{
- u32 i, j, data_length = 0L;
- u32 offset, length;
- u32 match_data_length = MATCH_DATA_LENGTH;
- u32 bits_avail = CHAR_BITS;
- u32 in_index = 0L;
-
- if (version > 0)
- --match_data_length;
-
- for (i = 0; i < out_length; ++i)
- out[i] = 0;
-
- /* Read number of bytes in data. */
- for (i = 0; i < sizeof(in_length); ++i) {
- data_length = data_length | (
- altera_read_packed(in,
- CHAR_BITS,
- &bits_avail,
- &in_index) << (i * CHAR_BITS));
- }
-
- if (data_length > out_length) {
- data_length = 0L;
- return data_length;
- }
-
- i = 0;
- while (i < data_length) {
- /* A 0 bit indicates literal data. */
- if (altera_read_packed(in, 1, &bits_avail,
- &in_index) == 0) {
- for (j = 0; j < DATA_BLOB_LENGTH; ++j) {
- if (i < data_length) {
- out[i] = (u8)altera_read_packed(in,
- CHAR_BITS,
- &bits_avail,
- &in_index);
- i++;
- }
- }
- } else {
- /* A 1 bit indicates offset/length to follow. */
- offset = altera_read_packed(in, altera_bits_req((s16)
- (i > match_data_length ?
- match_data_length : i)),
- &bits_avail,
- &in_index);
- length = altera_read_packed(in, CHAR_BITS,
- &bits_avail,
- &in_index);
- for (j = 0; j < length; ++j) {
- if (i < data_length) {
- out[i] = out[i - offset];
- i++;
- }
- }
- }
- }
-
- return data_length;
-}
diff --git a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-exprt.h b/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-exprt.h
deleted file mode 100644
index 39c38d84..00000000
--- a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-exprt.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * altera-exprt.h
- *
- * altera FPGA driver
- *
- * Copyright (C) Altera Corporation 1998-2001
- * Copyright (C) 2010 NetUP Inc.
- * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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 ALTERA_EXPRT_H
-#define ALTERA_EXPRT_H
-
-
-u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version);
-int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo);
-
-#endif /* ALTERA_EXPRT_H */
diff --git a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-jtag.c b/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-jtag.c
deleted file mode 100644
index f4bf2009..00000000
--- a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-jtag.c
+++ /dev/null
@@ -1,1021 +0,0 @@
-/*
- * altera-jtag.c
- *
- * altera FPGA driver
- *
- * Copyright (C) Altera Corporation 1998-2001
- * Copyright (C) 2010 NetUP Inc.
- * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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/delay.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <misc/altera.h>
-#include "altera-exprt.h"
-#include "altera-jtag.h"
-
-#define alt_jtag_io(a, b, c)\
- astate->config->jtag_io(astate->config->dev, a, b, c);
-
-#define alt_malloc(a) kzalloc(a, GFP_KERNEL);
-
-/*
- * This structure shows, for each JTAG state, which state is reached after
- * a single TCK clock cycle with TMS high or TMS low, respectively. This
- * describes all possible state transitions in the JTAG state machine.
- */
-struct altera_jtag_machine {
- enum altera_jtag_state tms_high;
- enum altera_jtag_state tms_low;
-};
-
-static const struct altera_jtag_machine altera_transitions[] = {
- /* RESET */ { RESET, IDLE },
- /* IDLE */ { DRSELECT, IDLE },
- /* DRSELECT */ { IRSELECT, DRCAPTURE },
- /* DRCAPTURE */ { DREXIT1, DRSHIFT },
- /* DRSHIFT */ { DREXIT1, DRSHIFT },
- /* DREXIT1 */ { DRUPDATE, DRPAUSE },
- /* DRPAUSE */ { DREXIT2, DRPAUSE },
- /* DREXIT2 */ { DRUPDATE, DRSHIFT },
- /* DRUPDATE */ { DRSELECT, IDLE },
- /* IRSELECT */ { RESET, IRCAPTURE },
- /* IRCAPTURE */ { IREXIT1, IRSHIFT },
- /* IRSHIFT */ { IREXIT1, IRSHIFT },
- /* IREXIT1 */ { IRUPDATE, IRPAUSE },
- /* IRPAUSE */ { IREXIT2, IRPAUSE },
- /* IREXIT2 */ { IRUPDATE, IRSHIFT },
- /* IRUPDATE */ { DRSELECT, IDLE }
-};
-
-/*
- * This table contains the TMS value to be used to take the NEXT STEP on
- * the path to the desired state. The array index is the current state,
- * and the bit position is the desired endstate. To find out which state
- * is used as the intermediate state, look up the TMS value in the
- * altera_transitions[] table.
- */
-static const u16 altera_jtag_path_map[16] = {
- /* RST RTI SDRS CDR SDR E1DR PDR E2DR */
- 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF,
- /* UDR SIRS CIR SIR E1IR PIR E2IR UIR */
- 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD
-};
-
-/* Flag bits for alt_jtag_io() function */
-#define TMS_HIGH 1
-#define TMS_LOW 0
-#define TDI_HIGH 1
-#define TDI_LOW 0
-#define READ_TDO 1
-#define IGNORE_TDO 0
-
-int altera_jinit(struct altera_state *astate)
-{
- struct altera_jtag *js = &astate->js;
-
- /* initial JTAG state is unknown */
- js->jtag_state = ILLEGAL_JTAG_STATE;
-
- /* initialize to default state */
- js->drstop_state = IDLE;
- js->irstop_state = IDLE;
- js->dr_pre = 0;
- js->dr_post = 0;
- js->ir_pre = 0;
- js->ir_post = 0;
- js->dr_length = 0;
- js->ir_length = 0;
-
- js->dr_pre_data = NULL;
- js->dr_post_data = NULL;
- js->ir_pre_data = NULL;
- js->ir_post_data = NULL;
- js->dr_buffer = NULL;
- js->ir_buffer = NULL;
-
- return 0;
-}
-
-int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
-{
- js->drstop_state = state;
-
- return 0;
-}
-
-int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
-{
- js->irstop_state = state;
-
- return 0;
-}
-
-int altera_set_dr_pre(struct altera_jtag *js,
- u32 count, u32 start_index,
- u8 *preamble_data)
-{
- int status = 0;
- u32 i;
- u32 j;
-
- if (count > js->dr_pre) {
- kfree(js->dr_pre_data);
- js->dr_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
- if (js->dr_pre_data == NULL)
- status = -ENOMEM;
- else
- js->dr_pre = count;
- } else
- js->dr_pre = count;
-
- if (status == 0) {
- for (i = 0; i < count; ++i) {
- j = i + start_index;
-
- if (preamble_data == NULL)
- js->dr_pre_data[i >> 3] |= (1 << (i & 7));
- else {
- if (preamble_data[j >> 3] & (1 << (j & 7)))
- js->dr_pre_data[i >> 3] |=
- (1 << (i & 7));
- else
- js->dr_pre_data[i >> 3] &=
- ~(u32)(1 << (i & 7));
-
- }
- }
- }
-
- return status;
-}
-
-int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
- u8 *preamble_data)
-{
- int status = 0;
- u32 i;
- u32 j;
-
- if (count > js->ir_pre) {
- kfree(js->ir_pre_data);
- js->ir_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
- if (js->ir_pre_data == NULL)
- status = -ENOMEM;
- else
- js->ir_pre = count;
-
- } else
- js->ir_pre = count;
-
- if (status == 0) {
- for (i = 0; i < count; ++i) {
- j = i + start_index;
- if (preamble_data == NULL)
- js->ir_pre_data[i >> 3] |= (1 << (i & 7));
- else {
- if (preamble_data[j >> 3] & (1 << (j & 7)))
- js->ir_pre_data[i >> 3] |=
- (1 << (i & 7));
- else
- js->ir_pre_data[i >> 3] &=
- ~(u32)(1 << (i & 7));
-
- }
- }
- }
-
- return status;
-}
-
-int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
- u8 *postamble_data)
-{
- int status = 0;
- u32 i;
- u32 j;
-
- if (count > js->dr_post) {
- kfree(js->dr_post_data);
- js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3);
-
- if (js->dr_post_data == NULL)
- status = -ENOMEM;
- else
- js->dr_post = count;
-
- } else
- js->dr_post = count;
-
- if (status == 0) {
- for (i = 0; i < count; ++i) {
- j = i + start_index;
-
- if (postamble_data == NULL)
- js->dr_post_data[i >> 3] |= (1 << (i & 7));
- else {
- if (postamble_data[j >> 3] & (1 << (j & 7)))
- js->dr_post_data[i >> 3] |=
- (1 << (i & 7));
- else
- js->dr_post_data[i >> 3] &=
- ~(u32)(1 << (i & 7));
-
- }
- }
- }
-
- return status;
-}
-
-int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
- u8 *postamble_data)
-{
- int status = 0;
- u32 i;
- u32 j;
-
- if (count > js->ir_post) {
- kfree(js->ir_post_data);
- js->ir_post_data = (u8 *)alt_malloc((count + 7) >> 3);
- if (js->ir_post_data == NULL)
- status = -ENOMEM;
- else
- js->ir_post = count;
-
- } else
- js->ir_post = count;
-
- if (status != 0)
- return status;
-
- for (i = 0; i < count; ++i) {
- j = i + start_index;
-
- if (postamble_data == NULL)
- js->ir_post_data[i >> 3] |= (1 << (i & 7));
- else {
- if (postamble_data[j >> 3] & (1 << (j & 7)))
- js->ir_post_data[i >> 3] |= (1 << (i & 7));
- else
- js->ir_post_data[i >> 3] &=
- ~(u32)(1 << (i & 7));
-
- }
- }
-
- return status;
-}
-
-static void altera_jreset_idle(struct altera_state *astate)
-{
- struct altera_jtag *js = &astate->js;
- int i;
- /* Go to Test Logic Reset (no matter what the starting state may be) */
- for (i = 0; i < 5; ++i)
- alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
-
- /* Now step to Run Test / Idle */
- alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
- js->jtag_state = IDLE;
-}
-
-int altera_goto_jstate(struct altera_state *astate,
- enum altera_jtag_state state)
-{
- struct altera_jtag *js = &astate->js;
- int tms;
- int count = 0;
- int status = 0;
-
- if (js->jtag_state == ILLEGAL_JTAG_STATE)
- /* initialize JTAG chain to known state */
- altera_jreset_idle(astate);
-
- if (js->jtag_state == state) {
- /*
- * We are already in the desired state.
- * If it is a stable state, loop here.
- * Otherwise do nothing (no clock cycles).
- */
- if ((state == IDLE) || (state == DRSHIFT) ||
- (state == DRPAUSE) || (state == IRSHIFT) ||
- (state == IRPAUSE)) {
- alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
- } else if (state == RESET)
- alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
-
- } else {
- while ((js->jtag_state != state) && (count < 9)) {
- /* Get TMS value to take a step toward desired state */
- tms = (altera_jtag_path_map[js->jtag_state] &
- (1 << state))
- ? TMS_HIGH : TMS_LOW;
-
- /* Take a step */
- alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
-
- if (tms)
- js->jtag_state =
- altera_transitions[js->jtag_state].tms_high;
- else
- js->jtag_state =
- altera_transitions[js->jtag_state].tms_low;
-
- ++count;
- }
- }
-
- if (js->jtag_state != state)
- status = -EREMOTEIO;
-
- return status;
-}
-
-int altera_wait_cycles(struct altera_state *astate,
- s32 cycles,
- enum altera_jtag_state wait_state)
-{
- struct altera_jtag *js = &astate->js;
- int tms;
- s32 count;
- int status = 0;
-
- if (js->jtag_state != wait_state)
- status = altera_goto_jstate(astate, wait_state);
-
- if (status == 0) {
- /*
- * Set TMS high to loop in RESET state
- * Set TMS low to loop in any other stable state
- */
- tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
-
- for (count = 0L; count < cycles; count++)
- alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
-
- }
-
- return status;
-}
-
-int altera_wait_msecs(struct altera_state *astate,
- s32 microseconds, enum altera_jtag_state wait_state)
-/*
- * Causes JTAG hardware to sit in the specified stable
- * state for the specified duration of real time. If
- * no JTAG operations have been performed yet, then only
- * a delay is performed. This permits the WAIT USECS
- * statement to be used in VECTOR programs without causing
- * any JTAG operations.
- * Returns 0 for success, else appropriate error code.
- */
-{
- struct altera_jtag *js = &astate->js;
- int status = 0;
-
- if ((js->jtag_state != ILLEGAL_JTAG_STATE) &&
- (js->jtag_state != wait_state))
- status = altera_goto_jstate(astate, wait_state);
-
- if (status == 0)
- /* Wait for specified time interval */
- udelay(microseconds);
-
- return status;
-}
-
-static void altera_concatenate_data(u8 *buffer,
- u8 *preamble_data,
- u32 preamble_count,
- u8 *target_data,
- u32 start_index,
- u32 target_count,
- u8 *postamble_data,
- u32 postamble_count)
-/*
- * Copies preamble data, target data, and postamble data
- * into one buffer for IR or DR scans.
- */
-{
- u32 i, j, k;
-
- for (i = 0L; i < preamble_count; ++i) {
- if (preamble_data[i >> 3L] & (1L << (i & 7L)))
- buffer[i >> 3L] |= (1L << (i & 7L));
- else
- buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
-
- }
-
- j = start_index;
- k = preamble_count + target_count;
- for (; i < k; ++i, ++j) {
- if (target_data[j >> 3L] & (1L << (j & 7L)))
- buffer[i >> 3L] |= (1L << (i & 7L));
- else
- buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
-
- }
-
- j = 0L;
- k = preamble_count + target_count + postamble_count;
- for (; i < k; ++i, ++j) {
- if (postamble_data[j >> 3L] & (1L << (j & 7L)))
- buffer[i >> 3L] |= (1L << (i & 7L));
- else
- buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
-
- }
-}
-
-static int alt_jtag_drscan(struct altera_state *astate,
- int start_state,
- int count,
- u8 *tdi,
- u8 *tdo)
-{
- int i = 0;
- int tdo_bit = 0;
- int status = 1;
-
- /* First go to DRSHIFT state */
- switch (start_state) {
- case 0: /* IDLE */
- alt_jtag_io(1, 0, 0); /* DRSELECT */
- alt_jtag_io(0, 0, 0); /* DRCAPTURE */
- alt_jtag_io(0, 0, 0); /* DRSHIFT */
- break;
-
- case 1: /* DRPAUSE */
- alt_jtag_io(1, 0, 0); /* DREXIT2 */
- alt_jtag_io(1, 0, 0); /* DRUPDATE */
- alt_jtag_io(1, 0, 0); /* DRSELECT */
- alt_jtag_io(0, 0, 0); /* DRCAPTURE */
- alt_jtag_io(0, 0, 0); /* DRSHIFT */
- break;
-
- case 2: /* IRPAUSE */
- alt_jtag_io(1, 0, 0); /* IREXIT2 */
- alt_jtag_io(1, 0, 0); /* IRUPDATE */
- alt_jtag_io(1, 0, 0); /* DRSELECT */
- alt_jtag_io(0, 0, 0); /* DRCAPTURE */
- alt_jtag_io(0, 0, 0); /* DRSHIFT */
- break;
-
- default:
- status = 0;
- }
-
- if (status) {
- /* loop in the SHIFT-DR state */
- for (i = 0; i < count; i++) {
- tdo_bit = alt_jtag_io(
- (i == count - 1),
- tdi[i >> 3] & (1 << (i & 7)),
- (tdo != NULL));
-
- if (tdo != NULL) {
- if (tdo_bit)
- tdo[i >> 3] |= (1 << (i & 7));
- else
- tdo[i >> 3] &= ~(u32)(1 << (i & 7));
-
- }
- }
-
- alt_jtag_io(0, 0, 0); /* DRPAUSE */
- }
-
- return status;
-}
-
-static int alt_jtag_irscan(struct altera_state *astate,
- int start_state,
- int count,
- u8 *tdi,
- u8 *tdo)
-{
- int i = 0;
- int tdo_bit = 0;
- int status = 1;
-
- /* First go to IRSHIFT state */
- switch (start_state) {
- case 0: /* IDLE */
- alt_jtag_io(1, 0, 0); /* DRSELECT */
- alt_jtag_io(1, 0, 0); /* IRSELECT */
- alt_jtag_io(0, 0, 0); /* IRCAPTURE */
- alt_jtag_io(0, 0, 0); /* IRSHIFT */
- break;
-
- case 1: /* DRPAUSE */
- alt_jtag_io(1, 0, 0); /* DREXIT2 */
- alt_jtag_io(1, 0, 0); /* DRUPDATE */
- alt_jtag_io(1, 0, 0); /* DRSELECT */
- alt_jtag_io(1, 0, 0); /* IRSELECT */
- alt_jtag_io(0, 0, 0); /* IRCAPTURE */
- alt_jtag_io(0, 0, 0); /* IRSHIFT */
- break;
-
- case 2: /* IRPAUSE */
- alt_jtag_io(1, 0, 0); /* IREXIT2 */
- alt_jtag_io(1, 0, 0); /* IRUPDATE */
- alt_jtag_io(1, 0, 0); /* DRSELECT */
- alt_jtag_io(1, 0, 0); /* IRSELECT */
- alt_jtag_io(0, 0, 0); /* IRCAPTURE */
- alt_jtag_io(0, 0, 0); /* IRSHIFT */
- break;
-
- default:
- status = 0;
- }
-
- if (status) {
- /* loop in the SHIFT-IR state */
- for (i = 0; i < count; i++) {
- tdo_bit = alt_jtag_io(
- (i == count - 1),
- tdi[i >> 3] & (1 << (i & 7)),
- (tdo != NULL));
- if (tdo != NULL) {
- if (tdo_bit)
- tdo[i >> 3] |= (1 << (i & 7));
- else
- tdo[i >> 3] &= ~(u32)(1 << (i & 7));
-
- }
- }
-
- alt_jtag_io(0, 0, 0); /* IRPAUSE */
- }
-
- return status;
-}
-
-static void altera_extract_target_data(u8 *buffer,
- u8 *target_data,
- u32 start_index,
- u32 preamble_count,
- u32 target_count)
-/*
- * Copies target data from scan buffer, filtering out
- * preamble and postamble data.
- */
-{
- u32 i;
- u32 j;
- u32 k;
-
- j = preamble_count;
- k = start_index + target_count;
- for (i = start_index; i < k; ++i, ++j) {
- if (buffer[j >> 3] & (1 << (j & 7)))
- target_data[i >> 3] |= (1 << (i & 7));
- else
- target_data[i >> 3] &= ~(u32)(1 << (i & 7));
-
- }
-}
-
-int altera_irscan(struct altera_state *astate,
- u32 count,
- u8 *tdi_data,
- u32 start_index)
-/* Shifts data into instruction register */
-{
- struct altera_jtag *js = &astate->js;
- int start_code = 0;
- u32 alloc_chars = 0;
- u32 shift_count = js->ir_pre + count + js->ir_post;
- int status = 0;
- enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
-
- switch (js->jtag_state) {
- case ILLEGAL_JTAG_STATE:
- case RESET:
- case IDLE:
- start_code = 0;
- start_state = IDLE;
- break;
-
- case DRSELECT:
- case DRCAPTURE:
- case DRSHIFT:
- case DREXIT1:
- case DRPAUSE:
- case DREXIT2:
- case DRUPDATE:
- start_code = 1;
- start_state = DRPAUSE;
- break;
-
- case IRSELECT:
- case IRCAPTURE:
- case IRSHIFT:
- case IREXIT1:
- case IRPAUSE:
- case IREXIT2:
- case IRUPDATE:
- start_code = 2;
- start_state = IRPAUSE;
- break;
-
- default:
- status = -EREMOTEIO;
- break;
- }
-
- if (status == 0)
- if (js->jtag_state != start_state)
- status = altera_goto_jstate(astate, start_state);
-
- if (status == 0) {
- if (shift_count > js->ir_length) {
- alloc_chars = (shift_count + 7) >> 3;
- kfree(js->ir_buffer);
- js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
- if (js->ir_buffer == NULL)
- status = -ENOMEM;
- else
- js->ir_length = alloc_chars * 8;
-
- }
- }
-
- if (status == 0) {
- /*
- * Copy preamble data, IR data,
- * and postamble data into a buffer
- */
- altera_concatenate_data(js->ir_buffer,
- js->ir_pre_data,
- js->ir_pre,
- tdi_data,
- start_index,
- count,
- js->ir_post_data,
- js->ir_post);
- /* Do the IRSCAN */
- alt_jtag_irscan(astate,
- start_code,
- shift_count,
- js->ir_buffer,
- NULL);
-
- /* alt_jtag_irscan() always ends in IRPAUSE state */
- js->jtag_state = IRPAUSE;
- }
-
- if (status == 0)
- if (js->irstop_state != IRPAUSE)
- status = altera_goto_jstate(astate, js->irstop_state);
-
-
- return status;
-}
-
-int altera_swap_ir(struct altera_state *astate,
- u32 count,
- u8 *in_data,
- u32 in_index,
- u8 *out_data,
- u32 out_index)
-/* Shifts data into instruction register, capturing output data */
-{
- struct altera_jtag *js = &astate->js;
- int start_code = 0;
- u32 alloc_chars = 0;
- u32 shift_count = js->ir_pre + count + js->ir_post;
- int status = 0;
- enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
-
- switch (js->jtag_state) {
- case ILLEGAL_JTAG_STATE:
- case RESET:
- case IDLE:
- start_code = 0;
- start_state = IDLE;
- break;
-
- case DRSELECT:
- case DRCAPTURE:
- case DRSHIFT:
- case DREXIT1:
- case DRPAUSE:
- case DREXIT2:
- case DRUPDATE:
- start_code = 1;
- start_state = DRPAUSE;
- break;
-
- case IRSELECT:
- case IRCAPTURE:
- case IRSHIFT:
- case IREXIT1:
- case IRPAUSE:
- case IREXIT2:
- case IRUPDATE:
- start_code = 2;
- start_state = IRPAUSE;
- break;
-
- default:
- status = -EREMOTEIO;
- break;
- }
-
- if (status == 0)
- if (js->jtag_state != start_state)
- status = altera_goto_jstate(astate, start_state);
-
- if (status == 0) {
- if (shift_count > js->ir_length) {
- alloc_chars = (shift_count + 7) >> 3;
- kfree(js->ir_buffer);
- js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
- if (js->ir_buffer == NULL)
- status = -ENOMEM;
- else
- js->ir_length = alloc_chars * 8;
-
- }
- }
-
- if (status == 0) {
- /*
- * Copy preamble data, IR data,
- * and postamble data into a buffer
- */
- altera_concatenate_data(js->ir_buffer,
- js->ir_pre_data,
- js->ir_pre,
- in_data,
- in_index,
- count,
- js->ir_post_data,
- js->ir_post);
-
- /* Do the IRSCAN */
- alt_jtag_irscan(astate,
- start_code,
- shift_count,
- js->ir_buffer,
- js->ir_buffer);
-
- /* alt_jtag_irscan() always ends in IRPAUSE state */
- js->jtag_state = IRPAUSE;
- }
-
- if (status == 0)
- if (js->irstop_state != IRPAUSE)
- status = altera_goto_jstate(astate, js->irstop_state);
-
-
- if (status == 0)
- /* Now extract the returned data from the buffer */
- altera_extract_target_data(js->ir_buffer,
- out_data, out_index,
- js->ir_pre, count);
-
- return status;
-}
-
-int altera_drscan(struct altera_state *astate,
- u32 count,
- u8 *tdi_data,
- u32 start_index)
-/* Shifts data into data register (ignoring output data) */
-{
- struct altera_jtag *js = &astate->js;
- int start_code = 0;
- u32 alloc_chars = 0;
- u32 shift_count = js->dr_pre + count + js->dr_post;
- int status = 0;
- enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
-
- switch (js->jtag_state) {
- case ILLEGAL_JTAG_STATE:
- case RESET:
- case IDLE:
- start_code = 0;
- start_state = IDLE;
- break;
-
- case DRSELECT:
- case DRCAPTURE:
- case DRSHIFT:
- case DREXIT1:
- case DRPAUSE:
- case DREXIT2:
- case DRUPDATE:
- start_code = 1;
- start_state = DRPAUSE;
- break;
-
- case IRSELECT:
- case IRCAPTURE:
- case IRSHIFT:
- case IREXIT1:
- case IRPAUSE:
- case IREXIT2:
- case IRUPDATE:
- start_code = 2;
- start_state = IRPAUSE;
- break;
-
- default:
- status = -EREMOTEIO;
- break;
- }
-
- if (status == 0)
- if (js->jtag_state != start_state)
- status = altera_goto_jstate(astate, start_state);
-
- if (status == 0) {
- if (shift_count > js->dr_length) {
- alloc_chars = (shift_count + 7) >> 3;
- kfree(js->dr_buffer);
- js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
- if (js->dr_buffer == NULL)
- status = -ENOMEM;
- else
- js->dr_length = alloc_chars * 8;
-
- }
- }
-
- if (status == 0) {
- /*
- * Copy preamble data, DR data,
- * and postamble data into a buffer
- */
- altera_concatenate_data(js->dr_buffer,
- js->dr_pre_data,
- js->dr_pre,
- tdi_data,
- start_index,
- count,
- js->dr_post_data,
- js->dr_post);
- /* Do the DRSCAN */
- alt_jtag_drscan(astate, start_code, shift_count,
- js->dr_buffer, NULL);
- /* alt_jtag_drscan() always ends in DRPAUSE state */
- js->jtag_state = DRPAUSE;
- }
-
- if (status == 0)
- if (js->drstop_state != DRPAUSE)
- status = altera_goto_jstate(astate, js->drstop_state);
-
- return status;
-}
-
-int altera_swap_dr(struct altera_state *astate, u32 count,
- u8 *in_data, u32 in_index,
- u8 *out_data, u32 out_index)
-/* Shifts data into data register, capturing output data */
-{
- struct altera_jtag *js = &astate->js;
- int start_code = 0;
- u32 alloc_chars = 0;
- u32 shift_count = js->dr_pre + count + js->dr_post;
- int status = 0;
- enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
-
- switch (js->jtag_state) {
- case ILLEGAL_JTAG_STATE:
- case RESET:
- case IDLE:
- start_code = 0;
- start_state = IDLE;
- break;
-
- case DRSELECT:
- case DRCAPTURE:
- case DRSHIFT:
- case DREXIT1:
- case DRPAUSE:
- case DREXIT2:
- case DRUPDATE:
- start_code = 1;
- start_state = DRPAUSE;
- break;
-
- case IRSELECT:
- case IRCAPTURE:
- case IRSHIFT:
- case IREXIT1:
- case IRPAUSE:
- case IREXIT2:
- case IRUPDATE:
- start_code = 2;
- start_state = IRPAUSE;
- break;
-
- default:
- status = -EREMOTEIO;
- break;
- }
-
- if (status == 0)
- if (js->jtag_state != start_state)
- status = altera_goto_jstate(astate, start_state);
-
- if (status == 0) {
- if (shift_count > js->dr_length) {
- alloc_chars = (shift_count + 7) >> 3;
- kfree(js->dr_buffer);
- js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
-
- if (js->dr_buffer == NULL)
- status = -ENOMEM;
- else
- js->dr_length = alloc_chars * 8;
-
- }
- }
-
- if (status == 0) {
- /*
- * Copy preamble data, DR data,
- * and postamble data into a buffer
- */
- altera_concatenate_data(js->dr_buffer,
- js->dr_pre_data,
- js->dr_pre,
- in_data,
- in_index,
- count,
- js->dr_post_data,
- js->dr_post);
-
- /* Do the DRSCAN */
- alt_jtag_drscan(astate,
- start_code,
- shift_count,
- js->dr_buffer,
- js->dr_buffer);
-
- /* alt_jtag_drscan() always ends in DRPAUSE state */
- js->jtag_state = DRPAUSE;
- }
-
- if (status == 0)
- if (js->drstop_state != DRPAUSE)
- status = altera_goto_jstate(astate, js->drstop_state);
-
- if (status == 0)
- /* Now extract the returned data from the buffer */
- altera_extract_target_data(js->dr_buffer,
- out_data,
- out_index,
- js->dr_pre,
- count);
-
- return status;
-}
-
-void altera_free_buffers(struct altera_state *astate)
-{
- struct altera_jtag *js = &astate->js;
- /* If the JTAG interface was used, reset it to TLR */
- if (js->jtag_state != ILLEGAL_JTAG_STATE)
- altera_jreset_idle(astate);
-
- kfree(js->dr_pre_data);
- js->dr_pre_data = NULL;
-
- kfree(js->dr_post_data);
- js->dr_post_data = NULL;
-
- kfree(js->dr_buffer);
- js->dr_buffer = NULL;
-
- kfree(js->ir_pre_data);
- js->ir_pre_data = NULL;
-
- kfree(js->ir_post_data);
- js->ir_post_data = NULL;
-
- kfree(js->ir_buffer);
- js->ir_buffer = NULL;
-}
diff --git a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-jtag.h b/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-jtag.h
deleted file mode 100644
index 2f97e36a..00000000
--- a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-jtag.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * altera-jtag.h
- *
- * altera FPGA driver
- *
- * Copyright (C) Altera Corporation 1998-2001
- * Copyright (C) 2010 NetUP Inc.
- * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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 ALTERA_JTAG_H
-#define ALTERA_JTAG_H
-
-/* Function Prototypes */
-enum altera_jtag_state {
- ILLEGAL_JTAG_STATE = -1,
- RESET = 0,
- IDLE = 1,
- DRSELECT = 2,
- DRCAPTURE = 3,
- DRSHIFT = 4,
- DREXIT1 = 5,
- DRPAUSE = 6,
- DREXIT2 = 7,
- DRUPDATE = 8,
- IRSELECT = 9,
- IRCAPTURE = 10,
- IRSHIFT = 11,
- IREXIT1 = 12,
- IRPAUSE = 13,
- IREXIT2 = 14,
- IRUPDATE = 15
-
-};
-
-struct altera_jtag {
- /* Global variable to store the current JTAG state */
- enum altera_jtag_state jtag_state;
-
- /* Store current stop-state for DR and IR scan commands */
- enum altera_jtag_state drstop_state;
- enum altera_jtag_state irstop_state;
-
- /* Store current padding values */
- u32 dr_pre;
- u32 dr_post;
- u32 ir_pre;
- u32 ir_post;
- u32 dr_length;
- u32 ir_length;
- u8 *dr_pre_data;
- u8 *dr_post_data;
- u8 *ir_pre_data;
- u8 *ir_post_data;
- u8 *dr_buffer;
- u8 *ir_buffer;
-};
-
-#define ALTERA_STACK_SIZE 128
-#define ALTERA_MESSAGE_LENGTH 1024
-
-struct altera_state {
- struct altera_config *config;
- struct altera_jtag js;
- char msg_buff[ALTERA_MESSAGE_LENGTH + 1];
- long stack[ALTERA_STACK_SIZE];
-};
-
-int altera_jinit(struct altera_state *astate);
-int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state);
-int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state);
-int altera_set_dr_pre(struct altera_jtag *js, u32 count, u32 start_index,
- u8 *preamble_data);
-int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
- u8 *preamble_data);
-int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
- u8 *postamble_data);
-int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
- u8 *postamble_data);
-int altera_goto_jstate(struct altera_state *astate,
- enum altera_jtag_state state);
-int altera_wait_cycles(struct altera_state *astate, s32 cycles,
- enum altera_jtag_state wait_state);
-int altera_wait_msecs(struct altera_state *astate, s32 microseconds,
- enum altera_jtag_state wait_state);
-int altera_irscan(struct altera_state *astate, u32 count,
- u8 *tdi_data, u32 start_index);
-int altera_swap_ir(struct altera_state *astate,
- u32 count, u8 *in_data,
- u32 in_index, u8 *out_data,
- u32 out_index);
-int altera_drscan(struct altera_state *astate, u32 count,
- u8 *tdi_data, u32 start_index);
-int altera_swap_dr(struct altera_state *astate, u32 count,
- u8 *in_data, u32 in_index,
- u8 *out_data, u32 out_index);
-void altera_free_buffers(struct altera_state *astate);
-#endif /* ALTERA_JTAG_H */
diff --git a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-lpt.c b/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-lpt.c
deleted file mode 100644
index 91456a03..00000000
--- a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera-lpt.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * altera-lpt.c
- *
- * altera FPGA driver
- *
- * Copyright (C) Altera Corporation 1998-2001
- * Copyright (C) 2010 NetUP Inc.
- * Copyright (C) 2010 Abylay Ospan <aospan@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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/io.h>
-#include <linux/kernel.h>
-#include "altera-exprt.h"
-
-static int lpt_hardware_initialized;
-
-static void byteblaster_write(int port, int data)
-{
- outb((u8)data, (u16)(port + 0x378));
-};
-
-static int byteblaster_read(int port)
-{
- int data = 0;
- data = inb((u16)(port + 0x378));
- return data & 0xff;
-};
-
-int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo)
-{
- int data = 0;
- int tdo = 0;
- int initial_lpt_ctrl = 0;
-
- if (!lpt_hardware_initialized) {
- initial_lpt_ctrl = byteblaster_read(2);
- byteblaster_write(2, (initial_lpt_ctrl | 0x02) & 0xdf);
- lpt_hardware_initialized = 1;
- }
-
- data = ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0));
-
- byteblaster_write(0, data);
-
- if (read_tdo) {
- tdo = byteblaster_read(1);
- tdo = ((tdo & 0x80) ? 0 : 1);
- }
-
- byteblaster_write(0, data | 0x01);
-
- byteblaster_write(0, data);
-
- return tdo;
-}
diff --git a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera.c b/ANDROID_3.4.5/drivers/misc/altera-stapl/altera.c
deleted file mode 100644
index 24272e02..00000000
--- a/ANDROID_3.4.5/drivers/misc/altera-stapl/altera.c
+++ /dev/null
@@ -1,2537 +0,0 @@
-/*
- * altera.c
- *
- * altera FPGA driver
- *
- * Copyright (C) Altera Corporation 1998-2001
- * Copyright (C) 2010,2011 NetUP Inc.
- * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT 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 <asm/unaligned.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <misc/altera.h>
-#include "altera-exprt.h"
-#include "altera-jtag.h"
-
-static int debug = 1;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "enable debugging information");
-
-MODULE_DESCRIPTION("altera FPGA kernel module");
-MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>");
-MODULE_LICENSE("GPL");
-
-#define dprintk(args...) \
- if (debug) { \
- printk(KERN_DEBUG args); \
- }
-
-enum altera_fpga_opcode {
- OP_NOP = 0,
- OP_DUP,
- OP_SWP,
- OP_ADD,
- OP_SUB,
- OP_MULT,
- OP_DIV,
- OP_MOD,
- OP_SHL,
- OP_SHR,
- OP_NOT,
- OP_AND,
- OP_OR,
- OP_XOR,
- OP_INV,
- OP_GT,
- OP_LT,
- OP_RET,
- OP_CMPS,
- OP_PINT,
- OP_PRNT,
- OP_DSS,
- OP_DSSC,
- OP_ISS,
- OP_ISSC,
- OP_DPR = 0x1c,
- OP_DPRL,
- OP_DPO,
- OP_DPOL,
- OP_IPR,
- OP_IPRL,
- OP_IPO,
- OP_IPOL,
- OP_PCHR,
- OP_EXIT,
- OP_EQU,
- OP_POPT,
- OP_ABS = 0x2c,
- OP_BCH0,
- OP_PSH0 = 0x2f,
- OP_PSHL = 0x40,
- OP_PSHV,
- OP_JMP,
- OP_CALL,
- OP_NEXT,
- OP_PSTR,
- OP_SINT = 0x47,
- OP_ST,
- OP_ISTP,
- OP_DSTP,
- OP_SWPN,
- OP_DUPN,
- OP_POPV,
- OP_POPE,
- OP_POPA,
- OP_JMPZ,
- OP_DS,
- OP_IS,
- OP_DPRA,
- OP_DPOA,
- OP_IPRA,
- OP_IPOA,
- OP_EXPT,
- OP_PSHE,
- OP_PSHA,
- OP_DYNA,
- OP_EXPV = 0x5c,
- OP_COPY = 0x80,
- OP_REVA,
- OP_DSC,
- OP_ISC,
- OP_WAIT,
- OP_VS,
- OP_CMPA = 0xc0,
- OP_VSC,
-};
-
-struct altera_procinfo {
- char *name;
- u8 attrs;
- struct altera_procinfo *next;
-};
-
-/* This function checks if enough parameters are available on the stack. */
-static int altera_check_stack(int stack_ptr, int count, int *status)
-{
- if (stack_ptr < count) {
- *status = -EOVERFLOW;
- return 0;
- }
-
- return 1;
-}
-
-static void altera_export_int(char *key, s32 value)
-{
- dprintk("Export: key = \"%s\", value = %d\n", key, value);
-}
-
-#define HEX_LINE_CHARS 72
-#define HEX_LINE_BITS (HEX_LINE_CHARS * 4)
-
-static void altera_export_bool_array(char *key, u8 *data, s32 count)
-{
- char string[HEX_LINE_CHARS + 1];
- s32 i, offset;
- u32 size, line, lines, linebits, value, j, k;
-
- if (count > HEX_LINE_BITS) {
- dprintk("Export: key = \"%s\", %d bits, value = HEX\n",
- key, count);
- lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS;
-
- for (line = 0; line < lines; ++line) {
- if (line < (lines - 1)) {
- linebits = HEX_LINE_BITS;
- size = HEX_LINE_CHARS;
- offset = count - ((line + 1) * HEX_LINE_BITS);
- } else {
- linebits =
- count - ((lines - 1) * HEX_LINE_BITS);
- size = (linebits + 3) / 4;
- offset = 0L;
- }
-
- string[size] = '\0';
- j = size - 1;
- value = 0;
-
- for (k = 0; k < linebits; ++k) {
- i = k + offset;
- if (data[i >> 3] & (1 << (i & 7)))
- value |= (1 << (i & 3));
- if ((i & 3) == 3) {
- sprintf(&string[j], "%1x", value);
- value = 0;
- --j;
- }
- }
- if ((k & 3) > 0)
- sprintf(&string[j], "%1x", value);
-
- dprintk("%s\n", string);
- }
-
- } else {
- size = (count + 3) / 4;
- string[size] = '\0';
- j = size - 1;
- value = 0;
-
- for (i = 0; i < count; ++i) {
- if (data[i >> 3] & (1 << (i & 7)))
- value |= (1 << (i & 3));
- if ((i & 3) == 3) {
- sprintf(&string[j], "%1x", value);
- value = 0;
- --j;
- }
- }
- if ((i & 3) > 0)
- sprintf(&string[j], "%1x", value);
-
- dprintk("Export: key = \"%s\", %d bits, value = HEX %s\n",
- key, count, string);
- }
-}
-
-static int altera_execute(struct altera_state *astate,
- u8 *p,
- s32 program_size,
- s32 *error_address,
- int *exit_code,
- int *format_version)
-{
- struct altera_config *aconf = astate->config;
- char *msg_buff = astate->msg_buff;
- long *stack = astate->stack;
- int status = 0;
- u32 first_word = 0L;
- u32 action_table = 0L;
- u32 proc_table = 0L;
- u32 str_table = 0L;
- u32 sym_table = 0L;
- u32 data_sect = 0L;
- u32 code_sect = 0L;
- u32 debug_sect = 0L;
- u32 action_count = 0L;
- u32 proc_count = 0L;
- u32 sym_count = 0L;
- long *vars = NULL;
- s32 *var_size = NULL;
- char *attrs = NULL;
- u8 *proc_attributes = NULL;
- u32 pc;
- u32 opcode_address;
- u32 args[3];
- u32 opcode;
- u32 name_id;
- u8 charbuf[4];
- long long_tmp;
- u32 variable_id;
- u8 *charptr_tmp;
- u8 *charptr_tmp2;
- long *longptr_tmp;
- int version = 0;
- int delta = 0;
- int stack_ptr = 0;
- u32 arg_count;
- int done = 0;
- int bad_opcode = 0;
- u32 count;
- u32 index;
- u32 index2;
- s32 long_count;
- s32 long_idx;
- s32 long_idx2;
- u32 i;
- u32 j;
- u32 uncomp_size;
- u32 offset;
- u32 value;
- int current_proc = 0;
- int reverse;
-
- char *name;
-
- dprintk("%s\n", __func__);
-
- /* Read header information */
- if (program_size > 52L) {
- first_word = get_unaligned_be32(&p[0]);
- version = (first_word & 1L);
- *format_version = version + 1;
- delta = version * 8;
-
- action_table = get_unaligned_be32(&p[4]);
- proc_table = get_unaligned_be32(&p[8]);
- str_table = get_unaligned_be32(&p[4 + delta]);
- sym_table = get_unaligned_be32(&p[16 + delta]);
- data_sect = get_unaligned_be32(&p[20 + delta]);
- code_sect = get_unaligned_be32(&p[24 + delta]);
- debug_sect = get_unaligned_be32(&p[28 + delta]);
- action_count = get_unaligned_be32(&p[40 + delta]);
- proc_count = get_unaligned_be32(&p[44 + delta]);
- sym_count = get_unaligned_be32(&p[48 + (2 * delta)]);
- }
-
- if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) {
- done = 1;
- status = -EIO;
- goto exit_done;
- }
-
- if (sym_count <= 0)
- goto exit_done;
-
- vars = kzalloc(sym_count * sizeof(long), GFP_KERNEL);
-
- if (vars == NULL)
- status = -ENOMEM;
-
- if (status == 0) {
- var_size = kzalloc(sym_count * sizeof(s32), GFP_KERNEL);
-
- if (var_size == NULL)
- status = -ENOMEM;
- }
-
- if (status == 0) {
- attrs = kzalloc(sym_count, GFP_KERNEL);
-
- if (attrs == NULL)
- status = -ENOMEM;
- }
-
- if ((status == 0) && (version > 0)) {
- proc_attributes = kzalloc(proc_count, GFP_KERNEL);
-
- if (proc_attributes == NULL)
- status = -ENOMEM;
- }
-
- if (status != 0)
- goto exit_done;
-
- delta = version * 2;
-
- for (i = 0; i < sym_count; ++i) {
- offset = (sym_table + ((11 + delta) * i));
-
- value = get_unaligned_be32(&p[offset + 3 + delta]);
-
- attrs[i] = p[offset];
-
- /*
- * use bit 7 of attribute byte to indicate that
- * this buffer was dynamically allocated
- * and should be freed later
- */
- attrs[i] &= 0x7f;
-
- var_size[i] = get_unaligned_be32(&p[offset + 7 + delta]);
-
- /*
- * Attribute bits:
- * bit 0: 0 = read-only, 1 = read-write
- * bit 1: 0 = not compressed, 1 = compressed
- * bit 2: 0 = not initialized, 1 = initialized
- * bit 3: 0 = scalar, 1 = array
- * bit 4: 0 = Boolean, 1 = integer
- * bit 5: 0 = declared variable,
- * 1 = compiler created temporary variable
- */
-
- if ((attrs[i] & 0x0c) == 0x04)
- /* initialized scalar variable */
- vars[i] = value;
- else if ((attrs[i] & 0x1e) == 0x0e) {
- /* initialized compressed Boolean array */
- uncomp_size = get_unaligned_le32(&p[data_sect + value]);
-
- /* allocate a buffer for the uncompressed data */
- vars[i] = (long)kzalloc(uncomp_size, GFP_KERNEL);
- if (vars[i] == 0L)
- status = -ENOMEM;
- else {
- /* set flag so buffer will be freed later */
- attrs[i] |= 0x80;
-
- /* uncompress the data */
- if (altera_shrink(&p[data_sect + value],
- var_size[i],
- (u8 *)vars[i],
- uncomp_size,
- version) != uncomp_size)
- /* decompression failed */
- status = -EIO;
- else
- var_size[i] = uncomp_size * 8L;
-
- }
- } else if ((attrs[i] & 0x1e) == 0x0c) {
- /* initialized Boolean array */
- vars[i] = value + data_sect + (long)p;
- } else if ((attrs[i] & 0x1c) == 0x1c) {
- /* initialized integer array */
- vars[i] = value + data_sect;
- } else if ((attrs[i] & 0x0c) == 0x08) {
- /* uninitialized array */
-
- /* flag attrs so that memory is freed */
- attrs[i] |= 0x80;
-
- if (var_size[i] > 0) {
- u32 size;
-
- if (attrs[i] & 0x10)
- /* integer array */
- size = (var_size[i] * sizeof(s32));
- else
- /* Boolean array */
- size = ((var_size[i] + 7L) / 8L);
-
- vars[i] = (long)kzalloc(size, GFP_KERNEL);
-
- if (vars[i] == 0) {
- status = -ENOMEM;
- } else {
- /* zero out memory */
- for (j = 0; j < size; ++j)
- ((u8 *)(vars[i]))[j] = 0;
-
- }
- } else
- vars[i] = 0;
-
- } else
- vars[i] = 0;
-
- }
-
-exit_done:
- if (status != 0)
- done = 1;
-
- altera_jinit(astate);
-
- pc = code_sect;
- msg_buff[0] = '\0';
-
- /*
- * For JBC version 2, we will execute the procedures corresponding to
- * the selected ACTION
- */
- if (version > 0) {
- if (aconf->action == NULL) {
- status = -EINVAL;
- done = 1;
- } else {
- int action_found = 0;
- for (i = 0; (i < action_count) && !action_found; ++i) {
- name_id = get_unaligned_be32(&p[action_table +
- (12 * i)]);
-
- name = &p[str_table + name_id];
-
- if (strnicmp(aconf->action, name, strlen(name)) == 0) {
- action_found = 1;
- current_proc =
- get_unaligned_be32(&p[action_table +
- (12 * i) + 8]);
- }
- }
-
- if (!action_found) {
- status = -EINVAL;
- done = 1;
- }
- }
-
- if (status == 0) {
- int first_time = 1;
- i = current_proc;
- while ((i != 0) || first_time) {
- first_time = 0;
- /* check procedure attribute byte */
- proc_attributes[i] =
- (p[proc_table +
- (13 * i) + 8] &
- 0x03);
-
- /*
- * BIT0 - OPTIONAL
- * BIT1 - RECOMMENDED
- * BIT6 - FORCED OFF
- * BIT7 - FORCED ON
- */
-
- i = get_unaligned_be32(&p[proc_table +
- (13 * i) + 4]);
- }
-
- /*
- * Set current_proc to the first procedure
- * to be executed
- */
- i = current_proc;
- while ((i != 0) &&
- ((proc_attributes[i] == 1) ||
- ((proc_attributes[i] & 0xc0) == 0x40))) {
- i = get_unaligned_be32(&p[proc_table +
- (13 * i) + 4]);
- }
-
- if ((i != 0) || ((i == 0) && (current_proc == 0) &&
- ((proc_attributes[0] != 1) &&
- ((proc_attributes[0] & 0xc0) != 0x40)))) {
- current_proc = i;
- pc = code_sect +
- get_unaligned_be32(&p[proc_table +
- (13 * i) + 9]);
- if ((pc < code_sect) || (pc >= debug_sect))
- status = -ERANGE;
- } else
- /* there are no procedures to execute! */
- done = 1;
-
- }
- }
-
- msg_buff[0] = '\0';
-
- while (!done) {
- opcode = (p[pc] & 0xff);
- opcode_address = pc;
- ++pc;
-
- if (debug > 1)
- printk("opcode: %02x\n", opcode);
-
- arg_count = (opcode >> 6) & 3;
- for (i = 0; i < arg_count; ++i) {
- args[i] = get_unaligned_be32(&p[pc]);
- pc += 4;
- }
-
- switch (opcode) {
- case OP_NOP:
- break;
- case OP_DUP:
- if (altera_check_stack(stack_ptr, 1, &status)) {
- stack[stack_ptr] = stack[stack_ptr - 1];
- ++stack_ptr;
- }
- break;
- case OP_SWP:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- long_tmp = stack[stack_ptr - 2];
- stack[stack_ptr - 2] = stack[stack_ptr - 1];
- stack[stack_ptr - 1] = long_tmp;
- }
- break;
- case OP_ADD:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] += stack[stack_ptr];
- }
- break;
- case OP_SUB:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] -= stack[stack_ptr];
- }
- break;
- case OP_MULT:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] *= stack[stack_ptr];
- }
- break;
- case OP_DIV:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] /= stack[stack_ptr];
- }
- break;
- case OP_MOD:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] %= stack[stack_ptr];
- }
- break;
- case OP_SHL:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] <<= stack[stack_ptr];
- }
- break;
- case OP_SHR:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] >>= stack[stack_ptr];
- }
- break;
- case OP_NOT:
- if (altera_check_stack(stack_ptr, 1, &status))
- stack[stack_ptr - 1] ^= (-1L);
-
- break;
- case OP_AND:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] &= stack[stack_ptr];
- }
- break;
- case OP_OR:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] |= stack[stack_ptr];
- }
- break;
- case OP_XOR:
- if (altera_check_stack(stack_ptr, 2, &status)) {
- --stack_ptr;
- stack[stack_ptr - 1] ^= stack[stack_ptr];
- }
- break;
- case OP_INV:
- if (!altera_check_stack(stack_ptr, 1, &status))
- break;
- stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L;
- break;
- case OP_GT:
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- --stack_ptr;
- stack[stack_ptr - 1] =
- (stack[stack_ptr - 1] > stack[stack_ptr]) ?
- 1L : 0L;
-
- break;
- case OP_LT:
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- --stack_ptr;
- stack[stack_ptr - 1] =
- (stack[stack_ptr - 1] < stack[stack_ptr]) ?
- 1L : 0L;
-
- break;
- case OP_RET:
- if ((version > 0) && (stack_ptr == 0)) {
- /*
- * We completed one of the main procedures
- * of an ACTION.
- * Find the next procedure
- * to be executed and jump to it.
- * If there are no more procedures, then EXIT.
- */
- i = get_unaligned_be32(&p[proc_table +
- (13 * current_proc) + 4]);
- while ((i != 0) &&
- ((proc_attributes[i] == 1) ||
- ((proc_attributes[i] & 0xc0) == 0x40)))
- i = get_unaligned_be32(&p[proc_table +
- (13 * i) + 4]);
-
- if (i == 0) {
- /* no procedures to execute! */
- done = 1;
- *exit_code = 0; /* success */
- } else {
- current_proc = i;
- pc = code_sect + get_unaligned_be32(
- &p[proc_table +
- (13 * i) + 9]);
- if ((pc < code_sect) ||
- (pc >= debug_sect))
- status = -ERANGE;
- }
-
- } else
- if (altera_check_stack(stack_ptr, 1, &status)) {
- pc = stack[--stack_ptr] + code_sect;
- if ((pc <= code_sect) ||
- (pc >= debug_sect))
- status = -ERANGE;
-
- }
-
- break;
- case OP_CMPS:
- /*
- * Array short compare
- * ...stack 0 is source 1 value
- * ...stack 1 is source 2 value
- * ...stack 2 is mask value
- * ...stack 3 is count
- */
- if (altera_check_stack(stack_ptr, 4, &status)) {
- s32 a = stack[--stack_ptr];
- s32 b = stack[--stack_ptr];
- long_tmp = stack[--stack_ptr];
- count = stack[stack_ptr - 1];
-
- if ((count < 1) || (count > 32))
- status = -ERANGE;
- else {
- long_tmp &= ((-1L) >> (32 - count));
-
- stack[stack_ptr - 1] =
- ((a & long_tmp) == (b & long_tmp))
- ? 1L : 0L;
- }
- }
- break;
- case OP_PINT:
- /*
- * PRINT add integer
- * ...stack 0 is integer value
- */
- if (!altera_check_stack(stack_ptr, 1, &status))
- break;
- sprintf(&msg_buff[strlen(msg_buff)],
- "%ld", stack[--stack_ptr]);
- break;
- case OP_PRNT:
- /* PRINT finish */
- if (debug)
- printk(msg_buff, "\n");
-
- msg_buff[0] = '\0';
- break;
- case OP_DSS:
- /*
- * DRSCAN short
- * ...stack 0 is scan data
- * ...stack 1 is count
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- long_tmp = stack[--stack_ptr];
- count = stack[--stack_ptr];
- put_unaligned_le32(long_tmp, &charbuf[0]);
- status = altera_drscan(astate, count, charbuf, 0);
- break;
- case OP_DSSC:
- /*
- * DRSCAN short with capture
- * ...stack 0 is scan data
- * ...stack 1 is count
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- long_tmp = stack[--stack_ptr];
- count = stack[stack_ptr - 1];
- put_unaligned_le32(long_tmp, &charbuf[0]);
- status = altera_swap_dr(astate, count, charbuf,
- 0, charbuf, 0);
- stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);
- break;
- case OP_ISS:
- /*
- * IRSCAN short
- * ...stack 0 is scan data
- * ...stack 1 is count
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- long_tmp = stack[--stack_ptr];
- count = stack[--stack_ptr];
- put_unaligned_le32(long_tmp, &charbuf[0]);
- status = altera_irscan(astate, count, charbuf, 0);
- break;
- case OP_ISSC:
- /*
- * IRSCAN short with capture
- * ...stack 0 is scan data
- * ...stack 1 is count
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- long_tmp = stack[--stack_ptr];
- count = stack[stack_ptr - 1];
- put_unaligned_le32(long_tmp, &charbuf[0]);
- status = altera_swap_ir(astate, count, charbuf,
- 0, charbuf, 0);
- stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);
- break;
- case OP_DPR:
- if (!altera_check_stack(stack_ptr, 1, &status))
- break;
- count = stack[--stack_ptr];
- status = altera_set_dr_pre(&astate->js, count, 0, NULL);
- break;
- case OP_DPRL:
- /*
- * DRPRE with literal data
- * ...stack 0 is count
- * ...stack 1 is literal data
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- count = stack[--stack_ptr];
- long_tmp = stack[--stack_ptr];
- put_unaligned_le32(long_tmp, &charbuf[0]);
- status = altera_set_dr_pre(&astate->js, count, 0,
- charbuf);
- break;
- case OP_DPO:
- /*
- * DRPOST
- * ...stack 0 is count
- */
- if (altera_check_stack(stack_ptr, 1, &status)) {
- count = stack[--stack_ptr];
- status = altera_set_dr_post(&astate->js, count,
- 0, NULL);
- }
- break;
- case OP_DPOL:
- /*
- * DRPOST with literal data
- * ...stack 0 is count
- * ...stack 1 is literal data
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- count = stack[--stack_ptr];
- long_tmp = stack[--stack_ptr];
- put_unaligned_le32(long_tmp, &charbuf[0]);
- status = altera_set_dr_post(&astate->js, count, 0,
- charbuf);
- break;
- case OP_IPR:
- if (altera_check_stack(stack_ptr, 1, &status)) {
- count = stack[--stack_ptr];
- status = altera_set_ir_pre(&astate->js, count,
- 0, NULL);
- }
- break;
- case OP_IPRL:
- /*
- * IRPRE with literal data
- * ...stack 0 is count
- * ...stack 1 is literal data
- */
- if (altera_check_stack(stack_ptr, 2, &status)) {
- count = stack[--stack_ptr];
- long_tmp = stack[--stack_ptr];
- put_unaligned_le32(long_tmp, &charbuf[0]);
- status = altera_set_ir_pre(&astate->js, count,
- 0, charbuf);
- }
- break;
- case OP_IPO:
- /*
- * IRPOST
- * ...stack 0 is count
- */
- if (altera_check_stack(stack_ptr, 1, &status)) {
- count = stack[--stack_ptr];
- status = altera_set_ir_post(&astate->js, count,
- 0, NULL);
- }
- break;
- case OP_IPOL:
- /*
- * IRPOST with literal data
- * ...stack 0 is count
- * ...stack 1 is literal data
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- count = stack[--stack_ptr];
- long_tmp = stack[--stack_ptr];
- put_unaligned_le32(long_tmp, &charbuf[0]);
- status = altera_set_ir_post(&astate->js, count, 0,
- charbuf);
- break;
- case OP_PCHR:
- if (altera_check_stack(stack_ptr, 1, &status)) {
- u8 ch;
- count = strlen(msg_buff);
- ch = (char) stack[--stack_ptr];
- if ((ch < 1) || (ch > 127)) {
- /*
- * character code out of range
- * instead of flagging an error,
- * force the value to 127
- */
- ch = 127;
- }
- msg_buff[count] = ch;
- msg_buff[count + 1] = '\0';
- }
- break;
- case OP_EXIT:
- if (altera_check_stack(stack_ptr, 1, &status))
- *exit_code = stack[--stack_ptr];
-
- done = 1;
- break;
- case OP_EQU:
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- --stack_ptr;
- stack[stack_ptr - 1] =
- (stack[stack_ptr - 1] == stack[stack_ptr]) ?
- 1L : 0L;
- break;
- case OP_POPT:
- if (altera_check_stack(stack_ptr, 1, &status))
- --stack_ptr;
-
- break;
- case OP_ABS:
- if (!altera_check_stack(stack_ptr, 1, &status))
- break;
- if (stack[stack_ptr - 1] < 0)
- stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1];
-
- break;
- case OP_BCH0:
- /*
- * Batch operation 0
- * SWP
- * SWPN 7
- * SWP
- * SWPN 6
- * DUPN 8
- * SWPN 2
- * SWP
- * DUPN 6
- * DUPN 6
- */
-
- /* SWP */
- if (altera_check_stack(stack_ptr, 2, &status)) {
- long_tmp = stack[stack_ptr - 2];
- stack[stack_ptr - 2] = stack[stack_ptr - 1];
- stack[stack_ptr - 1] = long_tmp;
- }
-
- /* SWPN 7 */
- index = 7 + 1;
- if (altera_check_stack(stack_ptr, index, &status)) {
- long_tmp = stack[stack_ptr - index];
- stack[stack_ptr - index] = stack[stack_ptr - 1];
- stack[stack_ptr - 1] = long_tmp;
- }
-
- /* SWP */
- if (altera_check_stack(stack_ptr, 2, &status)) {
- long_tmp = stack[stack_ptr - 2];
- stack[stack_ptr - 2] = stack[stack_ptr - 1];
- stack[stack_ptr - 1] = long_tmp;
- }
-
- /* SWPN 6 */
- index = 6 + 1;
- if (altera_check_stack(stack_ptr, index, &status)) {
- long_tmp = stack[stack_ptr - index];
- stack[stack_ptr - index] = stack[stack_ptr - 1];
- stack[stack_ptr - 1] = long_tmp;
- }
-
- /* DUPN 8 */
- index = 8 + 1;
- if (altera_check_stack(stack_ptr, index, &status)) {
- stack[stack_ptr] = stack[stack_ptr - index];
- ++stack_ptr;
- }
-
- /* SWPN 2 */
- index = 2 + 1;
- if (altera_check_stack(stack_ptr, index, &status)) {
- long_tmp = stack[stack_ptr - index];
- stack[stack_ptr - index] = stack[stack_ptr - 1];
- stack[stack_ptr - 1] = long_tmp;
- }
-
- /* SWP */
- if (altera_check_stack(stack_ptr, 2, &status)) {
- long_tmp = stack[stack_ptr - 2];
- stack[stack_ptr - 2] = stack[stack_ptr - 1];
- stack[stack_ptr - 1] = long_tmp;
- }
-
- /* DUPN 6 */
- index = 6 + 1;
- if (altera_check_stack(stack_ptr, index, &status)) {
- stack[stack_ptr] = stack[stack_ptr - index];
- ++stack_ptr;
- }
-
- /* DUPN 6 */
- index = 6 + 1;
- if (altera_check_stack(stack_ptr, index, &status)) {
- stack[stack_ptr] = stack[stack_ptr - index];
- ++stack_ptr;
- }
- break;
- case OP_PSH0:
- stack[stack_ptr++] = 0;
- break;
- case OP_PSHL:
- stack[stack_ptr++] = (s32) args[0];
- break;
- case OP_PSHV:
- stack[stack_ptr++] = vars[args[0]];
- break;
- case OP_JMP:
- pc = args[0] + code_sect;
- if ((pc < code_sect) || (pc >= debug_sect))
- status = -ERANGE;
- break;
- case OP_CALL:
- stack[stack_ptr++] = pc;
- pc = args[0] + code_sect;
- if ((pc < code_sect) || (pc >= debug_sect))
- status = -ERANGE;
- break;
- case OP_NEXT:
- /*
- * Process FOR / NEXT loop
- * ...argument 0 is variable ID
- * ...stack 0 is step value
- * ...stack 1 is end value
- * ...stack 2 is top address
- */
- if (altera_check_stack(stack_ptr, 3, &status)) {
- s32 step = stack[stack_ptr - 1];
- s32 end = stack[stack_ptr - 2];
- s32 top = stack[stack_ptr - 3];
- s32 iterator = vars[args[0]];
- int break_out = 0;
-
- if (step < 0) {
- if (iterator <= end)
- break_out = 1;
- } else if (iterator >= end)
- break_out = 1;
-
- if (break_out) {
- stack_ptr -= 3;
- } else {
- vars[args[0]] = iterator + step;
- pc = top + code_sect;
- if ((pc < code_sect) ||
- (pc >= debug_sect))
- status = -ERANGE;
- }
- }
- break;
- case OP_PSTR:
- /*
- * PRINT add string
- * ...argument 0 is string ID
- */
- count = strlen(msg_buff);
- strlcpy(&msg_buff[count],
- &p[str_table + args[0]],
- ALTERA_MESSAGE_LENGTH - count);
- break;
- case OP_SINT:
- /*
- * STATE intermediate state
- * ...argument 0 is state code
- */
- status = altera_goto_jstate(astate, args[0]);
- break;
- case OP_ST:
- /*
- * STATE final state
- * ...argument 0 is state code
- */
- status = altera_goto_jstate(astate, args[0]);
- break;
- case OP_ISTP:
- /*
- * IRSTOP state
- * ...argument 0 is state code
- */
- status = altera_set_irstop(&astate->js, args[0]);
- break;
- case OP_DSTP:
- /*
- * DRSTOP state
- * ...argument 0 is state code
- */
- status = altera_set_drstop(&astate->js, args[0]);
- break;
-
- case OP_SWPN:
- /*
- * Exchange top with Nth stack value
- * ...argument 0 is 0-based stack entry
- * to swap with top element
- */
- index = (args[0]) + 1;
- if (altera_check_stack(stack_ptr, index, &status)) {
- long_tmp = stack[stack_ptr - index];
- stack[stack_ptr - index] = stack[stack_ptr - 1];
- stack[stack_ptr - 1] = long_tmp;
- }
- break;
- case OP_DUPN:
- /*
- * Duplicate Nth stack value
- * ...argument 0 is 0-based stack entry to duplicate
- */
- index = (args[0]) + 1;
- if (altera_check_stack(stack_ptr, index, &status)) {
- stack[stack_ptr] = stack[stack_ptr - index];
- ++stack_ptr;
- }
- break;
- case OP_POPV:
- /*
- * Pop stack into scalar variable
- * ...argument 0 is variable ID
- * ...stack 0 is value
- */
- if (altera_check_stack(stack_ptr, 1, &status))
- vars[args[0]] = stack[--stack_ptr];
-
- break;
- case OP_POPE:
- /*
- * Pop stack into integer array element
- * ...argument 0 is variable ID
- * ...stack 0 is array index
- * ...stack 1 is value
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- variable_id = args[0];
-
- /*
- * If variable is read-only,
- * convert to writable array
- */
- if ((version > 0) &&
- ((attrs[variable_id] & 0x9c) == 0x1c)) {
- /* Allocate a writable buffer for this array */
- count = var_size[variable_id];
- long_tmp = vars[variable_id];
- longptr_tmp = kzalloc(count * sizeof(long),
- GFP_KERNEL);
- vars[variable_id] = (long)longptr_tmp;
-
- if (vars[variable_id] == 0) {
- status = -ENOMEM;
- break;
- }
-
- /* copy previous contents into buffer */
- for (i = 0; i < count; ++i) {
- longptr_tmp[i] =
- get_unaligned_be32(&p[long_tmp]);
- long_tmp += sizeof(long);
- }
-
- /*
- * set bit 7 - buffer was
- * dynamically allocated
- */
- attrs[variable_id] |= 0x80;
-
- /* clear bit 2 - variable is writable */
- attrs[variable_id] &= ~0x04;
- attrs[variable_id] |= 0x01;
-
- }
-
- /* check that variable is a writable integer array */
- if ((attrs[variable_id] & 0x1c) != 0x18)
- status = -ERANGE;
- else {
- longptr_tmp = (long *)vars[variable_id];
-
- /* pop the array index */
- index = stack[--stack_ptr];
-
- /* pop the value and store it into the array */
- longptr_tmp[index] = stack[--stack_ptr];
- }
-
- break;
- case OP_POPA:
- /*
- * Pop stack into Boolean array
- * ...argument 0 is variable ID
- * ...stack 0 is count
- * ...stack 1 is array index
- * ...stack 2 is value
- */
- if (!altera_check_stack(stack_ptr, 3, &status))
- break;
- variable_id = args[0];
-
- /*
- * If variable is read-only,
- * convert to writable array
- */
- if ((version > 0) &&
- ((attrs[variable_id] & 0x9c) == 0x0c)) {
- /* Allocate a writable buffer for this array */
- long_tmp =
- (var_size[variable_id] + 7L) >> 3L;
- charptr_tmp2 = (u8 *)vars[variable_id];
- charptr_tmp =
- kzalloc(long_tmp, GFP_KERNEL);
- vars[variable_id] = (long)charptr_tmp;
-
- if (vars[variable_id] == 0) {
- status = -ENOMEM;
- break;
- }
-
- /* zero the buffer */
- for (long_idx = 0L;
- long_idx < long_tmp;
- ++long_idx) {
- charptr_tmp[long_idx] = 0;
- }
-
- /* copy previous contents into buffer */
- for (long_idx = 0L;
- long_idx < var_size[variable_id];
- ++long_idx) {
- long_idx2 = long_idx;
-
- if (charptr_tmp2[long_idx2 >> 3] &
- (1 << (long_idx2 & 7))) {
- charptr_tmp[long_idx >> 3] |=
- (1 << (long_idx & 7));
- }
- }
-
- /*
- * set bit 7 - buffer was
- * dynamically allocated
- */
- attrs[variable_id] |= 0x80;
-
- /* clear bit 2 - variable is writable */
- attrs[variable_id] &= ~0x04;
- attrs[variable_id] |= 0x01;
-
- }
-
- /*
- * check that variable is
- * a writable Boolean array
- */
- if ((attrs[variable_id] & 0x1c) != 0x08) {
- status = -ERANGE;
- break;
- }
-
- charptr_tmp = (u8 *)vars[variable_id];
-
- /* pop the count (number of bits to copy) */
- long_count = stack[--stack_ptr];
-
- /* pop the array index */
- long_idx = stack[--stack_ptr];
-
- reverse = 0;
-
- if (version > 0) {
- /*
- * stack 0 = array right index
- * stack 1 = array left index
- */
-
- if (long_idx > long_count) {
- reverse = 1;
- long_tmp = long_count;
- long_count = 1 + long_idx -
- long_count;
- long_idx = long_tmp;
-
- /* reverse POPA is not supported */
- status = -ERANGE;
- break;
- } else
- long_count = 1 + long_count -
- long_idx;
-
- }
-
- /* pop the data */
- long_tmp = stack[--stack_ptr];
-
- if (long_count < 1) {
- status = -ERANGE;
- break;
- }
-
- for (i = 0; i < long_count; ++i) {
- if (long_tmp & (1L << (s32) i))
- charptr_tmp[long_idx >> 3L] |=
- (1L << (long_idx & 7L));
- else
- charptr_tmp[long_idx >> 3L] &=
- ~(1L << (long_idx & 7L));
-
- ++long_idx;
- }
-
- break;
- case OP_JMPZ:
- /*
- * Pop stack and branch if zero
- * ...argument 0 is address
- * ...stack 0 is condition value
- */
- if (altera_check_stack(stack_ptr, 1, &status)) {
- if (stack[--stack_ptr] == 0) {
- pc = args[0] + code_sect;
- if ((pc < code_sect) ||
- (pc >= debug_sect))
- status = -ERANGE;
- }
- }
- break;
- case OP_DS:
- case OP_IS:
- /*
- * DRSCAN
- * IRSCAN
- * ...argument 0 is scan data variable ID
- * ...stack 0 is array index
- * ...stack 1 is count
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- long_idx = stack[--stack_ptr];
- long_count = stack[--stack_ptr];
- reverse = 0;
- if (version > 0) {
- /*
- * stack 0 = array right index
- * stack 1 = array left index
- * stack 2 = count
- */
- long_tmp = long_count;
- long_count = stack[--stack_ptr];
-
- if (long_idx > long_tmp) {
- reverse = 1;
- long_idx = long_tmp;
- }
- }
-
- charptr_tmp = (u8 *)vars[args[0]];
-
- if (reverse) {
- /*
- * allocate a buffer
- * and reverse the data order
- */
- charptr_tmp2 = charptr_tmp;
- charptr_tmp = kzalloc((long_count >> 3) + 1,
- GFP_KERNEL);
- if (charptr_tmp == NULL) {
- status = -ENOMEM;
- break;
- }
-
- long_tmp = long_idx + long_count - 1;
- long_idx2 = 0;
- while (long_idx2 < long_count) {
- if (charptr_tmp2[long_tmp >> 3] &
- (1 << (long_tmp & 7)))
- charptr_tmp[long_idx2 >> 3] |=
- (1 << (long_idx2 & 7));
- else
- charptr_tmp[long_idx2 >> 3] &=
- ~(1 << (long_idx2 & 7));
-
- --long_tmp;
- ++long_idx2;
- }
- }
-
- if (opcode == 0x51) /* DS */
- status = altera_drscan(astate, long_count,
- charptr_tmp, long_idx);
- else /* IS */
- status = altera_irscan(astate, long_count,
- charptr_tmp, long_idx);
-
- if (reverse)
- kfree(charptr_tmp);
-
- break;
- case OP_DPRA:
- /*
- * DRPRE with array data
- * ...argument 0 is variable ID
- * ...stack 0 is array index
- * ...stack 1 is count
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- index = stack[--stack_ptr];
- count = stack[--stack_ptr];
-
- if (version > 0)
- /*
- * stack 0 = array right index
- * stack 1 = array left index
- */
- count = 1 + count - index;
-
- charptr_tmp = (u8 *)vars[args[0]];
- status = altera_set_dr_pre(&astate->js, count, index,
- charptr_tmp);
- break;
- case OP_DPOA:
- /*
- * DRPOST with array data
- * ...argument 0 is variable ID
- * ...stack 0 is array index
- * ...stack 1 is count
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- index = stack[--stack_ptr];
- count = stack[--stack_ptr];
-
- if (version > 0)
- /*
- * stack 0 = array right index
- * stack 1 = array left index
- */
- count = 1 + count - index;
-
- charptr_tmp = (u8 *)vars[args[0]];
- status = altera_set_dr_post(&astate->js, count, index,
- charptr_tmp);
- break;
- case OP_IPRA:
- /*
- * IRPRE with array data
- * ...argument 0 is variable ID
- * ...stack 0 is array index
- * ...stack 1 is count
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- index = stack[--stack_ptr];
- count = stack[--stack_ptr];
-
- if (version > 0)
- /*
- * stack 0 = array right index
- * stack 1 = array left index
- */
- count = 1 + count - index;
-
- charptr_tmp = (u8 *)vars[args[0]];
- status = altera_set_ir_pre(&astate->js, count, index,
- charptr_tmp);
-
- break;
- case OP_IPOA:
- /*
- * IRPOST with array data
- * ...argument 0 is variable ID
- * ...stack 0 is array index
- * ...stack 1 is count
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- index = stack[--stack_ptr];
- count = stack[--stack_ptr];
-
- if (version > 0)
- /*
- * stack 0 = array right index
- * stack 1 = array left index
- */
- count = 1 + count - index;
-
- charptr_tmp = (u8 *)vars[args[0]];
- status = altera_set_ir_post(&astate->js, count, index,
- charptr_tmp);
-
- break;
- case OP_EXPT:
- /*
- * EXPORT
- * ...argument 0 is string ID
- * ...stack 0 is integer expression
- */
- if (altera_check_stack(stack_ptr, 1, &status)) {
- name = &p[str_table + args[0]];
- long_tmp = stack[--stack_ptr];
- altera_export_int(name, long_tmp);
- }
- break;
- case OP_PSHE:
- /*
- * Push integer array element
- * ...argument 0 is variable ID
- * ...stack 0 is array index
- */
- if (!altera_check_stack(stack_ptr, 1, &status))
- break;
- variable_id = args[0];
- index = stack[stack_ptr - 1];
-
- /* check variable type */
- if ((attrs[variable_id] & 0x1f) == 0x19) {
- /* writable integer array */
- longptr_tmp = (long *)vars[variable_id];
- stack[stack_ptr - 1] = longptr_tmp[index];
- } else if ((attrs[variable_id] & 0x1f) == 0x1c) {
- /* read-only integer array */
- long_tmp = vars[variable_id] +
- (index * sizeof(long));
- stack[stack_ptr - 1] =
- get_unaligned_be32(&p[long_tmp]);
- } else
- status = -ERANGE;
-
- break;
- case OP_PSHA:
- /*
- * Push Boolean array
- * ...argument 0 is variable ID
- * ...stack 0 is count
- * ...stack 1 is array index
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- variable_id = args[0];
-
- /* check that variable is a Boolean array */
- if ((attrs[variable_id] & 0x18) != 0x08) {
- status = -ERANGE;
- break;
- }
-
- charptr_tmp = (u8 *)vars[variable_id];
-
- /* pop the count (number of bits to copy) */
- count = stack[--stack_ptr];
-
- /* pop the array index */
- index = stack[stack_ptr - 1];
-
- if (version > 0)
- /*
- * stack 0 = array right index
- * stack 1 = array left index
- */
- count = 1 + count - index;
-
- if ((count < 1) || (count > 32)) {
- status = -ERANGE;
- break;
- }
-
- long_tmp = 0L;
-
- for (i = 0; i < count; ++i)
- if (charptr_tmp[(i + index) >> 3] &
- (1 << ((i + index) & 7)))
- long_tmp |= (1L << i);
-
- stack[stack_ptr - 1] = long_tmp;
-
- break;
- case OP_DYNA:
- /*
- * Dynamically change size of array
- * ...argument 0 is variable ID
- * ...stack 0 is new size
- */
- if (!altera_check_stack(stack_ptr, 1, &status))
- break;
- variable_id = args[0];
- long_tmp = stack[--stack_ptr];
-
- if (long_tmp > var_size[variable_id]) {
- var_size[variable_id] = long_tmp;
-
- if (attrs[variable_id] & 0x10)
- /* allocate integer array */
- long_tmp *= sizeof(long);
- else
- /* allocate Boolean array */
- long_tmp = (long_tmp + 7) >> 3;
-
- /*
- * If the buffer was previously allocated,
- * free it
- */
- if (attrs[variable_id] & 0x80) {
- kfree((void *)vars[variable_id]);
- vars[variable_id] = 0;
- }
-
- /*
- * Allocate a new buffer
- * of the requested size
- */
- vars[variable_id] = (long)
- kzalloc(long_tmp, GFP_KERNEL);
-
- if (vars[variable_id] == 0) {
- status = -ENOMEM;
- break;
- }
-
- /*
- * Set the attribute bit to indicate that
- * this buffer was dynamically allocated and
- * should be freed later
- */
- attrs[variable_id] |= 0x80;
-
- /* zero out memory */
- count = ((var_size[variable_id] + 7L) /
- 8L);
- charptr_tmp = (u8 *)(vars[variable_id]);
- for (index = 0; index < count; ++index)
- charptr_tmp[index] = 0;
-
- }
-
- break;
- case OP_EXPV:
- /*
- * Export Boolean array
- * ...argument 0 is string ID
- * ...stack 0 is variable ID
- * ...stack 1 is array right index
- * ...stack 2 is array left index
- */
- if (!altera_check_stack(stack_ptr, 3, &status))
- break;
- if (version == 0) {
- /* EXPV is not supported in JBC 1.0 */
- bad_opcode = 1;
- break;
- }
- name = &p[str_table + args[0]];
- variable_id = stack[--stack_ptr];
- long_idx = stack[--stack_ptr];/* right indx */
- long_idx2 = stack[--stack_ptr];/* left indx */
-
- if (long_idx > long_idx2) {
- /* reverse indices not supported */
- status = -ERANGE;
- break;
- }
-
- long_count = 1 + long_idx2 - long_idx;
-
- charptr_tmp = (u8 *)vars[variable_id];
- charptr_tmp2 = NULL;
-
- if ((long_idx & 7L) != 0) {
- s32 k = long_idx;
- charptr_tmp2 =
- kzalloc(((long_count + 7L) / 8L),
- GFP_KERNEL);
- if (charptr_tmp2 == NULL) {
- status = -ENOMEM;
- break;
- }
-
- for (i = 0; i < long_count; ++i) {
- if (charptr_tmp[k >> 3] &
- (1 << (k & 7)))
- charptr_tmp2[i >> 3] |=
- (1 << (i & 7));
- else
- charptr_tmp2[i >> 3] &=
- ~(1 << (i & 7));
-
- ++k;
- }
- charptr_tmp = charptr_tmp2;
-
- } else if (long_idx != 0)
- charptr_tmp = &charptr_tmp[long_idx >> 3];
-
- altera_export_bool_array(name, charptr_tmp,
- long_count);
-
- /* free allocated buffer */
- if ((long_idx & 7L) != 0)
- kfree(charptr_tmp2);
-
- break;
- case OP_COPY: {
- /*
- * Array copy
- * ...argument 0 is dest ID
- * ...argument 1 is source ID
- * ...stack 0 is count
- * ...stack 1 is dest index
- * ...stack 2 is source index
- */
- s32 copy_count;
- s32 copy_index;
- s32 copy_index2;
- s32 destleft;
- s32 src_count;
- s32 dest_count;
- int src_reverse = 0;
- int dest_reverse = 0;
-
- if (!altera_check_stack(stack_ptr, 3, &status))
- break;
-
- copy_count = stack[--stack_ptr];
- copy_index = stack[--stack_ptr];
- copy_index2 = stack[--stack_ptr];
- reverse = 0;
-
- if (version > 0) {
- /*
- * stack 0 = source right index
- * stack 1 = source left index
- * stack 2 = destination right index
- * stack 3 = destination left index
- */
- destleft = stack[--stack_ptr];
-
- if (copy_count > copy_index) {
- src_reverse = 1;
- reverse = 1;
- src_count = 1 + copy_count - copy_index;
- /* copy_index = source start index */
- } else {
- src_count = 1 + copy_index - copy_count;
- /* source start index */
- copy_index = copy_count;
- }
-
- if (copy_index2 > destleft) {
- dest_reverse = 1;
- reverse = !reverse;
- dest_count = 1 + copy_index2 - destleft;
- /* destination start index */
- copy_index2 = destleft;
- } else
- dest_count = 1 + destleft - copy_index2;
-
- copy_count = (src_count < dest_count) ?
- src_count : dest_count;
-
- if ((src_reverse || dest_reverse) &&
- (src_count != dest_count))
- /*
- * If either the source or destination
- * is reversed, we can't tolerate
- * a length mismatch, because we
- * "left justify" arrays when copying.
- * This won't work correctly
- * with reversed arrays.
- */
- status = -ERANGE;
-
- }
-
- count = copy_count;
- index = copy_index;
- index2 = copy_index2;
-
- /*
- * If destination is a read-only array,
- * allocate a buffer and convert it to a writable array
- */
- variable_id = args[1];
- if ((version > 0) &&
- ((attrs[variable_id] & 0x9c) == 0x0c)) {
- /* Allocate a writable buffer for this array */
- long_tmp =
- (var_size[variable_id] + 7L) >> 3L;
- charptr_tmp2 = (u8 *)vars[variable_id];
- charptr_tmp =
- kzalloc(long_tmp, GFP_KERNEL);
- vars[variable_id] = (long)charptr_tmp;
-
- if (vars[variable_id] == 0) {
- status = -ENOMEM;
- break;
- }
-
- /* zero the buffer */
- for (long_idx = 0L; long_idx < long_tmp;
- ++long_idx)
- charptr_tmp[long_idx] = 0;
-
- /* copy previous contents into buffer */
- for (long_idx = 0L;
- long_idx < var_size[variable_id];
- ++long_idx) {
- long_idx2 = long_idx;
-
- if (charptr_tmp2[long_idx2 >> 3] &
- (1 << (long_idx2 & 7)))
- charptr_tmp[long_idx >> 3] |=
- (1 << (long_idx & 7));
-
- }
-
- /*
- set bit 7 - buffer was dynamically allocated */
- attrs[variable_id] |= 0x80;
-
- /* clear bit 2 - variable is writable */
- attrs[variable_id] &= ~0x04;
- attrs[variable_id] |= 0x01;
- }
-
- charptr_tmp = (u8 *)vars[args[1]];
- charptr_tmp2 = (u8 *)vars[args[0]];
-
- /* check if destination is a writable Boolean array */
- if ((attrs[args[1]] & 0x1c) != 0x08) {
- status = -ERANGE;
- break;
- }
-
- if (count < 1) {
- status = -ERANGE;
- break;
- }
-
- if (reverse)
- index2 += (count - 1);
-
- for (i = 0; i < count; ++i) {
- if (charptr_tmp2[index >> 3] &
- (1 << (index & 7)))
- charptr_tmp[index2 >> 3] |=
- (1 << (index2 & 7));
- else
- charptr_tmp[index2 >> 3] &=
- ~(1 << (index2 & 7));
-
- ++index;
- if (reverse)
- --index2;
- else
- ++index2;
- }
-
- break;
- }
- case OP_DSC:
- case OP_ISC: {
- /*
- * DRSCAN with capture
- * IRSCAN with capture
- * ...argument 0 is scan data variable ID
- * ...argument 1 is capture variable ID
- * ...stack 0 is capture index
- * ...stack 1 is scan data index
- * ...stack 2 is count
- */
- s32 scan_right, scan_left;
- s32 capture_count = 0;
- s32 scan_count = 0;
- s32 capture_index;
- s32 scan_index;
-
- if (!altera_check_stack(stack_ptr, 3, &status))
- break;
-
- capture_index = stack[--stack_ptr];
- scan_index = stack[--stack_ptr];
-
- if (version > 0) {
- /*
- * stack 0 = capture right index
- * stack 1 = capture left index
- * stack 2 = scan right index
- * stack 3 = scan left index
- * stack 4 = count
- */
- scan_right = stack[--stack_ptr];
- scan_left = stack[--stack_ptr];
- capture_count = 1 + scan_index - capture_index;
- scan_count = 1 + scan_left - scan_right;
- scan_index = scan_right;
- }
-
- long_count = stack[--stack_ptr];
- /*
- * If capture array is read-only, allocate a buffer
- * and convert it to a writable array
- */
- variable_id = args[1];
- if ((version > 0) &&
- ((attrs[variable_id] & 0x9c) == 0x0c)) {
- /* Allocate a writable buffer for this array */
- long_tmp =
- (var_size[variable_id] + 7L) >> 3L;
- charptr_tmp2 = (u8 *)vars[variable_id];
- charptr_tmp =
- kzalloc(long_tmp, GFP_KERNEL);
- vars[variable_id] = (long)charptr_tmp;
-
- if (vars[variable_id] == 0) {
- status = -ENOMEM;
- break;
- }
-
- /* zero the buffer */
- for (long_idx = 0L; long_idx < long_tmp;
- ++long_idx)
- charptr_tmp[long_idx] = 0;
-
- /* copy previous contents into buffer */
- for (long_idx = 0L;
- long_idx < var_size[variable_id];
- ++long_idx) {
- long_idx2 = long_idx;
-
- if (charptr_tmp2[long_idx2 >> 3] &
- (1 << (long_idx2 & 7)))
- charptr_tmp[long_idx >> 3] |=
- (1 << (long_idx & 7));
-
- }
-
- /*
- * set bit 7 - buffer was
- * dynamically allocated
- */
- attrs[variable_id] |= 0x80;
-
- /* clear bit 2 - variable is writable */
- attrs[variable_id] &= ~0x04;
- attrs[variable_id] |= 0x01;
-
- }
-
- charptr_tmp = (u8 *)vars[args[0]];
- charptr_tmp2 = (u8 *)vars[args[1]];
-
- if ((version > 0) &&
- ((long_count > capture_count) ||
- (long_count > scan_count))) {
- status = -ERANGE;
- break;
- }
-
- /*
- * check that capture array
- * is a writable Boolean array
- */
- if ((attrs[args[1]] & 0x1c) != 0x08) {
- status = -ERANGE;
- break;
- }
-
- if (status == 0) {
- if (opcode == 0x82) /* DSC */
- status = altera_swap_dr(astate,
- long_count,
- charptr_tmp,
- scan_index,
- charptr_tmp2,
- capture_index);
- else /* ISC */
- status = altera_swap_ir(astate,
- long_count,
- charptr_tmp,
- scan_index,
- charptr_tmp2,
- capture_index);
-
- }
-
- break;
- }
- case OP_WAIT:
- /*
- * WAIT
- * ...argument 0 is wait state
- * ...argument 1 is end state
- * ...stack 0 is cycles
- * ...stack 1 is microseconds
- */
- if (!altera_check_stack(stack_ptr, 2, &status))
- break;
- long_tmp = stack[--stack_ptr];
-
- if (long_tmp != 0L)
- status = altera_wait_cycles(astate, long_tmp,
- args[0]);
-
- long_tmp = stack[--stack_ptr];
-
- if ((status == 0) && (long_tmp != 0L))
- status = altera_wait_msecs(astate,
- long_tmp,
- args[0]);
-
- if ((status == 0) && (args[1] != args[0]))
- status = altera_goto_jstate(astate,
- args[1]);
-
- if (version > 0) {
- --stack_ptr; /* throw away MAX cycles */
- --stack_ptr; /* throw away MAX microseconds */
- }
- break;
- case OP_CMPA: {
- /*
- * Array compare
- * ...argument 0 is source 1 ID
- * ...argument 1 is source 2 ID
- * ...argument 2 is mask ID
- * ...stack 0 is source 1 index
- * ...stack 1 is source 2 index
- * ...stack 2 is mask index
- * ...stack 3 is count
- */
- s32 a, b;
- u8 *source1 = (u8 *)vars[args[0]];
- u8 *source2 = (u8 *)vars[args[1]];
- u8 *mask = (u8 *)vars[args[2]];
- u32 index1;
- u32 index2;
- u32 mask_index;
-
- if (!altera_check_stack(stack_ptr, 4, &status))
- break;
-
- index1 = stack[--stack_ptr];
- index2 = stack[--stack_ptr];
- mask_index = stack[--stack_ptr];
- long_count = stack[--stack_ptr];
-
- if (version > 0) {
- /*
- * stack 0 = source 1 right index
- * stack 1 = source 1 left index
- * stack 2 = source 2 right index
- * stack 3 = source 2 left index
- * stack 4 = mask right index
- * stack 5 = mask left index
- */
- s32 mask_right = stack[--stack_ptr];
- s32 mask_left = stack[--stack_ptr];
- /* source 1 count */
- a = 1 + index2 - index1;
- /* source 2 count */
- b = 1 + long_count - mask_index;
- a = (a < b) ? a : b;
- /* mask count */
- b = 1 + mask_left - mask_right;
- a = (a < b) ? a : b;
- /* source 2 start index */
- index2 = mask_index;
- /* mask start index */
- mask_index = mask_right;
- long_count = a;
- }
-
- long_tmp = 1L;
-
- if (long_count < 1)
- status = -ERANGE;
- else {
- count = long_count;
-
- for (i = 0; i < count; ++i) {
- if (mask[mask_index >> 3] &
- (1 << (mask_index & 7))) {
- a = source1[index1 >> 3] &
- (1 << (index1 & 7))
- ? 1 : 0;
- b = source2[index2 >> 3] &
- (1 << (index2 & 7))
- ? 1 : 0;
-
- if (a != b) /* failure */
- long_tmp = 0L;
- }
- ++index1;
- ++index2;
- ++mask_index;
- }
- }
-
- stack[stack_ptr++] = long_tmp;
-
- break;
- }
- default:
- /* Unrecognized opcode -- ERROR! */
- bad_opcode = 1;
- break;
- }
-
- if (bad_opcode)
- status = -ENOSYS;
-
- if ((stack_ptr < 0) || (stack_ptr >= ALTERA_STACK_SIZE))
- status = -EOVERFLOW;
-
- if (status != 0) {
- done = 1;
- *error_address = (s32)(opcode_address - code_sect);
- }
- }
-
- altera_free_buffers(astate);
-
- /* Free all dynamically allocated arrays */
- if ((attrs != NULL) && (vars != NULL))
- for (i = 0; i < sym_count; ++i)
- if (attrs[i] & 0x80)
- kfree((void *)vars[i]);
-
- kfree(vars);
- kfree(var_size);
- kfree(attrs);
- kfree(proc_attributes);
-
- return status;
-}
-
-static int altera_get_note(u8 *p, s32 program_size,
- s32 *offset, char *key, char *value, int length)
-/*
- * Gets key and value of NOTE fields in the JBC file.
- * Can be called in two modes: if offset pointer is NULL,
- * then the function searches for note fields which match
- * the key string provided. If offset is not NULL, then
- * the function finds the next note field of any key,
- * starting at the offset specified by the offset pointer.
- * Returns 0 for success, else appropriate error code
- */
-{
- int status = -ENODATA;
- u32 note_strings = 0L;
- u32 note_table = 0L;
- u32 note_count = 0L;
- u32 first_word = 0L;
- int version = 0;
- int delta = 0;
- char *key_ptr;
- char *value_ptr;
- int i;
-
- /* Read header information */
- if (program_size > 52L) {
- first_word = get_unaligned_be32(&p[0]);
- version = (first_word & 1L);
- delta = version * 8;
-
- note_strings = get_unaligned_be32(&p[8 + delta]);
- note_table = get_unaligned_be32(&p[12 + delta]);
- note_count = get_unaligned_be32(&p[44 + (2 * delta)]);
- }
-
- if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
- return -EIO;
-
- if (note_count <= 0L)
- return status;
-
- if (offset == NULL) {
- /*
- * We will search for the first note with a specific key,
- * and return only the value
- */
- for (i = 0; (i < note_count) &&
- (status != 0); ++i) {
- key_ptr = &p[note_strings +
- get_unaligned_be32(
- &p[note_table + (8 * i)])];
- if ((strnicmp(key, key_ptr, strlen(key_ptr)) == 0) &&
- (key != NULL)) {
- status = 0;
-
- value_ptr = &p[note_strings +
- get_unaligned_be32(
- &p[note_table + (8 * i) + 4])];
-
- if (value != NULL)
- strlcpy(value, value_ptr, length);
-
- }
- }
- } else {
- /*
- * We will search for the next note, regardless of the key,
- * and return both the value and the key
- */
-
- i = *offset;
-
- if ((i >= 0) && (i < note_count)) {
- status = 0;
-
- if (key != NULL)
- strlcpy(key, &p[note_strings +
- get_unaligned_be32(
- &p[note_table + (8 * i)])],
- length);
-
- if (value != NULL)
- strlcpy(value, &p[note_strings +
- get_unaligned_be32(
- &p[note_table + (8 * i) + 4])],
- length);
-
- *offset = i + 1;
- }
- }
-
- return status;
-}
-
-static int altera_check_crc(u8 *p, s32 program_size)
-{
- int status = 0;
- u16 local_expected = 0,
- local_actual = 0,
- shift_reg = 0xffff;
- int bit, feedback;
- u8 databyte;
- u32 i;
- u32 crc_section = 0L;
- u32 first_word = 0L;
- int version = 0;
- int delta = 0;
-
- if (program_size > 52L) {
- first_word = get_unaligned_be32(&p[0]);
- version = (first_word & 1L);
- delta = version * 8;
-
- crc_section = get_unaligned_be32(&p[32 + delta]);
- }
-
- if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
- status = -EIO;
-
- if (crc_section >= program_size)
- status = -EIO;
-
- if (status == 0) {
- local_expected = (u16)get_unaligned_be16(&p[crc_section]);
-
- for (i = 0; i < crc_section; ++i) {
- databyte = p[i];
- for (bit = 0; bit < 8; bit++) {
- feedback = (databyte ^ shift_reg) & 0x01;
- shift_reg >>= 1;
- if (feedback)
- shift_reg ^= 0x8408;
-
- databyte >>= 1;
- }
- }
-
- local_actual = (u16)~shift_reg;
-
- if (local_expected != local_actual)
- status = -EILSEQ;
-
- }
-
- if (debug || status) {
- switch (status) {
- case 0:
- printk(KERN_INFO "%s: CRC matched: %04x\n", __func__,
- local_actual);
- break;
- case -EILSEQ:
- printk(KERN_ERR "%s: CRC mismatch: expected %04x, "
- "actual %04x\n", __func__, local_expected,
- local_actual);
- break;
- case -ENODATA:
- printk(KERN_ERR "%s: expected CRC not found, "
- "actual CRC = %04x\n", __func__,
- local_actual);
- break;
- case -EIO:
- printk(KERN_ERR "%s: error: format isn't "
- "recognized.\n", __func__);
- break;
- default:
- printk(KERN_ERR "%s: CRC function returned error "
- "code %d\n", __func__, status);
- break;
- }
- }
-
- return status;
-}
-
-static int altera_get_file_info(u8 *p,
- s32 program_size,
- int *format_version,
- int *action_count,
- int *procedure_count)
-{
- int status = -EIO;
- u32 first_word = 0;
- int version = 0;
-
- if (program_size <= 52L)
- return status;
-
- first_word = get_unaligned_be32(&p[0]);
-
- if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) {
- status = 0;
-
- version = (first_word & 1L);
- *format_version = version + 1;
-
- if (version > 0) {
- *action_count = get_unaligned_be32(&p[48]);
- *procedure_count = get_unaligned_be32(&p[52]);
- }
- }
-
- return status;
-}
-
-static int altera_get_act_info(u8 *p,
- s32 program_size,
- int index,
- char **name,
- char **description,
- struct altera_procinfo **proc_list)
-{
- int status = -EIO;
- struct altera_procinfo *procptr = NULL;
- struct altera_procinfo *tmpptr = NULL;
- u32 first_word = 0L;
- u32 action_table = 0L;
- u32 proc_table = 0L;
- u32 str_table = 0L;
- u32 note_strings = 0L;
- u32 action_count = 0L;
- u32 proc_count = 0L;
- u32 act_name_id = 0L;
- u32 act_desc_id = 0L;
- u32 act_proc_id = 0L;
- u32 act_proc_name = 0L;
- u8 act_proc_attribute = 0;
-
- if (program_size <= 52L)
- return status;
- /* Read header information */
- first_word = get_unaligned_be32(&p[0]);
-
- if (first_word != 0x4A414D01L)
- return status;
-
- action_table = get_unaligned_be32(&p[4]);
- proc_table = get_unaligned_be32(&p[8]);
- str_table = get_unaligned_be32(&p[12]);
- note_strings = get_unaligned_be32(&p[16]);
- action_count = get_unaligned_be32(&p[48]);
- proc_count = get_unaligned_be32(&p[52]);
-
- if (index >= action_count)
- return status;
-
- act_name_id = get_unaligned_be32(&p[action_table + (12 * index)]);
- act_desc_id = get_unaligned_be32(&p[action_table + (12 * index) + 4]);
- act_proc_id = get_unaligned_be32(&p[action_table + (12 * index) + 8]);
-
- *name = &p[str_table + act_name_id];
-
- if (act_desc_id < (note_strings - str_table))
- *description = &p[str_table + act_desc_id];
-
- do {
- act_proc_name = get_unaligned_be32(
- &p[proc_table + (13 * act_proc_id)]);
- act_proc_attribute =
- (p[proc_table + (13 * act_proc_id) + 8] & 0x03);
-
- procptr =
- kzalloc(sizeof(struct altera_procinfo),
- GFP_KERNEL);
-
- if (procptr == NULL)
- status = -ENOMEM;
- else {
- procptr->name = &p[str_table + act_proc_name];
- procptr->attrs = act_proc_attribute;
- procptr->next = NULL;
-
- /* add record to end of linked list */
- if (*proc_list == NULL)
- *proc_list = procptr;
- else {
- tmpptr = *proc_list;
- while (tmpptr->next != NULL)
- tmpptr = tmpptr->next;
- tmpptr->next = procptr;
- }
- }
-
- act_proc_id = get_unaligned_be32(
- &p[proc_table + (13 * act_proc_id) + 4]);
- } while ((act_proc_id != 0) && (act_proc_id < proc_count));
-
- return status;
-}
-
-int altera_init(struct altera_config *config, const struct firmware *fw)
-{
- struct altera_state *astate = NULL;
- struct altera_procinfo *proc_list = NULL;
- struct altera_procinfo *procptr = NULL;
- char *key = NULL;
- char *value = NULL;
- char *action_name = NULL;
- char *description = NULL;
- int exec_result = 0;
- int exit_code = 0;
- int format_version = 0;
- int action_count = 0;
- int procedure_count = 0;
- int index = 0;
- s32 offset = 0L;
- s32 error_address = 0L;
- int retval = 0;
-
- key = kzalloc(33, GFP_KERNEL);
- if (!key) {
- retval = -ENOMEM;
- goto out;
- }
- value = kzalloc(257, GFP_KERNEL);
- if (!value) {
- retval = -ENOMEM;
- goto free_key;
- }
- astate = kzalloc(sizeof(struct altera_state), GFP_KERNEL);
- if (!astate) {
- retval = -ENOMEM;
- goto free_value;
- }
-
- astate->config = config;
- if (!astate->config->jtag_io) {
- dprintk(KERN_INFO "%s: using byteblaster!\n", __func__);
- astate->config->jtag_io = netup_jtag_io_lpt;
- }
-
- altera_check_crc((u8 *)fw->data, fw->size);
-
- if (debug) {
- altera_get_file_info((u8 *)fw->data, fw->size, &format_version,
- &action_count, &procedure_count);
- printk(KERN_INFO "%s: File format is %s ByteCode format\n",
- __func__, (format_version == 2) ? "Jam STAPL" :
- "pre-standardized Jam 1.1");
- while (altera_get_note((u8 *)fw->data, fw->size,
- &offset, key, value, 256) == 0)
- printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n",
- __func__, key, value);
- }
-
- if (debug && (format_version == 2) && (action_count > 0)) {
- printk(KERN_INFO "%s: Actions available:\n", __func__);
- for (index = 0; index < action_count; ++index) {
- altera_get_act_info((u8 *)fw->data, fw->size,
- index, &action_name,
- &description,
- &proc_list);
-
- if (description == NULL)
- printk(KERN_INFO "%s: %s\n",
- __func__,
- action_name);
- else
- printk(KERN_INFO "%s: %s \"%s\"\n",
- __func__,
- action_name,
- description);
-
- procptr = proc_list;
- while (procptr != NULL) {
- if (procptr->attrs != 0)
- printk(KERN_INFO "%s: %s (%s)\n",
- __func__,
- procptr->name,
- (procptr->attrs == 1) ?
- "optional" : "recommended");
-
- proc_list = procptr->next;
- kfree(procptr);
- procptr = proc_list;
- }
- }
-
- printk(KERN_INFO "\n");
- }
-
- exec_result = altera_execute(astate, (u8 *)fw->data, fw->size,
- &error_address, &exit_code, &format_version);
-
- if (exit_code)
- exec_result = -EREMOTEIO;
-
- if ((format_version == 2) && (exec_result == -EINVAL)) {
- if (astate->config->action == NULL)
- printk(KERN_ERR "%s: error: no action specified for "
- "Jam STAPL file.\nprogram terminated.\n",
- __func__);
- else
- printk(KERN_ERR "%s: error: action \"%s\""
- " is not supported "
- "for this Jam STAPL file.\n"
- "Program terminated.\n", __func__,
- astate->config->action);
-
- } else if (exec_result)
- printk(KERN_ERR "%s: error %d\n", __func__, exec_result);
-
- kfree(astate);
-free_value:
- kfree(value);
-free_key:
- kfree(key);
-out:
- return retval;
-}
-EXPORT_SYMBOL(altera_init);
diff --git a/ANDROID_3.4.5/drivers/misc/apds9802als.c b/ANDROID_3.4.5/drivers/misc/apds9802als.c
deleted file mode 100644
index 0314773f..00000000
--- a/ANDROID_3.4.5/drivers/misc/apds9802als.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * apds9802als.c - apds9802 ALS Driver
- *
- * Copyright (C) 2009 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; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/sysfs.h>
-#include <linux/pm_runtime.h>
-
-#define ALS_MIN_RANGE_VAL 1
-#define ALS_MAX_RANGE_VAL 2
-#define POWER_STA_ENABLE 1
-#define POWER_STA_DISABLE 0
-
-#define DRIVER_NAME "apds9802als"
-
-struct als_data {
- struct mutex mutex;
-};
-
-static ssize_t als_sensing_range_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- int val;
-
- val = i2c_smbus_read_byte_data(client, 0x81);
- if (val < 0)
- return val;
- if (val & 1)
- return sprintf(buf, "4095\n");
- else
- return sprintf(buf, "65535\n");
-}
-
-static int als_wait_for_data_ready(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- int ret;
- int retry = 10;
-
- do {
- msleep(30);
- ret = i2c_smbus_read_byte_data(client, 0x86);
- } while (!(ret & 0x80) && retry--);
-
- if (!retry) {
- dev_warn(dev, "timeout waiting for data ready\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static ssize_t als_lux0_input_data_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct als_data *data = i2c_get_clientdata(client);
- int ret_val;
- int temp;
-
- /* Protect against parallel reads */
- pm_runtime_get_sync(dev);
- mutex_lock(&data->mutex);
-
- /* clear EOC interrupt status */
- i2c_smbus_write_byte(client, 0x40);
- /* start measurement */
- temp = i2c_smbus_read_byte_data(client, 0x81);
- i2c_smbus_write_byte_data(client, 0x81, temp | 0x08);
-
- ret_val = als_wait_for_data_ready(dev);
- if (ret_val < 0)
- goto failed;
-
- temp = i2c_smbus_read_byte_data(client, 0x8C); /* LSB data */
- if (temp < 0) {
- ret_val = temp;
- goto failed;
- }
- ret_val = i2c_smbus_read_byte_data(client, 0x8D); /* MSB data */
- if (ret_val < 0)
- goto failed;
-
- mutex_unlock(&data->mutex);
- pm_runtime_put_sync(dev);
-
- temp = (ret_val << 8) | temp;
- return sprintf(buf, "%d\n", temp);
-failed:
- mutex_unlock(&data->mutex);
- pm_runtime_put_sync(dev);
- return ret_val;
-}
-
-static ssize_t als_sensing_range_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct als_data *data = i2c_get_clientdata(client);
- int ret_val;
- unsigned long val;
-
- if (strict_strtoul(buf, 10, &val))
- return -EINVAL;
-
- if (val < 4096)
- val = 1;
- else if (val < 65536)
- val = 2;
- else
- return -ERANGE;
-
- pm_runtime_get_sync(dev);
-
- /* Make sure nobody else reads/modifies/writes 0x81 while we
- are active */
- mutex_lock(&data->mutex);
-
- ret_val = i2c_smbus_read_byte_data(client, 0x81);
- if (ret_val < 0)
- goto fail;
-
- /* Reset the bits before setting them */
- ret_val = ret_val & 0xFA;
-
- if (val == 1) /* Setting detection range up to 4k LUX */
- ret_val = (ret_val | 0x01);
- else /* Setting detection range up to 64k LUX*/
- ret_val = (ret_val | 0x00);
-
- ret_val = i2c_smbus_write_byte_data(client, 0x81, ret_val);
-
- if (ret_val >= 0) {
- /* All OK */
- mutex_unlock(&data->mutex);
- pm_runtime_put_sync(dev);
- return count;
- }
-fail:
- mutex_unlock(&data->mutex);
- pm_runtime_put_sync(dev);
- return ret_val;
-}
-
-static int als_set_power_state(struct i2c_client *client, bool on_off)
-{
- int ret_val;
- struct als_data *data = i2c_get_clientdata(client);
-
- mutex_lock(&data->mutex);
- ret_val = i2c_smbus_read_byte_data(client, 0x80);
- if (ret_val < 0)
- goto fail;
- if (on_off)
- ret_val = ret_val | 0x01;
- else
- ret_val = ret_val & 0xFE;
- ret_val = i2c_smbus_write_byte_data(client, 0x80, ret_val);
-fail:
- mutex_unlock(&data->mutex);
- return ret_val;
-}
-
-static DEVICE_ATTR(lux0_sensor_range, S_IRUGO | S_IWUSR,
- als_sensing_range_show, als_sensing_range_store);
-static DEVICE_ATTR(lux0_input, S_IRUGO, als_lux0_input_data_show, NULL);
-
-static struct attribute *mid_att_als[] = {
- &dev_attr_lux0_sensor_range.attr,
- &dev_attr_lux0_input.attr,
- NULL
-};
-
-static struct attribute_group m_als_gr = {
- .name = "apds9802als",
- .attrs = mid_att_als
-};
-
-static int als_set_default_config(struct i2c_client *client)
-{
- int ret_val;
- /* Write the command and then switch on */
- ret_val = i2c_smbus_write_byte_data(client, 0x80, 0x01);
- if (ret_val < 0) {
- dev_err(&client->dev, "failed default switch on write\n");
- return ret_val;
- }
- /* detection range: 1~64K Lux, maunal measurement */
- ret_val = i2c_smbus_write_byte_data(client, 0x81, 0x08);
- if (ret_val < 0)
- dev_err(&client->dev, "failed default LUX on write\n");
-
- /* We always get 0 for the 1st measurement after system power on,
- * so make sure it is finished before user asks for data.
- */
- als_wait_for_data_ready(&client->dev);
-
- return ret_val;
-}
-
-static int apds9802als_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int res;
- struct als_data *data;
-
- data = kzalloc(sizeof(struct als_data), GFP_KERNEL);
- if (data == NULL) {
- dev_err(&client->dev, "Memory allocation failed\n");
- return -ENOMEM;
- }
- i2c_set_clientdata(client, data);
- res = sysfs_create_group(&client->dev.kobj, &m_als_gr);
- if (res) {
- dev_err(&client->dev, "device create file failed\n");
- goto als_error1;
- }
- dev_info(&client->dev, "ALS chip found\n");
- als_set_default_config(client);
- mutex_init(&data->mutex);
-
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
-
- return res;
-als_error1:
- kfree(data);
- return res;
-}
-
-static int __devexit apds9802als_remove(struct i2c_client *client)
-{
- struct als_data *data = i2c_get_clientdata(client);
-
- pm_runtime_get_sync(&client->dev);
-
- als_set_power_state(client, false);
- sysfs_remove_group(&client->dev.kobj, &m_als_gr);
-
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
- pm_runtime_put_noidle(&client->dev);
-
- kfree(data);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int apds9802als_suspend(struct i2c_client *client, pm_message_t mesg)
-{
- als_set_power_state(client, false);
- return 0;
-}
-
-static int apds9802als_resume(struct i2c_client *client)
-{
- als_set_default_config(client);
- return 0;
-}
-
-static int apds9802als_runtime_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
-
- als_set_power_state(client, false);
- return 0;
-}
-
-static int apds9802als_runtime_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
-
- als_set_power_state(client, true);
- return 0;
-}
-
-static const struct dev_pm_ops apds9802als_pm_ops = {
- .runtime_suspend = apds9802als_runtime_suspend,
- .runtime_resume = apds9802als_runtime_resume,
-};
-
-#define APDS9802ALS_PM_OPS (&apds9802als_pm_ops)
-
-#else /* CONFIG_PM */
-#define apds9802als_suspend NULL
-#define apds9802als_resume NULL
-#define APDS9802ALS_PM_OPS NULL
-#endif /* CONFIG_PM */
-
-static struct i2c_device_id apds9802als_id[] = {
- { DRIVER_NAME, 0 },
- { }
-};
-
-MODULE_DEVICE_TABLE(i2c, apds9802als_id);
-
-static struct i2c_driver apds9802als_driver = {
- .driver = {
- .name = DRIVER_NAME,
- .pm = APDS9802ALS_PM_OPS,
- },
- .probe = apds9802als_probe,
- .remove = __devexit_p(apds9802als_remove),
- .suspend = apds9802als_suspend,
- .resume = apds9802als_resume,
- .id_table = apds9802als_id,
-};
-
-module_i2c_driver(apds9802als_driver);
-
-MODULE_AUTHOR("Anantha Narayanan <Anantha.Narayanan@intel.com");
-MODULE_DESCRIPTION("Avago apds9802als ALS Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/misc/apds990x.c b/ANDROID_3.4.5/drivers/misc/apds990x.c
deleted file mode 100644
index ee74244a..00000000
--- a/ANDROID_3.4.5/drivers/misc/apds990x.c
+++ /dev/null
@@ -1,1286 +0,0 @@
-/*
- * This file is part of the APDS990x sensor driver.
- * Chip is combined proximity and ambient light sensor.
- *
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/regulator/consumer.h>
-#include <linux/pm_runtime.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <linux/i2c/apds990x.h>
-
-/* Register map */
-#define APDS990X_ENABLE 0x00 /* Enable of states and interrupts */
-#define APDS990X_ATIME 0x01 /* ALS ADC time */
-#define APDS990X_PTIME 0x02 /* Proximity ADC time */
-#define APDS990X_WTIME 0x03 /* Wait time */
-#define APDS990X_AILTL 0x04 /* ALS interrupt low threshold low byte */
-#define APDS990X_AILTH 0x05 /* ALS interrupt low threshold hi byte */
-#define APDS990X_AIHTL 0x06 /* ALS interrupt hi threshold low byte */
-#define APDS990X_AIHTH 0x07 /* ALS interrupt hi threshold hi byte */
-#define APDS990X_PILTL 0x08 /* Proximity interrupt low threshold low byte */
-#define APDS990X_PILTH 0x09 /* Proximity interrupt low threshold hi byte */
-#define APDS990X_PIHTL 0x0a /* Proximity interrupt hi threshold low byte */
-#define APDS990X_PIHTH 0x0b /* Proximity interrupt hi threshold hi byte */
-#define APDS990X_PERS 0x0c /* Interrupt persistence filters */
-#define APDS990X_CONFIG 0x0d /* Configuration */
-#define APDS990X_PPCOUNT 0x0e /* Proximity pulse count */
-#define APDS990X_CONTROL 0x0f /* Gain control register */
-#define APDS990X_REV 0x11 /* Revision Number */
-#define APDS990X_ID 0x12 /* Device ID */
-#define APDS990X_STATUS 0x13 /* Device status */
-#define APDS990X_CDATAL 0x14 /* Clear ADC low data register */
-#define APDS990X_CDATAH 0x15 /* Clear ADC high data register */
-#define APDS990X_IRDATAL 0x16 /* IR ADC low data register */
-#define APDS990X_IRDATAH 0x17 /* IR ADC high data register */
-#define APDS990X_PDATAL 0x18 /* Proximity ADC low data register */
-#define APDS990X_PDATAH 0x19 /* Proximity ADC high data register */
-
-/* Control */
-#define APDS990X_MAX_AGAIN 3
-
-/* Enable register */
-#define APDS990X_EN_PIEN (0x1 << 5)
-#define APDS990X_EN_AIEN (0x1 << 4)
-#define APDS990X_EN_WEN (0x1 << 3)
-#define APDS990X_EN_PEN (0x1 << 2)
-#define APDS990X_EN_AEN (0x1 << 1)
-#define APDS990X_EN_PON (0x1 << 0)
-#define APDS990X_EN_DISABLE_ALL 0
-
-/* Status register */
-#define APDS990X_ST_PINT (0x1 << 5)
-#define APDS990X_ST_AINT (0x1 << 4)
-
-/* I2C access types */
-#define APDS990x_CMD_TYPE_MASK (0x03 << 5)
-#define APDS990x_CMD_TYPE_RB (0x00 << 5) /* Repeated byte */
-#define APDS990x_CMD_TYPE_INC (0x01 << 5) /* Auto increment */
-#define APDS990x_CMD_TYPE_SPE (0x03 << 5) /* Special function */
-
-#define APDS990x_ADDR_SHIFT 0
-#define APDS990x_CMD 0x80
-
-/* Interrupt ack commands */
-#define APDS990X_INT_ACK_ALS 0x6
-#define APDS990X_INT_ACK_PS 0x5
-#define APDS990X_INT_ACK_BOTH 0x7
-
-/* ptime */
-#define APDS990X_PTIME_DEFAULT 0xff /* Recommended conversion time 2.7ms*/
-
-/* wtime */
-#define APDS990X_WTIME_DEFAULT 0xee /* ~50ms wait time */
-
-#define APDS990X_TIME_TO_ADC 1024 /* One timetick as ADC count value */
-
-/* Persistence */
-#define APDS990X_APERS_SHIFT 0
-#define APDS990X_PPERS_SHIFT 4
-
-/* Supported ID:s */
-#define APDS990X_ID_0 0x0
-#define APDS990X_ID_4 0x4
-#define APDS990X_ID_29 0x29
-
-/* pgain and pdiode settings */
-#define APDS_PGAIN_1X 0x0
-#define APDS_PDIODE_IR 0x2
-
-#define APDS990X_LUX_OUTPUT_SCALE 10
-
-/* Reverse chip factors for threshold calculation */
-struct reverse_factors {
- u32 afactor;
- int cf1;
- int irf1;
- int cf2;
- int irf2;
-};
-
-struct apds990x_chip {
- struct apds990x_platform_data *pdata;
- struct i2c_client *client;
- struct mutex mutex; /* avoid parallel access */
- struct regulator_bulk_data regs[2];
- wait_queue_head_t wait;
-
- int prox_en;
- bool prox_continuous_mode;
- bool lux_wait_fresh_res;
-
- /* Chip parameters */
- struct apds990x_chip_factors cf;
- struct reverse_factors rcf;
- u16 atime; /* als integration time */
- u16 arate; /* als reporting rate */
- u16 a_max_result; /* Max possible ADC value with current atime */
- u8 again_meas; /* Gain used in last measurement */
- u8 again_next; /* Next calculated gain */
- u8 pgain;
- u8 pdiode;
- u8 pdrive;
- u8 lux_persistence;
- u8 prox_persistence;
-
- u32 lux_raw;
- u32 lux;
- u16 lux_clear;
- u16 lux_ir;
- u16 lux_calib;
- u32 lux_thres_hi;
- u32 lux_thres_lo;
-
- u32 prox_thres;
- u16 prox_data;
- u16 prox_calib;
-
- char chipname[10];
- u8 revision;
-};
-
-#define APDS_CALIB_SCALER 8192
-#define APDS_LUX_NEUTRAL_CALIB_VALUE (1 * APDS_CALIB_SCALER)
-#define APDS_PROX_NEUTRAL_CALIB_VALUE (1 * APDS_CALIB_SCALER)
-
-#define APDS_PROX_DEF_THRES 600
-#define APDS_PROX_HYSTERESIS 50
-#define APDS_LUX_DEF_THRES_HI 101
-#define APDS_LUX_DEF_THRES_LO 100
-#define APDS_DEFAULT_PROX_PERS 1
-
-#define APDS_TIMEOUT 2000
-#define APDS_STARTUP_DELAY 25000 /* us */
-#define APDS_RANGE 65535
-#define APDS_PROX_RANGE 1023
-#define APDS_LUX_GAIN_LO_LIMIT 100
-#define APDS_LUX_GAIN_LO_LIMIT_STRICT 25
-
-#define TIMESTEP 87 /* 2.7ms is about 87 / 32 */
-#define TIME_STEP_SCALER 32
-
-#define APDS_LUX_AVERAGING_TIME 50 /* tolerates 50/60Hz ripple */
-#define APDS_LUX_DEFAULT_RATE 200
-
-static const u8 again[] = {1, 8, 16, 120}; /* ALS gain steps */
-static const u8 ir_currents[] = {100, 50, 25, 12}; /* IRled currents in mA */
-
-/* Following two tables must match i.e 10Hz rate means 1 as persistence value */
-static const u16 arates_hz[] = {10, 5, 2, 1};
-static const u8 apersis[] = {1, 2, 4, 5};
-
-/* Regulators */
-static const char reg_vcc[] = "Vdd";
-static const char reg_vled[] = "Vled";
-
-static int apds990x_read_byte(struct apds990x_chip *chip, u8 reg, u8 *data)
-{
- struct i2c_client *client = chip->client;
- s32 ret;
-
- reg &= ~APDS990x_CMD_TYPE_MASK;
- reg |= APDS990x_CMD | APDS990x_CMD_TYPE_RB;
-
- ret = i2c_smbus_read_byte_data(client, reg);
- *data = ret;
- return (int)ret;
-}
-
-static int apds990x_read_word(struct apds990x_chip *chip, u8 reg, u16 *data)
-{
- struct i2c_client *client = chip->client;
- s32 ret;
-
- reg &= ~APDS990x_CMD_TYPE_MASK;
- reg |= APDS990x_CMD | APDS990x_CMD_TYPE_INC;
-
- ret = i2c_smbus_read_word_data(client, reg);
- *data = ret;
- return (int)ret;
-}
-
-static int apds990x_write_byte(struct apds990x_chip *chip, u8 reg, u8 data)
-{
- struct i2c_client *client = chip->client;
- s32 ret;
-
- reg &= ~APDS990x_CMD_TYPE_MASK;
- reg |= APDS990x_CMD | APDS990x_CMD_TYPE_RB;
-
- ret = i2c_smbus_write_byte_data(client, reg, data);
- return (int)ret;
-}
-
-static int apds990x_write_word(struct apds990x_chip *chip, u8 reg, u16 data)
-{
- struct i2c_client *client = chip->client;
- s32 ret;
-
- reg &= ~APDS990x_CMD_TYPE_MASK;
- reg |= APDS990x_CMD | APDS990x_CMD_TYPE_INC;
-
- ret = i2c_smbus_write_word_data(client, reg, data);
- return (int)ret;
-}
-
-static int apds990x_mode_on(struct apds990x_chip *chip)
-{
- /* ALS is mandatory, proximity optional */
- u8 reg = APDS990X_EN_AIEN | APDS990X_EN_PON | APDS990X_EN_AEN |
- APDS990X_EN_WEN;
-
- if (chip->prox_en)
- reg |= APDS990X_EN_PIEN | APDS990X_EN_PEN;
-
- return apds990x_write_byte(chip, APDS990X_ENABLE, reg);
-}
-
-static u16 apds990x_lux_to_threshold(struct apds990x_chip *chip, u32 lux)
-{
- u32 thres;
- u32 cpl;
- u32 ir;
-
- if (lux == 0)
- return 0;
- else if (lux == APDS_RANGE)
- return APDS_RANGE;
-
- /*
- * Reported LUX value is a combination of the IR and CLEAR channel
- * values. However, interrupt threshold is only for clear channel.
- * This function approximates needed HW threshold value for a given
- * LUX value in the current lightning type.
- * IR level compared to visible light varies heavily depending on the
- * source of the light
- *
- * Calculate threshold value for the next measurement period.
- * Math: threshold = lux * cpl where
- * cpl = atime * again / (glass_attenuation * device_factor)
- * (count-per-lux)
- *
- * First remove calibration. Division by four is to avoid overflow
- */
- lux = lux * (APDS_CALIB_SCALER / 4) / (chip->lux_calib / 4);
-
- /* Multiplication by 64 is to increase accuracy */
- cpl = ((u32)chip->atime * (u32)again[chip->again_next] *
- APDS_PARAM_SCALE * 64) / (chip->cf.ga * chip->cf.df);
-
- thres = lux * cpl / 64;
- /*
- * Convert IR light from the latest result to match with
- * new gain step. This helps to adapt with the current
- * source of light.
- */
- ir = (u32)chip->lux_ir * (u32)again[chip->again_next] /
- (u32)again[chip->again_meas];
-
- /*
- * Compensate count with IR light impact
- * IAC1 > IAC2 (see apds990x_get_lux for formulas)
- */
- if (chip->lux_clear * APDS_PARAM_SCALE >=
- chip->rcf.afactor * chip->lux_ir)
- thres = (chip->rcf.cf1 * thres + chip->rcf.irf1 * ir) /
- APDS_PARAM_SCALE;
- else
- thres = (chip->rcf.cf2 * thres + chip->rcf.irf2 * ir) /
- APDS_PARAM_SCALE;
-
- if (thres >= chip->a_max_result)
- thres = chip->a_max_result - 1;
- return thres;
-}
-
-static inline int apds990x_set_atime(struct apds990x_chip *chip, u32 time_ms)
-{
- u8 reg_value;
-
- chip->atime = time_ms;
- /* Formula is specified in the data sheet */
- reg_value = 256 - ((time_ms * TIME_STEP_SCALER) / TIMESTEP);
- /* Calculate max ADC value for given integration time */
- chip->a_max_result = (u16)(256 - reg_value) * APDS990X_TIME_TO_ADC;
- return apds990x_write_byte(chip, APDS990X_ATIME, reg_value);
-}
-
-/* Called always with mutex locked */
-static int apds990x_refresh_pthres(struct apds990x_chip *chip, int data)
-{
- int ret, lo, hi;
-
- /* If the chip is not in use, don't try to access it */
- if (pm_runtime_suspended(&chip->client->dev))
- return 0;
-
- if (data < chip->prox_thres) {
- lo = 0;
- hi = chip->prox_thres;
- } else {
- lo = chip->prox_thres - APDS_PROX_HYSTERESIS;
- if (chip->prox_continuous_mode)
- hi = chip->prox_thres;
- else
- hi = APDS_RANGE;
- }
-
- ret = apds990x_write_word(chip, APDS990X_PILTL, lo);
- ret |= apds990x_write_word(chip, APDS990X_PIHTL, hi);
- return ret;
-}
-
-/* Called always with mutex locked */
-static int apds990x_refresh_athres(struct apds990x_chip *chip)
-{
- int ret;
- /* If the chip is not in use, don't try to access it */
- if (pm_runtime_suspended(&chip->client->dev))
- return 0;
-
- ret = apds990x_write_word(chip, APDS990X_AILTL,
- apds990x_lux_to_threshold(chip, chip->lux_thres_lo));
- ret |= apds990x_write_word(chip, APDS990X_AIHTL,
- apds990x_lux_to_threshold(chip, chip->lux_thres_hi));
-
- return ret;
-}
-
-/* Called always with mutex locked */
-static void apds990x_force_a_refresh(struct apds990x_chip *chip)
-{
- /* This will force ALS interrupt after the next measurement. */
- apds990x_write_word(chip, APDS990X_AILTL, APDS_LUX_DEF_THRES_LO);
- apds990x_write_word(chip, APDS990X_AIHTL, APDS_LUX_DEF_THRES_HI);
-}
-
-/* Called always with mutex locked */
-static void apds990x_force_p_refresh(struct apds990x_chip *chip)
-{
- /* This will force proximity interrupt after the next measurement. */
- apds990x_write_word(chip, APDS990X_PILTL, APDS_PROX_DEF_THRES - 1);
- apds990x_write_word(chip, APDS990X_PIHTL, APDS_PROX_DEF_THRES);
-}
-
-/* Called always with mutex locked */
-static int apds990x_calc_again(struct apds990x_chip *chip)
-{
- int curr_again = chip->again_meas;
- int next_again = chip->again_meas;
- int ret = 0;
-
- /* Calculate suitable als gain */
- if (chip->lux_clear == chip->a_max_result)
- next_again -= 2; /* ALS saturated. Decrease gain by 2 steps */
- else if (chip->lux_clear > chip->a_max_result / 2)
- next_again--;
- else if (chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT_STRICT)
- next_again += 2; /* Too dark. Increase gain by 2 steps */
- else if (chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT)
- next_again++;
-
- /* Limit gain to available range */
- if (next_again < 0)
- next_again = 0;
- else if (next_again > APDS990X_MAX_AGAIN)
- next_again = APDS990X_MAX_AGAIN;
-
- /* Let's check can we trust the measured result */
- if (chip->lux_clear == chip->a_max_result)
- /* Result can be totally garbage due to saturation */
- ret = -ERANGE;
- else if (next_again != curr_again &&
- chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT_STRICT)
- /*
- * Gain is changed and measurement result is very small.
- * Result can be totally garbage due to underflow
- */
- ret = -ERANGE;
-
- chip->again_next = next_again;
- apds990x_write_byte(chip, APDS990X_CONTROL,
- (chip->pdrive << 6) |
- (chip->pdiode << 4) |
- (chip->pgain << 2) |
- (chip->again_next << 0));
-
- /*
- * Error means bad result -> re-measurement is needed. The forced
- * refresh uses fastest possible persistence setting to get result
- * as soon as possible.
- */
- if (ret < 0)
- apds990x_force_a_refresh(chip);
- else
- apds990x_refresh_athres(chip);
-
- return ret;
-}
-
-/* Called always with mutex locked */
-static int apds990x_get_lux(struct apds990x_chip *chip, int clear, int ir)
-{
- int iac, iac1, iac2; /* IR adjusted counts */
- u32 lpc; /* Lux per count */
-
- /* Formulas:
- * iac1 = CF1 * CLEAR_CH - IRF1 * IR_CH
- * iac2 = CF2 * CLEAR_CH - IRF2 * IR_CH
- */
- iac1 = (chip->cf.cf1 * clear - chip->cf.irf1 * ir) / APDS_PARAM_SCALE;
- iac2 = (chip->cf.cf2 * clear - chip->cf.irf2 * ir) / APDS_PARAM_SCALE;
-
- iac = max(iac1, iac2);
- iac = max(iac, 0);
-
- lpc = APDS990X_LUX_OUTPUT_SCALE * (chip->cf.df * chip->cf.ga) /
- (u32)(again[chip->again_meas] * (u32)chip->atime);
-
- return (iac * lpc) / APDS_PARAM_SCALE;
-}
-
-static int apds990x_ack_int(struct apds990x_chip *chip, u8 mode)
-{
- struct i2c_client *client = chip->client;
- s32 ret;
- u8 reg = APDS990x_CMD | APDS990x_CMD_TYPE_SPE;
-
- switch (mode & (APDS990X_ST_AINT | APDS990X_ST_PINT)) {
- case APDS990X_ST_AINT:
- reg |= APDS990X_INT_ACK_ALS;
- break;
- case APDS990X_ST_PINT:
- reg |= APDS990X_INT_ACK_PS;
- break;
- default:
- reg |= APDS990X_INT_ACK_BOTH;
- break;
- }
-
- ret = i2c_smbus_read_byte_data(client, reg);
- return (int)ret;
-}
-
-static irqreturn_t apds990x_irq(int irq, void *data)
-{
- struct apds990x_chip *chip = data;
- u8 status;
-
- apds990x_read_byte(chip, APDS990X_STATUS, &status);
- apds990x_ack_int(chip, status);
-
- mutex_lock(&chip->mutex);
- if (!pm_runtime_suspended(&chip->client->dev)) {
- if (status & APDS990X_ST_AINT) {
- apds990x_read_word(chip, APDS990X_CDATAL,
- &chip->lux_clear);
- apds990x_read_word(chip, APDS990X_IRDATAL,
- &chip->lux_ir);
- /* Store used gain for calculations */
- chip->again_meas = chip->again_next;
-
- chip->lux_raw = apds990x_get_lux(chip,
- chip->lux_clear,
- chip->lux_ir);
-
- if (apds990x_calc_again(chip) == 0) {
- /* Result is valid */
- chip->lux = chip->lux_raw;
- chip->lux_wait_fresh_res = false;
- wake_up(&chip->wait);
- sysfs_notify(&chip->client->dev.kobj,
- NULL, "lux0_input");
- }
- }
-
- if ((status & APDS990X_ST_PINT) && chip->prox_en) {
- u16 clr_ch;
-
- apds990x_read_word(chip, APDS990X_CDATAL, &clr_ch);
- /*
- * If ALS channel is saturated at min gain,
- * proximity gives false posivite values.
- * Just ignore them.
- */
- if (chip->again_meas == 0 &&
- clr_ch == chip->a_max_result)
- chip->prox_data = 0;
- else
- apds990x_read_word(chip,
- APDS990X_PDATAL,
- &chip->prox_data);
-
- apds990x_refresh_pthres(chip, chip->prox_data);
- if (chip->prox_data < chip->prox_thres)
- chip->prox_data = 0;
- else if (!chip->prox_continuous_mode)
- chip->prox_data = APDS_PROX_RANGE;
- sysfs_notify(&chip->client->dev.kobj,
- NULL, "prox0_raw");
- }
- }
- mutex_unlock(&chip->mutex);
- return IRQ_HANDLED;
-}
-
-static int apds990x_configure(struct apds990x_chip *chip)
-{
- /* It is recommended to use disabled mode during these operations */
- apds990x_write_byte(chip, APDS990X_ENABLE, APDS990X_EN_DISABLE_ALL);
-
- /* conversion and wait times for different state machince states */
- apds990x_write_byte(chip, APDS990X_PTIME, APDS990X_PTIME_DEFAULT);
- apds990x_write_byte(chip, APDS990X_WTIME, APDS990X_WTIME_DEFAULT);
- apds990x_set_atime(chip, APDS_LUX_AVERAGING_TIME);
-
- apds990x_write_byte(chip, APDS990X_CONFIG, 0);
-
- /* Persistence levels */
- apds990x_write_byte(chip, APDS990X_PERS,
- (chip->lux_persistence << APDS990X_APERS_SHIFT) |
- (chip->prox_persistence << APDS990X_PPERS_SHIFT));
-
- apds990x_write_byte(chip, APDS990X_PPCOUNT, chip->pdata->ppcount);
-
- /* Start with relatively small gain */
- chip->again_meas = 1;
- chip->again_next = 1;
- apds990x_write_byte(chip, APDS990X_CONTROL,
- (chip->pdrive << 6) |
- (chip->pdiode << 4) |
- (chip->pgain << 2) |
- (chip->again_next << 0));
- return 0;
-}
-
-static int apds990x_detect(struct apds990x_chip *chip)
-{
- struct i2c_client *client = chip->client;
- int ret;
- u8 id;
-
- ret = apds990x_read_byte(chip, APDS990X_ID, &id);
- if (ret < 0) {
- dev_err(&client->dev, "ID read failed\n");
- return ret;
- }
-
- ret = apds990x_read_byte(chip, APDS990X_REV, &chip->revision);
- if (ret < 0) {
- dev_err(&client->dev, "REV read failed\n");
- return ret;
- }
-
- switch (id) {
- case APDS990X_ID_0:
- case APDS990X_ID_4:
- case APDS990X_ID_29:
- snprintf(chip->chipname, sizeof(chip->chipname), "APDS-990x");
- break;
- default:
- ret = -ENODEV;
- break;
- }
- return ret;
-}
-
-#if defined(CONFIG_PM) || defined(CONFIG_PM_RUNTIME)
-static int apds990x_chip_on(struct apds990x_chip *chip)
-{
- int err = regulator_bulk_enable(ARRAY_SIZE(chip->regs),
- chip->regs);
- if (err < 0)
- return err;
-
- usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY);
-
- /* Refresh all configs in case of regulators were off */
- chip->prox_data = 0;
- apds990x_configure(chip);
- apds990x_mode_on(chip);
- return 0;
-}
-#endif
-
-static int apds990x_chip_off(struct apds990x_chip *chip)
-{
- apds990x_write_byte(chip, APDS990X_ENABLE, APDS990X_EN_DISABLE_ALL);
- regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
- return 0;
-}
-
-static ssize_t apds990x_lux_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- ssize_t ret;
- u32 result;
- long timeout;
-
- if (pm_runtime_suspended(dev))
- return -EIO;
-
- timeout = wait_event_interruptible_timeout(chip->wait,
- !chip->lux_wait_fresh_res,
- msecs_to_jiffies(APDS_TIMEOUT));
- if (!timeout)
- return -EIO;
-
- mutex_lock(&chip->mutex);
- result = (chip->lux * chip->lux_calib) / APDS_CALIB_SCALER;
- if (result > (APDS_RANGE * APDS990X_LUX_OUTPUT_SCALE))
- result = APDS_RANGE * APDS990X_LUX_OUTPUT_SCALE;
-
- ret = sprintf(buf, "%d.%d\n",
- result / APDS990X_LUX_OUTPUT_SCALE,
- result % APDS990X_LUX_OUTPUT_SCALE);
- mutex_unlock(&chip->mutex);
- return ret;
-}
-
-static DEVICE_ATTR(lux0_input, S_IRUGO, apds990x_lux_show, NULL);
-
-static ssize_t apds990x_lux_range_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%u\n", APDS_RANGE);
-}
-
-static DEVICE_ATTR(lux0_sensor_range, S_IRUGO, apds990x_lux_range_show, NULL);
-
-static ssize_t apds990x_lux_calib_format_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%u\n", APDS_CALIB_SCALER);
-}
-
-static DEVICE_ATTR(lux0_calibscale_default, S_IRUGO,
- apds990x_lux_calib_format_show, NULL);
-
-static ssize_t apds990x_lux_calib_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
-
- return sprintf(buf, "%u\n", chip->lux_calib);
-}
-
-static ssize_t apds990x_lux_calib_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- if (chip->lux_calib > APDS_RANGE)
- return -EINVAL;
-
- chip->lux_calib = value;
-
- return len;
-}
-
-static DEVICE_ATTR(lux0_calibscale, S_IRUGO | S_IWUSR, apds990x_lux_calib_show,
- apds990x_lux_calib_store);
-
-static ssize_t apds990x_rate_avail(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int i;
- int pos = 0;
- for (i = 0; i < ARRAY_SIZE(arates_hz); i++)
- pos += sprintf(buf + pos, "%d ", arates_hz[i]);
- sprintf(buf + pos - 1, "\n");
- return pos;
-}
-
-static ssize_t apds990x_rate_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", chip->arate);
-}
-
-static int apds990x_set_arate(struct apds990x_chip *chip, int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(arates_hz); i++)
- if (rate >= arates_hz[i])
- break;
-
- if (i == ARRAY_SIZE(arates_hz))
- return -EINVAL;
-
- /* Pick up corresponding persistence value */
- chip->lux_persistence = apersis[i];
- chip->arate = arates_hz[i];
-
- /* If the chip is not in use, don't try to access it */
- if (pm_runtime_suspended(&chip->client->dev))
- return 0;
-
- /* Persistence levels */
- return apds990x_write_byte(chip, APDS990X_PERS,
- (chip->lux_persistence << APDS990X_APERS_SHIFT) |
- (chip->prox_persistence << APDS990X_PPERS_SHIFT));
-}
-
-static ssize_t apds990x_rate_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
- int ret;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- ret = apds990x_set_arate(chip, value);
- mutex_unlock(&chip->mutex);
-
- if (ret < 0)
- return ret;
- return len;
-}
-
-static DEVICE_ATTR(lux0_rate_avail, S_IRUGO, apds990x_rate_avail, NULL);
-
-static DEVICE_ATTR(lux0_rate, S_IRUGO | S_IWUSR, apds990x_rate_show,
- apds990x_rate_store);
-
-static ssize_t apds990x_prox_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- ssize_t ret;
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- if (pm_runtime_suspended(dev) || !chip->prox_en)
- return -EIO;
-
- mutex_lock(&chip->mutex);
- ret = sprintf(buf, "%d\n", chip->prox_data);
- mutex_unlock(&chip->mutex);
- return ret;
-}
-
-static DEVICE_ATTR(prox0_raw, S_IRUGO, apds990x_prox_show, NULL);
-
-static ssize_t apds990x_prox_range_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%u\n", APDS_PROX_RANGE);
-}
-
-static DEVICE_ATTR(prox0_sensor_range, S_IRUGO, apds990x_prox_range_show, NULL);
-
-static ssize_t apds990x_prox_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", chip->prox_en);
-}
-
-static ssize_t apds990x_prox_enable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
-
- if (!chip->prox_en)
- chip->prox_data = 0;
-
- if (value)
- chip->prox_en++;
- else if (chip->prox_en > 0)
- chip->prox_en--;
-
- if (!pm_runtime_suspended(dev))
- apds990x_mode_on(chip);
- mutex_unlock(&chip->mutex);
- return len;
-}
-
-static DEVICE_ATTR(prox0_raw_en, S_IRUGO | S_IWUSR, apds990x_prox_enable_show,
- apds990x_prox_enable_store);
-
-static const char reporting_modes[][9] = {"trigger", "periodic"};
-
-static ssize_t apds990x_prox_reporting_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n",
- reporting_modes[!!chip->prox_continuous_mode]);
-}
-
-static ssize_t apds990x_prox_reporting_mode_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
-
- if (sysfs_streq(buf, reporting_modes[0]))
- chip->prox_continuous_mode = 0;
- else if (sysfs_streq(buf, reporting_modes[1]))
- chip->prox_continuous_mode = 1;
- else
- return -EINVAL;
- return len;
-}
-
-static DEVICE_ATTR(prox0_reporting_mode, S_IRUGO | S_IWUSR,
- apds990x_prox_reporting_mode_show,
- apds990x_prox_reporting_mode_store);
-
-static ssize_t apds990x_prox_reporting_avail_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%s %s\n", reporting_modes[0], reporting_modes[1]);
-}
-
-static DEVICE_ATTR(prox0_reporting_mode_avail, S_IRUGO | S_IWUSR,
- apds990x_prox_reporting_avail_show, NULL);
-
-
-static ssize_t apds990x_lux_thresh_above_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", chip->lux_thres_hi);
-}
-
-static ssize_t apds990x_lux_thresh_below_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", chip->lux_thres_lo);
-}
-
-static ssize_t apds990x_set_lux_thresh(struct apds990x_chip *chip, u32 *target,
- const char *buf)
-{
- int ret = 0;
- unsigned long thresh;
-
- if (strict_strtoul(buf, 0, &thresh))
- return -EINVAL;
-
- if (thresh > APDS_RANGE)
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- *target = thresh;
- /*
- * Don't update values in HW if we are still waiting for
- * first interrupt to come after device handle open call.
- */
- if (!chip->lux_wait_fresh_res)
- apds990x_refresh_athres(chip);
- mutex_unlock(&chip->mutex);
- return ret;
-
-}
-
-static ssize_t apds990x_lux_thresh_above_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- int ret = apds990x_set_lux_thresh(chip, &chip->lux_thres_hi, buf);
- if (ret < 0)
- return ret;
- return len;
-}
-
-static ssize_t apds990x_lux_thresh_below_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- int ret = apds990x_set_lux_thresh(chip, &chip->lux_thres_lo, buf);
- if (ret < 0)
- return ret;
- return len;
-}
-
-static DEVICE_ATTR(lux0_thresh_above_value, S_IRUGO | S_IWUSR,
- apds990x_lux_thresh_above_show,
- apds990x_lux_thresh_above_store);
-
-static DEVICE_ATTR(lux0_thresh_below_value, S_IRUGO | S_IWUSR,
- apds990x_lux_thresh_below_show,
- apds990x_lux_thresh_below_store);
-
-static ssize_t apds990x_prox_threshold_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", chip->prox_thres);
-}
-
-static ssize_t apds990x_prox_threshold_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- if ((value > APDS_RANGE) || (value == 0) ||
- (value < APDS_PROX_HYSTERESIS))
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- chip->prox_thres = value;
-
- apds990x_force_p_refresh(chip);
- mutex_unlock(&chip->mutex);
- return len;
-}
-
-static DEVICE_ATTR(prox0_thresh_above_value, S_IRUGO | S_IWUSR,
- apds990x_prox_threshold_show,
- apds990x_prox_threshold_store);
-
-static ssize_t apds990x_power_state_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", !pm_runtime_suspended(dev));
- return 0;
-}
-
-static ssize_t apds990x_power_state_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
- if (value) {
- pm_runtime_get_sync(dev);
- mutex_lock(&chip->mutex);
- chip->lux_wait_fresh_res = true;
- apds990x_force_a_refresh(chip);
- apds990x_force_p_refresh(chip);
- mutex_unlock(&chip->mutex);
- } else {
- if (!pm_runtime_suspended(dev))
- pm_runtime_put(dev);
- }
- return len;
-}
-
-static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
- apds990x_power_state_show,
- apds990x_power_state_store);
-
-static ssize_t apds990x_chip_id_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct apds990x_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%s %d\n", chip->chipname, chip->revision);
-}
-
-static DEVICE_ATTR(chip_id, S_IRUGO, apds990x_chip_id_show, NULL);
-
-static struct attribute *sysfs_attrs_ctrl[] = {
- &dev_attr_lux0_calibscale.attr,
- &dev_attr_lux0_calibscale_default.attr,
- &dev_attr_lux0_input.attr,
- &dev_attr_lux0_sensor_range.attr,
- &dev_attr_lux0_rate.attr,
- &dev_attr_lux0_rate_avail.attr,
- &dev_attr_lux0_thresh_above_value.attr,
- &dev_attr_lux0_thresh_below_value.attr,
- &dev_attr_prox0_raw_en.attr,
- &dev_attr_prox0_raw.attr,
- &dev_attr_prox0_sensor_range.attr,
- &dev_attr_prox0_thresh_above_value.attr,
- &dev_attr_prox0_reporting_mode.attr,
- &dev_attr_prox0_reporting_mode_avail.attr,
- &dev_attr_chip_id.attr,
- &dev_attr_power_state.attr,
- NULL
-};
-
-static struct attribute_group apds990x_attribute_group[] = {
- {.attrs = sysfs_attrs_ctrl },
-};
-
-static int __devinit apds990x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct apds990x_chip *chip;
- int err;
-
- chip = kzalloc(sizeof *chip, GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- i2c_set_clientdata(client, chip);
- chip->client = client;
-
- init_waitqueue_head(&chip->wait);
- mutex_init(&chip->mutex);
- chip->pdata = client->dev.platform_data;
-
- if (chip->pdata == NULL) {
- dev_err(&client->dev, "platform data is mandatory\n");
- err = -EINVAL;
- goto fail1;
- }
-
- if (chip->pdata->cf.ga == 0) {
- /* set uncovered sensor default parameters */
- chip->cf.ga = 1966; /* 0.48 * APDS_PARAM_SCALE */
- chip->cf.cf1 = 4096; /* 1.00 * APDS_PARAM_SCALE */
- chip->cf.irf1 = 9134; /* 2.23 * APDS_PARAM_SCALE */
- chip->cf.cf2 = 2867; /* 0.70 * APDS_PARAM_SCALE */
- chip->cf.irf2 = 5816; /* 1.42 * APDS_PARAM_SCALE */
- chip->cf.df = 52;
- } else {
- chip->cf = chip->pdata->cf;
- }
-
- /* precalculate inverse chip factors for threshold control */
- chip->rcf.afactor =
- (chip->cf.irf1 - chip->cf.irf2) * APDS_PARAM_SCALE /
- (chip->cf.cf1 - chip->cf.cf2);
- chip->rcf.cf1 = APDS_PARAM_SCALE * APDS_PARAM_SCALE /
- chip->cf.cf1;
- chip->rcf.irf1 = chip->cf.irf1 * APDS_PARAM_SCALE /
- chip->cf.cf1;
- chip->rcf.cf2 = APDS_PARAM_SCALE * APDS_PARAM_SCALE /
- chip->cf.cf2;
- chip->rcf.irf2 = chip->cf.irf2 * APDS_PARAM_SCALE /
- chip->cf.cf2;
-
- /* Set something to start with */
- chip->lux_thres_hi = APDS_LUX_DEF_THRES_HI;
- chip->lux_thres_lo = APDS_LUX_DEF_THRES_LO;
- chip->lux_calib = APDS_LUX_NEUTRAL_CALIB_VALUE;
-
- chip->prox_thres = APDS_PROX_DEF_THRES;
- chip->pdrive = chip->pdata->pdrive;
- chip->pdiode = APDS_PDIODE_IR;
- chip->pgain = APDS_PGAIN_1X;
- chip->prox_calib = APDS_PROX_NEUTRAL_CALIB_VALUE;
- chip->prox_persistence = APDS_DEFAULT_PROX_PERS;
- chip->prox_continuous_mode = false;
-
- chip->regs[0].supply = reg_vcc;
- chip->regs[1].supply = reg_vled;
-
- err = regulator_bulk_get(&client->dev,
- ARRAY_SIZE(chip->regs), chip->regs);
- if (err < 0) {
- dev_err(&client->dev, "Cannot get regulators\n");
- goto fail1;
- }
-
- err = regulator_bulk_enable(ARRAY_SIZE(chip->regs), chip->regs);
- if (err < 0) {
- dev_err(&client->dev, "Cannot enable regulators\n");
- goto fail2;
- }
-
- usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY);
-
- err = apds990x_detect(chip);
- if (err < 0) {
- dev_err(&client->dev, "APDS990X not found\n");
- goto fail3;
- }
-
- pm_runtime_set_active(&client->dev);
-
- apds990x_configure(chip);
- apds990x_set_arate(chip, APDS_LUX_DEFAULT_RATE);
- apds990x_mode_on(chip);
-
- pm_runtime_enable(&client->dev);
-
- if (chip->pdata->setup_resources) {
- err = chip->pdata->setup_resources();
- if (err) {
- err = -EINVAL;
- goto fail3;
- }
- }
-
- err = sysfs_create_group(&chip->client->dev.kobj,
- apds990x_attribute_group);
- if (err < 0) {
- dev_err(&chip->client->dev, "Sysfs registration failed\n");
- goto fail4;
- }
-
- err = request_threaded_irq(client->irq, NULL,
- apds990x_irq,
- IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW |
- IRQF_ONESHOT,
- "apds990x", chip);
- if (err) {
- dev_err(&client->dev, "could not get IRQ %d\n",
- client->irq);
- goto fail5;
- }
- return err;
-fail5:
- sysfs_remove_group(&chip->client->dev.kobj,
- &apds990x_attribute_group[0]);
-fail4:
- if (chip->pdata && chip->pdata->release_resources)
- chip->pdata->release_resources();
-fail3:
- regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
-fail2:
- regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
-fail1:
- kfree(chip);
- return err;
-}
-
-static int __devexit apds990x_remove(struct i2c_client *client)
-{
- struct apds990x_chip *chip = i2c_get_clientdata(client);
-
- free_irq(client->irq, chip);
- sysfs_remove_group(&chip->client->dev.kobj,
- apds990x_attribute_group);
-
- if (chip->pdata && chip->pdata->release_resources)
- chip->pdata->release_resources();
-
- if (!pm_runtime_suspended(&client->dev))
- apds990x_chip_off(chip);
-
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
-
- regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
-
- kfree(chip);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int apds990x_suspend(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct apds990x_chip *chip = i2c_get_clientdata(client);
-
- apds990x_chip_off(chip);
- return 0;
-}
-
-static int apds990x_resume(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct apds990x_chip *chip = i2c_get_clientdata(client);
-
- /*
- * If we were enabled at suspend time, it is expected
- * everything works nice and smoothly. Chip_on is enough
- */
- apds990x_chip_on(chip);
-
- return 0;
-}
-#else
-#define apds990x_suspend NULL
-#define apds990x_resume NULL
-#define apds990x_shutdown NULL
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
-static int apds990x_runtime_suspend(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct apds990x_chip *chip = i2c_get_clientdata(client);
-
- apds990x_chip_off(chip);
- return 0;
-}
-
-static int apds990x_runtime_resume(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct apds990x_chip *chip = i2c_get_clientdata(client);
-
- apds990x_chip_on(chip);
- return 0;
-}
-
-#endif
-
-static const struct i2c_device_id apds990x_id[] = {
- {"apds990x", 0 },
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, apds990x_id);
-
-static const struct dev_pm_ops apds990x_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(apds990x_suspend, apds990x_resume)
- SET_RUNTIME_PM_OPS(apds990x_runtime_suspend,
- apds990x_runtime_resume,
- NULL)
-};
-
-static struct i2c_driver apds990x_driver = {
- .driver = {
- .name = "apds990x",
- .owner = THIS_MODULE,
- .pm = &apds990x_pm_ops,
- },
- .probe = apds990x_probe,
- .remove = __devexit_p(apds990x_remove),
- .id_table = apds990x_id,
-};
-
-module_i2c_driver(apds990x_driver);
-
-MODULE_DESCRIPTION("APDS990X combined ALS and proximity sensor");
-MODULE_AUTHOR("Samu Onkalo, Nokia Corporation");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/misc/arm-charlcd.c b/ANDROID_3.4.5/drivers/misc/arm-charlcd.c
deleted file mode 100644
index fe8616a8..00000000
--- a/ANDROID_3.4.5/drivers/misc/arm-charlcd.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Driver for the on-board character LCD found on some ARM reference boards
- * This is basically an Hitachi HD44780 LCD with a custom IP block to drive it
- * http://en.wikipedia.org/wiki/HD44780_Character_LCD
- * Currently it will just display the text "ARM Linux" and the linux version
- *
- * License terms: GNU General Public License (GPL) version 2
- * Author: Linus Walleij <triad@df.lth.se>
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <generated/utsrelease.h>
-
-#define DRIVERNAME "arm-charlcd"
-#define CHARLCD_TIMEOUT (msecs_to_jiffies(1000))
-
-/* Offsets to registers */
-#define CHAR_COM 0x00U
-#define CHAR_DAT 0x04U
-#define CHAR_RD 0x08U
-#define CHAR_RAW 0x0CU
-#define CHAR_MASK 0x10U
-#define CHAR_STAT 0x14U
-
-#define CHAR_RAW_CLEAR 0x00000000U
-#define CHAR_RAW_VALID 0x00000100U
-
-/* Hitachi HD44780 display commands */
-#define HD_CLEAR 0x01U
-#define HD_HOME 0x02U
-#define HD_ENTRYMODE 0x04U
-#define HD_ENTRYMODE_INCREMENT 0x02U
-#define HD_ENTRYMODE_SHIFT 0x01U
-#define HD_DISPCTRL 0x08U
-#define HD_DISPCTRL_ON 0x04U
-#define HD_DISPCTRL_CURSOR_ON 0x02U
-#define HD_DISPCTRL_CURSOR_BLINK 0x01U
-#define HD_CRSR_SHIFT 0x10U
-#define HD_CRSR_SHIFT_DISPLAY 0x08U
-#define HD_CRSR_SHIFT_DISPLAY_RIGHT 0x04U
-#define HD_FUNCSET 0x20U
-#define HD_FUNCSET_8BIT 0x10U
-#define HD_FUNCSET_2_LINES 0x08U
-#define HD_FUNCSET_FONT_5X10 0x04U
-#define HD_SET_CGRAM 0x40U
-#define HD_SET_DDRAM 0x80U
-#define HD_BUSY_FLAG 0x80U
-
-/**
- * @dev: a pointer back to containing device
- * @phybase: the offset to the controller in physical memory
- * @physize: the size of the physical page
- * @virtbase: the offset to the controller in virtual memory
- * @irq: reserved interrupt number
- * @complete: completion structure for the last LCD command
- */
-struct charlcd {
- struct device *dev;
- u32 phybase;
- u32 physize;
- void __iomem *virtbase;
- int irq;
- struct completion complete;
- struct delayed_work init_work;
-};
-
-static irqreturn_t charlcd_interrupt(int irq, void *data)
-{
- struct charlcd *lcd = data;
- u8 status;
-
- status = readl(lcd->virtbase + CHAR_STAT) & 0x01;
- /* Clear IRQ */
- writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW);
- if (status)
- complete(&lcd->complete);
- else
- dev_info(lcd->dev, "Spurious IRQ (%02x)\n", status);
- return IRQ_HANDLED;
-}
-
-
-static void charlcd_wait_complete_irq(struct charlcd *lcd)
-{
- int ret;
-
- ret = wait_for_completion_interruptible_timeout(&lcd->complete,
- CHARLCD_TIMEOUT);
- /* Disable IRQ after completion */
- writel(0x00, lcd->virtbase + CHAR_MASK);
-
- if (ret < 0) {
- dev_err(lcd->dev,
- "wait_for_completion_interruptible_timeout() "
- "returned %d waiting for ready\n", ret);
- return;
- }
-
- if (ret == 0) {
- dev_err(lcd->dev, "charlcd controller timed out "
- "waiting for ready\n");
- return;
- }
-}
-
-static u8 charlcd_4bit_read_char(struct charlcd *lcd)
-{
- u8 data;
- u32 val;
- int i;
-
- /* If we can, use an IRQ to wait for the data, else poll */
- if (lcd->irq >= 0)
- charlcd_wait_complete_irq(lcd);
- else {
- i = 0;
- val = 0;
- while (!(val & CHAR_RAW_VALID) && i < 10) {
- udelay(100);
- val = readl(lcd->virtbase + CHAR_RAW);
- i++;
- }
-
- writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW);
- }
- msleep(1);
-
- /* Read the 4 high bits of the data */
- data = readl(lcd->virtbase + CHAR_RD) & 0xf0;
-
- /*
- * The second read for the low bits does not trigger an IRQ
- * so in this case we have to poll for the 4 lower bits
- */
- i = 0;
- val = 0;
- while (!(val & CHAR_RAW_VALID) && i < 10) {
- udelay(100);
- val = readl(lcd->virtbase + CHAR_RAW);
- i++;
- }
- writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW);
- msleep(1);
-
- /* Read the 4 low bits of the data */
- data |= (readl(lcd->virtbase + CHAR_RD) >> 4) & 0x0f;
-
- return data;
-}
-
-static bool charlcd_4bit_read_bf(struct charlcd *lcd)
-{
- if (lcd->irq >= 0) {
- /*
- * If we'll use IRQs to wait for the busyflag, clear any
- * pending flag and enable IRQ
- */
- writel(CHAR_RAW_CLEAR, lcd->virtbase + CHAR_RAW);
- init_completion(&lcd->complete);
- writel(0x01, lcd->virtbase + CHAR_MASK);
- }
- readl(lcd->virtbase + CHAR_COM);
- return charlcd_4bit_read_char(lcd) & HD_BUSY_FLAG ? true : false;
-}
-
-static void charlcd_4bit_wait_busy(struct charlcd *lcd)
-{
- int retries = 50;
-
- udelay(100);
- while (charlcd_4bit_read_bf(lcd) && retries)
- retries--;
- if (!retries)
- dev_err(lcd->dev, "timeout waiting for busyflag\n");
-}
-
-static void charlcd_4bit_command(struct charlcd *lcd, u8 cmd)
-{
- u32 cmdlo = (cmd << 4) & 0xf0;
- u32 cmdhi = (cmd & 0xf0);
-
- writel(cmdhi, lcd->virtbase + CHAR_COM);
- udelay(10);
- writel(cmdlo, lcd->virtbase + CHAR_COM);
- charlcd_4bit_wait_busy(lcd);
-}
-
-static void charlcd_4bit_char(struct charlcd *lcd, u8 ch)
-{
- u32 chlo = (ch << 4) & 0xf0;
- u32 chhi = (ch & 0xf0);
-
- writel(chhi, lcd->virtbase + CHAR_DAT);
- udelay(10);
- writel(chlo, lcd->virtbase + CHAR_DAT);
- charlcd_4bit_wait_busy(lcd);
-}
-
-static void charlcd_4bit_print(struct charlcd *lcd, int line, const char *str)
-{
- u8 offset;
- int i;
-
- /*
- * We support line 0, 1
- * Line 1 runs from 0x00..0x27
- * Line 2 runs from 0x28..0x4f
- */
- if (line == 0)
- offset = 0;
- else if (line == 1)
- offset = 0x28;
- else
- return;
-
- /* Set offset */
- charlcd_4bit_command(lcd, HD_SET_DDRAM | offset);
-
- /* Send string */
- for (i = 0; i < strlen(str) && i < 0x28; i++)
- charlcd_4bit_char(lcd, str[i]);
-}
-
-static void charlcd_4bit_init(struct charlcd *lcd)
-{
- /* These commands cannot be checked with the busy flag */
- writel(HD_FUNCSET | HD_FUNCSET_8BIT, lcd->virtbase + CHAR_COM);
- msleep(5);
- writel(HD_FUNCSET | HD_FUNCSET_8BIT, lcd->virtbase + CHAR_COM);
- udelay(100);
- writel(HD_FUNCSET | HD_FUNCSET_8BIT, lcd->virtbase + CHAR_COM);
- udelay(100);
- /* Go to 4bit mode */
- writel(HD_FUNCSET, lcd->virtbase + CHAR_COM);
- udelay(100);
- /*
- * 4bit mode, 2 lines, 5x8 font, after this the number of lines
- * and the font cannot be changed until the next initialization sequence
- */
- charlcd_4bit_command(lcd, HD_FUNCSET | HD_FUNCSET_2_LINES);
- charlcd_4bit_command(lcd, HD_DISPCTRL | HD_DISPCTRL_ON);
- charlcd_4bit_command(lcd, HD_ENTRYMODE | HD_ENTRYMODE_INCREMENT);
- charlcd_4bit_command(lcd, HD_CLEAR);
- charlcd_4bit_command(lcd, HD_HOME);
- /* Put something useful in the display */
- charlcd_4bit_print(lcd, 0, "ARM Linux");
- charlcd_4bit_print(lcd, 1, UTS_RELEASE);
-}
-
-static void charlcd_init_work(struct work_struct *work)
-{
- struct charlcd *lcd =
- container_of(work, struct charlcd, init_work.work);
-
- charlcd_4bit_init(lcd);
-}
-
-static int __init charlcd_probe(struct platform_device *pdev)
-{
- int ret;
- struct charlcd *lcd;
- struct resource *res;
-
- lcd = kzalloc(sizeof(struct charlcd), GFP_KERNEL);
- if (!lcd)
- return -ENOMEM;
-
- lcd->dev = &pdev->dev;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- ret = -ENOENT;
- goto out_no_resource;
- }
- lcd->phybase = res->start;
- lcd->physize = resource_size(res);
-
- if (request_mem_region(lcd->phybase, lcd->physize,
- DRIVERNAME) == NULL) {
- ret = -EBUSY;
- goto out_no_memregion;
- }
-
- lcd->virtbase = ioremap(lcd->phybase, lcd->physize);
- if (!lcd->virtbase) {
- ret = -ENOMEM;
- goto out_no_remap;
- }
-
- lcd->irq = platform_get_irq(pdev, 0);
- /* If no IRQ is supplied, we'll survive without it */
- if (lcd->irq >= 0) {
- if (request_irq(lcd->irq, charlcd_interrupt, IRQF_DISABLED,
- DRIVERNAME, lcd)) {
- ret = -EIO;
- goto out_no_irq;
- }
- }
-
- platform_set_drvdata(pdev, lcd);
-
- /*
- * Initialize the display in a delayed work, because
- * it is VERY slow and would slow down the boot of the system.
- */
- INIT_DELAYED_WORK(&lcd->init_work, charlcd_init_work);
- schedule_delayed_work(&lcd->init_work, 0);
-
- dev_info(&pdev->dev, "initialized ARM character LCD at %08x\n",
- lcd->phybase);
-
- return 0;
-
-out_no_irq:
- iounmap(lcd->virtbase);
-out_no_remap:
- platform_set_drvdata(pdev, NULL);
-out_no_memregion:
- release_mem_region(lcd->phybase, SZ_4K);
-out_no_resource:
- kfree(lcd);
- return ret;
-}
-
-static int __exit charlcd_remove(struct platform_device *pdev)
-{
- struct charlcd *lcd = platform_get_drvdata(pdev);
-
- if (lcd) {
- free_irq(lcd->irq, lcd);
- iounmap(lcd->virtbase);
- release_mem_region(lcd->phybase, lcd->physize);
- platform_set_drvdata(pdev, NULL);
- kfree(lcd);
- }
-
- return 0;
-}
-
-static int charlcd_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct charlcd *lcd = platform_get_drvdata(pdev);
-
- /* Power the display off */
- charlcd_4bit_command(lcd, HD_DISPCTRL);
- return 0;
-}
-
-static int charlcd_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct charlcd *lcd = platform_get_drvdata(pdev);
-
- /* Turn the display back on */
- charlcd_4bit_command(lcd, HD_DISPCTRL | HD_DISPCTRL_ON);
- return 0;
-}
-
-static const struct dev_pm_ops charlcd_pm_ops = {
- .suspend = charlcd_suspend,
- .resume = charlcd_resume,
-};
-
-static struct platform_driver charlcd_driver = {
- .driver = {
- .name = DRIVERNAME,
- .owner = THIS_MODULE,
- .pm = &charlcd_pm_ops,
- },
- .remove = __exit_p(charlcd_remove),
-};
-
-static int __init charlcd_init(void)
-{
- return platform_driver_probe(&charlcd_driver, charlcd_probe);
-}
-
-static void __exit charlcd_exit(void)
-{
- platform_driver_unregister(&charlcd_driver);
-}
-
-module_init(charlcd_init);
-module_exit(charlcd_exit);
-
-MODULE_AUTHOR("Linus Walleij <triad@df.lth.se>");
-MODULE_DESCRIPTION("ARM Character LCD Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/misc/atmel-ssc.c b/ANDROID_3.4.5/drivers/misc/atmel-ssc.c
deleted file mode 100644
index 5bb18778..00000000
--- a/ANDROID_3.4.5/drivers/misc/atmel-ssc.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Atmel SSC driver
- *
- * Copyright (C) 2007 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/list.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <linux/atmel-ssc.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-/* Serialize access to ssc_list and user count */
-static DEFINE_SPINLOCK(user_lock);
-static LIST_HEAD(ssc_list);
-
-struct ssc_device *ssc_request(unsigned int ssc_num)
-{
- int ssc_valid = 0;
- struct ssc_device *ssc;
-
- spin_lock(&user_lock);
- list_for_each_entry(ssc, &ssc_list, list) {
- if (ssc->pdev->id == ssc_num) {
- ssc_valid = 1;
- break;
- }
- }
-
- if (!ssc_valid) {
- spin_unlock(&user_lock);
- pr_err("ssc: ssc%d platform device is missing\n", ssc_num);
- return ERR_PTR(-ENODEV);
- }
-
- if (ssc->user) {
- spin_unlock(&user_lock);
- dev_dbg(&ssc->pdev->dev, "module busy\n");
- return ERR_PTR(-EBUSY);
- }
- ssc->user++;
- spin_unlock(&user_lock);
-
- clk_enable(ssc->clk);
-
- return ssc;
-}
-EXPORT_SYMBOL(ssc_request);
-
-void ssc_free(struct ssc_device *ssc)
-{
- spin_lock(&user_lock);
- if (ssc->user) {
- ssc->user--;
- clk_disable(ssc->clk);
- } else {
- dev_dbg(&ssc->pdev->dev, "device already free\n");
- }
- spin_unlock(&user_lock);
-}
-EXPORT_SYMBOL(ssc_free);
-
-static int __init ssc_probe(struct platform_device *pdev)
-{
- int retval = 0;
- struct resource *regs;
- struct ssc_device *ssc;
-
- ssc = kzalloc(sizeof(struct ssc_device), GFP_KERNEL);
- if (!ssc) {
- dev_dbg(&pdev->dev, "out of memory\n");
- retval = -ENOMEM;
- goto out;
- }
-
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
- dev_dbg(&pdev->dev, "no mmio resource defined\n");
- retval = -ENXIO;
- goto out_free;
- }
-
- ssc->clk = clk_get(&pdev->dev, "pclk");
- if (IS_ERR(ssc->clk)) {
- dev_dbg(&pdev->dev, "no pclk clock defined\n");
- retval = -ENXIO;
- goto out_free;
- }
-
- ssc->pdev = pdev;
- ssc->regs = ioremap(regs->start, resource_size(regs));
- if (!ssc->regs) {
- dev_dbg(&pdev->dev, "ioremap failed\n");
- retval = -EINVAL;
- goto out_clk;
- }
-
- /* disable all interrupts */
- clk_enable(ssc->clk);
- ssc_writel(ssc->regs, IDR, ~0UL);
- ssc_readl(ssc->regs, SR);
- clk_disable(ssc->clk);
-
- ssc->irq = platform_get_irq(pdev, 0);
- if (!ssc->irq) {
- dev_dbg(&pdev->dev, "could not get irq\n");
- retval = -ENXIO;
- goto out_unmap;
- }
-
- spin_lock(&user_lock);
- list_add_tail(&ssc->list, &ssc_list);
- spin_unlock(&user_lock);
-
- platform_set_drvdata(pdev, ssc);
-
- dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n",
- ssc->regs, ssc->irq);
-
- goto out;
-
-out_unmap:
- iounmap(ssc->regs);
-out_clk:
- clk_put(ssc->clk);
-out_free:
- kfree(ssc);
-out:
- return retval;
-}
-
-static int __devexit ssc_remove(struct platform_device *pdev)
-{
- struct ssc_device *ssc = platform_get_drvdata(pdev);
-
- spin_lock(&user_lock);
- iounmap(ssc->regs);
- clk_put(ssc->clk);
- list_del(&ssc->list);
- kfree(ssc);
- spin_unlock(&user_lock);
-
- return 0;
-}
-
-static struct platform_driver ssc_driver = {
- .remove = __devexit_p(ssc_remove),
- .driver = {
- .name = "ssc",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init ssc_init(void)
-{
- return platform_driver_probe(&ssc_driver, ssc_probe);
-}
-module_init(ssc_init);
-
-static void __exit ssc_exit(void)
-{
- platform_driver_unregister(&ssc_driver);
-}
-module_exit(ssc_exit);
-
-MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
-MODULE_DESCRIPTION("SSC driver for Atmel AVR32 and AT91");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ssc");
diff --git a/ANDROID_3.4.5/drivers/misc/atmel_pwm.c b/ANDROID_3.4.5/drivers/misc/atmel_pwm.c
deleted file mode 100644
index 28f5aaa1..00000000
--- a/ANDROID_3.4.5/drivers/misc/atmel_pwm.c
+++ /dev/null
@@ -1,410 +0,0 @@
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/atmel_pwm.h>
-
-
-/*
- * This is a simple driver for the PWM controller found in various newer
- * Atmel SOCs, including the AVR32 series and the AT91sam9263.
- *
- * Chips with current Linux ports have only 4 PWM channels, out of max 32.
- * AT32UC3A and AT32UC3B chips have 7 channels (but currently no Linux).
- * Docs are inconsistent about the width of the channel counter registers;
- * it's at least 16 bits, but several places say 20 bits.
- */
-#define PWM_NCHAN 4 /* max 32 */
-
-struct pwm {
- spinlock_t lock;
- struct platform_device *pdev;
- u32 mask;
- int irq;
- void __iomem *base;
- struct clk *clk;
- struct pwm_channel *channel[PWM_NCHAN];
- void (*handler[PWM_NCHAN])(struct pwm_channel *);
-};
-
-
-/* global PWM controller registers */
-#define PWM_MR 0x00
-#define PWM_ENA 0x04
-#define PWM_DIS 0x08
-#define PWM_SR 0x0c
-#define PWM_IER 0x10
-#define PWM_IDR 0x14
-#define PWM_IMR 0x18
-#define PWM_ISR 0x1c
-
-static inline void pwm_writel(const struct pwm *p, unsigned offset, u32 val)
-{
- __raw_writel(val, p->base + offset);
-}
-
-static inline u32 pwm_readl(const struct pwm *p, unsigned offset)
-{
- return __raw_readl(p->base + offset);
-}
-
-static inline void __iomem *pwmc_regs(const struct pwm *p, int index)
-{
- return p->base + 0x200 + index * 0x20;
-}
-
-static struct pwm *pwm;
-
-static void pwm_dumpregs(struct pwm_channel *ch, char *tag)
-{
- struct device *dev = &pwm->pdev->dev;
-
- dev_dbg(dev, "%s: mr %08x, sr %08x, imr %08x\n",
- tag,
- pwm_readl(pwm, PWM_MR),
- pwm_readl(pwm, PWM_SR),
- pwm_readl(pwm, PWM_IMR));
- dev_dbg(dev,
- "pwm ch%d - mr %08x, dty %u, prd %u, cnt %u\n",
- ch->index,
- pwm_channel_readl(ch, PWM_CMR),
- pwm_channel_readl(ch, PWM_CDTY),
- pwm_channel_readl(ch, PWM_CPRD),
- pwm_channel_readl(ch, PWM_CCNT));
-}
-
-
-/**
- * pwm_channel_alloc - allocate an unused PWM channel
- * @index: identifies the channel
- * @ch: structure to be initialized
- *
- * Drivers allocate PWM channels according to the board's wiring, and
- * matching board-specific setup code. Returns zero or negative errno.
- */
-int pwm_channel_alloc(int index, struct pwm_channel *ch)
-{
- unsigned long flags;
- int status = 0;
-
- /* insist on PWM init, with this signal pinned out */
- if (!pwm || !(pwm->mask & 1 << index))
- return -ENODEV;
-
- if (index < 0 || index >= PWM_NCHAN || !ch)
- return -EINVAL;
- memset(ch, 0, sizeof *ch);
-
- spin_lock_irqsave(&pwm->lock, flags);
- if (pwm->channel[index])
- status = -EBUSY;
- else {
- clk_enable(pwm->clk);
-
- ch->regs = pwmc_regs(pwm, index);
- ch->index = index;
-
- /* REVISIT: ap7000 seems to go 2x as fast as we expect!! */
- ch->mck = clk_get_rate(pwm->clk);
-
- pwm->channel[index] = ch;
- pwm->handler[index] = NULL;
-
- /* channel and irq are always disabled when we return */
- pwm_writel(pwm, PWM_DIS, 1 << index);
- pwm_writel(pwm, PWM_IDR, 1 << index);
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
- return status;
-}
-EXPORT_SYMBOL(pwm_channel_alloc);
-
-static int pwmcheck(struct pwm_channel *ch)
-{
- int index;
-
- if (!pwm)
- return -ENODEV;
- if (!ch)
- return -EINVAL;
- index = ch->index;
- if (index < 0 || index >= PWM_NCHAN || pwm->channel[index] != ch)
- return -EINVAL;
-
- return index;
-}
-
-/**
- * pwm_channel_free - release a previously allocated channel
- * @ch: the channel being released
- *
- * The channel is completely shut down (counter and IRQ disabled),
- * and made available for re-use. Returns zero, or negative errno.
- */
-int pwm_channel_free(struct pwm_channel *ch)
-{
- unsigned long flags;
- int t;
-
- spin_lock_irqsave(&pwm->lock, flags);
- t = pwmcheck(ch);
- if (t >= 0) {
- pwm->channel[t] = NULL;
- pwm->handler[t] = NULL;
-
- /* channel and irq are always disabled when we return */
- pwm_writel(pwm, PWM_DIS, 1 << t);
- pwm_writel(pwm, PWM_IDR, 1 << t);
-
- clk_disable(pwm->clk);
- t = 0;
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
- return t;
-}
-EXPORT_SYMBOL(pwm_channel_free);
-
-int __pwm_channel_onoff(struct pwm_channel *ch, int enabled)
-{
- unsigned long flags;
- int t;
-
- /* OMITTED FUNCTIONALITY: starting several channels in synch */
-
- spin_lock_irqsave(&pwm->lock, flags);
- t = pwmcheck(ch);
- if (t >= 0) {
- pwm_writel(pwm, enabled ? PWM_ENA : PWM_DIS, 1 << t);
- t = 0;
- pwm_dumpregs(ch, enabled ? "enable" : "disable");
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
-
- return t;
-}
-EXPORT_SYMBOL(__pwm_channel_onoff);
-
-/**
- * pwm_clk_alloc - allocate and configure CLKA or CLKB
- * @prescale: from 0..10, the power of two used to divide MCK
- * @div: from 1..255, the linear divisor to use
- *
- * Returns PWM_CPR_CLKA, PWM_CPR_CLKB, or negative errno. The allocated
- * clock will run with a period of (2^prescale * div) / MCK, or twice as
- * long if center aligned PWM output is used. The clock must later be
- * deconfigured using pwm_clk_free().
- */
-int pwm_clk_alloc(unsigned prescale, unsigned div)
-{
- unsigned long flags;
- u32 mr;
- u32 val = (prescale << 8) | div;
- int ret = -EBUSY;
-
- if (prescale >= 10 || div == 0 || div > 255)
- return -EINVAL;
-
- spin_lock_irqsave(&pwm->lock, flags);
- mr = pwm_readl(pwm, PWM_MR);
- if ((mr & 0xffff) == 0) {
- mr |= val;
- ret = PWM_CPR_CLKA;
- } else if ((mr & (0xffff << 16)) == 0) {
- mr |= val << 16;
- ret = PWM_CPR_CLKB;
- }
- if (ret > 0)
- pwm_writel(pwm, PWM_MR, mr);
- spin_unlock_irqrestore(&pwm->lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(pwm_clk_alloc);
-
-/**
- * pwm_clk_free - deconfigure and release CLKA or CLKB
- *
- * Reverses the effect of pwm_clk_alloc().
- */
-void pwm_clk_free(unsigned clk)
-{
- unsigned long flags;
- u32 mr;
-
- spin_lock_irqsave(&pwm->lock, flags);
- mr = pwm_readl(pwm, PWM_MR);
- if (clk == PWM_CPR_CLKA)
- pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 0));
- if (clk == PWM_CPR_CLKB)
- pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 16));
- spin_unlock_irqrestore(&pwm->lock, flags);
-}
-EXPORT_SYMBOL(pwm_clk_free);
-
-/**
- * pwm_channel_handler - manage channel's IRQ handler
- * @ch: the channel
- * @handler: the handler to use, possibly NULL
- *
- * If the handler is non-null, the handler will be called after every
- * period of this PWM channel. If the handler is null, this channel
- * won't generate an IRQ.
- */
-int pwm_channel_handler(struct pwm_channel *ch,
- void (*handler)(struct pwm_channel *ch))
-{
- unsigned long flags;
- int t;
-
- spin_lock_irqsave(&pwm->lock, flags);
- t = pwmcheck(ch);
- if (t >= 0) {
- pwm->handler[t] = handler;
- pwm_writel(pwm, handler ? PWM_IER : PWM_IDR, 1 << t);
- t = 0;
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
-
- return t;
-}
-EXPORT_SYMBOL(pwm_channel_handler);
-
-static irqreturn_t pwm_irq(int id, void *_pwm)
-{
- struct pwm *p = _pwm;
- irqreturn_t handled = IRQ_NONE;
- u32 irqstat;
- int index;
-
- spin_lock(&p->lock);
-
- /* ack irqs, then handle them */
- irqstat = pwm_readl(pwm, PWM_ISR);
-
- while (irqstat) {
- struct pwm_channel *ch;
- void (*handler)(struct pwm_channel *ch);
-
- index = ffs(irqstat) - 1;
- irqstat &= ~(1 << index);
- ch = pwm->channel[index];
- handler = pwm->handler[index];
- if (handler && ch) {
- spin_unlock(&p->lock);
- handler(ch);
- spin_lock(&p->lock);
- handled = IRQ_HANDLED;
- }
- }
-
- spin_unlock(&p->lock);
- return handled;
-}
-
-static int __init pwm_probe(struct platform_device *pdev)
-{
- struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- int irq = platform_get_irq(pdev, 0);
- u32 *mp = pdev->dev.platform_data;
- struct pwm *p;
- int status = -EIO;
-
- if (pwm)
- return -EBUSY;
- if (!r || irq < 0 || !mp || !*mp)
- return -ENODEV;
- if (*mp & ~((1<<PWM_NCHAN)-1)) {
- dev_warn(&pdev->dev, "mask 0x%x ... more than %d channels\n",
- *mp, PWM_NCHAN);
- return -EINVAL;
- }
-
- p = kzalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
-
- spin_lock_init(&p->lock);
- p->pdev = pdev;
- p->mask = *mp;
- p->irq = irq;
- p->base = ioremap(r->start, resource_size(r));
- if (!p->base)
- goto fail;
- p->clk = clk_get(&pdev->dev, "pwm_clk");
- if (IS_ERR(p->clk)) {
- status = PTR_ERR(p->clk);
- p->clk = NULL;
- goto fail;
- }
-
- status = request_irq(irq, pwm_irq, 0, pdev->name, p);
- if (status < 0)
- goto fail;
-
- pwm = p;
- platform_set_drvdata(pdev, p);
-
- return 0;
-
-fail:
- if (p->clk)
- clk_put(p->clk);
- if (p->base)
- iounmap(p->base);
-
- kfree(p);
- return status;
-}
-
-static int __exit pwm_remove(struct platform_device *pdev)
-{
- struct pwm *p = platform_get_drvdata(pdev);
-
- if (p != pwm)
- return -EINVAL;
-
- clk_enable(pwm->clk);
- pwm_writel(pwm, PWM_DIS, (1 << PWM_NCHAN) - 1);
- pwm_writel(pwm, PWM_IDR, (1 << PWM_NCHAN) - 1);
- clk_disable(pwm->clk);
-
- pwm = NULL;
-
- free_irq(p->irq, p);
- clk_put(p->clk);
- iounmap(p->base);
- kfree(p);
-
- return 0;
-}
-
-static struct platform_driver atmel_pwm_driver = {
- .driver = {
- .name = "atmel_pwm",
- .owner = THIS_MODULE,
- },
- .remove = __exit_p(pwm_remove),
-
- /* NOTE: PWM can keep running in AVR32 "idle" and "frozen" states;
- * and all AT91sam9263 states, albeit at reduced clock rate if
- * MCK becomes the slow clock (i.e. what Linux labels STR).
- */
-};
-
-static int __init pwm_init(void)
-{
- return platform_driver_probe(&atmel_pwm_driver, pwm_probe);
-}
-module_init(pwm_init);
-
-static void __exit pwm_exit(void)
-{
- platform_driver_unregister(&atmel_pwm_driver);
-}
-module_exit(pwm_exit);
-
-MODULE_DESCRIPTION("Driver for AT32/AT91 PWM module");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:atmel_pwm");
diff --git a/ANDROID_3.4.5/drivers/misc/atmel_tclib.c b/ANDROID_3.4.5/drivers/misc/atmel_tclib.c
deleted file mode 100644
index c8d8e38d..00000000
--- a/ANDROID_3.4.5/drivers/misc/atmel_tclib.c
+++ /dev/null
@@ -1,207 +0,0 @@
-#include <linux/atmel_tc.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/of.h>
-
-/*
- * This is a thin library to solve the problem of how to portably allocate
- * one of the TC blocks. For simplicity, it doesn't currently expect to
- * share individual timers between different drivers.
- */
-
-#if defined(CONFIG_AVR32)
-/* AVR32 has these divide PBB */
-const u8 atmel_tc_divisors[5] = { 0, 4, 8, 16, 32, };
-EXPORT_SYMBOL(atmel_tc_divisors);
-
-#elif defined(CONFIG_ARCH_AT91)
-/* AT91 has these divide MCK */
-const u8 atmel_tc_divisors[5] = { 2, 8, 32, 128, 0, };
-EXPORT_SYMBOL(atmel_tc_divisors);
-
-#endif
-
-static DEFINE_SPINLOCK(tc_list_lock);
-static LIST_HEAD(tc_list);
-
-/**
- * atmel_tc_alloc - allocate a specified TC block
- * @block: which block to allocate
- * @name: name to be associated with the iomem resource
- *
- * Caller allocates a block. If it is available, a pointer to a
- * pre-initialized struct atmel_tc is returned. The caller can access
- * the registers directly through the "regs" field.
- */
-struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name)
-{
- struct atmel_tc *tc;
- struct platform_device *pdev = NULL;
- struct resource *r;
- size_t size;
-
- spin_lock(&tc_list_lock);
- list_for_each_entry(tc, &tc_list, node) {
- if (tc->pdev->dev.of_node) {
- if (of_alias_get_id(tc->pdev->dev.of_node, "tcb")
- == block) {
- pdev = tc->pdev;
- break;
- }
- } else if (tc->pdev->id == block) {
- pdev = tc->pdev;
- break;
- }
- }
-
- if (!pdev || tc->iomem)
- goto fail;
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!r)
- goto fail;
-
- size = resource_size(r);
- r = request_mem_region(r->start, size, name);
- if (!r)
- goto fail;
-
- tc->regs = ioremap(r->start, size);
- if (!tc->regs)
- goto fail_ioremap;
-
- tc->iomem = r;
-
-out:
- spin_unlock(&tc_list_lock);
- return tc;
-
-fail_ioremap:
- release_mem_region(r->start, size);
-fail:
- tc = NULL;
- goto out;
-}
-EXPORT_SYMBOL_GPL(atmel_tc_alloc);
-
-/**
- * atmel_tc_free - release a specified TC block
- * @tc: Timer/counter block that was returned by atmel_tc_alloc()
- *
- * This reverses the effect of atmel_tc_alloc(), unmapping the I/O
- * registers, invalidating the resource returned by that routine and
- * making the TC available to other drivers.
- */
-void atmel_tc_free(struct atmel_tc *tc)
-{
- spin_lock(&tc_list_lock);
- if (tc->regs) {
- iounmap(tc->regs);
- release_mem_region(tc->iomem->start, resource_size(tc->iomem));
- tc->regs = NULL;
- tc->iomem = NULL;
- }
- spin_unlock(&tc_list_lock);
-}
-EXPORT_SYMBOL_GPL(atmel_tc_free);
-
-#if defined(CONFIG_OF)
-static struct atmel_tcb_config tcb_rm9200_config = {
- .counter_width = 16,
-};
-
-static struct atmel_tcb_config tcb_sam9x5_config = {
- .counter_width = 32,
-};
-
-static const struct of_device_id atmel_tcb_dt_ids[] = {
- {
- .compatible = "atmel,at91rm9200-tcb",
- .data = &tcb_rm9200_config,
- }, {
- .compatible = "atmel,at91sam9x5-tcb",
- .data = &tcb_sam9x5_config,
- }, {
- /* sentinel */
- }
-};
-
-MODULE_DEVICE_TABLE(of, atmel_tcb_dt_ids);
-#endif
-
-static int __init tc_probe(struct platform_device *pdev)
-{
- struct atmel_tc *tc;
- struct clk *clk;
- int irq;
-
- if (!platform_get_resource(pdev, IORESOURCE_MEM, 0))
- return -EINVAL;
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return -EINVAL;
-
- tc = kzalloc(sizeof(struct atmel_tc), GFP_KERNEL);
- if (!tc)
- return -ENOMEM;
-
- tc->pdev = pdev;
-
- clk = clk_get(&pdev->dev, "t0_clk");
- if (IS_ERR(clk)) {
- kfree(tc);
- return -EINVAL;
- }
-
- /* Now take SoC information if available */
- if (pdev->dev.of_node) {
- const struct of_device_id *match;
- match = of_match_node(atmel_tcb_dt_ids, pdev->dev.of_node);
- if (match)
- tc->tcb_config = match->data;
- }
-
- tc->clk[0] = clk;
- tc->clk[1] = clk_get(&pdev->dev, "t1_clk");
- if (IS_ERR(tc->clk[1]))
- tc->clk[1] = clk;
- tc->clk[2] = clk_get(&pdev->dev, "t2_clk");
- if (IS_ERR(tc->clk[2]))
- tc->clk[2] = clk;
-
- tc->irq[0] = irq;
- tc->irq[1] = platform_get_irq(pdev, 1);
- if (tc->irq[1] < 0)
- tc->irq[1] = irq;
- tc->irq[2] = platform_get_irq(pdev, 2);
- if (tc->irq[2] < 0)
- tc->irq[2] = irq;
-
- spin_lock(&tc_list_lock);
- list_add_tail(&tc->node, &tc_list);
- spin_unlock(&tc_list_lock);
-
- return 0;
-}
-
-static struct platform_driver tc_driver = {
- .driver = {
- .name = "atmel_tcb",
- .of_match_table = of_match_ptr(atmel_tcb_dt_ids),
- },
-};
-
-static int __init tc_init(void)
-{
- return platform_driver_probe(&tc_driver, tc_probe);
-}
-arch_initcall(tc_init);
diff --git a/ANDROID_3.4.5/drivers/misc/bcm2079x-i2c.c b/ANDROID_3.4.5/drivers/misc/bcm2079x-i2c.c
deleted file mode 100644
index 34f15cdf..00000000
--- a/ANDROID_3.4.5/drivers/misc/bcm2079x-i2c.c
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * Copyright (C) 2012 Broadcom Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <linux/jiffies.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/poll.h>
-#include <linux/version.h>
-
-//Platform specific
-#include <mach/gpio.h>
-#include <mach/wmt_iomux.h>
-#include <mach/hardware.h>
-#include <mach/wmt_pmc.h>
-
-//#include <mach/sys_config.h>
-//Platform specific
-#include <linux/nfc/bcm2079x.h>
-
-#define USE_WAKE_LOCK
-
-#ifdef USE_WAKE_LOCK
-#include <linux/wakelock.h>
-#endif
-
-#define TRUE 1
-#define FALSE 0
-#define STATE_HIGH 1
-#define STATE_LOW 0
-
-unsigned int enable;
-
-
-/* end of compile options */
-
-/* do not change below */
-#define MAX_BUFFER_SIZE 780
-
- /* Read data */
-#define PACKET_HEADER_SIZE_NCI (4)
-#define PACKET_HEADER_SIZE_HCI (3)
-#define PACKET_TYPE_NCI (16)
-#define PACKET_TYPE_HCIEV (4)
-#define MAX_PACKET_SIZE (PACKET_HEADER_SIZE_NCI + 255)
-
-#define CLIENT_ADDR 0x77
-#define WMT_BCM2079X_I2C_CHANNEL 3
-struct i2c_client *bcm2079x_client;
-
-
-struct bcm2079x_dev {
- wait_queue_head_t read_wq;
- struct mutex read_mutex;
- struct i2c_client *client;
- struct miscdevice bcm2079x_device;
- unsigned int wake_gpio;
- unsigned int en_gpio;
- unsigned int irq_gpio;
- unsigned int irq_no;
- bool irq_enabled;
- spinlock_t irq_enabled_lock;
- unsigned int error_write;
- unsigned int error_read;
- unsigned int count_read;
- unsigned int count_irq;
- int original_address;
-#ifdef USE_WAKE_LOCK
- struct wake_lock wake_lock;
-#endif
-};
-
-#define BCM2079X_NAME "bcm2079x-i2c"
-#define VERSION "AMPAK-BCM2079X-DRIVER-VERSION-1.0.0"
-unsigned int nfc_handle = -1;
-unsigned int bcm2079x_irq_handle(void *para);
-
-/*hang on i2c bus no.3*/
-static __u32 twi_id = 3;
-
-static struct bcm2079x_platform_data bcm2079x_pdata = {
- .irq_gpio = WMT_PIN_GP62_WAKEUP3,//GPIOG(11), //NFC_IRQ, GPIOG(11)
- .irq_no = IRQ_PMC_WAKEUP,
- .en_gpio = WMT_PIN_GP62_SUSGPIO0,//GPIOM(5), //NFC_EN, GPIOM(5)
- .wake_gpio = WMT_PIN_GP1_GPIO9,//GPIOG(10), //NFC_FIRM,
-};
-
-int bcm2079x_detect(struct i2c_client *client, struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
-
- if(twi_id == adapter->nr)
- {
- dev_info(&client->dev, "%s: Detected chip %s at adapter %d, address 0x%02x\n",\
- __func__, BCM2079X_NAME, i2c_adapter_id(adapter), client->addr);
- strlcpy(info->type, BCM2079X_NAME, I2C_NAME_SIZE);
- info->platform_data = &bcm2079x_pdata;
- return 0;
- }else{
- return -ENODEV;
- }
-}
-
-static void bcm2079x_init_stat(struct bcm2079x_dev *bcm2079x_dev)
-{
- bcm2079x_dev->error_write = 0;
- bcm2079x_dev->error_read = 0;
- bcm2079x_dev->count_read = 0;
- bcm2079x_dev->count_irq = 0;
-}
-
-static void bcm2079x_disable_irq(struct bcm2079x_dev *bcm2079x_dev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&bcm2079x_dev->irq_enabled_lock, flags);
- if (bcm2079x_dev->irq_enabled) {
- pmc_disable_wakeup_isr(WKS_WK3);//disable_irq_nosync(bcm2079x_dev->client->irq);
- bcm2079x_dev->irq_enabled = false;
- }
- spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
-}
-
-static void bcm2079x_enable_irq(struct bcm2079x_dev *bcm2079x_dev)
-{
- unsigned long flags;
- spin_lock_irqsave(&bcm2079x_dev->irq_enabled_lock, flags);
- if (!bcm2079x_dev->irq_enabled) {
- bcm2079x_dev->irq_enabled = true;
- pmc_enable_wakeup_isr(WKS_WK3,3);//enable_irq(bcm2079x_dev->client->irq);
- }
- spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
-}
-
-/*
- The alias address 0x79, when sent as a 7-bit address from the host processor
- will match the first byte (highest 2 bits) of the default client address
- (0x1FA) that is programmed in bcm20791.
- When used together with the first byte (0xFA) of the byte sequence below,
- it can be used to address the bcm20791 in a system that does not support
- 10-bit address and change the default address to 0x38.
- the new address can be changed by changing the CLIENT_ADDRESS below if 0x38
- conflicts with other device on the same i2c bus.
- */
-#define ALIAS_ADDRESS 0x79
-
-static void set_client_addr(struct bcm2079x_dev *bcm2079x_dev, int addr)
-{
- struct i2c_client *client = bcm2079x_dev->client;
- client->addr = addr;
- if (addr > 0x7F)
- client->flags |= I2C_CLIENT_TEN;
- else
- client->flags &= ~I2C_CLIENT_TEN;
-
- dev_info(&client->dev,
- "Set client device changed to (0x%04X) flag = %04x\n",
- client->addr, client->flags);
-}
-
-static void change_client_addr(struct bcm2079x_dev *bcm2079x_dev, int addr)
-{
- struct i2c_client *client;
- int ret;
- int i;
- int offset = 1;
- char addr_data[] = {
- 0xFA, 0xF2, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x2A
- };
-
- client = bcm2079x_dev->client;
- if ((client->flags & I2C_CLIENT_TEN) == I2C_CLIENT_TEN) {
- client->addr = ALIAS_ADDRESS;
- client->flags &= ~I2C_CLIENT_TEN;
- offset = 0;
- }
-
- addr_data[5] = addr & 0xFF;
- ret = 0;
- for (i = 1; i < sizeof(addr_data) - 1; ++i)
- ret += addr_data[i];
- addr_data[sizeof(addr_data) - 1] = (ret & 0xFF);
- dev_info(&client->dev,
- "Change client device from (0x%04X) flag = "\
- "%04x, addr_data[%d] = %02x\n",
- client->addr, client->flags, sizeof(addr_data) - 1,
- addr_data[sizeof(addr_data) - 1]);
- ret = i2c_master_send(client, addr_data+offset, sizeof(addr_data)-offset);
- if (ret != sizeof(addr_data)-offset) {
- client->addr = ALIAS_ADDRESS;
- client->flags &= ~I2C_CLIENT_TEN;
- dev_info(&client->dev,
- "Change client device from (0x%04X) flag = "\
- "%04x, addr_data[%d] = %02x\n",
- client->addr, client->flags, sizeof(addr_data) - 1,
- addr_data[sizeof(addr_data) - 1]);
- ret = i2c_master_send(client, addr_data, sizeof(addr_data));
- }
- client->addr = addr_data[5];
-
- dev_info(&client->dev,
- "Change client device changed to (0x%04X) flag = %04x, ret = %d\n",
- client->addr, client->flags, ret);
-}
-
-static irqreturn_t bcm2079x_dev_irq_handler(int irq, void *dev_id)
-{
- struct bcm2079x_dev *bcm2079x_dev = dev_id;
- unsigned long flags;
- //unsigned int status_i;
-
- //status_i = PMCIS_VAL;
-
- //rmb();
- if(bcm2079x_dev->client == bcm2079x_client){
- if(enable){
- #ifdef USE_WAKE_LOCK
- int wakelockcnt = 0;
- if(! (wakelockcnt = wake_lock_active(&bcm2079x_dev->wake_lock )))
- {
- printk("irq aquire wake lock\n");
- wake_lock(&bcm2079x_dev->wake_lock);
- }else
- {
- // printk("irq wake lock count = %d\n", wakelockcnt);
- }
- //printk("irq handler ( wake lock %d)...\n", wakelockcnt);
- #endif
-
- spin_lock_irqsave(&bcm2079x_dev->irq_enabled_lock, flags);
- bcm2079x_dev->count_irq++;
- spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
- wake_up(&bcm2079x_dev->read_wq);
- }
- pmc_clear_intr_status(WKS_WK3);
- return IRQ_HANDLED;
- }
- else
- return IRQ_NONE;
-}
-
-static unsigned int bcm2079x_dev_poll(struct file *filp, poll_table *wait)
-{
- struct bcm2079x_dev *bcm2079x_dev = filp->private_data;
- unsigned int mask = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&bcm2079x_dev->irq_enabled_lock, flags);
- //if(!gpio_get_value(bcm2079x_dev->irq_gpio) && (bcm2079x_dev->count_irq < 1) )
- //Platform specific API
- if(!__gpio_get_value(bcm2079x_dev->irq_gpio) && (bcm2079x_dev->count_irq < 1) )
- {
- spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
- printk("poll wait, irq count %d, irq_gpio %d\n", bcm2079x_dev->count_irq, bcm2079x_dev->irq_gpio );
- poll_wait(filp, &bcm2079x_dev->read_wq, wait);
- }else
- {
- if (bcm2079x_dev->count_irq < 1)
- bcm2079x_dev->count_irq = 1;
-
- spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
- printk("poll there is data to read!!! no wait any more.\n");
- return (POLLIN | POLLRDNORM);
- }
-
- spin_lock_irqsave(&bcm2079x_dev->irq_enabled_lock, flags);
- if (bcm2079x_dev->count_irq > 0)
- mask |= POLLIN | POLLRDNORM;
- spin_unlock_irqrestore(&bcm2079x_dev->irq_enabled_lock, flags);
-
- return mask;
-}
-
-static ssize_t bcm2079x_dev_read(struct file *filp, char __user *buf,
- size_t count, loff_t *offset)
-{
- struct bcm2079x_dev *bcm2079x_dev = filp->private_data;
- unsigned char tmp[MAX_BUFFER_SIZE];
- int total, len, ret;
-
- total = 0;
- len = 0;
-
- if (bcm2079x_dev->count_irq > 0)
- bcm2079x_dev->count_irq--;
-
- bcm2079x_dev->count_read++;
- if (count > MAX_BUFFER_SIZE)
- count = MAX_BUFFER_SIZE;
-
- mutex_lock(&bcm2079x_dev->read_mutex);
-
- /** Read the first 4 bytes to include the length of the NCI or HCI packet.
- **/
- ret = i2c_master_recv(bcm2079x_dev->client, tmp, 4);
- if (ret == 4) {
- total = ret;
- /** First byte is the packet type
- **/
- switch(tmp[0]) {
- case PACKET_TYPE_NCI:
- len = tmp[PACKET_HEADER_SIZE_NCI-1];
- break;
-
- case PACKET_TYPE_HCIEV:
- len = tmp[PACKET_HEADER_SIZE_HCI-1];
- if (len == 0)
- total--; /*Since payload is 0, decrement total size (from 4 to 3) */
- else
- len--; /*First byte of payload is in tmp[3] already */
- break;
-
- default:
- len = 0; /*Unknown packet byte */
- break;
- } /* switch*/
-
- /** make sure full packet fits in the buffer
- **/
- if (len > 0 && (len + total) <= count) {
- /** read the remainder of the packet.
- **/
- ret = i2c_master_recv(bcm2079x_dev->client, tmp+total, len);
- if (ret == len)
- total += len;
- } /* if */
- } /* if */
-
- mutex_unlock(&bcm2079x_dev->read_mutex);
-
- if (total > count || copy_to_user(buf, tmp, total)) {
- dev_err(&bcm2079x_dev->client->dev,
- "failed to copy to user space, total = %d\n", total);
- total = -EFAULT;
- bcm2079x_dev->error_read++;
- }
-
- return total;
-}
-
-static ssize_t bcm2079x_dev_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *offset)
-{
- struct bcm2079x_dev *bcm2079x_dev = filp->private_data;
- char tmp[MAX_BUFFER_SIZE];
- int ret;
-
- if (count > MAX_BUFFER_SIZE) {
- dev_err(&bcm2079x_dev->client->dev, "out of memory\n");
- return -ENOMEM;
- }
-
- if (copy_from_user(tmp, buf, count)) {
- dev_err(&bcm2079x_dev->client->dev,
- "failed to copy from user space\n");
- return -EFAULT;
- }
-
- mutex_lock(&bcm2079x_dev->read_mutex);
- /* Write data */
-
- ret = i2c_master_send(bcm2079x_dev->client, tmp, count);
- if (ret != count) {
- if ((bcm2079x_dev->client->flags & I2C_CLIENT_TEN) != I2C_CLIENT_TEN && bcm2079x_dev->error_write == 0) {
- set_client_addr(bcm2079x_dev, 0x1FA);
- ret = i2c_master_send(bcm2079x_dev->client, tmp, count);
- if (ret != count)
- bcm2079x_dev->error_write++;
- set_client_addr(bcm2079x_dev, bcm2079x_dev->original_address);
- } else {
- dev_err(&bcm2079x_dev->client->dev,
- "failed to write %d\n", ret);
- ret = -EIO;
- bcm2079x_dev->error_write++;
- }
- }
- mutex_unlock(&bcm2079x_dev->read_mutex);
-
- return ret;
-}
-
-static int bcm2079x_dev_open(struct inode *inode, struct file *filp)
-{
- int ret = 0;
-
- struct bcm2079x_dev *bcm2079x_dev = container_of(filp->private_data,
- struct bcm2079x_dev,
- bcm2079x_device);
- filp->private_data = bcm2079x_dev;
- bcm2079x_init_stat(bcm2079x_dev);
- bcm2079x_enable_irq(bcm2079x_dev);
- dev_info(&bcm2079x_dev->client->dev,
- "device node major=%d, minor=%d\n", imajor(inode), iminor(inode));
-
- return ret;
-}
-
-static long bcm2079x_dev_unlocked_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- struct bcm2079x_dev *bcm2079x_dev = filp->private_data;
-
- switch (cmd) {
- case BCMNFC_READ_FULL_PACKET:
- break;
- case BCMNFC_READ_MULTI_PACKETS:
- break;
- case BCMNFC_CHANGE_ADDR:
- dev_info(&bcm2079x_dev->client->dev,
- "%s, BCMNFC_CHANGE_ADDR (%x, %lx):\n", __func__, cmd,
- arg);
- change_client_addr(bcm2079x_dev, arg);
- break;
- case BCMNFC_POWER_CTL:
- dev_info(&bcm2079x_dev->client->dev,
- "%s, BCMNFC_POWER_CTL (%x, %lx):\n", __func__, cmd,
- arg);
- if (arg != 1)
- set_client_addr(bcm2079x_dev, bcm2079x_dev->original_address);
- //gpio_set_value(bcm2079x_dev->en_gpio, arg);
- //Platform specific API
- __gpio_set_value(bcm2079x_dev->en_gpio, arg);
- enable = arg;
- break;
- case BCMNFC_WAKE_CTL:
- dev_info(&bcm2079x_dev->client->dev,
- "%s, BCMNFC_WAKE_CTL (%x, %lx):\n", __func__, cmd,
- arg);
-#ifdef USE_WAKE_LOCK
- if(arg != 0)
- {
- while(wake_lock_active(&bcm2079x_dev->wake_lock ))
- {
- printk("release wake lock!!!\n");
- wake_unlock(&bcm2079x_dev->wake_lock);
- }
- //wake_lock_timeout(&bcm2079x_dev->wake_lock, HZ*2);
- }
-#endif
- //gpio_set_value(bcm2079x_dev->wake_gpio, arg);
- //Platform specific API
- __gpio_set_value(bcm2079x_dev->wake_gpio, arg);
- break;
- default:
- dev_err(&bcm2079x_dev->client->dev,
- "%s, unknown cmd (%x, %lx)\n", __func__, cmd, arg);
- return 0;
- }
-
- return 0;
-}
-
-static const struct file_operations bcm2079x_dev_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .poll = bcm2079x_dev_poll,
- .read = bcm2079x_dev_read,
- .write = bcm2079x_dev_write,
- .open = bcm2079x_dev_open,
- .unlocked_ioctl = bcm2079x_dev_unlocked_ioctl
-};
-
-unsigned int bcm2079x_irq_handle(void *para)
-{
- bcm2079x_dev_irq_handler(0, para);
- return 0;
-}
-
-static int bcm2079x_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int ret;
- struct bcm2079x_platform_data *platform_data;
- struct bcm2079x_dev *bcm2079x_dev;
-
- platform_data = client->dev.platform_data;
- /*Keep this DRIVER information*/
- dev_info(&client->dev, "Driver Version: %s\n", VERSION);
-
- dev_info(&client->dev, "%s, probing bcm2079x driver flags = %x\n", __func__, client->flags);
- if (platform_data == NULL) {
- dev_err(&client->dev, "nfc probe fail\n");
- return -ENODEV;
- }
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- dev_err(&client->dev, "need I2C_FUNC_I2C\n");
- return -ENODEV;
- }
-
- ret = gpio_request(platform_data->irq_gpio, "nfc_int");
- if (ret)
- //dev_err(&client->dev, "fail to request nfc_int\n");
- return -ENODEV;
-
- ret = gpio_request(platform_data->en_gpio, "nfc_ven");
- if (ret)
- //dev_err(&client->dev, "fail to request nfc_ven\n");
- goto err_en;
-
- ret = gpio_request(platform_data->wake_gpio, "nfc_firm");
- if (ret)
- //dev_err(&client->dev, "fail to request nfc_firm\n");
- goto err_firm;
-
- gpio_direction_output(platform_data->en_gpio, 0 );
- gpio_direction_output(platform_data->wake_gpio, 0);
- //gpio_set_value(platform_data->en_gpio, 0);
- //gpio_set_value(platform_data->wake_gpio, 0);
-
- //Platform specific API
- __gpio_set_value(platform_data->en_gpio, 0);
- __gpio_set_value(platform_data->wake_gpio, 0);
-
- gpio_direction_input(platform_data->irq_gpio );
- wmt_gpio_setpull(platform_data->irq_gpio, WMT_GPIO_PULL_DOWN);
-
- bcm2079x_dev = kzalloc(sizeof(*bcm2079x_dev), GFP_KERNEL);
- if (bcm2079x_dev == NULL) {
- dev_err(&client->dev,
- "failed to allocate memory for module data\n");
- ret = -ENOMEM;
- goto err_exit;
- }
-
- //Platform specific API
- client->irq = platform_data->irq_no;//__gpio_to_irq(platform_data->irq_gpio);
- if (client->irq == -ENXIO) {
- dev_err(&client->dev,"[bcm2079x]: get gpio irq fail.\n");
- goto err_exit;
- }
-
- bcm2079x_dev->wake_gpio = platform_data->wake_gpio;
- bcm2079x_dev->irq_gpio = platform_data->irq_gpio;
- bcm2079x_dev->irq_no = platform_data->irq_no;
- bcm2079x_dev->en_gpio = platform_data->en_gpio;
- bcm2079x_dev->client = client;
-
- /* init mutex and queues */
- init_waitqueue_head(&bcm2079x_dev->read_wq);
- mutex_init(&bcm2079x_dev->read_mutex);
- spin_lock_init(&bcm2079x_dev->irq_enabled_lock);
-
- bcm2079x_dev->bcm2079x_device.minor = MISC_DYNAMIC_MINOR;
- bcm2079x_dev->bcm2079x_device.name = "bcm2079x";
- bcm2079x_dev->bcm2079x_device.fops = &bcm2079x_dev_fops;
-
- ret = misc_register(&bcm2079x_dev->bcm2079x_device);
- if (ret) {
- dev_err(&client->dev, "misc_register failed\n");
- goto err_misc_register;
- }
-
- dev_info(&client->dev,
- "%s, saving address %d\n",
- __func__, client->addr);
- bcm2079x_dev->original_address = client->addr;
-
- /* request irq. the irq is set whenever the chip has data available
- * for reading. it is cleared when all data has been read.
- */
- dev_info(&client->dev, "requesting IRQ %d with IRQF_NO_SUSPEND\n", client->irq);
- bcm2079x_dev->irq_enabled = true;
- /*
- ret = request_irq(client->irq, bcm2079x_dev_irq_handler,
- IRQF_TRIGGER_RISING|IRQF_NO_SUSPEND, client->name, bcm2079x_dev);
- if (ret) {
- dev_err(&client->dev, "request_irq failed\n");
- goto err_request_irq_failed;
- }
- enable_irq_wake(client->irq);
-
- */
- //Platform specific API
- nfc_handle = request_irq(bcm2079x_dev->irq_no, bcm2079x_dev_irq_handler,IRQF_NO_SUSPEND|IRQF_SHARED,BCM2079X_NAME,
- bcm2079x_dev);
-
- if (nfc_handle) {
- dev_err(&client->dev, "request_irq failed.\n");
- goto err_request_irq_failed;
- }
-
- bcm2079x_disable_irq(bcm2079x_dev);
- i2c_set_clientdata(client, bcm2079x_dev);
- dev_info(&client->dev,
- "%s, probing bcm2079x driver exited successfully\n",
- __func__);
-
-#ifdef USE_WAKE_LOCK
- wake_lock_init(&bcm2079x_dev->wake_lock , WAKE_LOCK_SUSPEND, "nfcwakelock" );
-#endif
- return 0;
-
-err_request_irq_failed:
- misc_deregister(&bcm2079x_dev->bcm2079x_device);
-err_misc_register:
- mutex_destroy(&bcm2079x_dev->read_mutex);
- kfree(bcm2079x_dev);
-err_exit:
- gpio_free(platform_data->wake_gpio);
-err_firm:
- gpio_free(platform_data->en_gpio);
-err_en:
- gpio_free(platform_data->irq_gpio);
- return ret;
-}
-
-static int bcm2079x_remove(struct i2c_client *client)
-{
- struct bcm2079x_dev *bcm2079x_dev;
-
- bcm2079x_dev = i2c_get_clientdata(client);
- //free_irq(client->irq, bcm2079x_dev);
- //Platform specific API
- if (!nfc_handle)
- free_irq(bcm2079x_dev->irq_no,bcm2079x_dev);
-
- misc_deregister(&bcm2079x_dev->bcm2079x_device);
- mutex_destroy(&bcm2079x_dev->read_mutex);
- gpio_free(bcm2079x_dev->irq_gpio);
- gpio_free(bcm2079x_dev->en_gpio);
- gpio_free(bcm2079x_dev->wake_gpio);
- kfree(bcm2079x_dev);
-
- return 0;
-}
-
-static const struct i2c_device_id bcm2079x_id[] = {
- {"bcm2079x-i2c", 0},
- {}
-};
-
-/*******************************************************************/
-/* AP6493 */
-/*******************************************************************/
-static const unsigned short normal_i2c[] = {0x77, I2C_CLIENT_END};
-/*******************************************************************/
-/* AP6441 */
-/*******************************************************************/
-//static const unsigned short normal_i2c[] = {0x76, I2C_CLIENT_END};
-
-static struct i2c_driver bcm2079x_driver = {
- .class = I2C_CLASS_HWMON,
- .id_table = bcm2079x_id,
- .probe = bcm2079x_probe,
- .remove = bcm2079x_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "bcm2079x-i2c",
- },
- .address_list = normal_i2c,
-};
-
-/*
- * module load/unload record keeping
- */
- struct i2c_board_info wmt_bcm2079x_bi = {
- .type = BCM2079X_NAME,
- .flags = 0x00,
- .addr = CLIENT_ADDR,
- .platform_data = &bcm2079x_pdata,
- .archdata = NULL,
- .irq = IRQ_PMC_WAKEUP,
- };
-
-static int __init bcm2079x_dev_init(void)
-{
- int r;
- struct i2c_adapter *adapter;
-
- adapter = i2c_get_adapter(WMT_BCM2079X_I2C_CHANNEL);
- if (adapter == NULL) {
- printk("can not get i2c adapter, client address error");
- return -ENODEV;
- }
-
- bcm2079x_client = i2c_new_device(adapter, &wmt_bcm2079x_bi);
- if ( bcm2079x_client == NULL) {
- printk("allocate i2c client failed");
- return -ENOMEM;
- }
-
- i2c_put_adapter(adapter);
-
- r = i2c_add_driver(&bcm2079x_driver);
- if (r) {
- pr_err(BCM2079X_NAME ": driver registration failed\n");
- return r;
- }
-
- return 0;
- /*bcm2079x_driver.detect = bcm2079x_detect;
-
- return i2c_add_driver(&bcm2079x_driver);*/
-}
-module_init(bcm2079x_dev_init);
-
-static void __exit bcm2079x_dev_exit(void)
-{
- i2c_del_driver(&bcm2079x_driver);
- i2c_unregister_device(bcm2079x_client);
-}
-module_exit(bcm2079x_dev_exit);
-
-MODULE_AUTHOR("Broadcom");
-MODULE_DESCRIPTION("NFC bcm2079x driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/bh1770glc.c b/ANDROID_3.4.5/drivers/misc/bh1770glc.c
deleted file mode 100644
index 3d56ae7e..00000000
--- a/ANDROID_3.4.5/drivers/misc/bh1770glc.c
+++ /dev/null
@@ -1,1406 +0,0 @@
-/*
- * This file is part of the ROHM BH1770GLC / OSRAM SFH7770 sensor driver.
- * Chip is combined proximity and ambient light sensor.
- *
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/i2c/bh1770glc.h>
-#include <linux/regulator/consumer.h>
-#include <linux/pm_runtime.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-
-#define BH1770_ALS_CONTROL 0x80 /* ALS operation mode control */
-#define BH1770_PS_CONTROL 0x81 /* PS operation mode control */
-#define BH1770_I_LED 0x82 /* active LED and LED1, LED2 current */
-#define BH1770_I_LED3 0x83 /* LED3 current setting */
-#define BH1770_ALS_PS_MEAS 0x84 /* Forced mode trigger */
-#define BH1770_PS_MEAS_RATE 0x85 /* PS meas. rate at stand alone mode */
-#define BH1770_ALS_MEAS_RATE 0x86 /* ALS meas. rate at stand alone mode */
-#define BH1770_PART_ID 0x8a /* Part number and revision ID */
-#define BH1770_MANUFACT_ID 0x8b /* Manufacturerer ID */
-#define BH1770_ALS_DATA_0 0x8c /* ALS DATA low byte */
-#define BH1770_ALS_DATA_1 0x8d /* ALS DATA high byte */
-#define BH1770_ALS_PS_STATUS 0x8e /* Measurement data and int status */
-#define BH1770_PS_DATA_LED1 0x8f /* PS data from LED1 */
-#define BH1770_PS_DATA_LED2 0x90 /* PS data from LED2 */
-#define BH1770_PS_DATA_LED3 0x91 /* PS data from LED3 */
-#define BH1770_INTERRUPT 0x92 /* Interrupt setting */
-#define BH1770_PS_TH_LED1 0x93 /* PS interrupt threshold for LED1 */
-#define BH1770_PS_TH_LED2 0x94 /* PS interrupt threshold for LED2 */
-#define BH1770_PS_TH_LED3 0x95 /* PS interrupt threshold for LED3 */
-#define BH1770_ALS_TH_UP_0 0x96 /* ALS upper threshold low byte */
-#define BH1770_ALS_TH_UP_1 0x97 /* ALS upper threshold high byte */
-#define BH1770_ALS_TH_LOW_0 0x98 /* ALS lower threshold low byte */
-#define BH1770_ALS_TH_LOW_1 0x99 /* ALS lower threshold high byte */
-
-/* MANUFACT_ID */
-#define BH1770_MANUFACT_ROHM 0x01
-#define BH1770_MANUFACT_OSRAM 0x03
-
-/* PART_ID */
-#define BH1770_PART 0x90
-#define BH1770_PART_MASK 0xf0
-#define BH1770_REV_MASK 0x0f
-#define BH1770_REV_SHIFT 0
-#define BH1770_REV_0 0x00
-#define BH1770_REV_1 0x01
-
-/* Operating modes for both */
-#define BH1770_STANDBY 0x00
-#define BH1770_FORCED 0x02
-#define BH1770_STANDALONE 0x03
-#define BH1770_SWRESET (0x01 << 2)
-
-#define BH1770_PS_TRIG_MEAS (1 << 0)
-#define BH1770_ALS_TRIG_MEAS (1 << 1)
-
-/* Interrupt control */
-#define BH1770_INT_OUTPUT_MODE (1 << 3) /* 0 = latched */
-#define BH1770_INT_POLARITY (1 << 2) /* 1 = active high */
-#define BH1770_INT_ALS_ENA (1 << 1)
-#define BH1770_INT_PS_ENA (1 << 0)
-
-/* Interrupt status */
-#define BH1770_INT_LED1_DATA (1 << 0)
-#define BH1770_INT_LED1_INT (1 << 1)
-#define BH1770_INT_LED2_DATA (1 << 2)
-#define BH1770_INT_LED2_INT (1 << 3)
-#define BH1770_INT_LED3_DATA (1 << 4)
-#define BH1770_INT_LED3_INT (1 << 5)
-#define BH1770_INT_LEDS_INT ((1 << 1) | (1 << 3) | (1 << 5))
-#define BH1770_INT_ALS_DATA (1 << 6)
-#define BH1770_INT_ALS_INT (1 << 7)
-
-/* Led channels */
-#define BH1770_LED1 0x00
-
-#define BH1770_DISABLE 0
-#define BH1770_ENABLE 1
-#define BH1770_PROX_CHANNELS 1
-
-#define BH1770_LUX_DEFAULT_RATE 1 /* Index to lux rate table */
-#define BH1770_PROX_DEFAULT_RATE 1 /* Direct HW value =~ 50Hz */
-#define BH1770_PROX_DEF_RATE_THRESH 6 /* Direct HW value =~ 5 Hz */
-#define BH1770_STARTUP_DELAY 50
-#define BH1770_RESET_TIME 10
-#define BH1770_TIMEOUT 2100 /* Timeout in 2.1 seconds */
-
-#define BH1770_LUX_RANGE 65535
-#define BH1770_PROX_RANGE 255
-#define BH1770_COEF_SCALER 1024
-#define BH1770_CALIB_SCALER 8192
-#define BH1770_LUX_NEUTRAL_CALIB_VALUE (1 * BH1770_CALIB_SCALER)
-#define BH1770_LUX_DEF_THRES 1000
-#define BH1770_PROX_DEF_THRES 70
-#define BH1770_PROX_DEF_ABS_THRES 100
-#define BH1770_DEFAULT_PERSISTENCE 10
-#define BH1770_PROX_MAX_PERSISTENCE 50
-#define BH1770_LUX_GA_SCALE 16384
-#define BH1770_LUX_CF_SCALE 2048 /* CF ChipFactor */
-#define BH1770_NEUTRAL_CF BH1770_LUX_CF_SCALE
-#define BH1770_LUX_CORR_SCALE 4096
-
-#define PROX_ABOVE_THRESHOLD 1
-#define PROX_BELOW_THRESHOLD 0
-
-#define PROX_IGNORE_LUX_LIMIT 500
-
-struct bh1770_chip {
- struct bh1770_platform_data *pdata;
- char chipname[10];
- u8 revision;
- struct i2c_client *client;
- struct regulator_bulk_data regs[2];
- struct mutex mutex; /* avoid parallel access */
- wait_queue_head_t wait;
-
- bool int_mode_prox;
- bool int_mode_lux;
- struct delayed_work prox_work;
- u32 lux_cf; /* Chip specific factor */
- u32 lux_ga;
- u32 lux_calib;
- int lux_rate_index;
- u32 lux_corr;
- u16 lux_data_raw;
- u16 lux_threshold_hi;
- u16 lux_threshold_lo;
- u16 lux_thres_hi_onchip;
- u16 lux_thres_lo_onchip;
- bool lux_wait_result;
-
- int prox_enable_count;
- u16 prox_coef;
- u16 prox_const;
- int prox_rate;
- int prox_rate_threshold;
- u8 prox_persistence;
- u8 prox_persistence_counter;
- u8 prox_data;
- u8 prox_threshold;
- u8 prox_threshold_hw;
- bool prox_force_update;
- u8 prox_abs_thres;
- u8 prox_led;
-};
-
-static const char reg_vcc[] = "Vcc";
-static const char reg_vleds[] = "Vleds";
-
-/*
- * Supported stand alone rates in ms from chip data sheet
- * {10, 20, 30, 40, 70, 100, 200, 500, 1000, 2000};
- */
-static const s16 prox_rates_hz[] = {100, 50, 33, 25, 14, 10, 5, 2};
-static const s16 prox_rates_ms[] = {10, 20, 30, 40, 70, 100, 200, 500};
-
-/* Supported IR-led currents in mA */
-static const u8 prox_curr_ma[] = {5, 10, 20, 50, 100, 150, 200};
-
-/*
- * Supported stand alone rates in ms from chip data sheet
- * {100, 200, 500, 1000, 2000};
- */
-static const s16 lux_rates_hz[] = {10, 5, 2, 1, 0};
-
-/*
- * interrupt control functions are called while keeping chip->mutex
- * excluding module probe / remove
- */
-static inline int bh1770_lux_interrupt_control(struct bh1770_chip *chip,
- int lux)
-{
- chip->int_mode_lux = lux;
- /* Set interrupt modes, interrupt active low, latched */
- return i2c_smbus_write_byte_data(chip->client,
- BH1770_INTERRUPT,
- (lux << 1) | chip->int_mode_prox);
-}
-
-static inline int bh1770_prox_interrupt_control(struct bh1770_chip *chip,
- int ps)
-{
- chip->int_mode_prox = ps;
- return i2c_smbus_write_byte_data(chip->client,
- BH1770_INTERRUPT,
- (chip->int_mode_lux << 1) | (ps << 0));
-}
-
-/* chip->mutex is always kept here */
-static int bh1770_lux_rate(struct bh1770_chip *chip, int rate_index)
-{
- /* sysfs may call this when the chip is powered off */
- if (pm_runtime_suspended(&chip->client->dev))
- return 0;
-
- /* Proper proximity response needs fastest lux rate (100ms) */
- if (chip->prox_enable_count)
- rate_index = 0;
-
- return i2c_smbus_write_byte_data(chip->client,
- BH1770_ALS_MEAS_RATE,
- rate_index);
-}
-
-static int bh1770_prox_rate(struct bh1770_chip *chip, int mode)
-{
- int rate;
-
- rate = (mode == PROX_ABOVE_THRESHOLD) ?
- chip->prox_rate_threshold : chip->prox_rate;
-
- return i2c_smbus_write_byte_data(chip->client,
- BH1770_PS_MEAS_RATE,
- rate);
-}
-
-/* InfraredLED is controlled by the chip during proximity scanning */
-static inline int bh1770_led_cfg(struct bh1770_chip *chip)
-{
- /* LED cfg, current for leds 1 and 2 */
- return i2c_smbus_write_byte_data(chip->client,
- BH1770_I_LED,
- (BH1770_LED1 << 6) |
- (BH1770_LED_5mA << 3) |
- chip->prox_led);
-}
-
-/*
- * Following two functions converts raw ps values from HW to normalized
- * values. Purpose is to compensate differences between different sensor
- * versions and variants so that result means about the same between
- * versions.
- */
-static inline u8 bh1770_psraw_to_adjusted(struct bh1770_chip *chip, u8 psraw)
-{
- u16 adjusted;
- adjusted = (u16)(((u32)(psraw + chip->prox_const) * chip->prox_coef) /
- BH1770_COEF_SCALER);
- if (adjusted > BH1770_PROX_RANGE)
- adjusted = BH1770_PROX_RANGE;
- return adjusted;
-}
-
-static inline u8 bh1770_psadjusted_to_raw(struct bh1770_chip *chip, u8 ps)
-{
- u16 raw;
-
- raw = (((u32)ps * BH1770_COEF_SCALER) / chip->prox_coef);
- if (raw > chip->prox_const)
- raw = raw - chip->prox_const;
- else
- raw = 0;
- return raw;
-}
-
-/*
- * Following two functions converts raw lux values from HW to normalized
- * values. Purpose is to compensate differences between different sensor
- * versions and variants so that result means about the same between
- * versions. Chip->mutex is kept when this is called.
- */
-static int bh1770_prox_set_threshold(struct bh1770_chip *chip)
-{
- u8 tmp = 0;
-
- /* sysfs may call this when the chip is powered off */
- if (pm_runtime_suspended(&chip->client->dev))
- return 0;
-
- tmp = bh1770_psadjusted_to_raw(chip, chip->prox_threshold);
- chip->prox_threshold_hw = tmp;
-
- return i2c_smbus_write_byte_data(chip->client, BH1770_PS_TH_LED1,
- tmp);
-}
-
-static inline u16 bh1770_lux_raw_to_adjusted(struct bh1770_chip *chip, u16 raw)
-{
- u32 lux;
- lux = ((u32)raw * chip->lux_corr) / BH1770_LUX_CORR_SCALE;
- return min(lux, (u32)BH1770_LUX_RANGE);
-}
-
-static inline u16 bh1770_lux_adjusted_to_raw(struct bh1770_chip *chip,
- u16 adjusted)
-{
- return (u32)adjusted * BH1770_LUX_CORR_SCALE / chip->lux_corr;
-}
-
-/* chip->mutex is kept when this is called */
-static int bh1770_lux_update_thresholds(struct bh1770_chip *chip,
- u16 threshold_hi, u16 threshold_lo)
-{
- u8 data[4];
- int ret;
-
- /* sysfs may call this when the chip is powered off */
- if (pm_runtime_suspended(&chip->client->dev))
- return 0;
-
- /*
- * Compensate threshold values with the correction factors if not
- * set to minimum or maximum.
- * Min & max values disables interrupts.
- */
- if (threshold_hi != BH1770_LUX_RANGE && threshold_hi != 0)
- threshold_hi = bh1770_lux_adjusted_to_raw(chip, threshold_hi);
-
- if (threshold_lo != BH1770_LUX_RANGE && threshold_lo != 0)
- threshold_lo = bh1770_lux_adjusted_to_raw(chip, threshold_lo);
-
- if (chip->lux_thres_hi_onchip == threshold_hi &&
- chip->lux_thres_lo_onchip == threshold_lo)
- return 0;
-
- chip->lux_thres_hi_onchip = threshold_hi;
- chip->lux_thres_lo_onchip = threshold_lo;
-
- data[0] = threshold_hi;
- data[1] = threshold_hi >> 8;
- data[2] = threshold_lo;
- data[3] = threshold_lo >> 8;
-
- ret = i2c_smbus_write_i2c_block_data(chip->client,
- BH1770_ALS_TH_UP_0,
- ARRAY_SIZE(data),
- data);
- return ret;
-}
-
-static int bh1770_lux_get_result(struct bh1770_chip *chip)
-{
- u16 data;
- int ret;
-
- ret = i2c_smbus_read_byte_data(chip->client, BH1770_ALS_DATA_0);
- if (ret < 0)
- return ret;
-
- data = ret & 0xff;
- ret = i2c_smbus_read_byte_data(chip->client, BH1770_ALS_DATA_1);
- if (ret < 0)
- return ret;
-
- chip->lux_data_raw = data | ((ret & 0xff) << 8);
-
- return 0;
-}
-
-/* Calculate correction value which contains chip and device specific parts */
-static u32 bh1770_get_corr_value(struct bh1770_chip *chip)
-{
- u32 tmp;
- /* Impact of glass attenuation correction */
- tmp = (BH1770_LUX_CORR_SCALE * chip->lux_ga) / BH1770_LUX_GA_SCALE;
- /* Impact of chip factor correction */
- tmp = (tmp * chip->lux_cf) / BH1770_LUX_CF_SCALE;
- /* Impact of Device specific calibration correction */
- tmp = (tmp * chip->lux_calib) / BH1770_CALIB_SCALER;
- return tmp;
-}
-
-static int bh1770_lux_read_result(struct bh1770_chip *chip)
-{
- bh1770_lux_get_result(chip);
- return bh1770_lux_raw_to_adjusted(chip, chip->lux_data_raw);
-}
-
-/*
- * Chip on / off functions are called while keeping mutex except probe
- * or remove phase
- */
-static int bh1770_chip_on(struct bh1770_chip *chip)
-{
- int ret = regulator_bulk_enable(ARRAY_SIZE(chip->regs),
- chip->regs);
- if (ret < 0)
- return ret;
-
- usleep_range(BH1770_STARTUP_DELAY, BH1770_STARTUP_DELAY * 2);
-
- /* Reset the chip */
- i2c_smbus_write_byte_data(chip->client, BH1770_ALS_CONTROL,
- BH1770_SWRESET);
- usleep_range(BH1770_RESET_TIME, BH1770_RESET_TIME * 2);
-
- /*
- * ALS is started always since proximity needs als results
- * for realibility estimation.
- * Let's assume dark until the first ALS measurement is ready.
- */
- chip->lux_data_raw = 0;
- chip->prox_data = 0;
- ret = i2c_smbus_write_byte_data(chip->client,
- BH1770_ALS_CONTROL, BH1770_STANDALONE);
-
- /* Assume reset defaults */
- chip->lux_thres_hi_onchip = BH1770_LUX_RANGE;
- chip->lux_thres_lo_onchip = 0;
-
- return ret;
-}
-
-static void bh1770_chip_off(struct bh1770_chip *chip)
-{
- i2c_smbus_write_byte_data(chip->client,
- BH1770_INTERRUPT, BH1770_DISABLE);
- i2c_smbus_write_byte_data(chip->client,
- BH1770_ALS_CONTROL, BH1770_STANDBY);
- i2c_smbus_write_byte_data(chip->client,
- BH1770_PS_CONTROL, BH1770_STANDBY);
- regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
-}
-
-/* chip->mutex is kept when this is called */
-static int bh1770_prox_mode_control(struct bh1770_chip *chip)
-{
- if (chip->prox_enable_count) {
- chip->prox_force_update = true; /* Force immediate update */
-
- bh1770_lux_rate(chip, chip->lux_rate_index);
- bh1770_prox_set_threshold(chip);
- bh1770_led_cfg(chip);
- bh1770_prox_rate(chip, PROX_BELOW_THRESHOLD);
- bh1770_prox_interrupt_control(chip, BH1770_ENABLE);
- i2c_smbus_write_byte_data(chip->client,
- BH1770_PS_CONTROL, BH1770_STANDALONE);
- } else {
- chip->prox_data = 0;
- bh1770_lux_rate(chip, chip->lux_rate_index);
- bh1770_prox_interrupt_control(chip, BH1770_DISABLE);
- i2c_smbus_write_byte_data(chip->client,
- BH1770_PS_CONTROL, BH1770_STANDBY);
- }
- return 0;
-}
-
-/* chip->mutex is kept when this is called */
-static int bh1770_prox_read_result(struct bh1770_chip *chip)
-{
- int ret;
- bool above;
- u8 mode;
-
- ret = i2c_smbus_read_byte_data(chip->client, BH1770_PS_DATA_LED1);
- if (ret < 0)
- goto out;
-
- if (ret > chip->prox_threshold_hw)
- above = true;
- else
- above = false;
-
- /*
- * when ALS levels goes above limit, proximity result may be
- * false proximity. Thus ignore the result. With real proximity
- * there is a shadow causing low als levels.
- */
- if (chip->lux_data_raw > PROX_IGNORE_LUX_LIMIT)
- ret = 0;
-
- chip->prox_data = bh1770_psraw_to_adjusted(chip, ret);
-
- /* Strong proximity level or force mode requires immediate response */
- if (chip->prox_data >= chip->prox_abs_thres ||
- chip->prox_force_update)
- chip->prox_persistence_counter = chip->prox_persistence;
-
- chip->prox_force_update = false;
-
- /* Persistence filttering to reduce false proximity events */
- if (likely(above)) {
- if (chip->prox_persistence_counter < chip->prox_persistence) {
- chip->prox_persistence_counter++;
- ret = -ENODATA;
- } else {
- mode = PROX_ABOVE_THRESHOLD;
- ret = 0;
- }
- } else {
- chip->prox_persistence_counter = 0;
- mode = PROX_BELOW_THRESHOLD;
- chip->prox_data = 0;
- ret = 0;
- }
-
- /* Set proximity detection rate based on above or below value */
- if (ret == 0) {
- bh1770_prox_rate(chip, mode);
- sysfs_notify(&chip->client->dev.kobj, NULL, "prox0_raw");
- }
-out:
- return ret;
-}
-
-static int bh1770_detect(struct bh1770_chip *chip)
-{
- struct i2c_client *client = chip->client;
- s32 ret;
- u8 manu, part;
-
- ret = i2c_smbus_read_byte_data(client, BH1770_MANUFACT_ID);
- if (ret < 0)
- goto error;
- manu = (u8)ret;
-
- ret = i2c_smbus_read_byte_data(client, BH1770_PART_ID);
- if (ret < 0)
- goto error;
- part = (u8)ret;
-
- chip->revision = (part & BH1770_REV_MASK) >> BH1770_REV_SHIFT;
- chip->prox_coef = BH1770_COEF_SCALER;
- chip->prox_const = 0;
- chip->lux_cf = BH1770_NEUTRAL_CF;
-
- if ((manu == BH1770_MANUFACT_ROHM) &&
- ((part & BH1770_PART_MASK) == BH1770_PART)) {
- snprintf(chip->chipname, sizeof(chip->chipname), "BH1770GLC");
- return 0;
- }
-
- if ((manu == BH1770_MANUFACT_OSRAM) &&
- ((part & BH1770_PART_MASK) == BH1770_PART)) {
- snprintf(chip->chipname, sizeof(chip->chipname), "SFH7770");
- /* Values selected by comparing different versions */
- chip->prox_coef = 819; /* 0.8 * BH1770_COEF_SCALER */
- chip->prox_const = 40;
- return 0;
- }
-
- ret = -ENODEV;
-error:
- dev_dbg(&client->dev, "BH1770 or SFH7770 not found\n");
-
- return ret;
-}
-
-/*
- * This work is re-scheduled at every proximity interrupt.
- * If this work is running, it means that there hasn't been any
- * proximity interrupt in time. Situation is handled as no-proximity.
- * It would be nice to have low-threshold interrupt or interrupt
- * when measurement and hi-threshold are both 0. But neither of those exists.
- * This is a workaroud for missing HW feature.
- */
-
-static void bh1770_prox_work(struct work_struct *work)
-{
- struct bh1770_chip *chip =
- container_of(work, struct bh1770_chip, prox_work.work);
-
- mutex_lock(&chip->mutex);
- bh1770_prox_read_result(chip);
- mutex_unlock(&chip->mutex);
-}
-
-/* This is threaded irq handler */
-static irqreturn_t bh1770_irq(int irq, void *data)
-{
- struct bh1770_chip *chip = data;
- int status;
- int rate = 0;
-
- mutex_lock(&chip->mutex);
- status = i2c_smbus_read_byte_data(chip->client, BH1770_ALS_PS_STATUS);
-
- /* Acknowledge interrupt by reading this register */
- i2c_smbus_read_byte_data(chip->client, BH1770_INTERRUPT);
-
- /*
- * Check if there is fresh data available for als.
- * If this is the very first data, update thresholds after that.
- */
- if (status & BH1770_INT_ALS_DATA) {
- bh1770_lux_get_result(chip);
- if (unlikely(chip->lux_wait_result)) {
- chip->lux_wait_result = false;
- wake_up(&chip->wait);
- bh1770_lux_update_thresholds(chip,
- chip->lux_threshold_hi,
- chip->lux_threshold_lo);
- }
- }
-
- /* Disable interrupt logic to guarantee acknowledgement */
- i2c_smbus_write_byte_data(chip->client, BH1770_INTERRUPT,
- (0 << 1) | (0 << 0));
-
- if ((status & BH1770_INT_ALS_INT))
- sysfs_notify(&chip->client->dev.kobj, NULL, "lux0_input");
-
- if (chip->int_mode_prox && (status & BH1770_INT_LEDS_INT)) {
- rate = prox_rates_ms[chip->prox_rate_threshold];
- bh1770_prox_read_result(chip);
- }
-
- /* Re-enable interrupt logic */
- i2c_smbus_write_byte_data(chip->client, BH1770_INTERRUPT,
- (chip->int_mode_lux << 1) |
- (chip->int_mode_prox << 0));
- mutex_unlock(&chip->mutex);
-
- /*
- * Can't cancel work while keeping mutex since the work uses the
- * same mutex.
- */
- if (rate) {
- /*
- * Simulate missing no-proximity interrupt 50ms after the
- * next expected interrupt time.
- */
- cancel_delayed_work_sync(&chip->prox_work);
- schedule_delayed_work(&chip->prox_work,
- msecs_to_jiffies(rate + 50));
- }
- return IRQ_HANDLED;
-}
-
-static ssize_t bh1770_power_state_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
- ssize_t ret;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- if (value) {
- pm_runtime_get_sync(dev);
-
- ret = bh1770_lux_rate(chip, chip->lux_rate_index);
- if (ret < 0) {
- pm_runtime_put(dev);
- goto leave;
- }
-
- ret = bh1770_lux_interrupt_control(chip, BH1770_ENABLE);
- if (ret < 0) {
- pm_runtime_put(dev);
- goto leave;
- }
-
- /* This causes interrupt after the next measurement cycle */
- bh1770_lux_update_thresholds(chip, BH1770_LUX_DEF_THRES,
- BH1770_LUX_DEF_THRES);
- /* Inform that we are waiting for a result from ALS */
- chip->lux_wait_result = true;
- bh1770_prox_mode_control(chip);
- } else if (!pm_runtime_suspended(dev)) {
- pm_runtime_put(dev);
- }
- ret = count;
-leave:
- mutex_unlock(&chip->mutex);
- return ret;
-}
-
-static ssize_t bh1770_power_state_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", !pm_runtime_suspended(dev));
-}
-
-static ssize_t bh1770_lux_result_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- ssize_t ret;
- long timeout;
-
- if (pm_runtime_suspended(dev))
- return -EIO; /* Chip is not enabled at all */
-
- timeout = wait_event_interruptible_timeout(chip->wait,
- !chip->lux_wait_result,
- msecs_to_jiffies(BH1770_TIMEOUT));
- if (!timeout)
- return -EIO;
-
- mutex_lock(&chip->mutex);
- ret = sprintf(buf, "%d\n", bh1770_lux_read_result(chip));
- mutex_unlock(&chip->mutex);
-
- return ret;
-}
-
-static ssize_t bh1770_lux_range_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", BH1770_LUX_RANGE);
-}
-
-static ssize_t bh1770_prox_enable_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- /* Assume no proximity. Sensor will tell real state soon */
- if (!chip->prox_enable_count)
- chip->prox_data = 0;
-
- if (value)
- chip->prox_enable_count++;
- else if (chip->prox_enable_count > 0)
- chip->prox_enable_count--;
- else
- goto leave;
-
- /* Run control only when chip is powered on */
- if (!pm_runtime_suspended(dev))
- bh1770_prox_mode_control(chip);
-leave:
- mutex_unlock(&chip->mutex);
- return count;
-}
-
-static ssize_t bh1770_prox_enable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- ssize_t len;
-
- mutex_lock(&chip->mutex);
- len = sprintf(buf, "%d\n", chip->prox_enable_count);
- mutex_unlock(&chip->mutex);
- return len;
-}
-
-static ssize_t bh1770_prox_result_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- ssize_t ret;
-
- mutex_lock(&chip->mutex);
- if (chip->prox_enable_count && !pm_runtime_suspended(dev))
- ret = sprintf(buf, "%d\n", chip->prox_data);
- else
- ret = -EIO;
- mutex_unlock(&chip->mutex);
- return ret;
-}
-
-static ssize_t bh1770_prox_range_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%d\n", BH1770_PROX_RANGE);
-}
-
-static ssize_t bh1770_get_prox_rate_avail(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int i;
- int pos = 0;
- for (i = 0; i < ARRAY_SIZE(prox_rates_hz); i++)
- pos += sprintf(buf + pos, "%d ", prox_rates_hz[i]);
- sprintf(buf + pos - 1, "\n");
- return pos;
-}
-
-static ssize_t bh1770_get_prox_rate_above(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", prox_rates_hz[chip->prox_rate_threshold]);
-}
-
-static ssize_t bh1770_get_prox_rate_below(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", prox_rates_hz[chip->prox_rate]);
-}
-
-static int bh1770_prox_rate_validate(int rate)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(prox_rates_hz) - 1; i++)
- if (rate >= prox_rates_hz[i])
- break;
- return i;
-}
-
-static ssize_t bh1770_set_prox_rate_above(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- chip->prox_rate_threshold = bh1770_prox_rate_validate(value);
- mutex_unlock(&chip->mutex);
- return count;
-}
-
-static ssize_t bh1770_set_prox_rate_below(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- chip->prox_rate = bh1770_prox_rate_validate(value);
- mutex_unlock(&chip->mutex);
- return count;
-}
-
-static ssize_t bh1770_get_prox_thres(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", chip->prox_threshold);
-}
-
-static ssize_t bh1770_set_prox_thres(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
- int ret;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
- if (value > BH1770_PROX_RANGE)
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- chip->prox_threshold = value;
- ret = bh1770_prox_set_threshold(chip);
- mutex_unlock(&chip->mutex);
- if (ret < 0)
- return ret;
- return count;
-}
-
-static ssize_t bh1770_prox_persistence_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
-
- return sprintf(buf, "%u\n", chip->prox_persistence);
-}
-
-static ssize_t bh1770_prox_persistence_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- if (value > BH1770_PROX_MAX_PERSISTENCE)
- return -EINVAL;
-
- chip->prox_persistence = value;
-
- return len;
-}
-
-static ssize_t bh1770_prox_abs_thres_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%u\n", chip->prox_abs_thres);
-}
-
-static ssize_t bh1770_prox_abs_thres_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- if (value > BH1770_PROX_RANGE)
- return -EINVAL;
-
- chip->prox_abs_thres = value;
-
- return len;
-}
-
-static ssize_t bh1770_chip_id_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%s rev %d\n", chip->chipname, chip->revision);
-}
-
-static ssize_t bh1770_lux_calib_default_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return sprintf(buf, "%u\n", BH1770_CALIB_SCALER);
-}
-
-static ssize_t bh1770_lux_calib_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- ssize_t len;
-
- mutex_lock(&chip->mutex);
- len = sprintf(buf, "%u\n", chip->lux_calib);
- mutex_unlock(&chip->mutex);
- return len;
-}
-
-static ssize_t bh1770_lux_calib_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long value;
- u32 old_calib;
- u32 new_corr;
-
- if (strict_strtoul(buf, 0, &value))
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- old_calib = chip->lux_calib;
- chip->lux_calib = value;
- new_corr = bh1770_get_corr_value(chip);
- if (new_corr == 0) {
- chip->lux_calib = old_calib;
- mutex_unlock(&chip->mutex);
- return -EINVAL;
- }
- chip->lux_corr = new_corr;
- /* Refresh thresholds on HW after changing correction value */
- bh1770_lux_update_thresholds(chip, chip->lux_threshold_hi,
- chip->lux_threshold_lo);
-
- mutex_unlock(&chip->mutex);
-
- return len;
-}
-
-static ssize_t bh1770_get_lux_rate_avail(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int i;
- int pos = 0;
- for (i = 0; i < ARRAY_SIZE(lux_rates_hz); i++)
- pos += sprintf(buf + pos, "%d ", lux_rates_hz[i]);
- sprintf(buf + pos - 1, "\n");
- return pos;
-}
-
-static ssize_t bh1770_get_lux_rate(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", lux_rates_hz[chip->lux_rate_index]);
-}
-
-static ssize_t bh1770_set_lux_rate(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- unsigned long rate_hz;
- int ret, i;
-
- if (strict_strtoul(buf, 0, &rate_hz))
- return -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(lux_rates_hz) - 1; i++)
- if (rate_hz >= lux_rates_hz[i])
- break;
-
- mutex_lock(&chip->mutex);
- chip->lux_rate_index = i;
- ret = bh1770_lux_rate(chip, i);
- mutex_unlock(&chip->mutex);
-
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static ssize_t bh1770_get_lux_thresh_above(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", chip->lux_threshold_hi);
-}
-
-static ssize_t bh1770_get_lux_thresh_below(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", chip->lux_threshold_lo);
-}
-
-static ssize_t bh1770_set_lux_thresh(struct bh1770_chip *chip, u16 *target,
- const char *buf)
-{
- int ret = 0;
- unsigned long thresh;
-
- if (strict_strtoul(buf, 0, &thresh))
- return -EINVAL;
-
- if (thresh > BH1770_LUX_RANGE)
- return -EINVAL;
-
- mutex_lock(&chip->mutex);
- *target = thresh;
- /*
- * Don't update values in HW if we are still waiting for
- * first interrupt to come after device handle open call.
- */
- if (!chip->lux_wait_result)
- ret = bh1770_lux_update_thresholds(chip,
- chip->lux_threshold_hi,
- chip->lux_threshold_lo);
- mutex_unlock(&chip->mutex);
- return ret;
-
-}
-
-static ssize_t bh1770_set_lux_thresh_above(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- int ret = bh1770_set_lux_thresh(chip, &chip->lux_threshold_hi, buf);
- if (ret < 0)
- return ret;
- return len;
-}
-
-static ssize_t bh1770_set_lux_thresh_below(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t len)
-{
- struct bh1770_chip *chip = dev_get_drvdata(dev);
- int ret = bh1770_set_lux_thresh(chip, &chip->lux_threshold_lo, buf);
- if (ret < 0)
- return ret;
- return len;
-}
-
-static DEVICE_ATTR(prox0_raw_en, S_IRUGO | S_IWUSR, bh1770_prox_enable_show,
- bh1770_prox_enable_store);
-static DEVICE_ATTR(prox0_thresh_above1_value, S_IRUGO | S_IWUSR,
- bh1770_prox_abs_thres_show,
- bh1770_prox_abs_thres_store);
-static DEVICE_ATTR(prox0_thresh_above0_value, S_IRUGO | S_IWUSR,
- bh1770_get_prox_thres,
- bh1770_set_prox_thres);
-static DEVICE_ATTR(prox0_raw, S_IRUGO, bh1770_prox_result_show, NULL);
-static DEVICE_ATTR(prox0_sensor_range, S_IRUGO, bh1770_prox_range_show, NULL);
-static DEVICE_ATTR(prox0_thresh_above_count, S_IRUGO | S_IWUSR,
- bh1770_prox_persistence_show,
- bh1770_prox_persistence_store);
-static DEVICE_ATTR(prox0_rate_above, S_IRUGO | S_IWUSR,
- bh1770_get_prox_rate_above,
- bh1770_set_prox_rate_above);
-static DEVICE_ATTR(prox0_rate_below, S_IRUGO | S_IWUSR,
- bh1770_get_prox_rate_below,
- bh1770_set_prox_rate_below);
-static DEVICE_ATTR(prox0_rate_avail, S_IRUGO, bh1770_get_prox_rate_avail, NULL);
-
-static DEVICE_ATTR(lux0_calibscale, S_IRUGO | S_IWUSR, bh1770_lux_calib_show,
- bh1770_lux_calib_store);
-static DEVICE_ATTR(lux0_calibscale_default, S_IRUGO,
- bh1770_lux_calib_default_show,
- NULL);
-static DEVICE_ATTR(lux0_input, S_IRUGO, bh1770_lux_result_show, NULL);
-static DEVICE_ATTR(lux0_sensor_range, S_IRUGO, bh1770_lux_range_show, NULL);
-static DEVICE_ATTR(lux0_rate, S_IRUGO | S_IWUSR, bh1770_get_lux_rate,
- bh1770_set_lux_rate);
-static DEVICE_ATTR(lux0_rate_avail, S_IRUGO, bh1770_get_lux_rate_avail, NULL);
-static DEVICE_ATTR(lux0_thresh_above_value, S_IRUGO | S_IWUSR,
- bh1770_get_lux_thresh_above,
- bh1770_set_lux_thresh_above);
-static DEVICE_ATTR(lux0_thresh_below_value, S_IRUGO | S_IWUSR,
- bh1770_get_lux_thresh_below,
- bh1770_set_lux_thresh_below);
-static DEVICE_ATTR(chip_id, S_IRUGO, bh1770_chip_id_show, NULL);
-static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, bh1770_power_state_show,
- bh1770_power_state_store);
-
-
-static struct attribute *sysfs_attrs[] = {
- &dev_attr_lux0_calibscale.attr,
- &dev_attr_lux0_calibscale_default.attr,
- &dev_attr_lux0_input.attr,
- &dev_attr_lux0_sensor_range.attr,
- &dev_attr_lux0_rate.attr,
- &dev_attr_lux0_rate_avail.attr,
- &dev_attr_lux0_thresh_above_value.attr,
- &dev_attr_lux0_thresh_below_value.attr,
- &dev_attr_prox0_raw.attr,
- &dev_attr_prox0_sensor_range.attr,
- &dev_attr_prox0_raw_en.attr,
- &dev_attr_prox0_thresh_above_count.attr,
- &dev_attr_prox0_rate_above.attr,
- &dev_attr_prox0_rate_below.attr,
- &dev_attr_prox0_rate_avail.attr,
- &dev_attr_prox0_thresh_above0_value.attr,
- &dev_attr_prox0_thresh_above1_value.attr,
- &dev_attr_chip_id.attr,
- &dev_attr_power_state.attr,
- NULL
-};
-
-static struct attribute_group bh1770_attribute_group = {
- .attrs = sysfs_attrs
-};
-
-static int __devinit bh1770_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct bh1770_chip *chip;
- int err;
-
- chip = kzalloc(sizeof *chip, GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- i2c_set_clientdata(client, chip);
- chip->client = client;
-
- mutex_init(&chip->mutex);
- init_waitqueue_head(&chip->wait);
- INIT_DELAYED_WORK(&chip->prox_work, bh1770_prox_work);
-
- if (client->dev.platform_data == NULL) {
- dev_err(&client->dev, "platform data is mandatory\n");
- err = -EINVAL;
- goto fail1;
- }
-
- chip->pdata = client->dev.platform_data;
- chip->lux_calib = BH1770_LUX_NEUTRAL_CALIB_VALUE;
- chip->lux_rate_index = BH1770_LUX_DEFAULT_RATE;
- chip->lux_threshold_lo = BH1770_LUX_DEF_THRES;
- chip->lux_threshold_hi = BH1770_LUX_DEF_THRES;
-
- if (chip->pdata->glass_attenuation == 0)
- chip->lux_ga = BH1770_NEUTRAL_GA;
- else
- chip->lux_ga = chip->pdata->glass_attenuation;
-
- chip->prox_threshold = BH1770_PROX_DEF_THRES;
- chip->prox_led = chip->pdata->led_def_curr;
- chip->prox_abs_thres = BH1770_PROX_DEF_ABS_THRES;
- chip->prox_persistence = BH1770_DEFAULT_PERSISTENCE;
- chip->prox_rate_threshold = BH1770_PROX_DEF_RATE_THRESH;
- chip->prox_rate = BH1770_PROX_DEFAULT_RATE;
- chip->prox_data = 0;
-
- chip->regs[0].supply = reg_vcc;
- chip->regs[1].supply = reg_vleds;
-
- err = regulator_bulk_get(&client->dev,
- ARRAY_SIZE(chip->regs), chip->regs);
- if (err < 0) {
- dev_err(&client->dev, "Cannot get regulators\n");
- goto fail1;
- }
-
- err = regulator_bulk_enable(ARRAY_SIZE(chip->regs),
- chip->regs);
- if (err < 0) {
- dev_err(&client->dev, "Cannot enable regulators\n");
- goto fail2;
- }
-
- usleep_range(BH1770_STARTUP_DELAY, BH1770_STARTUP_DELAY * 2);
- err = bh1770_detect(chip);
- if (err < 0)
- goto fail3;
-
- /* Start chip */
- bh1770_chip_on(chip);
- pm_runtime_set_active(&client->dev);
- pm_runtime_enable(&client->dev);
-
- chip->lux_corr = bh1770_get_corr_value(chip);
- if (chip->lux_corr == 0) {
- dev_err(&client->dev, "Improper correction values\n");
- err = -EINVAL;
- goto fail3;
- }
-
- if (chip->pdata->setup_resources) {
- err = chip->pdata->setup_resources();
- if (err) {
- err = -EINVAL;
- goto fail3;
- }
- }
-
- err = sysfs_create_group(&chip->client->dev.kobj,
- &bh1770_attribute_group);
- if (err < 0) {
- dev_err(&chip->client->dev, "Sysfs registration failed\n");
- goto fail4;
- }
-
- /*
- * Chip needs level triggered interrupt to work. However,
- * level triggering doesn't work always correctly with power
- * management. Select both
- */
- err = request_threaded_irq(client->irq, NULL,
- bh1770_irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT |
- IRQF_TRIGGER_LOW,
- "bh1770", chip);
- if (err) {
- dev_err(&client->dev, "could not get IRQ %d\n",
- client->irq);
- goto fail5;
- }
- regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
- return err;
-fail5:
- sysfs_remove_group(&chip->client->dev.kobj,
- &bh1770_attribute_group);
-fail4:
- if (chip->pdata->release_resources)
- chip->pdata->release_resources();
-fail3:
- regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
-fail2:
- regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
-fail1:
- kfree(chip);
- return err;
-}
-
-static int __devexit bh1770_remove(struct i2c_client *client)
-{
- struct bh1770_chip *chip = i2c_get_clientdata(client);
-
- free_irq(client->irq, chip);
-
- sysfs_remove_group(&chip->client->dev.kobj,
- &bh1770_attribute_group);
-
- if (chip->pdata->release_resources)
- chip->pdata->release_resources();
-
- cancel_delayed_work_sync(&chip->prox_work);
-
- if (!pm_runtime_suspended(&client->dev))
- bh1770_chip_off(chip);
-
- pm_runtime_disable(&client->dev);
- pm_runtime_set_suspended(&client->dev);
-
- regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
- kfree(chip);
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int bh1770_suspend(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct bh1770_chip *chip = i2c_get_clientdata(client);
-
- bh1770_chip_off(chip);
-
- return 0;
-}
-
-static int bh1770_resume(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct bh1770_chip *chip = i2c_get_clientdata(client);
- int ret = 0;
-
- bh1770_chip_on(chip);
-
- if (!pm_runtime_suspended(dev)) {
- /*
- * If we were enabled at suspend time, it is expected
- * everything works nice and smoothly
- */
- ret = bh1770_lux_rate(chip, chip->lux_rate_index);
- ret |= bh1770_lux_interrupt_control(chip, BH1770_ENABLE);
-
- /* This causes interrupt after the next measurement cycle */
- bh1770_lux_update_thresholds(chip, BH1770_LUX_DEF_THRES,
- BH1770_LUX_DEF_THRES);
- /* Inform that we are waiting for a result from ALS */
- chip->lux_wait_result = true;
- bh1770_prox_mode_control(chip);
- }
- return ret;
-}
-
-#else
-#define bh1770_suspend NULL
-#define bh1770_shutdown NULL
-#define bh1770_resume NULL
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
-static int bh1770_runtime_suspend(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct bh1770_chip *chip = i2c_get_clientdata(client);
-
- bh1770_chip_off(chip);
-
- return 0;
-}
-
-static int bh1770_runtime_resume(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct bh1770_chip *chip = i2c_get_clientdata(client);
-
- bh1770_chip_on(chip);
-
- return 0;
-}
-#endif
-
-static const struct i2c_device_id bh1770_id[] = {
- {"bh1770glc", 0 },
- {"sfh7770", 0 },
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, bh1770_id);
-
-static const struct dev_pm_ops bh1770_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(bh1770_suspend, bh1770_resume)
- SET_RUNTIME_PM_OPS(bh1770_runtime_suspend, bh1770_runtime_resume, NULL)
-};
-
-static struct i2c_driver bh1770_driver = {
- .driver = {
- .name = "bh1770glc",
- .owner = THIS_MODULE,
- .pm = &bh1770_pm_ops,
- },
- .probe = bh1770_probe,
- .remove = __devexit_p(bh1770_remove),
- .id_table = bh1770_id,
-};
-
-module_i2c_driver(bh1770_driver);
-
-MODULE_DESCRIPTION("BH1770GLC / SFH7770 combined ALS and proximity sensor");
-MODULE_AUTHOR("Samu Onkalo, Nokia Corporation");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/misc/bh1780gli.c b/ANDROID_3.4.5/drivers/misc/bh1780gli.c
deleted file mode 100644
index 54f6f39f..00000000
--- a/ANDROID_3.4.5/drivers/misc/bh1780gli.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * bh1780gli.c
- * ROHM Ambient Light Sensor Driver
- *
- * Copyright (C) 2010 Texas Instruments
- * Author: Hemanth V <hemanthv@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-
-#define BH1780_REG_CONTROL 0x80
-#define BH1780_REG_PARTID 0x8A
-#define BH1780_REG_MANFID 0x8B
-#define BH1780_REG_DLOW 0x8C
-#define BH1780_REG_DHIGH 0x8D
-
-#define BH1780_REVMASK (0xf)
-#define BH1780_POWMASK (0x3)
-#define BH1780_POFF (0x0)
-#define BH1780_PON (0x3)
-
-/* power on settling time in ms */
-#define BH1780_PON_DELAY 2
-
-struct bh1780_data {
- struct i2c_client *client;
- int power_state;
- /* lock for sysfs operations */
- struct mutex lock;
-};
-
-static int bh1780_write(struct bh1780_data *ddata, u8 reg, u8 val, char *msg)
-{
- int ret = i2c_smbus_write_byte_data(ddata->client, reg, val);
- if (ret < 0)
- dev_err(&ddata->client->dev,
- "i2c_smbus_write_byte_data failed error %d Register (%s)\n",
- ret, msg);
- return ret;
-}
-
-static int bh1780_read(struct bh1780_data *ddata, u8 reg, char *msg)
-{
- int ret = i2c_smbus_read_byte_data(ddata->client, reg);
- if (ret < 0)
- dev_err(&ddata->client->dev,
- "i2c_smbus_read_byte_data failed error %d Register (%s)\n",
- ret, msg);
- return ret;
-}
-
-static ssize_t bh1780_show_lux(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct bh1780_data *ddata = platform_get_drvdata(pdev);
- int lsb, msb;
-
- lsb = bh1780_read(ddata, BH1780_REG_DLOW, "DLOW");
- if (lsb < 0)
- return lsb;
-
- msb = bh1780_read(ddata, BH1780_REG_DHIGH, "DHIGH");
- if (msb < 0)
- return msb;
-
- return sprintf(buf, "%d\n", (msb << 8) | lsb);
-}
-
-static ssize_t bh1780_show_power_state(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct bh1780_data *ddata = platform_get_drvdata(pdev);
- int state;
-
- state = bh1780_read(ddata, BH1780_REG_CONTROL, "CONTROL");
- if (state < 0)
- return state;
-
- return sprintf(buf, "%d\n", state & BH1780_POWMASK);
-}
-
-static ssize_t bh1780_store_power_state(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct bh1780_data *ddata = platform_get_drvdata(pdev);
- unsigned long val;
- int error;
-
- error = strict_strtoul(buf, 0, &val);
- if (error)
- return error;
-
- if (val < BH1780_POFF || val > BH1780_PON)
- return -EINVAL;
-
- mutex_lock(&ddata->lock);
-
- error = bh1780_write(ddata, BH1780_REG_CONTROL, val, "CONTROL");
- if (error < 0) {
- mutex_unlock(&ddata->lock);
- return error;
- }
-
- msleep(BH1780_PON_DELAY);
- ddata->power_state = val;
- mutex_unlock(&ddata->lock);
-
- return count;
-}
-
-static DEVICE_ATTR(lux, S_IRUGO, bh1780_show_lux, NULL);
-
-static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
- bh1780_show_power_state, bh1780_store_power_state);
-
-static struct attribute *bh1780_attributes[] = {
- &dev_attr_power_state.attr,
- &dev_attr_lux.attr,
- NULL
-};
-
-static const struct attribute_group bh1780_attr_group = {
- .attrs = bh1780_attributes,
-};
-
-static int __devinit bh1780_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int ret;
- struct bh1780_data *ddata = NULL;
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
- ret = -EIO;
- goto err_op_failed;
- }
-
- ddata = kzalloc(sizeof(struct bh1780_data), GFP_KERNEL);
- if (ddata == NULL) {
- ret = -ENOMEM;
- goto err_op_failed;
- }
-
- ddata->client = client;
- i2c_set_clientdata(client, ddata);
-
- ret = bh1780_read(ddata, BH1780_REG_PARTID, "PART ID");
- if (ret < 0)
- goto err_op_failed;
-
- dev_info(&client->dev, "Ambient Light Sensor, Rev : %d\n",
- (ret & BH1780_REVMASK));
-
- mutex_init(&ddata->lock);
-
- ret = sysfs_create_group(&client->dev.kobj, &bh1780_attr_group);
- if (ret)
- goto err_op_failed;
-
- return 0;
-
-err_op_failed:
- kfree(ddata);
- return ret;
-}
-
-static int __devexit bh1780_remove(struct i2c_client *client)
-{
- struct bh1780_data *ddata;
-
- ddata = i2c_get_clientdata(client);
- sysfs_remove_group(&client->dev.kobj, &bh1780_attr_group);
- kfree(ddata);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int bh1780_suspend(struct device *dev)
-{
- struct bh1780_data *ddata;
- int state, ret;
- struct i2c_client *client = to_i2c_client(dev);
-
- ddata = i2c_get_clientdata(client);
- state = bh1780_read(ddata, BH1780_REG_CONTROL, "CONTROL");
- if (state < 0)
- return state;
-
- ddata->power_state = state & BH1780_POWMASK;
-
- ret = bh1780_write(ddata, BH1780_REG_CONTROL, BH1780_POFF,
- "CONTROL");
-
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static int bh1780_resume(struct device *dev)
-{
- struct bh1780_data *ddata;
- int state, ret;
- struct i2c_client *client = to_i2c_client(dev);
-
- ddata = i2c_get_clientdata(client);
- state = ddata->power_state;
- ret = bh1780_write(ddata, BH1780_REG_CONTROL, state,
- "CONTROL");
-
- if (ret < 0)
- return ret;
-
- return 0;
-}
-static SIMPLE_DEV_PM_OPS(bh1780_pm, bh1780_suspend, bh1780_resume);
-#define BH1780_PMOPS (&bh1780_pm)
-#else
-#define BH1780_PMOPS NULL
-#endif /* CONFIG_PM */
-
-static const struct i2c_device_id bh1780_id[] = {
- { "bh1780", 0 },
- { },
-};
-
-static struct i2c_driver bh1780_driver = {
- .probe = bh1780_probe,
- .remove = bh1780_remove,
- .id_table = bh1780_id,
- .driver = {
- .name = "bh1780",
- .pm = BH1780_PMOPS,
- },
-};
-
-module_i2c_driver(bh1780_driver);
-
-MODULE_DESCRIPTION("BH1780GLI Ambient Light Sensor Driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>");
diff --git a/ANDROID_3.4.5/drivers/misc/bmp085.c b/ANDROID_3.4.5/drivers/misc/bmp085.c
deleted file mode 100644
index 76c30646..00000000
--- a/ANDROID_3.4.5/drivers/misc/bmp085.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/* Copyright (c) 2010 Christoph Mair <christoph.mair@gmail.com>
-
- This driver supports the bmp085 digital barometric pressure
- and temperature sensor from Bosch Sensortec. The datasheet
- is available from their website:
- http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf
-
- A pressure measurement is issued by reading from pressure0_input.
- The return value ranges from 30000 to 110000 pascal with a resulution
- of 1 pascal (0.01 millibar) which enables measurements from 9000m above
- to 500m below sea level.
-
- The temperature can be read from temp0_input. Values range from
- -400 to 850 representing the ambient temperature in degree celsius
- multiplied by 10.The resolution is 0.1 celsius.
-
- Because ambient pressure is temperature dependent, a temperature
- measurement will be executed automatically even if the user is reading
- from pressure0_input. This happens if the last temperature measurement
- has been executed more then one second ago.
-
- To decrease RMS noise from pressure measurements, the bmp085 can
- autonomously calculate the average of up to eight samples. This is
- set up by writing to the oversampling sysfs file. Accepted values
- are 0, 1, 2 and 3. 2^x when x is the value written to this file
- specifies the number of samples used to calculate the ambient pressure.
- RMS noise is specified with six pascal (without averaging) and decreases
- down to 3 pascal when using an oversampling setting of 3.
-
- This program is free software; you can redistribute 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/init.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-
-#define BMP085_I2C_ADDRESS 0x77
-#define BMP085_CHIP_ID 0x55
-
-#define BMP085_CALIBRATION_DATA_START 0xAA
-#define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */
-#define BMP085_CHIP_ID_REG 0xD0
-#define BMP085_VERSION_REG 0xD1
-#define BMP085_CTRL_REG 0xF4
-#define BMP085_TEMP_MEASUREMENT 0x2E
-#define BMP085_PRESSURE_MEASUREMENT 0x34
-#define BMP085_CONVERSION_REGISTER_MSB 0xF6
-#define BMP085_CONVERSION_REGISTER_LSB 0xF7
-#define BMP085_CONVERSION_REGISTER_XLSB 0xF8
-#define BMP085_TEMP_CONVERSION_TIME 5
-
-#define BMP085_CLIENT_NAME "bmp085"
-
-
-static const unsigned short normal_i2c[] = { BMP085_I2C_ADDRESS,
- I2C_CLIENT_END };
-
-struct bmp085_calibration_data {
- s16 AC1, AC2, AC3;
- u16 AC4, AC5, AC6;
- s16 B1, B2;
- s16 MB, MC, MD;
-};
-
-
-/* Each client has this additional data */
-struct bmp085_data {
- struct i2c_client *client;
- struct mutex lock;
- struct bmp085_calibration_data calibration;
- u32 raw_temperature;
- u32 raw_pressure;
- unsigned char oversampling_setting;
- unsigned long last_temp_measurement;
- s32 b6; /* calculated temperature correction coefficient */
-};
-
-
-static s32 bmp085_read_calibration_data(struct i2c_client *client)
-{
- u16 tmp[BMP085_CALIBRATION_DATA_LENGTH];
- struct bmp085_data *data = i2c_get_clientdata(client);
- struct bmp085_calibration_data *cali = &(data->calibration);
- s32 status = i2c_smbus_read_i2c_block_data(client,
- BMP085_CALIBRATION_DATA_START,
- BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16),
- (u8 *)tmp);
- if (status < 0)
- return status;
-
- if (status != BMP085_CALIBRATION_DATA_LENGTH*sizeof(u16))
- return -EIO;
-
- cali->AC1 = be16_to_cpu(tmp[0]);
- cali->AC2 = be16_to_cpu(tmp[1]);
- cali->AC3 = be16_to_cpu(tmp[2]);
- cali->AC4 = be16_to_cpu(tmp[3]);
- cali->AC5 = be16_to_cpu(tmp[4]);
- cali->AC6 = be16_to_cpu(tmp[5]);
- cali->B1 = be16_to_cpu(tmp[6]);
- cali->B2 = be16_to_cpu(tmp[7]);
- cali->MB = be16_to_cpu(tmp[8]);
- cali->MC = be16_to_cpu(tmp[9]);
- cali->MD = be16_to_cpu(tmp[10]);
- return 0;
-}
-
-
-static s32 bmp085_update_raw_temperature(struct bmp085_data *data)
-{
- u16 tmp;
- s32 status;
-
- mutex_lock(&data->lock);
- status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
- BMP085_TEMP_MEASUREMENT);
- if (status != 0) {
- dev_err(&data->client->dev,
- "Error while requesting temperature measurement.\n");
- goto exit;
- }
- msleep(BMP085_TEMP_CONVERSION_TIME);
-
- status = i2c_smbus_read_i2c_block_data(data->client,
- BMP085_CONVERSION_REGISTER_MSB, sizeof(tmp), (u8 *)&tmp);
- if (status < 0)
- goto exit;
- if (status != sizeof(tmp)) {
- dev_err(&data->client->dev,
- "Error while reading temperature measurement result\n");
- status = -EIO;
- goto exit;
- }
- data->raw_temperature = be16_to_cpu(tmp);
- data->last_temp_measurement = jiffies;
- status = 0; /* everything ok, return 0 */
-
-exit:
- mutex_unlock(&data->lock);
- return status;
-}
-
-static s32 bmp085_update_raw_pressure(struct bmp085_data *data)
-{
- u32 tmp = 0;
- s32 status;
-
- mutex_lock(&data->lock);
- status = i2c_smbus_write_byte_data(data->client, BMP085_CTRL_REG,
- BMP085_PRESSURE_MEASUREMENT + (data->oversampling_setting<<6));
- if (status != 0) {
- dev_err(&data->client->dev,
- "Error while requesting pressure measurement.\n");
- goto exit;
- }
-
- /* wait for the end of conversion */
- msleep(2+(3 << data->oversampling_setting));
-
- /* copy data into a u32 (4 bytes), but skip the first byte. */
- status = i2c_smbus_read_i2c_block_data(data->client,
- BMP085_CONVERSION_REGISTER_MSB, 3, ((u8 *)&tmp)+1);
- if (status < 0)
- goto exit;
- if (status != 3) {
- dev_err(&data->client->dev,
- "Error while reading pressure measurement results\n");
- status = -EIO;
- goto exit;
- }
- data->raw_pressure = be32_to_cpu((tmp));
- data->raw_pressure >>= (8-data->oversampling_setting);
- status = 0; /* everything ok, return 0 */
-
-exit:
- mutex_unlock(&data->lock);
- return status;
-}
-
-
-/*
- * This function starts the temperature measurement and returns the value
- * in tenth of a degree celsius.
- */
-static s32 bmp085_get_temperature(struct bmp085_data *data, int *temperature)
-{
- struct bmp085_calibration_data *cali = &data->calibration;
- long x1, x2;
- int status;
-
- status = bmp085_update_raw_temperature(data);
- if (status != 0)
- goto exit;
-
- x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15;
- x2 = (cali->MC << 11) / (x1 + cali->MD);
- data->b6 = x1 + x2 - 4000;
- /* if NULL just update b6. Used for pressure only measurements */
- if (temperature != NULL)
- *temperature = (x1+x2+8) >> 4;
-
-exit:
- return status;
-}
-
-/*
- * This function starts the pressure measurement and returns the value
- * in millibar. Since the pressure depends on the ambient temperature,
- * a temperature measurement is executed if the last known value is older
- * than one second.
- */
-static s32 bmp085_get_pressure(struct bmp085_data *data, int *pressure)
-{
- struct bmp085_calibration_data *cali = &data->calibration;
- s32 x1, x2, x3, b3;
- u32 b4, b7;
- s32 p;
- int status;
-
- /* alt least every second force an update of the ambient temperature */
- if (data->last_temp_measurement == 0 ||
- time_is_before_jiffies(data->last_temp_measurement + 1*HZ)) {
- status = bmp085_get_temperature(data, NULL);
- if (status != 0)
- goto exit;
- }
-
- status = bmp085_update_raw_pressure(data);
- if (status != 0)
- goto exit;
-
- x1 = (data->b6 * data->b6) >> 12;
- x1 *= cali->B2;
- x1 >>= 11;
-
- x2 = cali->AC2 * data->b6;
- x2 >>= 11;
-
- x3 = x1 + x2;
-
- b3 = (((((s32)cali->AC1) * 4 + x3) << data->oversampling_setting) + 2);
- b3 >>= 2;
-
- x1 = (cali->AC3 * data->b6) >> 13;
- x2 = (cali->B1 * ((data->b6 * data->b6) >> 12)) >> 16;
- x3 = (x1 + x2 + 2) >> 2;
- b4 = (cali->AC4 * (u32)(x3 + 32768)) >> 15;
-
- b7 = ((u32)data->raw_pressure - b3) *
- (50000 >> data->oversampling_setting);
- p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
-
- x1 = p >> 8;
- x1 *= x1;
- x1 = (x1 * 3038) >> 16;
- x2 = (-7357 * p) >> 16;
- p += (x1 + x2 + 3791) >> 4;
-
- *pressure = p;
-
-exit:
- return status;
-}
-
-/*
- * This function sets the chip-internal oversampling. Valid values are 0..3.
- * The chip will use 2^oversampling samples for internal averaging.
- * This influences the measurement time and the accuracy; larger values
- * increase both. The datasheet gives on overview on how measurement time,
- * accuracy and noise correlate.
- */
-static void bmp085_set_oversampling(struct bmp085_data *data,
- unsigned char oversampling)
-{
- if (oversampling > 3)
- oversampling = 3;
- data->oversampling_setting = oversampling;
-}
-
-/*
- * Returns the currently selected oversampling. Range: 0..3
- */
-static unsigned char bmp085_get_oversampling(struct bmp085_data *data)
-{
- return data->oversampling_setting;
-}
-
-/* sysfs callbacks */
-static ssize_t set_oversampling(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct bmp085_data *data = i2c_get_clientdata(client);
- unsigned long oversampling;
- int success = strict_strtoul(buf, 10, &oversampling);
- if (success == 0) {
- bmp085_set_oversampling(data, oversampling);
- return count;
- }
- return success;
-}
-
-static ssize_t show_oversampling(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct bmp085_data *data = i2c_get_clientdata(client);
- return sprintf(buf, "%u\n", bmp085_get_oversampling(data));
-}
-static DEVICE_ATTR(oversampling, S_IWUSR | S_IRUGO,
- show_oversampling, set_oversampling);
-
-
-static ssize_t show_temperature(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int temperature;
- int status;
- struct i2c_client *client = to_i2c_client(dev);
- struct bmp085_data *data = i2c_get_clientdata(client);
-
- status = bmp085_get_temperature(data, &temperature);
- if (status != 0)
- return status;
- else
- return sprintf(buf, "%d\n", temperature);
-}
-static DEVICE_ATTR(temp0_input, S_IRUGO, show_temperature, NULL);
-
-
-static ssize_t show_pressure(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int pressure;
- int status;
- struct i2c_client *client = to_i2c_client(dev);
- struct bmp085_data *data = i2c_get_clientdata(client);
-
- status = bmp085_get_pressure(data, &pressure);
- if (status != 0)
- return status;
- else
- return sprintf(buf, "%d\n", pressure);
-}
-static DEVICE_ATTR(pressure0_input, S_IRUGO, show_pressure, NULL);
-
-
-static struct attribute *bmp085_attributes[] = {
- &dev_attr_temp0_input.attr,
- &dev_attr_pressure0_input.attr,
- &dev_attr_oversampling.attr,
- NULL
-};
-
-static const struct attribute_group bmp085_attr_group = {
- .attrs = bmp085_attributes,
-};
-
-static int bmp085_detect(struct i2c_client *client, struct i2c_board_info *info)
-{
- if (client->addr != BMP085_I2C_ADDRESS)
- return -ENODEV;
-
- if (i2c_smbus_read_byte_data(client, BMP085_CHIP_ID_REG) != BMP085_CHIP_ID)
- return -ENODEV;
-
- return 0;
-}
-
-static int bmp085_init_client(struct i2c_client *client)
-{
- unsigned char version;
- int status;
- struct bmp085_data *data = i2c_get_clientdata(client);
- data->client = client;
- status = bmp085_read_calibration_data(client);
- if (status != 0)
- goto exit;
- version = i2c_smbus_read_byte_data(client, BMP085_VERSION_REG);
- data->last_temp_measurement = 0;
- data->oversampling_setting = 3;
- mutex_init(&data->lock);
- dev_info(&data->client->dev, "BMP085 ver. %d.%d found.\n",
- (version & 0x0F), (version & 0xF0) >> 4);
-exit:
- return status;
-}
-
-static int __devinit bmp085_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct bmp085_data *data;
- int err = 0;
-
- data = kzalloc(sizeof(struct bmp085_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
-
- /* default settings after POR */
- data->oversampling_setting = 0x00;
-
- i2c_set_clientdata(client, data);
-
- /* Initialize the BMP085 chip */
- err = bmp085_init_client(client);
- if (err != 0)
- goto exit_free;
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &bmp085_attr_group);
- if (err)
- goto exit_free;
-
- dev_info(&data->client->dev, "Successfully initialized bmp085!\n");
- goto exit;
-
-exit_free:
- kfree(data);
-exit:
- return err;
-}
-
-static int __devexit bmp085_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &bmp085_attr_group);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id bmp085_id[] = {
- { "bmp085", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, bmp085_id);
-
-static struct i2c_driver bmp085_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "bmp085"
- },
- .id_table = bmp085_id,
- .probe = bmp085_probe,
- .remove = __devexit_p(bmp085_remove),
-
- .detect = bmp085_detect,
- .address_list = normal_i2c
-};
-
-module_i2c_driver(bmp085_driver);
-
-MODULE_AUTHOR("Christoph Mair <christoph.mair@gmail.com");
-MODULE_DESCRIPTION("BMP085 driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/c2port/Kconfig b/ANDROID_3.4.5/drivers/misc/c2port/Kconfig
deleted file mode 100644
index e46af9a5..00000000
--- a/ANDROID_3.4.5/drivers/misc/c2port/Kconfig
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# C2 port devices
-#
-
-menuconfig C2PORT
- tristate "Silicon Labs C2 port support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- default no
- help
- This option enables support for Silicon Labs C2 port used to
- program Silicon micro controller chips (and other 8051 compatible).
-
- If your board have no such micro controllers you don't need this
- interface at all.
-
- To compile this driver as a module, choose M here: the module will
- be called c2port_core. Note that you also need a client module
- usually called c2port-*.
-
- If you are not sure, say N here.
-
-if C2PORT
-
-config C2PORT_DURAMAR_2150
- tristate "C2 port support for Eurotech's Duramar 2150 (EXPERIMENTAL)"
- depends on X86 && C2PORT
- default no
- help
- This option enables C2 support for the Eurotech's Duramar 2150
- on board micro controller.
-
- To compile this driver as a module, choose M here: the module will
- be called c2port-duramar2150.
-
-endif # C2PORT
diff --git a/ANDROID_3.4.5/drivers/misc/c2port/Makefile b/ANDROID_3.4.5/drivers/misc/c2port/Makefile
deleted file mode 100644
index 3b2cf43d..00000000
--- a/ANDROID_3.4.5/drivers/misc/c2port/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_C2PORT) += core.o
-
-obj-$(CONFIG_C2PORT_DURAMAR_2150) += c2port-duramar2150.o
diff --git a/ANDROID_3.4.5/drivers/misc/c2port/c2port-duramar2150.c b/ANDROID_3.4.5/drivers/misc/c2port/c2port-duramar2150.c
deleted file mode 100644
index 5484301d..00000000
--- a/ANDROID_3.4.5/drivers/misc/c2port/c2port-duramar2150.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Silicon Labs C2 port Linux support for Eurotech Duramar 2150
- *
- * Copyright (c) 2008 Rodolfo Giometti <giometti@linux.it>
- * Copyright (c) 2008 Eurotech S.p.A. <info@eurotech.it>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation
- */
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/ioport.h>
-#include <linux/c2port.h>
-
-#define DATA_PORT 0x325
-#define DIR_PORT 0x326
-#define C2D (1 << 0)
-#define C2CK (1 << 1)
-
-static DEFINE_MUTEX(update_lock);
-
-/*
- * C2 port operations
- */
-
-static void duramar2150_c2port_access(struct c2port_device *dev, int status)
-{
- u8 v;
-
- mutex_lock(&update_lock);
-
- v = inb(DIR_PORT);
-
- /* 0 = input, 1 = output */
- if (status)
- outb(v | (C2D | C2CK), DIR_PORT);
- else
- /* When access is "off" is important that both lines are set
- * as inputs or hi-impedance */
- outb(v & ~(C2D | C2CK), DIR_PORT);
-
- mutex_unlock(&update_lock);
-}
-
-static void duramar2150_c2port_c2d_dir(struct c2port_device *dev, int dir)
-{
- u8 v;
-
- mutex_lock(&update_lock);
-
- v = inb(DIR_PORT);
-
- if (dir)
- outb(v & ~C2D, DIR_PORT);
- else
- outb(v | C2D, DIR_PORT);
-
- mutex_unlock(&update_lock);
-}
-
-static int duramar2150_c2port_c2d_get(struct c2port_device *dev)
-{
- return inb(DATA_PORT) & C2D;
-}
-
-static void duramar2150_c2port_c2d_set(struct c2port_device *dev, int status)
-{
- u8 v;
-
- mutex_lock(&update_lock);
-
- v = inb(DATA_PORT);
-
- if (status)
- outb(v | C2D, DATA_PORT);
- else
- outb(v & ~C2D, DATA_PORT);
-
- mutex_unlock(&update_lock);
-}
-
-static void duramar2150_c2port_c2ck_set(struct c2port_device *dev, int status)
-{
- u8 v;
-
- mutex_lock(&update_lock);
-
- v = inb(DATA_PORT);
-
- if (status)
- outb(v | C2CK, DATA_PORT);
- else
- outb(v & ~C2CK, DATA_PORT);
-
- mutex_unlock(&update_lock);
-}
-
-static struct c2port_ops duramar2150_c2port_ops = {
- .block_size = 512, /* bytes */
- .blocks_num = 30, /* total flash size: 15360 bytes */
-
- .access = duramar2150_c2port_access,
- .c2d_dir = duramar2150_c2port_c2d_dir,
- .c2d_get = duramar2150_c2port_c2d_get,
- .c2d_set = duramar2150_c2port_c2d_set,
- .c2ck_set = duramar2150_c2port_c2ck_set,
-};
-
-static struct c2port_device *duramar2150_c2port_dev;
-
-/*
- * Module stuff
- */
-
-static int __init duramar2150_c2port_init(void)
-{
- struct resource *res;
- int ret = 0;
-
- res = request_region(0x325, 2, "c2port");
- if (!res)
- return -EBUSY;
-
- duramar2150_c2port_dev = c2port_device_register("uc",
- &duramar2150_c2port_ops, NULL);
- if (!duramar2150_c2port_dev) {
- ret = -ENODEV;
- goto free_region;
- }
-
- return 0;
-
-free_region:
- release_region(0x325, 2);
- return ret;
-}
-
-static void __exit duramar2150_c2port_exit(void)
-{
- /* Setup the GPIOs as input by default (access = 0) */
- duramar2150_c2port_access(duramar2150_c2port_dev, 0);
-
- c2port_device_unregister(duramar2150_c2port_dev);
-
- release_region(0x325, 2);
-}
-
-module_init(duramar2150_c2port_init);
-module_exit(duramar2150_c2port_exit);
-
-MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("Silicon Labs C2 port Linux support for Duramar 2150");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/c2port/core.c b/ANDROID_3.4.5/drivers/misc/c2port/core.c
deleted file mode 100644
index f428d86b..00000000
--- a/ANDROID_3.4.5/drivers/misc/c2port/core.c
+++ /dev/null
@@ -1,1006 +0,0 @@
-/*
- * Silicon Labs C2 port core Linux support
- *
- * Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it>
- * Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/kmemcheck.h>
-#include <linux/ctype.h>
-#include <linux/delay.h>
-#include <linux/idr.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <linux/c2port.h>
-
-#define DRIVER_NAME "c2port"
-#define DRIVER_VERSION "0.51.0"
-
-static DEFINE_SPINLOCK(c2port_idr_lock);
-static DEFINE_IDR(c2port_idr);
-
-/*
- * Local variables
- */
-
-static struct class *c2port_class;
-
-/*
- * C2 registers & commands defines
- */
-
-/* C2 registers */
-#define C2PORT_DEVICEID 0x00
-#define C2PORT_REVID 0x01
-#define C2PORT_FPCTL 0x02
-#define C2PORT_FPDAT 0xB4
-
-/* C2 interface commands */
-#define C2PORT_GET_VERSION 0x01
-#define C2PORT_DEVICE_ERASE 0x03
-#define C2PORT_BLOCK_READ 0x06
-#define C2PORT_BLOCK_WRITE 0x07
-#define C2PORT_PAGE_ERASE 0x08
-
-/* C2 status return codes */
-#define C2PORT_INVALID_COMMAND 0x00
-#define C2PORT_COMMAND_FAILED 0x02
-#define C2PORT_COMMAND_OK 0x0d
-
-/*
- * C2 port low level signal managements
- */
-
-static void c2port_reset(struct c2port_device *dev)
-{
- struct c2port_ops *ops = dev->ops;
-
- /* To reset the device we have to keep clock line low for at least
- * 20us.
- */
- local_irq_disable();
- ops->c2ck_set(dev, 0);
- udelay(25);
- ops->c2ck_set(dev, 1);
- local_irq_enable();
-
- udelay(1);
-}
-
-static void c2port_strobe_ck(struct c2port_device *dev)
-{
- struct c2port_ops *ops = dev->ops;
-
- /* During hi-low-hi transition we disable local IRQs to avoid
- * interructions since C2 port specification says that it must be
- * shorter than 5us, otherwise the microcontroller may consider
- * it as a reset signal!
- */
- local_irq_disable();
- ops->c2ck_set(dev, 0);
- udelay(1);
- ops->c2ck_set(dev, 1);
- local_irq_enable();
-
- udelay(1);
-}
-
-/*
- * C2 port basic functions
- */
-
-static void c2port_write_ar(struct c2port_device *dev, u8 addr)
-{
- struct c2port_ops *ops = dev->ops;
- int i;
-
- /* START field */
- c2port_strobe_ck(dev);
-
- /* INS field (11b, LSB first) */
- ops->c2d_dir(dev, 0);
- ops->c2d_set(dev, 1);
- c2port_strobe_ck(dev);
- ops->c2d_set(dev, 1);
- c2port_strobe_ck(dev);
-
- /* ADDRESS field */
- for (i = 0; i < 8; i++) {
- ops->c2d_set(dev, addr & 0x01);
- c2port_strobe_ck(dev);
-
- addr >>= 1;
- }
-
- /* STOP field */
- ops->c2d_dir(dev, 1);
- c2port_strobe_ck(dev);
-}
-
-static int c2port_read_ar(struct c2port_device *dev, u8 *addr)
-{
- struct c2port_ops *ops = dev->ops;
- int i;
-
- /* START field */
- c2port_strobe_ck(dev);
-
- /* INS field (10b, LSB first) */
- ops->c2d_dir(dev, 0);
- ops->c2d_set(dev, 0);
- c2port_strobe_ck(dev);
- ops->c2d_set(dev, 1);
- c2port_strobe_ck(dev);
-
- /* ADDRESS field */
- ops->c2d_dir(dev, 1);
- *addr = 0;
- for (i = 0; i < 8; i++) {
- *addr >>= 1; /* shift in 8-bit ADDRESS field LSB first */
-
- c2port_strobe_ck(dev);
- if (ops->c2d_get(dev))
- *addr |= 0x80;
- }
-
- /* STOP field */
- c2port_strobe_ck(dev);
-
- return 0;
-}
-
-static int c2port_write_dr(struct c2port_device *dev, u8 data)
-{
- struct c2port_ops *ops = dev->ops;
- int timeout, i;
-
- /* START field */
- c2port_strobe_ck(dev);
-
- /* INS field (01b, LSB first) */
- ops->c2d_dir(dev, 0);
- ops->c2d_set(dev, 1);
- c2port_strobe_ck(dev);
- ops->c2d_set(dev, 0);
- c2port_strobe_ck(dev);
-
- /* LENGTH field (00b, LSB first -> 1 byte) */
- ops->c2d_set(dev, 0);
- c2port_strobe_ck(dev);
- ops->c2d_set(dev, 0);
- c2port_strobe_ck(dev);
-
- /* DATA field */
- for (i = 0; i < 8; i++) {
- ops->c2d_set(dev, data & 0x01);
- c2port_strobe_ck(dev);
-
- data >>= 1;
- }
-
- /* WAIT field */
- ops->c2d_dir(dev, 1);
- timeout = 20;
- do {
- c2port_strobe_ck(dev);
- if (ops->c2d_get(dev))
- break;
-
- udelay(1);
- } while (--timeout > 0);
- if (timeout == 0)
- return -EIO;
-
- /* STOP field */
- c2port_strobe_ck(dev);
-
- return 0;
-}
-
-static int c2port_read_dr(struct c2port_device *dev, u8 *data)
-{
- struct c2port_ops *ops = dev->ops;
- int timeout, i;
-
- /* START field */
- c2port_strobe_ck(dev);
-
- /* INS field (00b, LSB first) */
- ops->c2d_dir(dev, 0);
- ops->c2d_set(dev, 0);
- c2port_strobe_ck(dev);
- ops->c2d_set(dev, 0);
- c2port_strobe_ck(dev);
-
- /* LENGTH field (00b, LSB first -> 1 byte) */
- ops->c2d_set(dev, 0);
- c2port_strobe_ck(dev);
- ops->c2d_set(dev, 0);
- c2port_strobe_ck(dev);
-
- /* WAIT field */
- ops->c2d_dir(dev, 1);
- timeout = 20;
- do {
- c2port_strobe_ck(dev);
- if (ops->c2d_get(dev))
- break;
-
- udelay(1);
- } while (--timeout > 0);
- if (timeout == 0)
- return -EIO;
-
- /* DATA field */
- *data = 0;
- for (i = 0; i < 8; i++) {
- *data >>= 1; /* shift in 8-bit DATA field LSB first */
-
- c2port_strobe_ck(dev);
- if (ops->c2d_get(dev))
- *data |= 0x80;
- }
-
- /* STOP field */
- c2port_strobe_ck(dev);
-
- return 0;
-}
-
-static int c2port_poll_in_busy(struct c2port_device *dev)
-{
- u8 addr;
- int ret, timeout = 20;
-
- do {
- ret = (c2port_read_ar(dev, &addr));
- if (ret < 0)
- return -EIO;
-
- if (!(addr & 0x02))
- break;
-
- udelay(1);
- } while (--timeout > 0);
- if (timeout == 0)
- return -EIO;
-
- return 0;
-}
-
-static int c2port_poll_out_ready(struct c2port_device *dev)
-{
- u8 addr;
- int ret, timeout = 10000; /* erase flash needs long time... */
-
- do {
- ret = (c2port_read_ar(dev, &addr));
- if (ret < 0)
- return -EIO;
-
- if (addr & 0x01)
- break;
-
- udelay(1);
- } while (--timeout > 0);
- if (timeout == 0)
- return -EIO;
-
- return 0;
-}
-
-/*
- * sysfs methods
- */
-
-static ssize_t c2port_show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
-
- return sprintf(buf, "%s\n", c2dev->name);
-}
-
-static ssize_t c2port_show_flash_blocks_num(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
- struct c2port_ops *ops = c2dev->ops;
-
- return sprintf(buf, "%d\n", ops->blocks_num);
-}
-
-static ssize_t c2port_show_flash_block_size(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
- struct c2port_ops *ops = c2dev->ops;
-
- return sprintf(buf, "%d\n", ops->block_size);
-}
-
-static ssize_t c2port_show_flash_size(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
- struct c2port_ops *ops = c2dev->ops;
-
- return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size);
-}
-
-static ssize_t c2port_show_access(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
-
- return sprintf(buf, "%d\n", c2dev->access);
-}
-
-static ssize_t c2port_store_access(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
- struct c2port_ops *ops = c2dev->ops;
- int status, ret;
-
- ret = sscanf(buf, "%d", &status);
- if (ret != 1)
- return -EINVAL;
-
- mutex_lock(&c2dev->mutex);
-
- c2dev->access = !!status;
-
- /* If access is "on" clock should be HIGH _before_ setting the line
- * as output and data line should be set as INPUT anyway */
- if (c2dev->access)
- ops->c2ck_set(c2dev, 1);
- ops->access(c2dev, c2dev->access);
- if (c2dev->access)
- ops->c2d_dir(c2dev, 1);
-
- mutex_unlock(&c2dev->mutex);
-
- return count;
-}
-
-static ssize_t c2port_store_reset(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
-
- /* Check the device access status */
- if (!c2dev->access)
- return -EBUSY;
-
- mutex_lock(&c2dev->mutex);
-
- c2port_reset(c2dev);
- c2dev->flash_access = 0;
-
- mutex_unlock(&c2dev->mutex);
-
- return count;
-}
-
-static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf)
-{
- u8 data;
- int ret;
-
- /* Select DEVICEID register for C2 data register accesses */
- c2port_write_ar(dev, C2PORT_DEVICEID);
-
- /* Read and return the device ID register */
- ret = c2port_read_dr(dev, &data);
- if (ret < 0)
- return ret;
-
- return sprintf(buf, "%d\n", data);
-}
-
-static ssize_t c2port_show_dev_id(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
- ssize_t ret;
-
- /* Check the device access status */
- if (!c2dev->access)
- return -EBUSY;
-
- mutex_lock(&c2dev->mutex);
- ret = __c2port_show_dev_id(c2dev, buf);
- mutex_unlock(&c2dev->mutex);
-
- if (ret < 0)
- dev_err(dev, "cannot read from %s\n", c2dev->name);
-
- return ret;
-}
-
-static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf)
-{
- u8 data;
- int ret;
-
- /* Select REVID register for C2 data register accesses */
- c2port_write_ar(dev, C2PORT_REVID);
-
- /* Read and return the revision ID register */
- ret = c2port_read_dr(dev, &data);
- if (ret < 0)
- return ret;
-
- return sprintf(buf, "%d\n", data);
-}
-
-static ssize_t c2port_show_rev_id(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
- ssize_t ret;
-
- /* Check the device access status */
- if (!c2dev->access)
- return -EBUSY;
-
- mutex_lock(&c2dev->mutex);
- ret = __c2port_show_rev_id(c2dev, buf);
- mutex_unlock(&c2dev->mutex);
-
- if (ret < 0)
- dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name);
-
- return ret;
-}
-
-static ssize_t c2port_show_flash_access(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
-
- return sprintf(buf, "%d\n", c2dev->flash_access);
-}
-
-static ssize_t __c2port_store_flash_access(struct c2port_device *dev,
- int status)
-{
- int ret;
-
- /* Check the device access status */
- if (!dev->access)
- return -EBUSY;
-
- dev->flash_access = !!status;
-
- /* If flash_access is off we have nothing to do... */
- if (dev->flash_access == 0)
- return 0;
-
- /* Target the C2 flash programming control register for C2 data
- * register access */
- c2port_write_ar(dev, C2PORT_FPCTL);
-
- /* Write the first keycode to enable C2 Flash programming */
- ret = c2port_write_dr(dev, 0x02);
- if (ret < 0)
- return ret;
-
- /* Write the second keycode to enable C2 Flash programming */
- ret = c2port_write_dr(dev, 0x01);
- if (ret < 0)
- return ret;
-
- /* Delay for at least 20ms to ensure the target is ready for
- * C2 flash programming */
- mdelay(25);
-
- return 0;
-}
-
-static ssize_t c2port_store_flash_access(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
- int status;
- ssize_t ret;
-
- ret = sscanf(buf, "%d", &status);
- if (ret != 1)
- return -EINVAL;
-
- mutex_lock(&c2dev->mutex);
- ret = __c2port_store_flash_access(c2dev, status);
- mutex_unlock(&c2dev->mutex);
-
- if (ret < 0) {
- dev_err(c2dev->dev, "cannot enable %s flash programming\n",
- c2dev->name);
- return ret;
- }
-
- return count;
-}
-
-static ssize_t __c2port_write_flash_erase(struct c2port_device *dev)
-{
- u8 status;
- int ret;
-
- /* Target the C2 flash programming data register for C2 data register
- * access.
- */
- c2port_write_ar(dev, C2PORT_FPDAT);
-
- /* Send device erase command */
- c2port_write_dr(dev, C2PORT_DEVICE_ERASE);
-
- /* Wait for input acknowledge */
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- /* Should check status before starting FLASH access sequence */
-
- /* Wait for status information */
- ret = c2port_poll_out_ready(dev);
- if (ret < 0)
- return ret;
-
- /* Read flash programming interface status */
- ret = c2port_read_dr(dev, &status);
- if (ret < 0)
- return ret;
- if (status != C2PORT_COMMAND_OK)
- return -EBUSY;
-
- /* Send a three-byte arming sequence to enable the device erase.
- * If the sequence is not received correctly, the command will be
- * ignored.
- * Sequence is: 0xde, 0xad, 0xa5.
- */
- c2port_write_dr(dev, 0xde);
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
- c2port_write_dr(dev, 0xad);
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
- c2port_write_dr(dev, 0xa5);
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- ret = c2port_poll_out_ready(dev);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-
-static ssize_t c2port_store_flash_erase(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct c2port_device *c2dev = dev_get_drvdata(dev);
- int ret;
-
- /* Check the device and flash access status */
- if (!c2dev->access || !c2dev->flash_access)
- return -EBUSY;
-
- mutex_lock(&c2dev->mutex);
- ret = __c2port_write_flash_erase(c2dev);
- mutex_unlock(&c2dev->mutex);
-
- if (ret < 0) {
- dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name);
- return ret;
- }
-
- return count;
-}
-
-static ssize_t __c2port_read_flash_data(struct c2port_device *dev,
- char *buffer, loff_t offset, size_t count)
-{
- struct c2port_ops *ops = dev->ops;
- u8 status, nread = 128;
- int i, ret;
-
- /* Check for flash end */
- if (offset >= ops->block_size * ops->blocks_num)
- return 0;
-
- if (ops->block_size * ops->blocks_num - offset < nread)
- nread = ops->block_size * ops->blocks_num - offset;
- if (count < nread)
- nread = count;
- if (nread == 0)
- return nread;
-
- /* Target the C2 flash programming data register for C2 data register
- * access */
- c2port_write_ar(dev, C2PORT_FPDAT);
-
- /* Send flash block read command */
- c2port_write_dr(dev, C2PORT_BLOCK_READ);
-
- /* Wait for input acknowledge */
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- /* Should check status before starting FLASH access sequence */
-
- /* Wait for status information */
- ret = c2port_poll_out_ready(dev);
- if (ret < 0)
- return ret;
-
- /* Read flash programming interface status */
- ret = c2port_read_dr(dev, &status);
- if (ret < 0)
- return ret;
- if (status != C2PORT_COMMAND_OK)
- return -EBUSY;
-
- /* Send address high byte */
- c2port_write_dr(dev, offset >> 8);
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- /* Send address low byte */
- c2port_write_dr(dev, offset & 0x00ff);
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- /* Send address block size */
- c2port_write_dr(dev, nread);
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- /* Should check status before reading FLASH block */
-
- /* Wait for status information */
- ret = c2port_poll_out_ready(dev);
- if (ret < 0)
- return ret;
-
- /* Read flash programming interface status */
- ret = c2port_read_dr(dev, &status);
- if (ret < 0)
- return ret;
- if (status != C2PORT_COMMAND_OK)
- return -EBUSY;
-
- /* Read flash block */
- for (i = 0; i < nread; i++) {
- ret = c2port_poll_out_ready(dev);
- if (ret < 0)
- return ret;
-
- ret = c2port_read_dr(dev, buffer+i);
- if (ret < 0)
- return ret;
- }
-
- return nread;
-}
-
-static ssize_t c2port_read_flash_data(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buffer, loff_t offset, size_t count)
-{
- struct c2port_device *c2dev =
- dev_get_drvdata(container_of(kobj,
- struct device, kobj));
- ssize_t ret;
-
- /* Check the device and flash access status */
- if (!c2dev->access || !c2dev->flash_access)
- return -EBUSY;
-
- mutex_lock(&c2dev->mutex);
- ret = __c2port_read_flash_data(c2dev, buffer, offset, count);
- mutex_unlock(&c2dev->mutex);
-
- if (ret < 0)
- dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name);
-
- return ret;
-}
-
-static ssize_t __c2port_write_flash_data(struct c2port_device *dev,
- char *buffer, loff_t offset, size_t count)
-{
- struct c2port_ops *ops = dev->ops;
- u8 status, nwrite = 128;
- int i, ret;
-
- if (nwrite > count)
- nwrite = count;
- if (ops->block_size * ops->blocks_num - offset < nwrite)
- nwrite = ops->block_size * ops->blocks_num - offset;
-
- /* Check for flash end */
- if (offset >= ops->block_size * ops->blocks_num)
- return -EINVAL;
-
- /* Target the C2 flash programming data register for C2 data register
- * access */
- c2port_write_ar(dev, C2PORT_FPDAT);
-
- /* Send flash block write command */
- c2port_write_dr(dev, C2PORT_BLOCK_WRITE);
-
- /* Wait for input acknowledge */
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- /* Should check status before starting FLASH access sequence */
-
- /* Wait for status information */
- ret = c2port_poll_out_ready(dev);
- if (ret < 0)
- return ret;
-
- /* Read flash programming interface status */
- ret = c2port_read_dr(dev, &status);
- if (ret < 0)
- return ret;
- if (status != C2PORT_COMMAND_OK)
- return -EBUSY;
-
- /* Send address high byte */
- c2port_write_dr(dev, offset >> 8);
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- /* Send address low byte */
- c2port_write_dr(dev, offset & 0x00ff);
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- /* Send address block size */
- c2port_write_dr(dev, nwrite);
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- /* Should check status before writing FLASH block */
-
- /* Wait for status information */
- ret = c2port_poll_out_ready(dev);
- if (ret < 0)
- return ret;
-
- /* Read flash programming interface status */
- ret = c2port_read_dr(dev, &status);
- if (ret < 0)
- return ret;
- if (status != C2PORT_COMMAND_OK)
- return -EBUSY;
-
- /* Write flash block */
- for (i = 0; i < nwrite; i++) {
- ret = c2port_write_dr(dev, *(buffer+i));
- if (ret < 0)
- return ret;
-
- ret = c2port_poll_in_busy(dev);
- if (ret < 0)
- return ret;
-
- }
-
- /* Wait for last flash write to complete */
- ret = c2port_poll_out_ready(dev);
- if (ret < 0)
- return ret;
-
- return nwrite;
-}
-
-static ssize_t c2port_write_flash_data(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buffer, loff_t offset, size_t count)
-{
- struct c2port_device *c2dev =
- dev_get_drvdata(container_of(kobj,
- struct device, kobj));
- int ret;
-
- /* Check the device access status */
- if (!c2dev->access || !c2dev->flash_access)
- return -EBUSY;
-
- mutex_lock(&c2dev->mutex);
- ret = __c2port_write_flash_data(c2dev, buffer, offset, count);
- mutex_unlock(&c2dev->mutex);
-
- if (ret < 0)
- dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name);
-
- return ret;
-}
-
-/*
- * Class attributes
- */
-
-static struct device_attribute c2port_attrs[] = {
- __ATTR(name, 0444, c2port_show_name, NULL),
- __ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL),
- __ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL),
- __ATTR(flash_size, 0444, c2port_show_flash_size, NULL),
- __ATTR(access, 0644, c2port_show_access, c2port_store_access),
- __ATTR(reset, 0200, NULL, c2port_store_reset),
- __ATTR(dev_id, 0444, c2port_show_dev_id, NULL),
- __ATTR(rev_id, 0444, c2port_show_rev_id, NULL),
-
- __ATTR(flash_access, 0644, c2port_show_flash_access,
- c2port_store_flash_access),
- __ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase),
- __ATTR_NULL,
-};
-
-static struct bin_attribute c2port_bin_attrs = {
- .attr = {
- .name = "flash_data",
- .mode = 0644
- },
- .read = c2port_read_flash_data,
- .write = c2port_write_flash_data,
- /* .size is computed at run-time */
-};
-
-/*
- * Exported functions
- */
-
-struct c2port_device *c2port_device_register(char *name,
- struct c2port_ops *ops, void *devdata)
-{
- struct c2port_device *c2dev;
- int id, ret;
-
- if (unlikely(!ops) || unlikely(!ops->access) || \
- unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \
- unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set))
- return ERR_PTR(-EINVAL);
-
- c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL);
- kmemcheck_annotate_bitfield(c2dev, flags);
- if (unlikely(!c2dev))
- return ERR_PTR(-ENOMEM);
-
- ret = idr_pre_get(&c2port_idr, GFP_KERNEL);
- if (!ret) {
- ret = -ENOMEM;
- goto error_idr_get_new;
- }
-
- spin_lock_irq(&c2port_idr_lock);
- ret = idr_get_new(&c2port_idr, c2dev, &id);
- spin_unlock_irq(&c2port_idr_lock);
-
- if (ret < 0)
- goto error_idr_get_new;
- c2dev->id = id;
-
- c2dev->dev = device_create(c2port_class, NULL, 0, c2dev,
- "c2port%d", id);
- if (unlikely(IS_ERR(c2dev->dev))) {
- ret = PTR_ERR(c2dev->dev);
- goto error_device_create;
- }
- dev_set_drvdata(c2dev->dev, c2dev);
-
- strncpy(c2dev->name, name, C2PORT_NAME_LEN);
- c2dev->ops = ops;
- mutex_init(&c2dev->mutex);
-
- /* Create binary file */
- c2port_bin_attrs.size = ops->blocks_num * ops->block_size;
- ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs);
- if (unlikely(ret))
- goto error_device_create_bin_file;
-
- /* By default C2 port access is off */
- c2dev->access = c2dev->flash_access = 0;
- ops->access(c2dev, 0);
-
- dev_info(c2dev->dev, "C2 port %s added\n", name);
- dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes "
- "(%d bytes total)\n",
- name, ops->blocks_num, ops->block_size,
- ops->blocks_num * ops->block_size);
-
- return c2dev;
-
-error_device_create_bin_file:
- device_destroy(c2port_class, 0);
-
-error_device_create:
- spin_lock_irq(&c2port_idr_lock);
- idr_remove(&c2port_idr, id);
- spin_unlock_irq(&c2port_idr_lock);
-
-error_idr_get_new:
- kfree(c2dev);
-
- return ERR_PTR(ret);
-}
-EXPORT_SYMBOL(c2port_device_register);
-
-void c2port_device_unregister(struct c2port_device *c2dev)
-{
- if (!c2dev)
- return;
-
- dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name);
-
- device_remove_bin_file(c2dev->dev, &c2port_bin_attrs);
- spin_lock_irq(&c2port_idr_lock);
- idr_remove(&c2port_idr, c2dev->id);
- spin_unlock_irq(&c2port_idr_lock);
-
- device_destroy(c2port_class, c2dev->id);
-
- kfree(c2dev);
-}
-EXPORT_SYMBOL(c2port_device_unregister);
-
-/*
- * Module stuff
- */
-
-static int __init c2port_init(void)
-{
- printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION
- " - (C) 2007 Rodolfo Giometti\n");
-
- c2port_class = class_create(THIS_MODULE, "c2port");
- if (IS_ERR(c2port_class)) {
- printk(KERN_ERR "c2port: failed to allocate class\n");
- return PTR_ERR(c2port_class);
- }
- c2port_class->dev_attrs = c2port_attrs;
-
- return 0;
-}
-
-static void __exit c2port_exit(void)
-{
- class_destroy(c2port_class);
-}
-
-module_init(c2port_init);
-module_exit(c2port_exit);
-
-MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION);
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/carma/Kconfig b/ANDROID_3.4.5/drivers/misc/carma/Kconfig
deleted file mode 100644
index c90370ed..00000000
--- a/ANDROID_3.4.5/drivers/misc/carma/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-config CARMA_FPGA
- tristate "CARMA DATA-FPGA Access Driver"
- depends on FSL_SOC && PPC_83xx && MEDIA_SUPPORT && HAS_DMA && FSL_DMA
- select VIDEOBUF_DMA_SG
- default n
- help
- Say Y here to include support for communicating with the data
- processing FPGAs on the OVRO CARMA board.
-
-config CARMA_FPGA_PROGRAM
- tristate "CARMA DATA-FPGA Programmer"
- depends on FSL_SOC && PPC_83xx && MEDIA_SUPPORT && HAS_DMA && FSL_DMA
- select VIDEOBUF_DMA_SG
- default n
- help
- Say Y here to include support for programming the data processing
- FPGAs on the OVRO CARMA board.
diff --git a/ANDROID_3.4.5/drivers/misc/carma/Makefile b/ANDROID_3.4.5/drivers/misc/carma/Makefile
deleted file mode 100644
index ff36ac2c..00000000
--- a/ANDROID_3.4.5/drivers/misc/carma/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_CARMA_FPGA) += carma-fpga.o
-obj-$(CONFIG_CARMA_FPGA_PROGRAM) += carma-fpga-program.o
diff --git a/ANDROID_3.4.5/drivers/misc/carma/carma-fpga-program.c b/ANDROID_3.4.5/drivers/misc/carma/carma-fpga-program.c
deleted file mode 100644
index a2d25e48..00000000
--- a/ANDROID_3.4.5/drivers/misc/carma/carma-fpga-program.c
+++ /dev/null
@@ -1,1140 +0,0 @@
-/*
- * CARMA Board DATA-FPGA Programmer
- *
- * Copyright (c) 2009-2011 Ira W. Snyder <iws@ovro.caltech.edu>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/of_platform.h>
-#include <linux/completion.h>
-#include <linux/miscdevice.h>
-#include <linux/dmaengine.h>
-#include <linux/interrupt.h>
-#include <linux/highmem.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/leds.h>
-#include <linux/slab.h>
-#include <linux/kref.h>
-#include <linux/fs.h>
-#include <linux/io.h>
-
-#include <media/videobuf-dma-sg.h>
-
-/* MPC8349EMDS specific get_immrbase() */
-#include <sysdev/fsl_soc.h>
-
-static const char drv_name[] = "carma-fpga-program";
-
-/*
- * Firmware images are always this exact size
- *
- * 12849552 bytes for a CARMA Digitizer Board (EP2S90 FPGAs)
- * 18662880 bytes for a CARMA Correlator Board (EP2S130 FPGAs)
- */
-#define FW_SIZE_EP2S90 12849552
-#define FW_SIZE_EP2S130 18662880
-
-struct fpga_dev {
- struct miscdevice miscdev;
-
- /* Reference count */
- struct kref ref;
-
- /* Device Registers */
- struct device *dev;
- void __iomem *regs;
- void __iomem *immr;
-
- /* Freescale DMA Device */
- struct dma_chan *chan;
-
- /* Interrupts */
- int irq, status;
- struct completion completion;
-
- /* FPGA Bitfile */
- struct mutex lock;
-
- struct videobuf_dmabuf vb;
- bool vb_allocated;
-
- /* max size and written bytes */
- size_t fw_size;
- size_t bytes;
-};
-
-/*
- * FPGA Bitfile Helpers
- */
-
-/**
- * fpga_drop_firmware_data() - drop the bitfile image from memory
- * @priv: the driver's private data structure
- *
- * LOCKING: must hold priv->lock
- */
-static void fpga_drop_firmware_data(struct fpga_dev *priv)
-{
- videobuf_dma_free(&priv->vb);
- priv->vb_allocated = false;
- priv->bytes = 0;
-}
-
-/*
- * Private Data Reference Count
- */
-
-static void fpga_dev_remove(struct kref *ref)
-{
- struct fpga_dev *priv = container_of(ref, struct fpga_dev, ref);
-
- /* free any firmware image that was not programmed */
- fpga_drop_firmware_data(priv);
-
- mutex_destroy(&priv->lock);
- kfree(priv);
-}
-
-/*
- * LED Trigger (could be a seperate module)
- */
-
-/*
- * NOTE: this whole thing does have the problem that whenever the led's are
- * NOTE: first set to use the fpga trigger, they could be in the wrong state
- */
-
-DEFINE_LED_TRIGGER(ledtrig_fpga);
-
-static void ledtrig_fpga_programmed(bool enabled)
-{
- if (enabled)
- led_trigger_event(ledtrig_fpga, LED_FULL);
- else
- led_trigger_event(ledtrig_fpga, LED_OFF);
-}
-
-/*
- * FPGA Register Helpers
- */
-
-/* Register Definitions */
-#define FPGA_CONFIG_CONTROL 0x40
-#define FPGA_CONFIG_STATUS 0x44
-#define FPGA_CONFIG_FIFO_SIZE 0x48
-#define FPGA_CONFIG_FIFO_USED 0x4C
-#define FPGA_CONFIG_TOTAL_BYTE_COUNT 0x50
-#define FPGA_CONFIG_CUR_BYTE_COUNT 0x54
-
-#define FPGA_FIFO_ADDRESS 0x3000
-
-static int fpga_fifo_size(void __iomem *regs)
-{
- return ioread32be(regs + FPGA_CONFIG_FIFO_SIZE);
-}
-
-#define CFG_STATUS_ERR_MASK 0xfffe
-
-static int fpga_config_error(void __iomem *regs)
-{
- return ioread32be(regs + FPGA_CONFIG_STATUS) & CFG_STATUS_ERR_MASK;
-}
-
-static int fpga_fifo_empty(void __iomem *regs)
-{
- return ioread32be(regs + FPGA_CONFIG_FIFO_USED) == 0;
-}
-
-static void fpga_fifo_write(void __iomem *regs, u32 val)
-{
- iowrite32be(val, regs + FPGA_FIFO_ADDRESS);
-}
-
-static void fpga_set_byte_count(void __iomem *regs, u32 count)
-{
- iowrite32be(count, regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);
-}
-
-#define CFG_CTL_ENABLE (1 << 0)
-#define CFG_CTL_RESET (1 << 1)
-#define CFG_CTL_DMA (1 << 2)
-
-static void fpga_programmer_enable(struct fpga_dev *priv, bool dma)
-{
- u32 val;
-
- val = (dma) ? (CFG_CTL_ENABLE | CFG_CTL_DMA) : CFG_CTL_ENABLE;
- iowrite32be(val, priv->regs + FPGA_CONFIG_CONTROL);
-}
-
-static void fpga_programmer_disable(struct fpga_dev *priv)
-{
- iowrite32be(0x0, priv->regs + FPGA_CONFIG_CONTROL);
-}
-
-static void fpga_dump_registers(struct fpga_dev *priv)
-{
- u32 control, status, size, used, total, curr;
-
- /* good status: do nothing */
- if (priv->status == 0)
- return;
-
- /* Dump all status registers */
- control = ioread32be(priv->regs + FPGA_CONFIG_CONTROL);
- status = ioread32be(priv->regs + FPGA_CONFIG_STATUS);
- size = ioread32be(priv->regs + FPGA_CONFIG_FIFO_SIZE);
- used = ioread32be(priv->regs + FPGA_CONFIG_FIFO_USED);
- total = ioread32be(priv->regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);
- curr = ioread32be(priv->regs + FPGA_CONFIG_CUR_BYTE_COUNT);
-
- dev_err(priv->dev, "Configuration failed, dumping status registers\n");
- dev_err(priv->dev, "Control: 0x%.8x\n", control);
- dev_err(priv->dev, "Status: 0x%.8x\n", status);
- dev_err(priv->dev, "FIFO Size: 0x%.8x\n", size);
- dev_err(priv->dev, "FIFO Used: 0x%.8x\n", used);
- dev_err(priv->dev, "FIFO Total: 0x%.8x\n", total);
- dev_err(priv->dev, "FIFO Curr: 0x%.8x\n", curr);
-}
-
-/*
- * FPGA Power Supply Code
- */
-
-#define CTL_PWR_CONTROL 0x2006
-#define CTL_PWR_STATUS 0x200A
-#define CTL_PWR_FAIL 0x200B
-
-#define PWR_CONTROL_ENABLE 0x01
-
-#define PWR_STATUS_ERROR_MASK 0x10
-#define PWR_STATUS_GOOD 0x0f
-
-/*
- * Determine if the FPGA power is good for all supplies
- */
-static bool fpga_power_good(struct fpga_dev *priv)
-{
- u8 val;
-
- val = ioread8(priv->regs + CTL_PWR_STATUS);
- if (val & PWR_STATUS_ERROR_MASK)
- return false;
-
- return val == PWR_STATUS_GOOD;
-}
-
-/*
- * Disable the FPGA power supplies
- */
-static void fpga_disable_power_supplies(struct fpga_dev *priv)
-{
- unsigned long start;
- u8 val;
-
- iowrite8(0x0, priv->regs + CTL_PWR_CONTROL);
-
- /*
- * Wait 500ms for the power rails to discharge
- *
- * Without this delay, the CTL-CPLD state machine can get into a
- * state where it is waiting for the power-goods to assert, but they
- * never do. This only happens when enabling and disabling the
- * power sequencer very rapidly.
- *
- * The loop below will also wait for the power goods to de-assert,
- * but testing has shown that they are always disabled by the time
- * the sleep completes. However, omitting the sleep and only waiting
- * for the power-goods to de-assert was not sufficient to ensure
- * that the power sequencer would not wedge itself.
- */
- msleep(500);
-
- start = jiffies;
- while (time_before(jiffies, start + HZ)) {
- val = ioread8(priv->regs + CTL_PWR_STATUS);
- if (!(val & PWR_STATUS_GOOD))
- break;
-
- usleep_range(5000, 10000);
- }
-
- val = ioread8(priv->regs + CTL_PWR_STATUS);
- if (val & PWR_STATUS_GOOD) {
- dev_err(priv->dev, "power disable failed: "
- "power goods: status 0x%.2x\n", val);
- }
-
- if (val & PWR_STATUS_ERROR_MASK) {
- dev_err(priv->dev, "power disable failed: "
- "alarm bit set: status 0x%.2x\n", val);
- }
-}
-
-/**
- * fpga_enable_power_supplies() - enable the DATA-FPGA power supplies
- * @priv: the driver's private data structure
- *
- * Enable the DATA-FPGA power supplies, waiting up to 1 second for
- * them to enable successfully.
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int fpga_enable_power_supplies(struct fpga_dev *priv)
-{
- unsigned long start = jiffies;
-
- if (fpga_power_good(priv)) {
- dev_dbg(priv->dev, "power was already good\n");
- return 0;
- }
-
- iowrite8(PWR_CONTROL_ENABLE, priv->regs + CTL_PWR_CONTROL);
- while (time_before(jiffies, start + HZ)) {
- if (fpga_power_good(priv))
- return 0;
-
- usleep_range(5000, 10000);
- }
-
- return fpga_power_good(priv) ? 0 : -ETIMEDOUT;
-}
-
-/*
- * Determine if the FPGA power supplies are all enabled
- */
-static bool fpga_power_enabled(struct fpga_dev *priv)
-{
- u8 val;
-
- val = ioread8(priv->regs + CTL_PWR_CONTROL);
- if (val & PWR_CONTROL_ENABLE)
- return true;
-
- return false;
-}
-
-/*
- * Determine if the FPGA's are programmed and running correctly
- */
-static bool fpga_running(struct fpga_dev *priv)
-{
- if (!fpga_power_good(priv))
- return false;
-
- /* Check the config done bit */
- return ioread32be(priv->regs + FPGA_CONFIG_STATUS) & (1 << 18);
-}
-
-/*
- * FPGA Programming Code
- */
-
-/**
- * fpga_program_block() - put a block of data into the programmer's FIFO
- * @priv: the driver's private data structure
- * @buf: the data to program
- * @count: the length of data to program (must be a multiple of 4 bytes)
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int fpga_program_block(struct fpga_dev *priv, void *buf, size_t count)
-{
- u32 *data = buf;
- int size = fpga_fifo_size(priv->regs);
- int i, len;
- unsigned long timeout;
-
- /* enforce correct data length for the FIFO */
- BUG_ON(count % 4 != 0);
-
- while (count > 0) {
-
- /* Get the size of the block to write (maximum is FIFO_SIZE) */
- len = min_t(size_t, count, size);
- timeout = jiffies + HZ / 4;
-
- /* Write the block */
- for (i = 0; i < len / 4; i++)
- fpga_fifo_write(priv->regs, data[i]);
-
- /* Update the amounts left */
- count -= len;
- data += len / 4;
-
- /* Wait for the fifo to empty */
- while (true) {
-
- if (fpga_fifo_empty(priv->regs)) {
- break;
- } else {
- dev_dbg(priv->dev, "Fifo not empty\n");
- cpu_relax();
- }
-
- if (fpga_config_error(priv->regs)) {
- dev_err(priv->dev, "Error detected\n");
- return -EIO;
- }
-
- if (time_after(jiffies, timeout)) {
- dev_err(priv->dev, "Fifo drain timeout\n");
- return -ETIMEDOUT;
- }
-
- usleep_range(5000, 10000);
- }
- }
-
- return 0;
-}
-
-/**
- * fpga_program_cpu() - program the DATA-FPGA's using the CPU
- * @priv: the driver's private data structure
- *
- * This is useful when the DMA programming method fails. It is possible to
- * wedge the Freescale DMA controller such that the DMA programming method
- * always fails. This method has always succeeded.
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static noinline int fpga_program_cpu(struct fpga_dev *priv)
-{
- int ret;
-
- /* Disable the programmer */
- fpga_programmer_disable(priv);
-
- /* Set the total byte count */
- fpga_set_byte_count(priv->regs, priv->bytes);
- dev_dbg(priv->dev, "total byte count %u bytes\n", priv->bytes);
-
- /* Enable the controller for programming */
- fpga_programmer_enable(priv, false);
- dev_dbg(priv->dev, "enabled the controller\n");
-
- /* Write each chunk of the FPGA bitfile to FPGA programmer */
- ret = fpga_program_block(priv, priv->vb.vaddr, priv->bytes);
- if (ret)
- goto out_disable_controller;
-
- /* Wait for the interrupt handler to signal that programming finished */
- ret = wait_for_completion_timeout(&priv->completion, 2 * HZ);
- if (!ret) {
- dev_err(priv->dev, "Timed out waiting for completion\n");
- ret = -ETIMEDOUT;
- goto out_disable_controller;
- }
-
- /* Retrieve the status from the interrupt handler */
- ret = priv->status;
-
-out_disable_controller:
- fpga_programmer_disable(priv);
- return ret;
-}
-
-#define FIFO_DMA_ADDRESS 0xf0003000
-#define FIFO_MAX_LEN 4096
-
-/**
- * fpga_program_dma() - program the DATA-FPGA's using the DMA engine
- * @priv: the driver's private data structure
- *
- * Program the DATA-FPGA's using the Freescale DMA engine. This requires that
- * the engine is programmed such that the hardware DMA request lines can
- * control the entire DMA transaction. The system controller FPGA then
- * completely offloads the programming from the CPU.
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static noinline int fpga_program_dma(struct fpga_dev *priv)
-{
- struct videobuf_dmabuf *vb = &priv->vb;
- struct dma_chan *chan = priv->chan;
- struct dma_async_tx_descriptor *tx;
- size_t num_pages, len, avail = 0;
- struct dma_slave_config config;
- struct scatterlist *sg;
- struct sg_table table;
- dma_cookie_t cookie;
- int ret, i;
-
- /* Disable the programmer */
- fpga_programmer_disable(priv);
-
- /* Allocate a scatterlist for the DMA destination */
- num_pages = DIV_ROUND_UP(priv->bytes, FIFO_MAX_LEN);
- ret = sg_alloc_table(&table, num_pages, GFP_KERNEL);
- if (ret) {
- dev_err(priv->dev, "Unable to allocate dst scatterlist\n");
- ret = -ENOMEM;
- goto out_return;
- }
-
- /*
- * This is an ugly hack
- *
- * We fill in a scatterlist as if it were mapped for DMA. This is
- * necessary because there exists no better structure for this
- * inside the kernel code.
- *
- * As an added bonus, we can use the DMAEngine API for all of this,
- * rather than inventing another extremely similar API.
- */
- avail = priv->bytes;
- for_each_sg(table.sgl, sg, num_pages, i) {
- len = min_t(size_t, avail, FIFO_MAX_LEN);
- sg_dma_address(sg) = FIFO_DMA_ADDRESS;
- sg_dma_len(sg) = len;
-
- avail -= len;
- }
-
- /* Map the buffer for DMA */
- ret = videobuf_dma_map(priv->dev, &priv->vb);
- if (ret) {
- dev_err(priv->dev, "Unable to map buffer for DMA\n");
- goto out_free_table;
- }
-
- /*
- * Configure the DMA channel to transfer FIFO_SIZE / 2 bytes per
- * transaction, and then put it under external control
- */
- memset(&config, 0, sizeof(config));
- config.direction = DMA_MEM_TO_DEV;
- config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- config.dst_maxburst = fpga_fifo_size(priv->regs) / 2 / 4;
- ret = chan->device->device_control(chan, DMA_SLAVE_CONFIG,
- (unsigned long)&config);
- if (ret) {
- dev_err(priv->dev, "DMA slave configuration failed\n");
- goto out_dma_unmap;
- }
-
- ret = chan->device->device_control(chan, FSLDMA_EXTERNAL_START, 1);
- if (ret) {
- dev_err(priv->dev, "DMA external control setup failed\n");
- goto out_dma_unmap;
- }
-
- /* setup and submit the DMA transaction */
- tx = chan->device->device_prep_dma_sg(chan,
- table.sgl, num_pages,
- vb->sglist, vb->sglen, 0);
- if (!tx) {
- dev_err(priv->dev, "Unable to prep DMA transaction\n");
- ret = -ENOMEM;
- goto out_dma_unmap;
- }
-
- cookie = tx->tx_submit(tx);
- if (dma_submit_error(cookie)) {
- dev_err(priv->dev, "Unable to submit DMA transaction\n");
- ret = -ENOMEM;
- goto out_dma_unmap;
- }
-
- dma_async_memcpy_issue_pending(chan);
-
- /* Set the total byte count */
- fpga_set_byte_count(priv->regs, priv->bytes);
- dev_dbg(priv->dev, "total byte count %u bytes\n", priv->bytes);
-
- /* Enable the controller for DMA programming */
- fpga_programmer_enable(priv, true);
- dev_dbg(priv->dev, "enabled the controller\n");
-
- /* Wait for the interrupt handler to signal that programming finished */
- ret = wait_for_completion_timeout(&priv->completion, 2 * HZ);
- if (!ret) {
- dev_err(priv->dev, "Timed out waiting for completion\n");
- ret = -ETIMEDOUT;
- goto out_disable_controller;
- }
-
- /* Retrieve the status from the interrupt handler */
- ret = priv->status;
-
-out_disable_controller:
- fpga_programmer_disable(priv);
-out_dma_unmap:
- videobuf_dma_unmap(priv->dev, vb);
-out_free_table:
- sg_free_table(&table);
-out_return:
- return ret;
-}
-
-/*
- * Interrupt Handling
- */
-
-static irqreturn_t fpga_irq(int irq, void *dev_id)
-{
- struct fpga_dev *priv = dev_id;
-
- /* Save the status */
- priv->status = fpga_config_error(priv->regs) ? -EIO : 0;
- dev_dbg(priv->dev, "INTERRUPT status %d\n", priv->status);
- fpga_dump_registers(priv);
-
- /* Disabling the programmer clears the interrupt */
- fpga_programmer_disable(priv);
-
- /* Notify any waiters */
- complete(&priv->completion);
-
- return IRQ_HANDLED;
-}
-
-/*
- * SYSFS Helpers
- */
-
-/**
- * fpga_do_stop() - deconfigure (reset) the DATA-FPGA's
- * @priv: the driver's private data structure
- *
- * LOCKING: must hold priv->lock
- */
-static int fpga_do_stop(struct fpga_dev *priv)
-{
- u32 val;
-
- /* Set the led to unprogrammed */
- ledtrig_fpga_programmed(false);
-
- /* Pulse the config line to reset the FPGA's */
- val = CFG_CTL_ENABLE | CFG_CTL_RESET;
- iowrite32be(val, priv->regs + FPGA_CONFIG_CONTROL);
- iowrite32be(0x0, priv->regs + FPGA_CONFIG_CONTROL);
-
- return 0;
-}
-
-static noinline int fpga_do_program(struct fpga_dev *priv)
-{
- int ret;
-
- if (priv->bytes != priv->fw_size) {
- dev_err(priv->dev, "Incorrect bitfile size: got %zu bytes, "
- "should be %zu bytes\n",
- priv->bytes, priv->fw_size);
- return -EINVAL;
- }
-
- if (!fpga_power_enabled(priv)) {
- dev_err(priv->dev, "Power not enabled\n");
- return -EINVAL;
- }
-
- if (!fpga_power_good(priv)) {
- dev_err(priv->dev, "Power not good\n");
- return -EINVAL;
- }
-
- /* Set the LED to unprogrammed */
- ledtrig_fpga_programmed(false);
-
- /* Try to program the FPGA's using DMA */
- ret = fpga_program_dma(priv);
-
- /* If DMA failed or doesn't exist, try with CPU */
- if (ret) {
- dev_warn(priv->dev, "Falling back to CPU programming\n");
- ret = fpga_program_cpu(priv);
- }
-
- if (ret) {
- dev_err(priv->dev, "Unable to program FPGA's\n");
- return ret;
- }
-
- /* Drop the firmware bitfile from memory */
- fpga_drop_firmware_data(priv);
-
- dev_dbg(priv->dev, "FPGA programming successful\n");
- ledtrig_fpga_programmed(true);
-
- return 0;
-}
-
-/*
- * File Operations
- */
-
-static int fpga_open(struct inode *inode, struct file *filp)
-{
- /*
- * The miscdevice layer puts our struct miscdevice into the
- * filp->private_data field. We use this to find our private
- * data and then overwrite it with our own private structure.
- */
- struct fpga_dev *priv = container_of(filp->private_data,
- struct fpga_dev, miscdev);
- unsigned int nr_pages;
- int ret;
-
- /* We only allow one process at a time */
- ret = mutex_lock_interruptible(&priv->lock);
- if (ret)
- return ret;
-
- filp->private_data = priv;
- kref_get(&priv->ref);
-
- /* Truncation: drop any existing data */
- if (filp->f_flags & O_TRUNC)
- priv->bytes = 0;
-
- /* Check if we have already allocated a buffer */
- if (priv->vb_allocated)
- return 0;
-
- /* Allocate a buffer to hold enough data for the bitfile */
- nr_pages = DIV_ROUND_UP(priv->fw_size, PAGE_SIZE);
- ret = videobuf_dma_init_kernel(&priv->vb, DMA_TO_DEVICE, nr_pages);
- if (ret) {
- dev_err(priv->dev, "unable to allocate data buffer\n");
- mutex_unlock(&priv->lock);
- kref_put(&priv->ref, fpga_dev_remove);
- return ret;
- }
-
- priv->vb_allocated = true;
- return 0;
-}
-
-static int fpga_release(struct inode *inode, struct file *filp)
-{
- struct fpga_dev *priv = filp->private_data;
-
- mutex_unlock(&priv->lock);
- kref_put(&priv->ref, fpga_dev_remove);
- return 0;
-}
-
-static ssize_t fpga_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *f_pos)
-{
- struct fpga_dev *priv = filp->private_data;
-
- /* FPGA bitfiles have an exact size: disallow anything else */
- if (priv->bytes >= priv->fw_size)
- return -ENOSPC;
-
- count = min_t(size_t, priv->fw_size - priv->bytes, count);
- if (copy_from_user(priv->vb.vaddr + priv->bytes, buf, count))
- return -EFAULT;
-
- priv->bytes += count;
- return count;
-}
-
-static ssize_t fpga_read(struct file *filp, char __user *buf, size_t count,
- loff_t *f_pos)
-{
- struct fpga_dev *priv = filp->private_data;
-
- count = min_t(size_t, priv->bytes - *f_pos, count);
- if (copy_to_user(buf, priv->vb.vaddr + *f_pos, count))
- return -EFAULT;
-
- *f_pos += count;
- return count;
-}
-
-static loff_t fpga_llseek(struct file *filp, loff_t offset, int origin)
-{
- struct fpga_dev *priv = filp->private_data;
- loff_t newpos;
-
- /* only read-only opens are allowed to seek */
- if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
- return -EINVAL;
-
- switch (origin) {
- case SEEK_SET: /* seek relative to the beginning of the file */
- newpos = offset;
- break;
- case SEEK_CUR: /* seek relative to current position in the file */
- newpos = filp->f_pos + offset;
- break;
- case SEEK_END: /* seek relative to the end of the file */
- newpos = priv->fw_size - offset;
- break;
- default:
- return -EINVAL;
- }
-
- /* check for sanity */
- if (newpos > priv->fw_size)
- return -EINVAL;
-
- filp->f_pos = newpos;
- return newpos;
-}
-
-static const struct file_operations fpga_fops = {
- .open = fpga_open,
- .release = fpga_release,
- .write = fpga_write,
- .read = fpga_read,
- .llseek = fpga_llseek,
-};
-
-/*
- * Device Attributes
- */
-
-static ssize_t pfail_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct fpga_dev *priv = dev_get_drvdata(dev);
- u8 val;
-
- val = ioread8(priv->regs + CTL_PWR_FAIL);
- return snprintf(buf, PAGE_SIZE, "0x%.2x\n", val);
-}
-
-static ssize_t pgood_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct fpga_dev *priv = dev_get_drvdata(dev);
- return snprintf(buf, PAGE_SIZE, "%d\n", fpga_power_good(priv));
-}
-
-static ssize_t penable_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct fpga_dev *priv = dev_get_drvdata(dev);
- return snprintf(buf, PAGE_SIZE, "%d\n", fpga_power_enabled(priv));
-}
-
-static ssize_t penable_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct fpga_dev *priv = dev_get_drvdata(dev);
- unsigned long val;
- int ret;
-
- if (strict_strtoul(buf, 0, &val))
- return -EINVAL;
-
- if (val) {
- ret = fpga_enable_power_supplies(priv);
- if (ret)
- return ret;
- } else {
- fpga_do_stop(priv);
- fpga_disable_power_supplies(priv);
- }
-
- return count;
-}
-
-static ssize_t program_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct fpga_dev *priv = dev_get_drvdata(dev);
- return snprintf(buf, PAGE_SIZE, "%d\n", fpga_running(priv));
-}
-
-static ssize_t program_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct fpga_dev *priv = dev_get_drvdata(dev);
- unsigned long val;
- int ret;
-
- if (strict_strtoul(buf, 0, &val))
- return -EINVAL;
-
- /* We can't have an image writer and be programming simultaneously */
- if (mutex_lock_interruptible(&priv->lock))
- return -ERESTARTSYS;
-
- /* Program or Reset the FPGA's */
- ret = val ? fpga_do_program(priv) : fpga_do_stop(priv);
- if (ret)
- goto out_unlock;
-
- /* Success */
- ret = count;
-
-out_unlock:
- mutex_unlock(&priv->lock);
- return ret;
-}
-
-static DEVICE_ATTR(power_fail, S_IRUGO, pfail_show, NULL);
-static DEVICE_ATTR(power_good, S_IRUGO, pgood_show, NULL);
-static DEVICE_ATTR(power_enable, S_IRUGO | S_IWUSR,
- penable_show, penable_store);
-
-static DEVICE_ATTR(program, S_IRUGO | S_IWUSR,
- program_show, program_store);
-
-static struct attribute *fpga_attributes[] = {
- &dev_attr_power_fail.attr,
- &dev_attr_power_good.attr,
- &dev_attr_power_enable.attr,
- &dev_attr_program.attr,
- NULL,
-};
-
-static const struct attribute_group fpga_attr_group = {
- .attrs = fpga_attributes,
-};
-
-/*
- * OpenFirmware Device Subsystem
- */
-
-#define SYS_REG_VERSION 0x00
-#define SYS_REG_GEOGRAPHIC 0x10
-
-static bool dma_filter(struct dma_chan *chan, void *data)
-{
- /*
- * DMA Channel #0 is the only acceptable device
- *
- * This probably won't survive an unload/load cycle of the Freescale
- * DMAEngine driver, but that won't be a problem
- */
- return chan->chan_id == 0 && chan->device->dev_id == 0;
-}
-
-static int fpga_of_remove(struct platform_device *op)
-{
- struct fpga_dev *priv = dev_get_drvdata(&op->dev);
- struct device *this_device = priv->miscdev.this_device;
-
- sysfs_remove_group(&this_device->kobj, &fpga_attr_group);
- misc_deregister(&priv->miscdev);
-
- free_irq(priv->irq, priv);
- irq_dispose_mapping(priv->irq);
-
- /* make sure the power supplies are off */
- fpga_disable_power_supplies(priv);
-
- /* unmap registers */
- iounmap(priv->immr);
- iounmap(priv->regs);
-
- dma_release_channel(priv->chan);
-
- /* drop our reference to the private data structure */
- kref_put(&priv->ref, fpga_dev_remove);
- return 0;
-}
-
-/* CTL-CPLD Version Register */
-#define CTL_CPLD_VERSION 0x2000
-
-static int fpga_of_probe(struct platform_device *op)
-{
- struct device_node *of_node = op->dev.of_node;
- struct device *this_device;
- struct fpga_dev *priv;
- dma_cap_mask_t mask;
- u32 ver;
- int ret;
-
- /* Allocate private data */
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&op->dev, "Unable to allocate private data\n");
- ret = -ENOMEM;
- goto out_return;
- }
-
- /* Setup the miscdevice */
- priv->miscdev.minor = MISC_DYNAMIC_MINOR;
- priv->miscdev.name = drv_name;
- priv->miscdev.fops = &fpga_fops;
-
- kref_init(&priv->ref);
-
- dev_set_drvdata(&op->dev, priv);
- priv->dev = &op->dev;
- mutex_init(&priv->lock);
- init_completion(&priv->completion);
- videobuf_dma_init(&priv->vb);
-
- dev_set_drvdata(priv->dev, priv);
- dma_cap_zero(mask);
- dma_cap_set(DMA_MEMCPY, mask);
- dma_cap_set(DMA_INTERRUPT, mask);
- dma_cap_set(DMA_SLAVE, mask);
- dma_cap_set(DMA_SG, mask);
-
- /* Get control of DMA channel #0 */
- priv->chan = dma_request_channel(mask, dma_filter, NULL);
- if (!priv->chan) {
- dev_err(&op->dev, "Unable to acquire DMA channel #0\n");
- ret = -ENODEV;
- goto out_free_priv;
- }
-
- /* Remap the registers for use */
- priv->regs = of_iomap(of_node, 0);
- if (!priv->regs) {
- dev_err(&op->dev, "Unable to ioremap registers\n");
- ret = -ENOMEM;
- goto out_dma_release_channel;
- }
-
- /* Remap the IMMR for use */
- priv->immr = ioremap(get_immrbase(), 0x100000);
- if (!priv->immr) {
- dev_err(&op->dev, "Unable to ioremap IMMR\n");
- ret = -ENOMEM;
- goto out_unmap_regs;
- }
-
- /*
- * Check that external DMA is configured
- *
- * U-Boot does this for us, but we should check it and bail out if
- * there is a problem. Failing to have this register setup correctly
- * will cause the DMA controller to transfer a single cacheline
- * worth of data, then wedge itself.
- */
- if ((ioread32be(priv->immr + 0x114) & 0xE00) != 0xE00) {
- dev_err(&op->dev, "External DMA control not configured\n");
- ret = -ENODEV;
- goto out_unmap_immr;
- }
-
- /*
- * Check the CTL-CPLD version
- *
- * This driver uses the CTL-CPLD DATA-FPGA power sequencer, and we
- * don't want to run on any version of the CTL-CPLD that does not use
- * a compatible register layout.
- *
- * v2: changed register layout, added power sequencer
- * v3: added glitch filter on the i2c overcurrent/overtemp outputs
- */
- ver = ioread8(priv->regs + CTL_CPLD_VERSION);
- if (ver != 0x02 && ver != 0x03) {
- dev_err(&op->dev, "CTL-CPLD is not version 0x02 or 0x03!\n");
- ret = -ENODEV;
- goto out_unmap_immr;
- }
-
- /* Set the exact size that the firmware image should be */
- ver = ioread32be(priv->regs + SYS_REG_VERSION);
- priv->fw_size = (ver & (1 << 18)) ? FW_SIZE_EP2S130 : FW_SIZE_EP2S90;
-
- /* Find the correct IRQ number */
- priv->irq = irq_of_parse_and_map(of_node, 0);
- if (priv->irq == NO_IRQ) {
- dev_err(&op->dev, "Unable to find IRQ line\n");
- ret = -ENODEV;
- goto out_unmap_immr;
- }
-
- /* Request the IRQ */
- ret = request_irq(priv->irq, fpga_irq, IRQF_SHARED, drv_name, priv);
- if (ret) {
- dev_err(&op->dev, "Unable to request IRQ %d\n", priv->irq);
- ret = -ENODEV;
- goto out_irq_dispose_mapping;
- }
-
- /* Reset and stop the FPGA's, just in case */
- fpga_do_stop(priv);
-
- /* Register the miscdevice */
- ret = misc_register(&priv->miscdev);
- if (ret) {
- dev_err(&op->dev, "Unable to register miscdevice\n");
- goto out_free_irq;
- }
-
- /* Create the sysfs files */
- this_device = priv->miscdev.this_device;
- dev_set_drvdata(this_device, priv);
- ret = sysfs_create_group(&this_device->kobj, &fpga_attr_group);
- if (ret) {
- dev_err(&op->dev, "Unable to create sysfs files\n");
- goto out_misc_deregister;
- }
-
- dev_info(priv->dev, "CARMA FPGA Programmer: %s rev%s with %s FPGAs\n",
- (ver & (1 << 17)) ? "Correlator" : "Digitizer",
- (ver & (1 << 16)) ? "B" : "A",
- (ver & (1 << 18)) ? "EP2S130" : "EP2S90");
-
- return 0;
-
-out_misc_deregister:
- misc_deregister(&priv->miscdev);
-out_free_irq:
- free_irq(priv->irq, priv);
-out_irq_dispose_mapping:
- irq_dispose_mapping(priv->irq);
-out_unmap_immr:
- iounmap(priv->immr);
-out_unmap_regs:
- iounmap(priv->regs);
-out_dma_release_channel:
- dma_release_channel(priv->chan);
-out_free_priv:
- kref_put(&priv->ref, fpga_dev_remove);
-out_return:
- return ret;
-}
-
-static struct of_device_id fpga_of_match[] = {
- { .compatible = "carma,fpga-programmer", },
- {},
-};
-
-static struct platform_driver fpga_of_driver = {
- .probe = fpga_of_probe,
- .remove = fpga_of_remove,
- .driver = {
- .name = drv_name,
- .of_match_table = fpga_of_match,
- .owner = THIS_MODULE,
- },
-};
-
-/*
- * Module Init / Exit
- */
-
-static int __init fpga_init(void)
-{
- led_trigger_register_simple("fpga", &ledtrig_fpga);
- return platform_driver_register(&fpga_of_driver);
-}
-
-static void __exit fpga_exit(void)
-{
- platform_driver_unregister(&fpga_of_driver);
- led_trigger_unregister_simple(ledtrig_fpga);
-}
-
-MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
-MODULE_DESCRIPTION("CARMA Board DATA-FPGA Programmer");
-MODULE_LICENSE("GPL");
-
-module_init(fpga_init);
-module_exit(fpga_exit);
diff --git a/ANDROID_3.4.5/drivers/misc/carma/carma-fpga.c b/ANDROID_3.4.5/drivers/misc/carma/carma-fpga.c
deleted file mode 100644
index 8c279da0..00000000
--- a/ANDROID_3.4.5/drivers/misc/carma/carma-fpga.c
+++ /dev/null
@@ -1,1447 +0,0 @@
-/*
- * CARMA DATA-FPGA Access Driver
- *
- * Copyright (c) 2009-2011 Ira W. Snyder <iws@ovro.caltech.edu>
- *
- * This program is free software; you can redistribute 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.
- */
-
-/*
- * FPGA Memory Dump Format
- *
- * FPGA #0 control registers (32 x 32-bit words)
- * FPGA #1 control registers (32 x 32-bit words)
- * FPGA #2 control registers (32 x 32-bit words)
- * FPGA #3 control registers (32 x 32-bit words)
- * SYSFPGA control registers (32 x 32-bit words)
- * FPGA #0 correlation array (NUM_CORL0 correlation blocks)
- * FPGA #1 correlation array (NUM_CORL1 correlation blocks)
- * FPGA #2 correlation array (NUM_CORL2 correlation blocks)
- * FPGA #3 correlation array (NUM_CORL3 correlation blocks)
- *
- * Each correlation array consists of:
- *
- * Correlation Data (2 x NUM_LAGSn x 32-bit words)
- * Pipeline Metadata (2 x NUM_METAn x 32-bit words)
- * Quantization Counters (2 x NUM_QCNTn x 32-bit words)
- *
- * The NUM_CORLn, NUM_LAGSn, NUM_METAn, and NUM_QCNTn values come from
- * the FPGA configuration registers. They do not change once the FPGA's
- * have been programmed, they only change on re-programming.
- */
-
-/*
- * Basic Description:
- *
- * This driver is used to capture correlation spectra off of the four data
- * processing FPGAs. The FPGAs are often reprogrammed at runtime, therefore
- * this driver supports dynamic enable/disable of capture while the device
- * remains open.
- *
- * The nominal capture rate is 64Hz (every 15.625ms). To facilitate this fast
- * capture rate, all buffers are pre-allocated to avoid any potentially long
- * running memory allocations while capturing.
- *
- * There are two lists and one pointer which are used to keep track of the
- * different states of data buffers.
- *
- * 1) free list
- * This list holds all empty data buffers which are ready to receive data.
- *
- * 2) inflight pointer
- * This pointer holds the currently inflight data buffer. This buffer is having
- * data copied into it by the DMA engine.
- *
- * 3) used list
- * This list holds data buffers which have been filled, and are waiting to be
- * read by userspace.
- *
- * All buffers start life on the free list, then move successively to the
- * inflight pointer, and then to the used list. After they have been read by
- * userspace, they are moved back to the free list. The cycle repeats as long
- * as necessary.
- *
- * It should be noted that all buffers are mapped and ready for DMA when they
- * are on any of the three lists. They are only unmapped when they are in the
- * process of being read by userspace.
- */
-
-/*
- * Notes on the IRQ masking scheme:
- *
- * The IRQ masking scheme here is different than most other hardware. The only
- * way for the DATA-FPGAs to detect if the kernel has taken too long to copy
- * the data is if the status registers are not cleared before the next
- * correlation data dump is ready.
- *
- * The interrupt line is connected to the status registers, such that when they
- * are cleared, the interrupt is de-asserted. Therein lies our problem. We need
- * to schedule a long-running DMA operation and return from the interrupt
- * handler quickly, but we cannot clear the status registers.
- *
- * To handle this, the system controller FPGA has the capability to connect the
- * interrupt line to a user-controlled GPIO pin. This pin is driven high
- * (unasserted) and left that way. To mask the interrupt, we change the
- * interrupt source to the GPIO pin. Tada, we hid the interrupt. :)
- */
-
-#include <linux/of_platform.h>
-#include <linux/dma-mapping.h>
-#include <linux/miscdevice.h>
-#include <linux/interrupt.h>
-#include <linux/dmaengine.h>
-#include <linux/seq_file.h>
-#include <linux/highmem.h>
-#include <linux/debugfs.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/kref.h>
-#include <linux/io.h>
-
-#include <media/videobuf-dma-sg.h>
-
-/* system controller registers */
-#define SYS_IRQ_SOURCE_CTL 0x24
-#define SYS_IRQ_OUTPUT_EN 0x28
-#define SYS_IRQ_OUTPUT_DATA 0x2C
-#define SYS_IRQ_INPUT_DATA 0x30
-#define SYS_FPGA_CONFIG_STATUS 0x44
-
-/* GPIO IRQ line assignment */
-#define IRQ_CORL_DONE 0x10
-
-/* FPGA registers */
-#define MMAP_REG_VERSION 0x00
-#define MMAP_REG_CORL_CONF1 0x08
-#define MMAP_REG_CORL_CONF2 0x0C
-#define MMAP_REG_STATUS 0x48
-
-#define SYS_FPGA_BLOCK 0xF0000000
-
-#define DATA_FPGA_START 0x400000
-#define DATA_FPGA_SIZE 0x80000
-
-static const char drv_name[] = "carma-fpga";
-
-#define NUM_FPGA 4
-
-#define MIN_DATA_BUFS 8
-#define MAX_DATA_BUFS 64
-
-struct fpga_info {
- unsigned int num_lag_ram;
- unsigned int blk_size;
-};
-
-struct data_buf {
- struct list_head entry;
- struct videobuf_dmabuf vb;
- size_t size;
-};
-
-struct fpga_device {
- /* character device */
- struct miscdevice miscdev;
- struct device *dev;
- struct mutex mutex;
-
- /* reference count */
- struct kref ref;
-
- /* FPGA registers and information */
- struct fpga_info info[NUM_FPGA];
- void __iomem *regs;
- int irq;
-
- /* FPGA Physical Address/Size Information */
- resource_size_t phys_addr;
- size_t phys_size;
-
- /* DMA structures */
- struct sg_table corl_table;
- unsigned int corl_nents;
- struct dma_chan *chan;
-
- /* Protection for all members below */
- spinlock_t lock;
-
- /* Device enable/disable flag */
- bool enabled;
-
- /* Correlation data buffers */
- wait_queue_head_t wait;
- struct list_head free;
- struct list_head used;
- struct data_buf *inflight;
-
- /* Information about data buffers */
- unsigned int num_dropped;
- unsigned int num_buffers;
- size_t bufsize;
- struct dentry *dbg_entry;
-};
-
-struct fpga_reader {
- struct fpga_device *priv;
- struct data_buf *buf;
- off_t buf_start;
-};
-
-static void fpga_device_release(struct kref *ref)
-{
- struct fpga_device *priv = container_of(ref, struct fpga_device, ref);
-
- /* the last reader has exited, cleanup the last bits */
- mutex_destroy(&priv->mutex);
- kfree(priv);
-}
-
-/*
- * Data Buffer Allocation Helpers
- */
-
-/**
- * data_free_buffer() - free a single data buffer and all allocated memory
- * @buf: the buffer to free
- *
- * This will free all of the pages allocated to the given data buffer, and
- * then free the structure itself
- */
-static void data_free_buffer(struct data_buf *buf)
-{
- /* It is ok to free a NULL buffer */
- if (!buf)
- return;
-
- /* free all memory */
- videobuf_dma_free(&buf->vb);
- kfree(buf);
-}
-
-/**
- * data_alloc_buffer() - allocate and fill a data buffer with pages
- * @bytes: the number of bytes required
- *
- * This allocates all space needed for a data buffer. It must be mapped before
- * use in a DMA transaction using videobuf_dma_map().
- *
- * Returns NULL on failure
- */
-static struct data_buf *data_alloc_buffer(const size_t bytes)
-{
- unsigned int nr_pages;
- struct data_buf *buf;
- int ret;
-
- /* calculate the number of pages necessary */
- nr_pages = DIV_ROUND_UP(bytes, PAGE_SIZE);
-
- /* allocate the buffer structure */
- buf = kzalloc(sizeof(*buf), GFP_KERNEL);
- if (!buf)
- goto out_return;
-
- /* initialize internal fields */
- INIT_LIST_HEAD(&buf->entry);
- buf->size = bytes;
-
- /* allocate the videobuf */
- videobuf_dma_init(&buf->vb);
- ret = videobuf_dma_init_kernel(&buf->vb, DMA_FROM_DEVICE, nr_pages);
- if (ret)
- goto out_free_buf;
-
- return buf;
-
-out_free_buf:
- kfree(buf);
-out_return:
- return NULL;
-}
-
-/**
- * data_free_buffers() - free all allocated buffers
- * @priv: the driver's private data structure
- *
- * Free all buffers allocated by the driver (except those currently in the
- * process of being read by userspace).
- *
- * LOCKING: must hold dev->mutex
- * CONTEXT: user
- */
-static void data_free_buffers(struct fpga_device *priv)
-{
- struct data_buf *buf, *tmp;
-
- /* the device should be stopped, no DMA in progress */
- BUG_ON(priv->inflight != NULL);
-
- list_for_each_entry_safe(buf, tmp, &priv->free, entry) {
- list_del_init(&buf->entry);
- videobuf_dma_unmap(priv->dev, &buf->vb);
- data_free_buffer(buf);
- }
-
- list_for_each_entry_safe(buf, tmp, &priv->used, entry) {
- list_del_init(&buf->entry);
- videobuf_dma_unmap(priv->dev, &buf->vb);
- data_free_buffer(buf);
- }
-
- priv->num_buffers = 0;
- priv->bufsize = 0;
-}
-
-/**
- * data_alloc_buffers() - allocate 1 seconds worth of data buffers
- * @priv: the driver's private data structure
- *
- * Allocate enough buffers for a whole second worth of data
- *
- * This routine will attempt to degrade nicely by succeeding even if a full
- * second worth of data buffers could not be allocated, as long as a minimum
- * number were allocated. In this case, it will print a message to the kernel
- * log.
- *
- * The device must not be modifying any lists when this is called.
- *
- * CONTEXT: user
- * LOCKING: must hold dev->mutex
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int data_alloc_buffers(struct fpga_device *priv)
-{
- struct data_buf *buf;
- int i, ret;
-
- for (i = 0; i < MAX_DATA_BUFS; i++) {
-
- /* allocate a buffer */
- buf = data_alloc_buffer(priv->bufsize);
- if (!buf)
- break;
-
- /* map it for DMA */
- ret = videobuf_dma_map(priv->dev, &buf->vb);
- if (ret) {
- data_free_buffer(buf);
- break;
- }
-
- /* add it to the list of free buffers */
- list_add_tail(&buf->entry, &priv->free);
- priv->num_buffers++;
- }
-
- /* Make sure we allocated the minimum required number of buffers */
- if (priv->num_buffers < MIN_DATA_BUFS) {
- dev_err(priv->dev, "Unable to allocate enough data buffers\n");
- data_free_buffers(priv);
- return -ENOMEM;
- }
-
- /* Warn if we are running in a degraded state, but do not fail */
- if (priv->num_buffers < MAX_DATA_BUFS) {
- dev_warn(priv->dev,
- "Unable to allocate %d buffers, using %d buffers instead\n",
- MAX_DATA_BUFS, i);
- }
-
- return 0;
-}
-
-/*
- * DMA Operations Helpers
- */
-
-/**
- * fpga_start_addr() - get the physical address a DATA-FPGA
- * @priv: the driver's private data structure
- * @fpga: the DATA-FPGA number (zero based)
- */
-static dma_addr_t fpga_start_addr(struct fpga_device *priv, unsigned int fpga)
-{
- return priv->phys_addr + 0x400000 + (0x80000 * fpga);
-}
-
-/**
- * fpga_block_addr() - get the physical address of a correlation data block
- * @priv: the driver's private data structure
- * @fpga: the DATA-FPGA number (zero based)
- * @blknum: the correlation block number (zero based)
- */
-static dma_addr_t fpga_block_addr(struct fpga_device *priv, unsigned int fpga,
- unsigned int blknum)
-{
- return fpga_start_addr(priv, fpga) + (0x10000 * (1 + blknum));
-}
-
-#define REG_BLOCK_SIZE (32 * 4)
-
-/**
- * data_setup_corl_table() - create the scatterlist for correlation dumps
- * @priv: the driver's private data structure
- *
- * Create the scatterlist for transferring a correlation dump from the
- * DATA FPGAs. This structure will be reused for each buffer than needs
- * to be filled with correlation data.
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int data_setup_corl_table(struct fpga_device *priv)
-{
- struct sg_table *table = &priv->corl_table;
- struct scatterlist *sg;
- struct fpga_info *info;
- int i, j, ret;
-
- /* Calculate the number of entries needed */
- priv->corl_nents = (1 + NUM_FPGA) * REG_BLOCK_SIZE;
- for (i = 0; i < NUM_FPGA; i++)
- priv->corl_nents += priv->info[i].num_lag_ram;
-
- /* Allocate the scatterlist table */
- ret = sg_alloc_table(table, priv->corl_nents, GFP_KERNEL);
- if (ret) {
- dev_err(priv->dev, "unable to allocate DMA table\n");
- return ret;
- }
-
- /* Add the DATA FPGA registers to the scatterlist */
- sg = table->sgl;
- for (i = 0; i < NUM_FPGA; i++) {
- sg_dma_address(sg) = fpga_start_addr(priv, i);
- sg_dma_len(sg) = REG_BLOCK_SIZE;
- sg = sg_next(sg);
- }
-
- /* Add the SYS-FPGA registers to the scatterlist */
- sg_dma_address(sg) = SYS_FPGA_BLOCK;
- sg_dma_len(sg) = REG_BLOCK_SIZE;
- sg = sg_next(sg);
-
- /* Add the FPGA correlation data blocks to the scatterlist */
- for (i = 0; i < NUM_FPGA; i++) {
- info = &priv->info[i];
- for (j = 0; j < info->num_lag_ram; j++) {
- sg_dma_address(sg) = fpga_block_addr(priv, i, j);
- sg_dma_len(sg) = info->blk_size;
- sg = sg_next(sg);
- }
- }
-
- /*
- * All physical addresses and lengths are present in the structure
- * now. It can be reused for every FPGA DATA interrupt
- */
- return 0;
-}
-
-/*
- * FPGA Register Access Helpers
- */
-
-static void fpga_write_reg(struct fpga_device *priv, unsigned int fpga,
- unsigned int reg, u32 val)
-{
- const int fpga_start = DATA_FPGA_START + (fpga * DATA_FPGA_SIZE);
- iowrite32be(val, priv->regs + fpga_start + reg);
-}
-
-static u32 fpga_read_reg(struct fpga_device *priv, unsigned int fpga,
- unsigned int reg)
-{
- const int fpga_start = DATA_FPGA_START + (fpga * DATA_FPGA_SIZE);
- return ioread32be(priv->regs + fpga_start + reg);
-}
-
-/**
- * data_calculate_bufsize() - calculate the data buffer size required
- * @priv: the driver's private data structure
- *
- * Calculate the total buffer size needed to hold a single block
- * of correlation data
- *
- * CONTEXT: user
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int data_calculate_bufsize(struct fpga_device *priv)
-{
- u32 num_corl, num_lags, num_meta, num_qcnt, num_pack;
- u32 conf1, conf2, version;
- u32 num_lag_ram, blk_size;
- int i;
-
- /* Each buffer starts with the 5 FPGA register areas */
- priv->bufsize = (1 + NUM_FPGA) * REG_BLOCK_SIZE;
-
- /* Read and store the configuration data for each FPGA */
- for (i = 0; i < NUM_FPGA; i++) {
- version = fpga_read_reg(priv, i, MMAP_REG_VERSION);
- conf1 = fpga_read_reg(priv, i, MMAP_REG_CORL_CONF1);
- conf2 = fpga_read_reg(priv, i, MMAP_REG_CORL_CONF2);
-
- /* minor version 2 and later */
- if ((version & 0x000000FF) >= 2) {
- num_corl = (conf1 & 0x000000F0) >> 4;
- num_pack = (conf1 & 0x00000F00) >> 8;
- num_lags = (conf1 & 0x00FFF000) >> 12;
- num_meta = (conf1 & 0x7F000000) >> 24;
- num_qcnt = (conf2 & 0x00000FFF) >> 0;
- } else {
- num_corl = (conf1 & 0x000000F0) >> 4;
- num_pack = 1; /* implied */
- num_lags = (conf1 & 0x000FFF00) >> 8;
- num_meta = (conf1 & 0x7FF00000) >> 20;
- num_qcnt = (conf2 & 0x00000FFF) >> 0;
- }
-
- num_lag_ram = (num_corl + num_pack - 1) / num_pack;
- blk_size = ((num_pack * num_lags) + num_meta + num_qcnt) * 8;
-
- priv->info[i].num_lag_ram = num_lag_ram;
- priv->info[i].blk_size = blk_size;
- priv->bufsize += num_lag_ram * blk_size;
-
- dev_dbg(priv->dev, "FPGA %d NUM_CORL: %d\n", i, num_corl);
- dev_dbg(priv->dev, "FPGA %d NUM_PACK: %d\n", i, num_pack);
- dev_dbg(priv->dev, "FPGA %d NUM_LAGS: %d\n", i, num_lags);
- dev_dbg(priv->dev, "FPGA %d NUM_META: %d\n", i, num_meta);
- dev_dbg(priv->dev, "FPGA %d NUM_QCNT: %d\n", i, num_qcnt);
- dev_dbg(priv->dev, "FPGA %d BLK_SIZE: %d\n", i, blk_size);
- }
-
- dev_dbg(priv->dev, "TOTAL BUFFER SIZE: %zu bytes\n", priv->bufsize);
- return 0;
-}
-
-/*
- * Interrupt Handling
- */
-
-/**
- * data_disable_interrupts() - stop the device from generating interrupts
- * @priv: the driver's private data structure
- *
- * Hide interrupts by switching to GPIO interrupt source
- *
- * LOCKING: must hold dev->lock
- */
-static void data_disable_interrupts(struct fpga_device *priv)
-{
- /* hide the interrupt by switching the IRQ driver to GPIO */
- iowrite32be(0x2F, priv->regs + SYS_IRQ_SOURCE_CTL);
-}
-
-/**
- * data_enable_interrupts() - allow the device to generate interrupts
- * @priv: the driver's private data structure
- *
- * Unhide interrupts by switching to the FPGA interrupt source. At the
- * same time, clear the DATA-FPGA status registers.
- *
- * LOCKING: must hold dev->lock
- */
-static void data_enable_interrupts(struct fpga_device *priv)
-{
- /* clear the actual FPGA corl_done interrupt */
- fpga_write_reg(priv, 0, MMAP_REG_STATUS, 0x0);
- fpga_write_reg(priv, 1, MMAP_REG_STATUS, 0x0);
- fpga_write_reg(priv, 2, MMAP_REG_STATUS, 0x0);
- fpga_write_reg(priv, 3, MMAP_REG_STATUS, 0x0);
-
- /* flush the writes */
- fpga_read_reg(priv, 0, MMAP_REG_STATUS);
- fpga_read_reg(priv, 1, MMAP_REG_STATUS);
- fpga_read_reg(priv, 2, MMAP_REG_STATUS);
- fpga_read_reg(priv, 3, MMAP_REG_STATUS);
-
- /* switch back to the external interrupt source */
- iowrite32be(0x3F, priv->regs + SYS_IRQ_SOURCE_CTL);
-}
-
-/**
- * data_dma_cb() - DMAEngine callback for DMA completion
- * @data: the driver's private data structure
- *
- * Complete a DMA transfer from the DATA-FPGA's
- *
- * This is called via the DMA callback mechanism, and will handle moving the
- * completed DMA transaction to the used list, and then wake any processes
- * waiting for new data
- *
- * CONTEXT: any, softirq expected
- */
-static void data_dma_cb(void *data)
-{
- struct fpga_device *priv = data;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- /* If there is no inflight buffer, we've got a bug */
- BUG_ON(priv->inflight == NULL);
-
- /* Move the inflight buffer onto the used list */
- list_move_tail(&priv->inflight->entry, &priv->used);
- priv->inflight = NULL;
-
- /*
- * If data dumping is still enabled, then clear the FPGA
- * status registers and re-enable FPGA interrupts
- */
- if (priv->enabled)
- data_enable_interrupts(priv);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /*
- * We've changed both the inflight and used lists, so we need
- * to wake up any processes that are blocking for those events
- */
- wake_up(&priv->wait);
-}
-
-/**
- * data_submit_dma() - prepare and submit the required DMA to fill a buffer
- * @priv: the driver's private data structure
- * @buf: the data buffer
- *
- * Prepare and submit the necessary DMA transactions to fill a correlation
- * data buffer.
- *
- * LOCKING: must hold dev->lock
- * CONTEXT: hardirq only
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int data_submit_dma(struct fpga_device *priv, struct data_buf *buf)
-{
- struct scatterlist *dst_sg, *src_sg;
- unsigned int dst_nents, src_nents;
- struct dma_chan *chan = priv->chan;
- struct dma_async_tx_descriptor *tx;
- dma_cookie_t cookie;
- dma_addr_t dst, src;
-
- dst_sg = buf->vb.sglist;
- dst_nents = buf->vb.sglen;
-
- src_sg = priv->corl_table.sgl;
- src_nents = priv->corl_nents;
-
- /*
- * All buffers passed to this function should be ready and mapped
- * for DMA already. Therefore, we don't need to do anything except
- * submit it to the Freescale DMA Engine for processing
- */
-
- /* setup the scatterlist to scatterlist transfer */
- tx = chan->device->device_prep_dma_sg(chan,
- dst_sg, dst_nents,
- src_sg, src_nents,
- 0);
- if (!tx) {
- dev_err(priv->dev, "unable to prep scatterlist DMA\n");
- return -ENOMEM;
- }
-
- /* submit the transaction to the DMA controller */
- cookie = tx->tx_submit(tx);
- if (dma_submit_error(cookie)) {
- dev_err(priv->dev, "unable to submit scatterlist DMA\n");
- return -ENOMEM;
- }
-
- /* Prepare the re-read of the SYS-FPGA block */
- dst = sg_dma_address(dst_sg) + (NUM_FPGA * REG_BLOCK_SIZE);
- src = SYS_FPGA_BLOCK;
- tx = chan->device->device_prep_dma_memcpy(chan, dst, src,
- REG_BLOCK_SIZE,
- DMA_PREP_INTERRUPT);
- if (!tx) {
- dev_err(priv->dev, "unable to prep SYS-FPGA DMA\n");
- return -ENOMEM;
- }
-
- /* Setup the callback */
- tx->callback = data_dma_cb;
- tx->callback_param = priv;
-
- /* submit the transaction to the DMA controller */
- cookie = tx->tx_submit(tx);
- if (dma_submit_error(cookie)) {
- dev_err(priv->dev, "unable to submit SYS-FPGA DMA\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-#define CORL_DONE 0x1
-#define CORL_ERR 0x2
-
-static irqreturn_t data_irq(int irq, void *dev_id)
-{
- struct fpga_device *priv = dev_id;
- bool submitted = false;
- struct data_buf *buf;
- u32 status;
- int i;
-
- /* detect spurious interrupts via FPGA status */
- for (i = 0; i < 4; i++) {
- status = fpga_read_reg(priv, i, MMAP_REG_STATUS);
- if (!(status & (CORL_DONE | CORL_ERR))) {
- dev_err(priv->dev, "spurious irq detected (FPGA)\n");
- return IRQ_NONE;
- }
- }
-
- /* detect spurious interrupts via raw IRQ pin readback */
- status = ioread32be(priv->regs + SYS_IRQ_INPUT_DATA);
- if (status & IRQ_CORL_DONE) {
- dev_err(priv->dev, "spurious irq detected (IRQ)\n");
- return IRQ_NONE;
- }
-
- spin_lock(&priv->lock);
-
- /*
- * This is an error case that should never happen.
- *
- * If this driver has a bug and manages to re-enable interrupts while
- * a DMA is in progress, then we will hit this statement and should
- * start paying attention immediately.
- */
- BUG_ON(priv->inflight != NULL);
-
- /* hide the interrupt by switching the IRQ driver to GPIO */
- data_disable_interrupts(priv);
-
- /* If there are no free buffers, drop this data */
- if (list_empty(&priv->free)) {
- priv->num_dropped++;
- goto out;
- }
-
- buf = list_first_entry(&priv->free, struct data_buf, entry);
- list_del_init(&buf->entry);
- BUG_ON(buf->size != priv->bufsize);
-
- /* Submit a DMA transfer to get the correlation data */
- if (data_submit_dma(priv, buf)) {
- dev_err(priv->dev, "Unable to setup DMA transfer\n");
- list_move_tail(&buf->entry, &priv->free);
- goto out;
- }
-
- /* Save the buffer for the DMA callback */
- priv->inflight = buf;
- submitted = true;
-
- /* Start the DMA Engine */
- dma_async_memcpy_issue_pending(priv->chan);
-
-out:
- /* If no DMA was submitted, re-enable interrupts */
- if (!submitted)
- data_enable_interrupts(priv);
-
- spin_unlock(&priv->lock);
- return IRQ_HANDLED;
-}
-
-/*
- * Realtime Device Enable Helpers
- */
-
-/**
- * data_device_enable() - enable the device for buffered dumping
- * @priv: the driver's private data structure
- *
- * Enable the device for buffered dumping. Allocates buffers and hooks up
- * the interrupt handler. When this finishes, data will come pouring in.
- *
- * LOCKING: must hold dev->mutex
- * CONTEXT: user context only
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int data_device_enable(struct fpga_device *priv)
-{
- bool enabled;
- u32 val;
- int ret;
-
- /* multiple enables are safe: they do nothing */
- spin_lock_irq(&priv->lock);
- enabled = priv->enabled;
- spin_unlock_irq(&priv->lock);
- if (enabled)
- return 0;
-
- /* check that the FPGAs are programmed */
- val = ioread32be(priv->regs + SYS_FPGA_CONFIG_STATUS);
- if (!(val & (1 << 18))) {
- dev_err(priv->dev, "DATA-FPGAs are not enabled\n");
- return -ENODATA;
- }
-
- /* read the FPGAs to calculate the buffer size */
- ret = data_calculate_bufsize(priv);
- if (ret) {
- dev_err(priv->dev, "unable to calculate buffer size\n");
- goto out_error;
- }
-
- /* allocate the correlation data buffers */
- ret = data_alloc_buffers(priv);
- if (ret) {
- dev_err(priv->dev, "unable to allocate buffers\n");
- goto out_error;
- }
-
- /* setup the source scatterlist for dumping correlation data */
- ret = data_setup_corl_table(priv);
- if (ret) {
- dev_err(priv->dev, "unable to setup correlation DMA table\n");
- goto out_error;
- }
-
- /* prevent the FPGAs from generating interrupts */
- data_disable_interrupts(priv);
-
- /* hookup the irq handler */
- ret = request_irq(priv->irq, data_irq, IRQF_SHARED, drv_name, priv);
- if (ret) {
- dev_err(priv->dev, "unable to request IRQ handler\n");
- goto out_error;
- }
-
- /* allow the DMA callback to re-enable FPGA interrupts */
- spin_lock_irq(&priv->lock);
- priv->enabled = true;
- spin_unlock_irq(&priv->lock);
-
- /* allow the FPGAs to generate interrupts */
- data_enable_interrupts(priv);
- return 0;
-
-out_error:
- sg_free_table(&priv->corl_table);
- priv->corl_nents = 0;
-
- data_free_buffers(priv);
- return ret;
-}
-
-/**
- * data_device_disable() - disable the device for buffered dumping
- * @priv: the driver's private data structure
- *
- * Disable the device for buffered dumping. Stops new DMA transactions from
- * being generated, waits for all outstanding DMA to complete, and then frees
- * all buffers.
- *
- * LOCKING: must hold dev->mutex
- * CONTEXT: user only
- *
- * Returns 0 on success, -ERRNO otherwise
- */
-static int data_device_disable(struct fpga_device *priv)
-{
- spin_lock_irq(&priv->lock);
-
- /* allow multiple disable */
- if (!priv->enabled) {
- spin_unlock_irq(&priv->lock);
- return 0;
- }
-
- /*
- * Mark the device disabled
- *
- * This stops DMA callbacks from re-enabling interrupts
- */
- priv->enabled = false;
-
- /* prevent the FPGAs from generating interrupts */
- data_disable_interrupts(priv);
-
- /* wait until all ongoing DMA has finished */
- while (priv->inflight != NULL) {
- spin_unlock_irq(&priv->lock);
- wait_event(priv->wait, priv->inflight == NULL);
- spin_lock_irq(&priv->lock);
- }
-
- spin_unlock_irq(&priv->lock);
-
- /* unhook the irq handler */
- free_irq(priv->irq, priv);
-
- /* free the correlation table */
- sg_free_table(&priv->corl_table);
- priv->corl_nents = 0;
-
- /* free all buffers: the free and used lists are not being changed */
- data_free_buffers(priv);
- return 0;
-}
-
-/*
- * DEBUGFS Interface
- */
-#ifdef CONFIG_DEBUG_FS
-
-/*
- * Count the number of entries in the given list
- */
-static unsigned int list_num_entries(struct list_head *list)
-{
- struct list_head *entry;
- unsigned int ret = 0;
-
- list_for_each(entry, list)
- ret++;
-
- return ret;
-}
-
-static int data_debug_show(struct seq_file *f, void *offset)
-{
- struct fpga_device *priv = f->private;
-
- spin_lock_irq(&priv->lock);
-
- seq_printf(f, "enabled: %d\n", priv->enabled);
- seq_printf(f, "bufsize: %d\n", priv->bufsize);
- seq_printf(f, "num_buffers: %d\n", priv->num_buffers);
- seq_printf(f, "num_free: %d\n", list_num_entries(&priv->free));
- seq_printf(f, "inflight: %d\n", priv->inflight != NULL);
- seq_printf(f, "num_used: %d\n", list_num_entries(&priv->used));
- seq_printf(f, "num_dropped: %d\n", priv->num_dropped);
-
- spin_unlock_irq(&priv->lock);
- return 0;
-}
-
-static int data_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, data_debug_show, inode->i_private);
-}
-
-static const struct file_operations data_debug_fops = {
- .owner = THIS_MODULE,
- .open = data_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int data_debugfs_init(struct fpga_device *priv)
-{
- priv->dbg_entry = debugfs_create_file(drv_name, S_IRUGO, NULL, priv,
- &data_debug_fops);
- if (IS_ERR(priv->dbg_entry))
- return PTR_ERR(priv->dbg_entry);
-
- return 0;
-}
-
-static void data_debugfs_exit(struct fpga_device *priv)
-{
- debugfs_remove(priv->dbg_entry);
-}
-
-#else
-
-static inline int data_debugfs_init(struct fpga_device *priv)
-{
- return 0;
-}
-
-static inline void data_debugfs_exit(struct fpga_device *priv)
-{
-}
-
-#endif /* CONFIG_DEBUG_FS */
-
-/*
- * SYSFS Attributes
- */
-
-static ssize_t data_en_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct fpga_device *priv = dev_get_drvdata(dev);
- int ret;
-
- spin_lock_irq(&priv->lock);
- ret = snprintf(buf, PAGE_SIZE, "%u\n", priv->enabled);
- spin_unlock_irq(&priv->lock);
-
- return ret;
-}
-
-static ssize_t data_en_set(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct fpga_device *priv = dev_get_drvdata(dev);
- unsigned long enable;
- int ret;
-
- ret = strict_strtoul(buf, 0, &enable);
- if (ret) {
- dev_err(priv->dev, "unable to parse enable input\n");
- return -EINVAL;
- }
-
- /* protect against concurrent enable/disable */
- ret = mutex_lock_interruptible(&priv->mutex);
- if (ret)
- return ret;
-
- if (enable)
- ret = data_device_enable(priv);
- else
- ret = data_device_disable(priv);
-
- if (ret) {
- dev_err(priv->dev, "device %s failed\n",
- enable ? "enable" : "disable");
- count = ret;
- goto out_unlock;
- }
-
-out_unlock:
- mutex_unlock(&priv->mutex);
- return count;
-}
-
-static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, data_en_show, data_en_set);
-
-static struct attribute *data_sysfs_attrs[] = {
- &dev_attr_enable.attr,
- NULL,
-};
-
-static const struct attribute_group rt_sysfs_attr_group = {
- .attrs = data_sysfs_attrs,
-};
-
-/*
- * FPGA Realtime Data Character Device
- */
-
-static int data_open(struct inode *inode, struct file *filp)
-{
- /*
- * The miscdevice layer puts our struct miscdevice into the
- * filp->private_data field. We use this to find our private
- * data and then overwrite it with our own private structure.
- */
- struct fpga_device *priv = container_of(filp->private_data,
- struct fpga_device, miscdev);
- struct fpga_reader *reader;
- int ret;
-
- /* allocate private data */
- reader = kzalloc(sizeof(*reader), GFP_KERNEL);
- if (!reader)
- return -ENOMEM;
-
- reader->priv = priv;
- reader->buf = NULL;
-
- filp->private_data = reader;
- ret = nonseekable_open(inode, filp);
- if (ret) {
- dev_err(priv->dev, "nonseekable-open failed\n");
- kfree(reader);
- return ret;
- }
-
- /*
- * success, increase the reference count of the private data structure
- * so that it doesn't disappear if the device is unbound
- */
- kref_get(&priv->ref);
- return 0;
-}
-
-static int data_release(struct inode *inode, struct file *filp)
-{
- struct fpga_reader *reader = filp->private_data;
- struct fpga_device *priv = reader->priv;
-
- /* free the per-reader structure */
- data_free_buffer(reader->buf);
- kfree(reader);
- filp->private_data = NULL;
-
- /* decrement our reference count to the private data */
- kref_put(&priv->ref, fpga_device_release);
- return 0;
-}
-
-static ssize_t data_read(struct file *filp, char __user *ubuf, size_t count,
- loff_t *f_pos)
-{
- struct fpga_reader *reader = filp->private_data;
- struct fpga_device *priv = reader->priv;
- struct list_head *used = &priv->used;
- bool drop_buffer = false;
- struct data_buf *dbuf;
- size_t avail;
- void *data;
- int ret;
-
- /* check if we already have a partial buffer */
- if (reader->buf) {
- dbuf = reader->buf;
- goto have_buffer;
- }
-
- spin_lock_irq(&priv->lock);
-
- /* Block until there is at least one buffer on the used list */
- while (list_empty(used)) {
- spin_unlock_irq(&priv->lock);
-
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
-
- ret = wait_event_interruptible(priv->wait, !list_empty(used));
- if (ret)
- return ret;
-
- spin_lock_irq(&priv->lock);
- }
-
- /* Grab the first buffer off of the used list */
- dbuf = list_first_entry(used, struct data_buf, entry);
- list_del_init(&dbuf->entry);
-
- spin_unlock_irq(&priv->lock);
-
- /* Buffers are always mapped: unmap it */
- videobuf_dma_unmap(priv->dev, &dbuf->vb);
-
- /* save the buffer for later */
- reader->buf = dbuf;
- reader->buf_start = 0;
-
-have_buffer:
- /* Get the number of bytes available */
- avail = dbuf->size - reader->buf_start;
- data = dbuf->vb.vaddr + reader->buf_start;
-
- /* Get the number of bytes we can transfer */
- count = min(count, avail);
-
- /* Copy the data to the userspace buffer */
- if (copy_to_user(ubuf, data, count))
- return -EFAULT;
-
- /* Update the amount of available space */
- avail -= count;
-
- /*
- * If there is still some data available, save the buffer for the
- * next userspace call to read() and return
- */
- if (avail > 0) {
- reader->buf_start += count;
- reader->buf = dbuf;
- return count;
- }
-
- /*
- * Get the buffer ready to be reused for DMA
- *
- * If it fails, we pretend that the read never happed and return
- * -EFAULT to userspace. The read will be retried.
- */
- ret = videobuf_dma_map(priv->dev, &dbuf->vb);
- if (ret) {
- dev_err(priv->dev, "unable to remap buffer for DMA\n");
- return -EFAULT;
- }
-
- /* Lock against concurrent enable/disable */
- spin_lock_irq(&priv->lock);
-
- /* the reader is finished with this buffer */
- reader->buf = NULL;
-
- /*
- * One of two things has happened, the device is disabled, or the
- * device has been reconfigured underneath us. In either case, we
- * should just throw away the buffer.
- *
- * Lockdep complains if this is done under the spinlock, so we
- * handle it during the unlock path.
- */
- if (!priv->enabled || dbuf->size != priv->bufsize) {
- drop_buffer = true;
- goto out_unlock;
- }
-
- /* The buffer is safe to reuse, so add it back to the free list */
- list_add_tail(&dbuf->entry, &priv->free);
-
-out_unlock:
- spin_unlock_irq(&priv->lock);
-
- if (drop_buffer) {
- videobuf_dma_unmap(priv->dev, &dbuf->vb);
- data_free_buffer(dbuf);
- }
-
- return count;
-}
-
-static unsigned int data_poll(struct file *filp, struct poll_table_struct *tbl)
-{
- struct fpga_reader *reader = filp->private_data;
- struct fpga_device *priv = reader->priv;
- unsigned int mask = 0;
-
- poll_wait(filp, &priv->wait, tbl);
-
- if (!list_empty(&priv->used))
- mask |= POLLIN | POLLRDNORM;
-
- return mask;
-}
-
-static int data_mmap(struct file *filp, struct vm_area_struct *vma)
-{
- struct fpga_reader *reader = filp->private_data;
- struct fpga_device *priv = reader->priv;
- unsigned long offset, vsize, psize, addr;
-
- /* VMA properties */
- offset = vma->vm_pgoff << PAGE_SHIFT;
- vsize = vma->vm_end - vma->vm_start;
- psize = priv->phys_size - offset;
- addr = (priv->phys_addr + offset) >> PAGE_SHIFT;
-
- /* Check against the FPGA region's physical memory size */
- if (vsize > psize) {
- dev_err(priv->dev, "requested mmap mapping too large\n");
- return -EINVAL;
- }
-
- /* IO memory (stop cacheing) */
- vma->vm_flags |= VM_IO | VM_RESERVED;
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- return io_remap_pfn_range(vma, vma->vm_start, addr, vsize,
- vma->vm_page_prot);
-}
-
-static const struct file_operations data_fops = {
- .owner = THIS_MODULE,
- .open = data_open,
- .release = data_release,
- .read = data_read,
- .poll = data_poll,
- .mmap = data_mmap,
- .llseek = no_llseek,
-};
-
-/*
- * OpenFirmware Device Subsystem
- */
-
-static bool dma_filter(struct dma_chan *chan, void *data)
-{
- /*
- * DMA Channel #0 is used for the FPGA Programmer, so ignore it
- *
- * This probably won't survive an unload/load cycle of the Freescale
- * DMAEngine driver, but that won't be a problem
- */
- if (chan->chan_id == 0 && chan->device->dev_id == 0)
- return false;
-
- return true;
-}
-
-static int data_of_probe(struct platform_device *op)
-{
- struct device_node *of_node = op->dev.of_node;
- struct device *this_device;
- struct fpga_device *priv;
- struct resource res;
- dma_cap_mask_t mask;
- int ret;
-
- /* Allocate private data */
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&op->dev, "Unable to allocate device private data\n");
- ret = -ENOMEM;
- goto out_return;
- }
-
- dev_set_drvdata(&op->dev, priv);
- priv->dev = &op->dev;
- kref_init(&priv->ref);
- mutex_init(&priv->mutex);
-
- dev_set_drvdata(priv->dev, priv);
- spin_lock_init(&priv->lock);
- INIT_LIST_HEAD(&priv->free);
- INIT_LIST_HEAD(&priv->used);
- init_waitqueue_head(&priv->wait);
-
- /* Setup the misc device */
- priv->miscdev.minor = MISC_DYNAMIC_MINOR;
- priv->miscdev.name = drv_name;
- priv->miscdev.fops = &data_fops;
-
- /* Get the physical address of the FPGA registers */
- ret = of_address_to_resource(of_node, 0, &res);
- if (ret) {
- dev_err(&op->dev, "Unable to find FPGA physical address\n");
- ret = -ENODEV;
- goto out_free_priv;
- }
-
- priv->phys_addr = res.start;
- priv->phys_size = resource_size(&res);
-
- /* ioremap the registers for use */
- priv->regs = of_iomap(of_node, 0);
- if (!priv->regs) {
- dev_err(&op->dev, "Unable to ioremap registers\n");
- ret = -ENOMEM;
- goto out_free_priv;
- }
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_MEMCPY, mask);
- dma_cap_set(DMA_INTERRUPT, mask);
- dma_cap_set(DMA_SLAVE, mask);
- dma_cap_set(DMA_SG, mask);
-
- /* Request a DMA channel */
- priv->chan = dma_request_channel(mask, dma_filter, NULL);
- if (!priv->chan) {
- dev_err(&op->dev, "Unable to request DMA channel\n");
- ret = -ENODEV;
- goto out_unmap_regs;
- }
-
- /* Find the correct IRQ number */
- priv->irq = irq_of_parse_and_map(of_node, 0);
- if (priv->irq == NO_IRQ) {
- dev_err(&op->dev, "Unable to find IRQ line\n");
- ret = -ENODEV;
- goto out_release_dma;
- }
-
- /* Drive the GPIO for FPGA IRQ high (no interrupt) */
- iowrite32be(IRQ_CORL_DONE, priv->regs + SYS_IRQ_OUTPUT_DATA);
-
- /* Register the miscdevice */
- ret = misc_register(&priv->miscdev);
- if (ret) {
- dev_err(&op->dev, "Unable to register miscdevice\n");
- goto out_irq_dispose_mapping;
- }
-
- /* Create the debugfs files */
- ret = data_debugfs_init(priv);
- if (ret) {
- dev_err(&op->dev, "Unable to create debugfs files\n");
- goto out_misc_deregister;
- }
-
- /* Create the sysfs files */
- this_device = priv->miscdev.this_device;
- dev_set_drvdata(this_device, priv);
- ret = sysfs_create_group(&this_device->kobj, &rt_sysfs_attr_group);
- if (ret) {
- dev_err(&op->dev, "Unable to create sysfs files\n");
- goto out_data_debugfs_exit;
- }
-
- dev_info(&op->dev, "CARMA FPGA Realtime Data Driver Loaded\n");
- return 0;
-
-out_data_debugfs_exit:
- data_debugfs_exit(priv);
-out_misc_deregister:
- misc_deregister(&priv->miscdev);
-out_irq_dispose_mapping:
- irq_dispose_mapping(priv->irq);
-out_release_dma:
- dma_release_channel(priv->chan);
-out_unmap_regs:
- iounmap(priv->regs);
-out_free_priv:
- kref_put(&priv->ref, fpga_device_release);
-out_return:
- return ret;
-}
-
-static int data_of_remove(struct platform_device *op)
-{
- struct fpga_device *priv = dev_get_drvdata(&op->dev);
- struct device *this_device = priv->miscdev.this_device;
-
- /* remove all sysfs files, now the device cannot be re-enabled */
- sysfs_remove_group(&this_device->kobj, &rt_sysfs_attr_group);
-
- /* remove all debugfs files */
- data_debugfs_exit(priv);
-
- /* disable the device from generating data */
- data_device_disable(priv);
-
- /* remove the character device to stop new readers from appearing */
- misc_deregister(&priv->miscdev);
-
- /* cleanup everything not needed by readers */
- irq_dispose_mapping(priv->irq);
- dma_release_channel(priv->chan);
- iounmap(priv->regs);
-
- /* release our reference */
- kref_put(&priv->ref, fpga_device_release);
- return 0;
-}
-
-static struct of_device_id data_of_match[] = {
- { .compatible = "carma,carma-fpga", },
- {},
-};
-
-static struct platform_driver data_of_driver = {
- .probe = data_of_probe,
- .remove = data_of_remove,
- .driver = {
- .name = drv_name,
- .of_match_table = data_of_match,
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(data_of_driver);
-
-MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
-MODULE_DESCRIPTION("CARMA DATA-FPGA Access Driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/cb710/Kconfig b/ANDROID_3.4.5/drivers/misc/cb710/Kconfig
deleted file mode 100644
index 22429b8b..00000000
--- a/ANDROID_3.4.5/drivers/misc/cb710/Kconfig
+++ /dev/null
@@ -1,25 +0,0 @@
-config CB710_CORE
- tristate "ENE CB710/720 Flash memory card reader support"
- depends on PCI
- help
- This option enables support for PCI ENE CB710/720 Flash memory card
- reader found in some laptops (ie. some versions of HP Compaq nx9500).
-
- You will also have to select some flash card format drivers (MMC/SD,
- MemoryStick).
-
- This driver can also be built as a module. If so, the module
- will be called cb710.
-
-config CB710_DEBUG
- bool "Enable driver debugging"
- depends on CB710_CORE != n
- default n
- help
- This is an option for use by developers; most people should
- say N here. This adds a lot of debugging output to dmesg.
-
-config CB710_DEBUG_ASSUMPTIONS
- bool
- depends on CB710_CORE != n
- default y
diff --git a/ANDROID_3.4.5/drivers/misc/cb710/Makefile b/ANDROID_3.4.5/drivers/misc/cb710/Makefile
deleted file mode 100644
index 467c8e9c..00000000
--- a/ANDROID_3.4.5/drivers/misc/cb710/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-ccflags-$(CONFIG_CB710_DEBUG) := -DDEBUG
-
-obj-$(CONFIG_CB710_CORE) += cb710.o
-
-cb710-y := core.o sgbuf2.o
-cb710-$(CONFIG_CB710_DEBUG) += debug.o
diff --git a/ANDROID_3.4.5/drivers/misc/cb710/core.c b/ANDROID_3.4.5/drivers/misc/cb710/core.c
deleted file mode 100644
index 85cc7710..00000000
--- a/ANDROID_3.4.5/drivers/misc/cb710/core.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * cb710/core.c
- *
- * Copyright by Michał Mirosław, 2008-2009
- *
- * 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/module.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/idr.h>
-#include <linux/cb710.h>
-#include <linux/gfp.h>
-
-static DEFINE_IDA(cb710_ida);
-static DEFINE_SPINLOCK(cb710_ida_lock);
-
-void cb710_pci_update_config_reg(struct pci_dev *pdev,
- int reg, uint32_t mask, uint32_t xor)
-{
- u32 rval;
-
- pci_read_config_dword(pdev, reg, &rval);
- rval = (rval & mask) ^ xor;
- pci_write_config_dword(pdev, reg, rval);
-}
-EXPORT_SYMBOL_GPL(cb710_pci_update_config_reg);
-
-/* Some magic writes based on Windows driver init code */
-static int __devinit cb710_pci_configure(struct pci_dev *pdev)
-{
- unsigned int devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
- struct pci_dev *pdev0;
- u32 val;
-
- cb710_pci_update_config_reg(pdev, 0x48,
- ~0x000000FF, 0x0000003F);
-
- pci_read_config_dword(pdev, 0x48, &val);
- if (val & 0x80000000)
- return 0;
-
- pdev0 = pci_get_slot(pdev->bus, devfn);
- if (!pdev0)
- return -ENODEV;
-
- if (pdev0->vendor == PCI_VENDOR_ID_ENE
- && pdev0->device == PCI_DEVICE_ID_ENE_720) {
- cb710_pci_update_config_reg(pdev0, 0x8C,
- ~0x00F00000, 0x00100000);
- cb710_pci_update_config_reg(pdev0, 0xB0,
- ~0x08000000, 0x08000000);
- }
-
- cb710_pci_update_config_reg(pdev0, 0x8C,
- ~0x00000F00, 0x00000200);
- cb710_pci_update_config_reg(pdev0, 0x90,
- ~0x00060000, 0x00040000);
-
- pci_dev_put(pdev0);
-
- return 0;
-}
-
-static irqreturn_t cb710_irq_handler(int irq, void *data)
-{
- struct cb710_chip *chip = data;
- struct cb710_slot *slot = &chip->slot[0];
- irqreturn_t handled = IRQ_NONE;
- unsigned nr;
-
- spin_lock(&chip->irq_lock); /* incl. smp_rmb() */
-
- for (nr = chip->slots; nr; ++slot, --nr) {
- cb710_irq_handler_t handler_func = slot->irq_handler;
- if (handler_func && handler_func(slot))
- handled = IRQ_HANDLED;
- }
-
- spin_unlock(&chip->irq_lock);
-
- return handled;
-}
-
-static void cb710_release_slot(struct device *dev)
-{
-#ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
- struct cb710_slot *slot = cb710_pdev_to_slot(to_platform_device(dev));
- struct cb710_chip *chip = cb710_slot_to_chip(slot);
-
- /* slot struct can be freed now */
- atomic_dec(&chip->slot_refs_count);
-#endif
-}
-
-static int __devinit cb710_register_slot(struct cb710_chip *chip,
- unsigned slot_mask, unsigned io_offset, const char *name)
-{
- int nr = chip->slots;
- struct cb710_slot *slot = &chip->slot[nr];
- int err;
-
- dev_dbg(cb710_chip_dev(chip),
- "register: %s.%d; slot %d; mask %d; IO offset: 0x%02X\n",
- name, chip->platform_id, nr, slot_mask, io_offset);
-
- /* slot->irq_handler == NULL here; this needs to be
- * seen before platform_device_register() */
- ++chip->slots;
- smp_wmb();
-
- slot->iobase = chip->iobase + io_offset;
- slot->pdev.name = name;
- slot->pdev.id = chip->platform_id;
- slot->pdev.dev.parent = &chip->pdev->dev;
- slot->pdev.dev.release = cb710_release_slot;
-
- err = platform_device_register(&slot->pdev);
-
-#ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
- atomic_inc(&chip->slot_refs_count);
-#endif
-
- if (err) {
- /* device_initialize() called from platform_device_register()
- * wants this on error path */
- platform_device_put(&slot->pdev);
-
- /* slot->irq_handler == NULL here anyway, so no lock needed */
- --chip->slots;
- return err;
- }
-
- chip->slot_mask |= slot_mask;
-
- return 0;
-}
-
-static void cb710_unregister_slot(struct cb710_chip *chip,
- unsigned slot_mask)
-{
- int nr = chip->slots - 1;
-
- if (!(chip->slot_mask & slot_mask))
- return;
-
- platform_device_unregister(&chip->slot[nr].pdev);
-
- /* complementary to spin_unlock() in cb710_set_irq_handler() */
- smp_rmb();
- BUG_ON(chip->slot[nr].irq_handler != NULL);
-
- /* slot->irq_handler == NULL here, so no lock needed */
- --chip->slots;
- chip->slot_mask &= ~slot_mask;
-}
-
-void cb710_set_irq_handler(struct cb710_slot *slot,
- cb710_irq_handler_t handler)
-{
- struct cb710_chip *chip = cb710_slot_to_chip(slot);
- unsigned long flags;
-
- spin_lock_irqsave(&chip->irq_lock, flags);
- slot->irq_handler = handler;
- spin_unlock_irqrestore(&chip->irq_lock, flags);
-}
-EXPORT_SYMBOL_GPL(cb710_set_irq_handler);
-
-#ifdef CONFIG_PM
-
-static int cb710_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct cb710_chip *chip = pci_get_drvdata(pdev);
-
- free_irq(pdev->irq, chip);
- pci_save_state(pdev);
- pci_disable_device(pdev);
- if (state.event & PM_EVENT_SLEEP)
- pci_set_power_state(pdev, PCI_D3cold);
- return 0;
-}
-
-static int cb710_resume(struct pci_dev *pdev)
-{
- struct cb710_chip *chip = pci_get_drvdata(pdev);
- int err;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- err = pcim_enable_device(pdev);
- if (err)
- return err;
-
- return devm_request_irq(&pdev->dev, pdev->irq,
- cb710_irq_handler, IRQF_SHARED, KBUILD_MODNAME, chip);
-}
-
-#endif /* CONFIG_PM */
-
-static int __devinit cb710_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct cb710_chip *chip;
- unsigned long flags;
- u32 val;
- int err;
- int n = 0;
-
- err = cb710_pci_configure(pdev);
- if (err)
- return err;
-
- /* this is actually magic... */
- pci_read_config_dword(pdev, 0x48, &val);
- if (!(val & 0x80000000)) {
- pci_write_config_dword(pdev, 0x48, val|0x71000000);
- pci_read_config_dword(pdev, 0x48, &val);
- }
-
- dev_dbg(&pdev->dev, "PCI config[0x48] = 0x%08X\n", val);
- if (!(val & 0x70000000))
- return -ENODEV;
- val = (val >> 28) & 7;
- if (val & CB710_SLOT_MMC)
- ++n;
- if (val & CB710_SLOT_MS)
- ++n;
- if (val & CB710_SLOT_SM)
- ++n;
-
- chip = devm_kzalloc(&pdev->dev,
- sizeof(*chip) + n * sizeof(*chip->slot), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- err = pcim_enable_device(pdev);
- if (err)
- return err;
-
- err = pcim_iomap_regions(pdev, 0x0001, KBUILD_MODNAME);
- if (err)
- return err;
-
- spin_lock_init(&chip->irq_lock);
- chip->pdev = pdev;
- chip->iobase = pcim_iomap_table(pdev)[0];
-
- pci_set_drvdata(pdev, chip);
-
- err = devm_request_irq(&pdev->dev, pdev->irq,
- cb710_irq_handler, IRQF_SHARED, KBUILD_MODNAME, chip);
- if (err)
- return err;
-
- do {
- if (!ida_pre_get(&cb710_ida, GFP_KERNEL))
- return -ENOMEM;
-
- spin_lock_irqsave(&cb710_ida_lock, flags);
- err = ida_get_new(&cb710_ida, &chip->platform_id);
- spin_unlock_irqrestore(&cb710_ida_lock, flags);
-
- if (err && err != -EAGAIN)
- return err;
- } while (err);
-
-
- dev_info(&pdev->dev, "id %d, IO 0x%p, IRQ %d\n",
- chip->platform_id, chip->iobase, pdev->irq);
-
- if (val & CB710_SLOT_MMC) { /* MMC/SD slot */
- err = cb710_register_slot(chip,
- CB710_SLOT_MMC, 0x00, "cb710-mmc");
- if (err)
- return err;
- }
-
- if (val & CB710_SLOT_MS) { /* MemoryStick slot */
- err = cb710_register_slot(chip,
- CB710_SLOT_MS, 0x40, "cb710-ms");
- if (err)
- goto unreg_mmc;
- }
-
- if (val & CB710_SLOT_SM) { /* SmartMedia slot */
- err = cb710_register_slot(chip,
- CB710_SLOT_SM, 0x60, "cb710-sm");
- if (err)
- goto unreg_ms;
- }
-
- return 0;
-unreg_ms:
- cb710_unregister_slot(chip, CB710_SLOT_MS);
-unreg_mmc:
- cb710_unregister_slot(chip, CB710_SLOT_MMC);
-
-#ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
- BUG_ON(atomic_read(&chip->slot_refs_count) != 0);
-#endif
- return err;
-}
-
-static void __devexit cb710_remove_one(struct pci_dev *pdev)
-{
- struct cb710_chip *chip = pci_get_drvdata(pdev);
- unsigned long flags;
-
- cb710_unregister_slot(chip, CB710_SLOT_SM);
- cb710_unregister_slot(chip, CB710_SLOT_MS);
- cb710_unregister_slot(chip, CB710_SLOT_MMC);
-#ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
- BUG_ON(atomic_read(&chip->slot_refs_count) != 0);
-#endif
-
- spin_lock_irqsave(&cb710_ida_lock, flags);
- ida_remove(&cb710_ida, chip->platform_id);
- spin_unlock_irqrestore(&cb710_ida_lock, flags);
-}
-
-static const struct pci_device_id cb710_pci_tbl[] = {
- { PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_CB710_FLASH,
- PCI_ANY_ID, PCI_ANY_ID, },
- { 0, }
-};
-
-static struct pci_driver cb710_driver = {
- .name = KBUILD_MODNAME,
- .id_table = cb710_pci_tbl,
- .probe = cb710_probe,
- .remove = __devexit_p(cb710_remove_one),
-#ifdef CONFIG_PM
- .suspend = cb710_suspend,
- .resume = cb710_resume,
-#endif
-};
-
-static int __init cb710_init_module(void)
-{
- return pci_register_driver(&cb710_driver);
-}
-
-static void __exit cb710_cleanup_module(void)
-{
- pci_unregister_driver(&cb710_driver);
- ida_destroy(&cb710_ida);
-}
-
-module_init(cb710_init_module);
-module_exit(cb710_cleanup_module);
-
-MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>");
-MODULE_DESCRIPTION("ENE CB710 memory card reader driver");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, cb710_pci_tbl);
diff --git a/ANDROID_3.4.5/drivers/misc/cb710/debug.c b/ANDROID_3.4.5/drivers/misc/cb710/debug.c
deleted file mode 100644
index fcb3b8e3..00000000
--- a/ANDROID_3.4.5/drivers/misc/cb710/debug.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * cb710/debug.c
- *
- * Copyright by Michał Mirosław, 2008-2009
- *
- * 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/cb710.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#define CB710_REG_COUNT 0x80
-
-static const u16 allow[CB710_REG_COUNT/16] = {
- 0xFFF0, 0xFFFF, 0xFFFF, 0xFFFF,
- 0xFFF0, 0xFFFF, 0xFFFF, 0xFFFF,
-};
-static const char *const prefix[ARRAY_SIZE(allow)] = {
- "MMC", "MMC", "MMC", "MMC",
- "MS?", "MS?", "SM?", "SM?"
-};
-
-static inline int allow_reg_read(unsigned block, unsigned offset, unsigned bits)
-{
- unsigned mask = (1 << bits/8) - 1;
- offset *= bits/8;
- return ((allow[block] >> offset) & mask) == mask;
-}
-
-#define CB710_READ_REGS_TEMPLATE(t) \
-static void cb710_read_regs_##t(void __iomem *iobase, \
- u##t *reg, unsigned select) \
-{ \
- unsigned i, j; \
- \
- for (i = 0; i < ARRAY_SIZE(allow); ++i, reg += 16/(t/8)) { \
- if (!(select & (1 << i))) \
- continue; \
- \
- for (j = 0; j < 0x10/(t/8); ++j) { \
- if (!allow_reg_read(i, j, t)) \
- continue; \
- reg[j] = ioread##t(iobase \
- + (i << 4) + (j * (t/8))); \
- } \
- } \
-}
-
-static const char cb710_regf_8[] = "%02X";
-static const char cb710_regf_16[] = "%04X";
-static const char cb710_regf_32[] = "%08X";
-static const char cb710_xes[] = "xxxxxxxx";
-
-#define CB710_DUMP_REGS_TEMPLATE(t) \
-static void cb710_dump_regs_##t(struct device *dev, \
- const u##t *reg, unsigned select) \
-{ \
- const char *const xp = &cb710_xes[8 - t/4]; \
- const char *const format = cb710_regf_##t; \
- \
- char msg[100], *p; \
- unsigned i, j; \
- \
- for (i = 0; i < ARRAY_SIZE(allow); ++i, reg += 16/(t/8)) { \
- if (!(select & (1 << i))) \
- continue; \
- p = msg; \
- for (j = 0; j < 0x10/(t/8); ++j) { \
- *p++ = ' '; \
- if (j == 8/(t/8)) \
- *p++ = ' '; \
- if (allow_reg_read(i, j, t)) \
- p += sprintf(p, format, reg[j]); \
- else \
- p += sprintf(p, "%s", xp); \
- } \
- dev_dbg(dev, "%s 0x%02X %s\n", prefix[i], i << 4, msg); \
- } \
-}
-
-#define CB710_READ_AND_DUMP_REGS_TEMPLATE(t) \
-static void cb710_read_and_dump_regs_##t(struct cb710_chip *chip, \
- unsigned select) \
-{ \
- u##t regs[CB710_REG_COUNT/sizeof(u##t)]; \
- \
- memset(&regs, 0, sizeof(regs)); \
- cb710_read_regs_##t(chip->iobase, regs, select); \
- cb710_dump_regs_##t(cb710_chip_dev(chip), regs, select); \
-}
-
-#define CB710_REG_ACCESS_TEMPLATES(t) \
- CB710_READ_REGS_TEMPLATE(t) \
- CB710_DUMP_REGS_TEMPLATE(t) \
- CB710_READ_AND_DUMP_REGS_TEMPLATE(t)
-
-CB710_REG_ACCESS_TEMPLATES(8)
-CB710_REG_ACCESS_TEMPLATES(16)
-CB710_REG_ACCESS_TEMPLATES(32)
-
-void cb710_dump_regs(struct cb710_chip *chip, unsigned select)
-{
- if (!(select & CB710_DUMP_REGS_MASK))
- select = CB710_DUMP_REGS_ALL;
- if (!(select & CB710_DUMP_ACCESS_MASK))
- select |= CB710_DUMP_ACCESS_8;
-
- if (select & CB710_DUMP_ACCESS_32)
- cb710_read_and_dump_regs_32(chip, select);
- if (select & CB710_DUMP_ACCESS_16)
- cb710_read_and_dump_regs_16(chip, select);
- if (select & CB710_DUMP_ACCESS_8)
- cb710_read_and_dump_regs_8(chip, select);
-}
-EXPORT_SYMBOL_GPL(cb710_dump_regs);
-
diff --git a/ANDROID_3.4.5/drivers/misc/cb710/sgbuf2.c b/ANDROID_3.4.5/drivers/misc/cb710/sgbuf2.c
deleted file mode 100644
index 2a40d0ef..00000000
--- a/ANDROID_3.4.5/drivers/misc/cb710/sgbuf2.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * cb710/sgbuf2.c
- *
- * Copyright by Michał Mirosław, 2008-2009
- *
- * 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/module.h>
-#include <linux/cb710.h>
-
-static bool sg_dwiter_next(struct sg_mapping_iter *miter)
-{
- if (sg_miter_next(miter)) {
- miter->consumed = 0;
- return true;
- } else
- return false;
-}
-
-static bool sg_dwiter_is_at_end(struct sg_mapping_iter *miter)
-{
- return miter->length == miter->consumed && !sg_dwiter_next(miter);
-}
-
-static uint32_t sg_dwiter_read_buffer(struct sg_mapping_iter *miter)
-{
- size_t len, left = 4;
- uint32_t data;
- void *addr = &data;
-
- do {
- len = min(miter->length - miter->consumed, left);
- memcpy(addr, miter->addr + miter->consumed, len);
- miter->consumed += len;
- left -= len;
- if (!left)
- return data;
- addr += len;
- } while (sg_dwiter_next(miter));
-
- memset(addr, 0, left);
- return data;
-}
-
-static inline bool needs_unaligned_copy(const void *ptr)
-{
-#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
- return false;
-#else
- return ((ptr - NULL) & 3) != 0;
-#endif
-}
-
-static bool sg_dwiter_get_next_block(struct sg_mapping_iter *miter, uint32_t **ptr)
-{
- size_t len;
-
- if (sg_dwiter_is_at_end(miter))
- return true;
-
- len = miter->length - miter->consumed;
-
- if (likely(len >= 4 && !needs_unaligned_copy(
- miter->addr + miter->consumed))) {
- *ptr = miter->addr + miter->consumed;
- miter->consumed += 4;
- return true;
- }
-
- return false;
-}
-
-/**
- * cb710_sg_dwiter_read_next_block() - get next 32-bit word from sg buffer
- * @miter: sg mapping iterator used for reading
- *
- * Description:
- * Returns 32-bit word starting at byte pointed to by @miter@
- * handling any alignment issues. Bytes past the buffer's end
- * are not accessed (read) but are returned as zeroes. @miter@
- * is advanced by 4 bytes or to the end of buffer whichever is
- * closer.
- *
- * Context:
- * Same requirements as in sg_miter_next().
- *
- * Returns:
- * 32-bit word just read.
- */
-uint32_t cb710_sg_dwiter_read_next_block(struct sg_mapping_iter *miter)
-{
- uint32_t *ptr = NULL;
-
- if (likely(sg_dwiter_get_next_block(miter, &ptr)))
- return ptr ? *ptr : 0;
-
- return sg_dwiter_read_buffer(miter);
-}
-EXPORT_SYMBOL_GPL(cb710_sg_dwiter_read_next_block);
-
-static void sg_dwiter_write_slow(struct sg_mapping_iter *miter, uint32_t data)
-{
- size_t len, left = 4;
- void *addr = &data;
-
- do {
- len = min(miter->length - miter->consumed, left);
- memcpy(miter->addr, addr, len);
- miter->consumed += len;
- left -= len;
- if (!left)
- return;
- addr += len;
- } while (sg_dwiter_next(miter));
-}
-
-/**
- * cb710_sg_dwiter_write_next_block() - write next 32-bit word to sg buffer
- * @miter: sg mapping iterator used for writing
- *
- * Description:
- * Writes 32-bit word starting at byte pointed to by @miter@
- * handling any alignment issues. Bytes which would be written
- * past the buffer's end are silently discarded. @miter@ is
- * advanced by 4 bytes or to the end of buffer whichever is closer.
- *
- * Context:
- * Same requirements as in sg_miter_next().
- */
-void cb710_sg_dwiter_write_next_block(struct sg_mapping_iter *miter, uint32_t data)
-{
- uint32_t *ptr = NULL;
-
- if (likely(sg_dwiter_get_next_block(miter, &ptr))) {
- if (ptr)
- *ptr = data;
- else
- return;
- } else
- sg_dwiter_write_slow(miter, data);
-}
-EXPORT_SYMBOL_GPL(cb710_sg_dwiter_write_next_block);
-
diff --git a/ANDROID_3.4.5/drivers/misc/cs5535-mfgpt.c b/ANDROID_3.4.5/drivers/misc/cs5535-mfgpt.c
deleted file mode 100644
index f505a40a..00000000
--- a/ANDROID_3.4.5/drivers/misc/cs5535-mfgpt.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Driver for the CS5535/CS5536 Multi-Function General Purpose Timers (MFGPT)
- *
- * Copyright (C) 2006, Advanced Micro Devices, Inc.
- * Copyright (C) 2007 Andres Salomon <dilinger@debian.org>
- * Copyright (C) 2009 Andres Salomon <dilinger@collabora.co.uk>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public License
- * as published by the Free Software Foundation.
- *
- * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book.
- */
-
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/cs5535.h>
-#include <linux/slab.h>
-
-#define DRV_NAME "cs5535-mfgpt"
-
-static int mfgpt_reset_timers;
-module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644);
-MODULE_PARM_DESC(mfgptfix, "Reset the MFGPT timers during init; "
- "required by some broken BIOSes (ie, TinyBIOS < 0.99).");
-
-struct cs5535_mfgpt_timer {
- struct cs5535_mfgpt_chip *chip;
- int nr;
-};
-
-static struct cs5535_mfgpt_chip {
- DECLARE_BITMAP(avail, MFGPT_MAX_TIMERS);
- resource_size_t base;
-
- struct platform_device *pdev;
- spinlock_t lock;
- int initialized;
-} cs5535_mfgpt_chip;
-
-int cs5535_mfgpt_toggle_event(struct cs5535_mfgpt_timer *timer, int cmp,
- int event, int enable)
-{
- uint32_t msr, mask, value, dummy;
- int shift = (cmp == MFGPT_CMP1) ? 0 : 8;
-
- if (!timer) {
- WARN_ON(1);
- return -EIO;
- }
-
- /*
- * The register maps for these are described in sections 6.17.1.x of
- * the AMD Geode CS5536 Companion Device Data Book.
- */
- switch (event) {
- case MFGPT_EVENT_RESET:
- /*
- * XXX: According to the docs, we cannot reset timers above
- * 6; that is, resets for 7 and 8 will be ignored. Is this
- * a problem? -dilinger
- */
- msr = MSR_MFGPT_NR;
- mask = 1 << (timer->nr + 24);
- break;
-
- case MFGPT_EVENT_NMI:
- msr = MSR_MFGPT_NR;
- mask = 1 << (timer->nr + shift);
- break;
-
- case MFGPT_EVENT_IRQ:
- msr = MSR_MFGPT_IRQ;
- mask = 1 << (timer->nr + shift);
- break;
-
- default:
- return -EIO;
- }
-
- rdmsr(msr, value, dummy);
-
- if (enable)
- value |= mask;
- else
- value &= ~mask;
-
- wrmsr(msr, value, dummy);
- return 0;
-}
-EXPORT_SYMBOL_GPL(cs5535_mfgpt_toggle_event);
-
-int cs5535_mfgpt_set_irq(struct cs5535_mfgpt_timer *timer, int cmp, int *irq,
- int enable)
-{
- uint32_t zsel, lpc, dummy;
- int shift;
-
- if (!timer) {
- WARN_ON(1);
- return -EIO;
- }
-
- /*
- * Unfortunately, MFGPTs come in pairs sharing their IRQ lines. If VSA
- * is using the same CMP of the timer's Siamese twin, the IRQ is set to
- * 2, and we mustn't use nor change it.
- * XXX: Likewise, 2 Linux drivers might clash if the 2nd overwrites the
- * IRQ of the 1st. This can only happen if forcing an IRQ, calling this
- * with *irq==0 is safe. Currently there _are_ no 2 drivers.
- */
- rdmsr(MSR_PIC_ZSEL_LOW, zsel, dummy);
- shift = ((cmp == MFGPT_CMP1 ? 0 : 4) + timer->nr % 4) * 4;
- if (((zsel >> shift) & 0xF) == 2)
- return -EIO;
-
- /* Choose IRQ: if none supplied, keep IRQ already set or use default */
- if (!*irq)
- *irq = (zsel >> shift) & 0xF;
- if (!*irq)
- *irq = CONFIG_CS5535_MFGPT_DEFAULT_IRQ;
-
- /* Can't use IRQ if it's 0 (=disabled), 2, or routed to LPC */
- if (*irq < 1 || *irq == 2 || *irq > 15)
- return -EIO;
- rdmsr(MSR_PIC_IRQM_LPC, lpc, dummy);
- if (lpc & (1 << *irq))
- return -EIO;
-
- /* All chosen and checked - go for it */
- if (cs5535_mfgpt_toggle_event(timer, cmp, MFGPT_EVENT_IRQ, enable))
- return -EIO;
- if (enable) {
- zsel = (zsel & ~(0xF << shift)) | (*irq << shift);
- wrmsr(MSR_PIC_ZSEL_LOW, zsel, dummy);
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cs5535_mfgpt_set_irq);
-
-struct cs5535_mfgpt_timer *cs5535_mfgpt_alloc_timer(int timer_nr, int domain)
-{
- struct cs5535_mfgpt_chip *mfgpt = &cs5535_mfgpt_chip;
- struct cs5535_mfgpt_timer *timer = NULL;
- unsigned long flags;
- int max;
-
- if (!mfgpt->initialized)
- goto done;
-
- /* only allocate timers from the working domain if requested */
- if (domain == MFGPT_DOMAIN_WORKING)
- max = 6;
- else
- max = MFGPT_MAX_TIMERS;
-
- if (timer_nr >= max) {
- /* programmer error. silly programmers! */
- WARN_ON(1);
- goto done;
- }
-
- spin_lock_irqsave(&mfgpt->lock, flags);
- if (timer_nr < 0) {
- unsigned long t;
-
- /* try to find any available timer */
- t = find_first_bit(mfgpt->avail, max);
- /* set timer_nr to -1 if no timers available */
- timer_nr = t < max ? (int) t : -1;
- } else {
- /* check if the requested timer's available */
- if (!test_bit(timer_nr, mfgpt->avail))
- timer_nr = -1;
- }
-
- if (timer_nr >= 0)
- /* if timer_nr is not -1, it's an available timer */
- __clear_bit(timer_nr, mfgpt->avail);
- spin_unlock_irqrestore(&mfgpt->lock, flags);
-
- if (timer_nr < 0)
- goto done;
-
- timer = kmalloc(sizeof(*timer), GFP_KERNEL);
- if (!timer) {
- /* aw hell */
- spin_lock_irqsave(&mfgpt->lock, flags);
- __set_bit(timer_nr, mfgpt->avail);
- spin_unlock_irqrestore(&mfgpt->lock, flags);
- goto done;
- }
- timer->chip = mfgpt;
- timer->nr = timer_nr;
- dev_info(&mfgpt->pdev->dev, "registered timer %d\n", timer_nr);
-
-done:
- return timer;
-}
-EXPORT_SYMBOL_GPL(cs5535_mfgpt_alloc_timer);
-
-/*
- * XXX: This frees the timer memory, but never resets the actual hardware
- * timer. The old geode_mfgpt code did this; it would be good to figure
- * out a way to actually release the hardware timer. See comments below.
- */
-void cs5535_mfgpt_free_timer(struct cs5535_mfgpt_timer *timer)
-{
- unsigned long flags;
- uint16_t val;
-
- /* timer can be made available again only if never set up */
- val = cs5535_mfgpt_read(timer, MFGPT_REG_SETUP);
- if (!(val & MFGPT_SETUP_SETUP)) {
- spin_lock_irqsave(&timer->chip->lock, flags);
- __set_bit(timer->nr, timer->chip->avail);
- spin_unlock_irqrestore(&timer->chip->lock, flags);
- }
-
- kfree(timer);
-}
-EXPORT_SYMBOL_GPL(cs5535_mfgpt_free_timer);
-
-uint16_t cs5535_mfgpt_read(struct cs5535_mfgpt_timer *timer, uint16_t reg)
-{
- return inw(timer->chip->base + reg + (timer->nr * 8));
-}
-EXPORT_SYMBOL_GPL(cs5535_mfgpt_read);
-
-void cs5535_mfgpt_write(struct cs5535_mfgpt_timer *timer, uint16_t reg,
- uint16_t value)
-{
- outw(value, timer->chip->base + reg + (timer->nr * 8));
-}
-EXPORT_SYMBOL_GPL(cs5535_mfgpt_write);
-
-/*
- * This is a sledgehammer that resets all MFGPT timers. This is required by
- * some broken BIOSes which leave the system in an unstable state
- * (TinyBIOS 0.98, for example; fixed in 0.99). It's uncertain as to
- * whether or not this secret MSR can be used to release individual timers.
- * Jordan tells me that he and Mitch once played w/ it, but it's unclear
- * what the results of that were (and they experienced some instability).
- */
-static void __devinit reset_all_timers(void)
-{
- uint32_t val, dummy;
-
- /* The following undocumented bit resets the MFGPT timers */
- val = 0xFF; dummy = 0;
- wrmsr(MSR_MFGPT_SETUP, val, dummy);
-}
-
-/*
- * Check whether any MFGPTs are available for the kernel to use. In most
- * cases, firmware that uses AMD's VSA code will claim all timers during
- * bootup; we certainly don't want to take them if they're already in use.
- * In other cases (such as with VSAless OpenFirmware), the system firmware
- * leaves timers available for us to use.
- */
-static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt)
-{
- struct cs5535_mfgpt_timer timer = { .chip = mfgpt };
- unsigned long flags;
- int timers = 0;
- uint16_t val;
- int i;
-
- /* bios workaround */
- if (mfgpt_reset_timers)
- reset_all_timers();
-
- /* just to be safe, protect this section w/ lock */
- spin_lock_irqsave(&mfgpt->lock, flags);
- for (i = 0; i < MFGPT_MAX_TIMERS; i++) {
- timer.nr = i;
- val = cs5535_mfgpt_read(&timer, MFGPT_REG_SETUP);
- if (!(val & MFGPT_SETUP_SETUP)) {
- __set_bit(i, mfgpt->avail);
- timers++;
- }
- }
- spin_unlock_irqrestore(&mfgpt->lock, flags);
-
- return timers;
-}
-
-static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev)
-{
- struct resource *res;
- int err = -EIO, t;
-
- /* There are two ways to get the MFGPT base address; one is by
- * fetching it from MSR_LBAR_MFGPT, the other is by reading the
- * PCI BAR info. The latter method is easier (especially across
- * different architectures), so we'll stick with that for now. If
- * it turns out to be unreliable in the face of crappy BIOSes, we
- * can always go back to using MSRs.. */
-
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (!res) {
- dev_err(&pdev->dev, "can't fetch device resource info\n");
- goto done;
- }
-
- if (!request_region(res->start, resource_size(res), pdev->name)) {
- dev_err(&pdev->dev, "can't request region\n");
- goto done;
- }
-
- /* set up the driver-specific struct */
- cs5535_mfgpt_chip.base = res->start;
- cs5535_mfgpt_chip.pdev = pdev;
- spin_lock_init(&cs5535_mfgpt_chip.lock);
-
- dev_info(&pdev->dev, "reserved resource region %pR\n", res);
-
- /* detect the available timers */
- t = scan_timers(&cs5535_mfgpt_chip);
- dev_info(&pdev->dev, "%d MFGPT timers available\n", t);
- cs5535_mfgpt_chip.initialized = 1;
- return 0;
-
-done:
- return err;
-}
-
-static struct platform_driver cs5535_mfgpt_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
- .probe = cs5535_mfgpt_probe,
-};
-
-
-static int __init cs5535_mfgpt_init(void)
-{
- return platform_driver_register(&cs5535_mfgpt_driver);
-}
-
-module_init(cs5535_mfgpt_init);
-
-MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
-MODULE_DESCRIPTION("CS5535/CS5536 MFGPT timer driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/ANDROID_3.4.5/drivers/misc/ds1682.c b/ANDROID_3.4.5/drivers/misc/ds1682.c
deleted file mode 100644
index 154b02e5..00000000
--- a/ANDROID_3.4.5/drivers/misc/ds1682.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Dallas Semiconductor DS1682 Elapsed Time Recorder device driver
- *
- * Written by: Grant Likely <grant.likely@secretlab.ca>
- *
- * Copyright (C) 2007 Secret Lab 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.
- */
-
-/*
- * The DS1682 elapsed timer recorder is a simple device that implements
- * one elapsed time counter, one event counter, an alarm signal and 10
- * bytes of general purpose EEPROM.
- *
- * This driver provides access to the DS1682 counters and user data via
- * the sysfs. The following attributes are added to the device node:
- * elapsed_time (u32): Total elapsed event time in ms resolution
- * alarm_time (u32): When elapsed time exceeds the value in alarm_time,
- * then the alarm pin is asserted.
- * event_count (u16): number of times the event pin has gone low.
- * eeprom (u8[10]): general purpose EEPROM
- *
- * Counter registers and user data are both read/write unless the device
- * has been write protected. This driver does not support turning off write
- * protection. Once write protection is turned on, it is impossible to
- * turn it off again, so I have left the feature out of this driver to avoid
- * accidental enabling, but it is trivial to add write protect support.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/string.h>
-#include <linux/list.h>
-#include <linux/sysfs.h>
-#include <linux/ctype.h>
-#include <linux/hwmon-sysfs.h>
-
-/* Device registers */
-#define DS1682_REG_CONFIG 0x00
-#define DS1682_REG_ALARM 0x01
-#define DS1682_REG_ELAPSED 0x05
-#define DS1682_REG_EVT_CNTR 0x09
-#define DS1682_REG_EEPROM 0x0b
-#define DS1682_REG_RESET 0x1d
-#define DS1682_REG_WRITE_DISABLE 0x1e
-#define DS1682_REG_WRITE_MEM_DISABLE 0x1f
-
-#define DS1682_EEPROM_SIZE 10
-
-/*
- * Generic counter attributes
- */
-static ssize_t ds1682_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
- struct i2c_client *client = to_i2c_client(dev);
- __le32 val = 0;
- int rc;
-
- dev_dbg(dev, "ds1682_show() called on %s\n", attr->attr.name);
-
- /* Read the register */
- rc = i2c_smbus_read_i2c_block_data(client, sattr->index, sattr->nr,
- (u8 *) & val);
- if (rc < 0)
- return -EIO;
-
- /* Special case: the 32 bit regs are time values with 1/4s
- * resolution, scale them up to milliseconds */
- if (sattr->nr == 4)
- return sprintf(buf, "%llu\n",
- ((unsigned long long)le32_to_cpu(val)) * 250);
-
- /* Format the output string and return # of bytes */
- return sprintf(buf, "%li\n", (long)le32_to_cpu(val));
-}
-
-static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
- struct i2c_client *client = to_i2c_client(dev);
- char *endp;
- u64 val;
- __le32 val_le;
- int rc;
-
- dev_dbg(dev, "ds1682_store() called on %s\n", attr->attr.name);
-
- /* Decode input */
- val = simple_strtoull(buf, &endp, 0);
- if (buf == endp) {
- dev_dbg(dev, "input string not a number\n");
- return -EINVAL;
- }
-
- /* Special case: the 32 bit regs are time values with 1/4s
- * resolution, scale input down to quarter-seconds */
- if (sattr->nr == 4)
- do_div(val, 250);
-
- /* write out the value */
- val_le = cpu_to_le32(val);
- rc = i2c_smbus_write_i2c_block_data(client, sattr->index, sattr->nr,
- (u8 *) & val_le);
- if (rc < 0) {
- dev_err(dev, "register write failed; reg=0x%x, size=%i\n",
- sattr->index, sattr->nr);
- return -EIO;
- }
-
- return count;
-}
-
-/*
- * Simple register attributes
- */
-static SENSOR_DEVICE_ATTR_2(elapsed_time, S_IRUGO | S_IWUSR, ds1682_show,
- ds1682_store, 4, DS1682_REG_ELAPSED);
-static SENSOR_DEVICE_ATTR_2(alarm_time, S_IRUGO | S_IWUSR, ds1682_show,
- ds1682_store, 4, DS1682_REG_ALARM);
-static SENSOR_DEVICE_ATTR_2(event_count, S_IRUGO | S_IWUSR, ds1682_show,
- ds1682_store, 2, DS1682_REG_EVT_CNTR);
-
-static const struct attribute_group ds1682_group = {
- .attrs = (struct attribute *[]) {
- &sensor_dev_attr_elapsed_time.dev_attr.attr,
- &sensor_dev_attr_alarm_time.dev_attr.attr,
- &sensor_dev_attr_event_count.dev_attr.attr,
- NULL,
- },
-};
-
-/*
- * User data attribute
- */
-static ssize_t ds1682_eeprom_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct i2c_client *client = kobj_to_i2c_client(kobj);
- int rc;
-
- dev_dbg(&client->dev, "ds1682_eeprom_read(p=%p, off=%lli, c=%zi)\n",
- buf, off, count);
-
- if (off >= DS1682_EEPROM_SIZE)
- return 0;
-
- if (off + count > DS1682_EEPROM_SIZE)
- count = DS1682_EEPROM_SIZE - off;
-
- rc = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + off,
- count, buf);
- if (rc < 0)
- return -EIO;
-
- return count;
-}
-
-static ssize_t ds1682_eeprom_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct i2c_client *client = kobj_to_i2c_client(kobj);
-
- dev_dbg(&client->dev, "ds1682_eeprom_write(p=%p, off=%lli, c=%zi)\n",
- buf, off, count);
-
- if (off >= DS1682_EEPROM_SIZE)
- return -ENOSPC;
-
- if (off + count > DS1682_EEPROM_SIZE)
- count = DS1682_EEPROM_SIZE - off;
-
- /* Write out to the device */
- if (i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + off,
- count, buf) < 0)
- return -EIO;
-
- return count;
-}
-
-static struct bin_attribute ds1682_eeprom_attr = {
- .attr = {
- .name = "eeprom",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = DS1682_EEPROM_SIZE,
- .read = ds1682_eeprom_read,
- .write = ds1682_eeprom_write,
-};
-
-/*
- * Called when a ds1682 device is matched with this driver
- */
-static int ds1682_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int rc;
-
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_I2C_BLOCK)) {
- dev_err(&client->dev, "i2c bus does not support the ds1682\n");
- rc = -ENODEV;
- goto exit;
- }
-
- rc = sysfs_create_group(&client->dev.kobj, &ds1682_group);
- if (rc)
- goto exit;
-
- rc = sysfs_create_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
- if (rc)
- goto exit_bin_attr;
-
- return 0;
-
- exit_bin_attr:
- sysfs_remove_group(&client->dev.kobj, &ds1682_group);
- exit:
- return rc;
-}
-
-static int ds1682_remove(struct i2c_client *client)
-{
- sysfs_remove_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
- sysfs_remove_group(&client->dev.kobj, &ds1682_group);
- return 0;
-}
-
-static const struct i2c_device_id ds1682_id[] = {
- { "ds1682", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ds1682_id);
-
-static struct i2c_driver ds1682_driver = {
- .driver = {
- .name = "ds1682",
- },
- .probe = ds1682_probe,
- .remove = ds1682_remove,
- .id_table = ds1682_id,
-};
-
-module_i2c_driver(ds1682_driver);
-
-MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
-MODULE_DESCRIPTION("DS1682 Elapsed Time Indicator driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/eeprom/Kconfig b/ANDROID_3.4.5/drivers/misc/eeprom/Kconfig
deleted file mode 100644
index 701edf65..00000000
--- a/ANDROID_3.4.5/drivers/misc/eeprom/Kconfig
+++ /dev/null
@@ -1,98 +0,0 @@
-menu "EEPROM support"
-
-config EEPROM_AT24
- tristate "I2C EEPROMs from most vendors"
- depends on I2C && SYSFS
- help
- Enable this driver to get read/write support to most I2C EEPROMs,
- after you configure the driver to know about each EEPROM on
- your target board. Use these generic chip names, instead of
- vendor-specific ones like at24c64 or 24lc02:
-
- 24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08,
- 24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024
-
- Unless you like data loss puzzles, always be sure that any chip
- you configure as a 24c32 (32 kbit) or larger is NOT really a
- 24c16 (16 kbit) or smaller, and vice versa. Marking the chip
- as read-only won't help recover from this. Also, if your chip
- has any software write-protect mechanism you may want to review the
- code to make sure this driver won't turn it on by accident.
-
- If you use this with an SMBus adapter instead of an I2C adapter,
- full functionality is not available. Only smaller devices are
- supported (24c16 and below, max 4 kByte).
-
- This driver can also be built as a module. If so, the module
- will be called at24.
-
-config EEPROM_AT25
- tristate "SPI EEPROMs from most vendors"
- depends on SPI && SYSFS
- help
- Enable this driver to get read/write support to most SPI EEPROMs,
- after you configure the board init code to know about each eeprom
- on your target board.
-
- This driver can also be built as a module. If so, the module
- will be called at25.
-
-config EEPROM_LEGACY
- tristate "Old I2C EEPROM reader"
- depends on I2C && SYSFS
- help
- If you say yes here you get read-only access to the EEPROM data
- available on modern memory DIMMs and Sony Vaio laptops via I2C. Such
- EEPROMs could theoretically be available on other devices as well.
-
- This driver can also be built as a module. If so, the module
- will be called eeprom.
-
-config EEPROM_MAX6875
- tristate "Maxim MAX6874/5 power supply supervisor"
- depends on I2C && EXPERIMENTAL
- help
- If you say yes here you get read-only support for the user EEPROM of
- the Maxim MAX6874/5 EEPROM-programmable, quad power-supply
- sequencer/supervisor.
-
- All other features of this chip should be accessed via i2c-dev.
-
- This driver can also be built as a module. If so, the module
- will be called max6875.
-
-
-config EEPROM_93CX6
- tristate "EEPROM 93CX6 support"
- help
- This is a driver for the EEPROM chipsets 93c46 and 93c66.
- The driver supports both read as well as write commands.
-
- If unsure, say N.
-
-config EEPROM_93XX46
- tristate "Microwire EEPROM 93XX46 support"
- depends on SPI && SYSFS
- help
- Driver for the microwire EEPROM chipsets 93xx46x. The driver
- supports both read and write commands and also the command to
- erase the whole EEPROM.
-
- This driver can also be built as a module. If so, the module
- will be called eeprom_93xx46.
-
- If unsure, say N.
-
-config EEPROM_DIGSY_MTC_CFG
- bool "DigsyMTC display configuration EEPROMs device"
- depends on GPIO_MPC5200 && SPI_GPIO
- help
- This option enables access to display configuration EEPROMs
- on digsy_mtc board. You have to additionally select Microwire
- EEPROM 93XX46 driver. sysfs entries will be created for that
- EEPROM allowing to read/write the configuration data or to
- erase the whole EEPROM.
-
- If unsure, say N.
-
-endmenu
diff --git a/ANDROID_3.4.5/drivers/misc/eeprom/Makefile b/ANDROID_3.4.5/drivers/misc/eeprom/Makefile
deleted file mode 100644
index fc1e81d2..00000000
--- a/ANDROID_3.4.5/drivers/misc/eeprom/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-obj-$(CONFIG_EEPROM_AT24) += at24.o
-obj-$(CONFIG_EEPROM_AT25) += at25.o
-obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o
-obj-$(CONFIG_EEPROM_MAX6875) += max6875.o
-obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
-obj-$(CONFIG_EEPROM_93XX46) += eeprom_93xx46.o
-obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o
diff --git a/ANDROID_3.4.5/drivers/misc/eeprom/at24.c b/ANDROID_3.4.5/drivers/misc/eeprom/at24.c
deleted file mode 100644
index ab1ad417..00000000
--- a/ANDROID_3.4.5/drivers/misc/eeprom/at24.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * at24.c - handle most I2C EEPROMs
- *
- * Copyright (C) 2005-2007 David Brownell
- * Copyright (C) 2008 Wolfram Sang, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/sysfs.h>
-#include <linux/mod_devicetable.h>
-#include <linux/log2.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/of.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-
-/*
- * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable.
- * Differences between different vendor product lines (like Atmel AT24C or
- * MicroChip 24LC, etc) won't much matter for typical read/write access.
- * There are also I2C RAM chips, likewise interchangeable. One example
- * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes).
- *
- * However, misconfiguration can lose data. "Set 16-bit memory address"
- * to a part with 8-bit addressing will overwrite data. Writing with too
- * big a page size also loses data. And it's not safe to assume that the
- * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC
- * uses 0x51, for just one example.
- *
- * Accordingly, explicit board-specific configuration data should be used
- * in almost all cases. (One partial exception is an SMBus used to access
- * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.)
- *
- * So this driver uses "new style" I2C driver binding, expecting to be
- * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or
- * similar kernel-resident tables; or, configuration data coming from
- * a bootloader.
- *
- * Other than binding model, current differences from "eeprom" driver are
- * that this one handles write access and isn't restricted to 24c02 devices.
- * It also handles larger devices (32 kbit and up) with two-byte addresses,
- * which won't work on pure SMBus systems.
- */
-
-struct at24_data {
- struct at24_platform_data chip;
- struct memory_accessor macc;
- int use_smbus;
-
- /*
- * Lock protects against activities from other Linux tasks,
- * but not from changes by other I2C masters.
- */
- struct mutex lock;
- struct bin_attribute bin;
-
- u8 *writebuf;
- unsigned write_max;
- unsigned num_addresses;
-
- /*
- * Some chips tie up multiple I2C addresses; dummy devices reserve
- * them for us, and we'll use them with SMBus calls.
- */
- struct i2c_client *client[];
-};
-
-/*
- * This parameter is to help this driver avoid blocking other drivers out
- * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C
- * clock, one 256 byte read takes about 1/43 second which is excessive;
- * but the 1/170 second it takes at 400 kHz may be quite reasonable; and
- * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible.
- *
- * This value is forced to be a power of two so that writes align on pages.
- */
-static unsigned io_limit = 128;
-module_param(io_limit, uint, 0);
-MODULE_PARM_DESC(io_limit, "Maximum bytes per I/O (default 128)");
-
-/*
- * Specs often allow 5 msec for a page write, sometimes 20 msec;
- * it's important to recover from write timeouts.
- */
-static unsigned write_timeout = 25;
-module_param(write_timeout, uint, 0);
-MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)");
-
-#define AT24_SIZE_BYTELEN 5
-#define AT24_SIZE_FLAGS 8
-
-#define AT24_BITMASK(x) (BIT(x) - 1)
-
-/* create non-zero magic value for given eeprom parameters */
-#define AT24_DEVICE_MAGIC(_len, _flags) \
- ((1 << AT24_SIZE_FLAGS | (_flags)) \
- << AT24_SIZE_BYTELEN | ilog2(_len))
-
-static const struct i2c_device_id at24_ids[] = {
- /* needs 8 addresses as A0-A2 are ignored */
- { "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) },
- /* old variants can't be handled with this generic entry! */
- { "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) },
- { "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) },
- /* spd is a 24c02 in memory DIMMs */
- { "spd", AT24_DEVICE_MAGIC(2048 / 8,
- AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },
- { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },
- /* 24rf08 quirk is handled at i2c-core */
- { "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },
- { "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },
- { "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },
- { "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },
- { "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) },
- { "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) },
- { "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) },
- { "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) },
- { "at24", 0 },
- { /* END OF LIST */ }
-};
-MODULE_DEVICE_TABLE(i2c, at24_ids);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * This routine supports chips which consume multiple I2C addresses. It
- * computes the addressing information to be used for a given r/w request.
- * Assumes that sanity checks for offset happened at sysfs-layer.
- */
-static struct i2c_client *at24_translate_offset(struct at24_data *at24,
- unsigned *offset)
-{
- unsigned i;
-
- if (at24->chip.flags & AT24_FLAG_ADDR16) {
- i = *offset >> 16;
- *offset &= 0xffff;
- } else {
- i = *offset >> 8;
- *offset &= 0xff;
- }
-
- return at24->client[i];
-}
-
-static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
- unsigned offset, size_t count)
-{
- struct i2c_msg msg[2];
- u8 msgbuf[2];
- struct i2c_client *client;
- unsigned long timeout, read_time;
- int status, i;
-
- memset(msg, 0, sizeof(msg));
-
- /*
- * REVISIT some multi-address chips don't rollover page reads to
- * the next slave address, so we may need to truncate the count.
- * Those chips might need another quirk flag.
- *
- * If the real hardware used four adjacent 24c02 chips and that
- * were misconfigured as one 24c08, that would be a similar effect:
- * one "eeprom" file not four, but larger reads would fail when
- * they crossed certain pages.
- */
-
- /*
- * Slave address and byte offset derive from the offset. Always
- * set the byte address; on a multi-master board, another master
- * may have changed the chip's "current" address pointer.
- */
- client = at24_translate_offset(at24, &offset);
-
- if (count > io_limit)
- count = io_limit;
-
- switch (at24->use_smbus) {
- case I2C_SMBUS_I2C_BLOCK_DATA:
- /* Smaller eeproms can work given some SMBus extension calls */
- if (count > I2C_SMBUS_BLOCK_MAX)
- count = I2C_SMBUS_BLOCK_MAX;
- break;
- case I2C_SMBUS_WORD_DATA:
- count = 2;
- break;
- case I2C_SMBUS_BYTE_DATA:
- count = 1;
- break;
- default:
- /*
- * When we have a better choice than SMBus calls, use a
- * combined I2C message. Write address; then read up to
- * io_limit data bytes. Note that read page rollover helps us
- * here (unlike writes). msgbuf is u8 and will cast to our
- * needs.
- */
- i = 0;
- if (at24->chip.flags & AT24_FLAG_ADDR16)
- msgbuf[i++] = offset >> 8;
- msgbuf[i++] = offset;
-
- msg[0].addr = client->addr;
- msg[0].buf = msgbuf;
- msg[0].len = i;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].buf = buf;
- msg[1].len = count;
- }
-
- /*
- * Reads fail if the previous write didn't complete yet. We may
- * loop a few times until this one succeeds, waiting at least
- * long enough for one entire page write to work.
- */
- timeout = jiffies + msecs_to_jiffies(write_timeout);
- do {
- read_time = jiffies;
- switch (at24->use_smbus) {
- case I2C_SMBUS_I2C_BLOCK_DATA:
- status = i2c_smbus_read_i2c_block_data(client, offset,
- count, buf);
- break;
- case I2C_SMBUS_WORD_DATA:
- status = i2c_smbus_read_word_data(client, offset);
- if (status >= 0) {
- buf[0] = status & 0xff;
- buf[1] = status >> 8;
- status = count;
- }
- break;
- case I2C_SMBUS_BYTE_DATA:
- status = i2c_smbus_read_byte_data(client, offset);
- if (status >= 0) {
- buf[0] = status;
- status = count;
- }
- break;
- default:
- status = i2c_transfer(client->adapter, msg, 2);
- if (status == 2)
- status = count;
- }
- dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n",
- count, offset, status, jiffies);
-
- if (status == count)
- return count;
-
- /* REVISIT: at HZ=100, this is sloooow */
- msleep(1);
- } while (time_before(read_time, timeout));
-
- return -ETIMEDOUT;
-}
-
-static ssize_t at24_read(struct at24_data *at24,
- char *buf, loff_t off, size_t count)
-{
- ssize_t retval = 0;
-
- if (unlikely(!count))
- return count;
-
- /*
- * Read data from chip, protecting against concurrent updates
- * from this host, but not from other I2C masters.
- */
- mutex_lock(&at24->lock);
-
- while (count) {
- ssize_t status;
-
- status = at24_eeprom_read(at24, buf, off, count);
- if (status <= 0) {
- if (retval == 0)
- retval = status;
- break;
- }
- buf += status;
- off += status;
- count -= status;
- retval += status;
- }
-
- mutex_unlock(&at24->lock);
-
- return retval;
-}
-
-static ssize_t at24_bin_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct at24_data *at24;
-
- at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
- return at24_read(at24, buf, off, count);
-}
-
-
-/*
- * Note that if the hardware write-protect pin is pulled high, the whole
- * chip is normally write protected. But there are plenty of product
- * variants here, including OTP fuses and partial chip protect.
- *
- * We only use page mode writes; the alternative is sloooow. This routine
- * writes at most one page.
- */
-static ssize_t at24_eeprom_write(struct at24_data *at24, const char *buf,
- unsigned offset, size_t count)
-{
- struct i2c_client *client;
- struct i2c_msg msg;
- ssize_t status;
- unsigned long timeout, write_time;
- unsigned next_page;
-
- /* Get corresponding I2C address and adjust offset */
- client = at24_translate_offset(at24, &offset);
-
- /* write_max is at most a page */
- if (count > at24->write_max)
- count = at24->write_max;
-
- /* Never roll over backwards, to the start of this page */
- next_page = roundup(offset + 1, at24->chip.page_size);
- if (offset + count > next_page)
- count = next_page - offset;
-
- /* If we'll use I2C calls for I/O, set up the message */
- if (!at24->use_smbus) {
- int i = 0;
-
- msg.addr = client->addr;
- msg.flags = 0;
-
- /* msg.buf is u8 and casts will mask the values */
- msg.buf = at24->writebuf;
- if (at24->chip.flags & AT24_FLAG_ADDR16)
- msg.buf[i++] = offset >> 8;
-
- msg.buf[i++] = offset;
- memcpy(&msg.buf[i], buf, count);
- msg.len = i + count;
- }
-
- /*
- * Writes fail if the previous one didn't complete yet. We may
- * loop a few times until this one succeeds, waiting at least
- * long enough for one entire page write to work.
- */
- timeout = jiffies + msecs_to_jiffies(write_timeout);
- do {
- write_time = jiffies;
- if (at24->use_smbus) {
- status = i2c_smbus_write_i2c_block_data(client,
- offset, count, buf);
- if (status == 0)
- status = count;
- } else {
- status = i2c_transfer(client->adapter, &msg, 1);
- if (status == 1)
- status = count;
- }
- dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n",
- count, offset, status, jiffies);
-
- if (status == count)
- return count;
-
- /* REVISIT: at HZ=100, this is sloooow */
- msleep(1);
- } while (time_before(write_time, timeout));
-
- return -ETIMEDOUT;
-}
-
-static ssize_t at24_write(struct at24_data *at24, const char *buf, loff_t off,
- size_t count)
-{
- ssize_t retval = 0;
-
- if (unlikely(!count))
- return count;
-
- /*
- * Write data to chip, protecting against concurrent updates
- * from this host, but not from other I2C masters.
- */
- mutex_lock(&at24->lock);
-
- while (count) {
- ssize_t status;
-
- status = at24_eeprom_write(at24, buf, off, count);
- if (status <= 0) {
- if (retval == 0)
- retval = status;
- break;
- }
- buf += status;
- off += status;
- count -= status;
- retval += status;
- }
-
- mutex_unlock(&at24->lock);
-
- return retval;
-}
-
-static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct at24_data *at24;
-
- at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
- return at24_write(at24, buf, off, count);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * This lets other kernel code access the eeprom data. For example, it
- * might hold a board's Ethernet address, or board-specific calibration
- * data generated on the manufacturing floor.
- */
-
-static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf,
- off_t offset, size_t count)
-{
- struct at24_data *at24 = container_of(macc, struct at24_data, macc);
-
- return at24_read(at24, buf, offset, count);
-}
-
-static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf,
- off_t offset, size_t count)
-{
- struct at24_data *at24 = container_of(macc, struct at24_data, macc);
-
- return at24_write(at24, buf, offset, count);
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_OF
-static void at24_get_ofdata(struct i2c_client *client,
- struct at24_platform_data *chip)
-{
- const __be32 *val;
- struct device_node *node = client->dev.of_node;
-
- if (node) {
- if (of_get_property(node, "read-only", NULL))
- chip->flags |= AT24_FLAG_READONLY;
- val = of_get_property(node, "pagesize", NULL);
- if (val)
- chip->page_size = be32_to_cpup(val);
- }
-}
-#else
-static void at24_get_ofdata(struct i2c_client *client,
- struct at24_platform_data *chip)
-{ }
-#endif /* CONFIG_OF */
-
-static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct at24_platform_data chip;
- bool writable;
- int use_smbus = 0;
- struct at24_data *at24;
- int err;
- unsigned i, num_addresses;
- kernel_ulong_t magic;
-
- if (client->dev.platform_data) {
- chip = *(struct at24_platform_data *)client->dev.platform_data;
- } else {
- if (!id->driver_data) {
- err = -ENODEV;
- goto err_out;
- }
- magic = id->driver_data;
- chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN));
- magic >>= AT24_SIZE_BYTELEN;
- chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS);
- /*
- * This is slow, but we can't know all eeproms, so we better
- * play safe. Specifying custom eeprom-types via platform_data
- * is recommended anyhow.
- */
- chip.page_size = 1;
-
- /* update chipdata if OF is present */
- at24_get_ofdata(client, &chip);
-
- chip.setup = NULL;
- chip.context = NULL;
- }
-
- if (!is_power_of_2(chip.byte_len))
- dev_warn(&client->dev,
- "byte_len looks suspicious (no power of 2)!\n");
- if (!chip.page_size) {
- dev_err(&client->dev, "page_size must not be 0!\n");
- err = -EINVAL;
- goto err_out;
- }
- if (!is_power_of_2(chip.page_size))
- dev_warn(&client->dev,
- "page_size looks suspicious (no power of 2)!\n");
-
- /* Use I2C operations unless we're stuck with SMBus extensions. */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- if (chip.flags & AT24_FLAG_ADDR16) {
- err = -EPFNOSUPPORT;
- goto err_out;
- }
- if (i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
- use_smbus = I2C_SMBUS_I2C_BLOCK_DATA;
- } else if (i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_WORD_DATA)) {
- use_smbus = I2C_SMBUS_WORD_DATA;
- } else if (i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
- use_smbus = I2C_SMBUS_BYTE_DATA;
- } else {
- err = -EPFNOSUPPORT;
- goto err_out;
- }
- }
-
- if (chip.flags & AT24_FLAG_TAKE8ADDR)
- num_addresses = 8;
- else
- num_addresses = DIV_ROUND_UP(chip.byte_len,
- (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256);
-
- at24 = kzalloc(sizeof(struct at24_data) +
- num_addresses * sizeof(struct i2c_client *), GFP_KERNEL);
- if (!at24) {
- err = -ENOMEM;
- goto err_out;
- }
-
- mutex_init(&at24->lock);
- at24->use_smbus = use_smbus;
- at24->chip = chip;
- at24->num_addresses = num_addresses;
-
- /*
- * Export the EEPROM bytes through sysfs, since that's convenient.
- * By default, only root should see the data (maybe passwords etc)
- */
- sysfs_bin_attr_init(&at24->bin);
- at24->bin.attr.name = "eeprom";
- at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR;
- at24->bin.read = at24_bin_read;
- at24->bin.size = chip.byte_len;
-
- at24->macc.read = at24_macc_read;
-
- writable = !(chip.flags & AT24_FLAG_READONLY);
- if (writable) {
- if (!use_smbus || i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
-
- unsigned write_max = chip.page_size;
-
- at24->macc.write = at24_macc_write;
-
- at24->bin.write = at24_bin_write;
- at24->bin.attr.mode |= S_IWUSR;
-
- if (write_max > io_limit)
- write_max = io_limit;
- if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX)
- write_max = I2C_SMBUS_BLOCK_MAX;
- at24->write_max = write_max;
-
- /* buffer (data + address at the beginning) */
- at24->writebuf = kmalloc(write_max + 2, GFP_KERNEL);
- if (!at24->writebuf) {
- err = -ENOMEM;
- goto err_struct;
- }
- } else {
- dev_warn(&client->dev,
- "cannot write due to controller restrictions.");
- }
- }
-
- at24->client[0] = client;
-
- /* use dummy devices for multiple-address chips */
- for (i = 1; i < num_addresses; i++) {
- at24->client[i] = i2c_new_dummy(client->adapter,
- client->addr + i);
- if (!at24->client[i]) {
- dev_err(&client->dev, "address 0x%02x unavailable\n",
- client->addr + i);
- err = -EADDRINUSE;
- goto err_clients;
- }
- }
-
- err = sysfs_create_bin_file(&client->dev.kobj, &at24->bin);
- if (err)
- goto err_clients;
-
- i2c_set_clientdata(client, at24);
-
- dev_info(&client->dev, "%zu byte %s EEPROM, %s, %u bytes/write\n",
- at24->bin.size, client->name,
- writable ? "writable" : "read-only", at24->write_max);
- if (use_smbus == I2C_SMBUS_WORD_DATA ||
- use_smbus == I2C_SMBUS_BYTE_DATA) {
- dev_notice(&client->dev, "Falling back to %s reads, "
- "performance will suffer\n", use_smbus ==
- I2C_SMBUS_WORD_DATA ? "word" : "byte");
- }
-
- /* export data to kernel code */
- if (chip.setup)
- chip.setup(&at24->macc, chip.context);
-
- return 0;
-
-err_clients:
- for (i = 1; i < num_addresses; i++)
- if (at24->client[i])
- i2c_unregister_device(at24->client[i]);
-
- kfree(at24->writebuf);
-err_struct:
- kfree(at24);
-err_out:
- dev_dbg(&client->dev, "probe error %d\n", err);
- return err;
-}
-
-static int __devexit at24_remove(struct i2c_client *client)
-{
- struct at24_data *at24;
- int i;
-
- at24 = i2c_get_clientdata(client);
- sysfs_remove_bin_file(&client->dev.kobj, &at24->bin);
-
- for (i = 1; i < at24->num_addresses; i++)
- i2c_unregister_device(at24->client[i]);
-
- kfree(at24->writebuf);
- kfree(at24);
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static struct i2c_driver at24_driver = {
- .driver = {
- .name = "at24",
- .owner = THIS_MODULE,
- },
- .probe = at24_probe,
- .remove = __devexit_p(at24_remove),
- .id_table = at24_ids,
-};
-
-static int __init at24_init(void)
-{
- if (!io_limit) {
- pr_err("at24: io_limit must not be 0!\n");
- return -EINVAL;
- }
-
- io_limit = rounddown_pow_of_two(io_limit);
- return i2c_add_driver(&at24_driver);
-}
-module_init(at24_init);
-
-static void __exit at24_exit(void)
-{
- i2c_del_driver(&at24_driver);
-}
-module_exit(at24_exit);
-
-MODULE_DESCRIPTION("Driver for most I2C EEPROMs");
-MODULE_AUTHOR("David Brownell and Wolfram Sang");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/eeprom/at25.c b/ANDROID_3.4.5/drivers/misc/eeprom/at25.c
deleted file mode 100644
index 01ab3c9b..00000000
--- a/ANDROID_3.4.5/drivers/misc/eeprom/at25.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * at25.c -- support most SPI EEPROMs, such as Atmel AT25 models
- *
- * Copyright (C) 2006 David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/sched.h>
-
-#include <linux/spi/spi.h>
-#include <linux/spi/eeprom.h>
-
-
-/*
- * NOTE: this is an *EEPROM* driver. The vagaries of product naming
- * mean that some AT25 products are EEPROMs, and others are FLASH.
- * Handle FLASH chips with the drivers/mtd/devices/m25p80.c driver,
- * not this one!
- */
-
-struct at25_data {
- struct spi_device *spi;
- struct memory_accessor mem;
- struct mutex lock;
- struct spi_eeprom chip;
- struct bin_attribute bin;
- unsigned addrlen;
-};
-
-#define AT25_WREN 0x06 /* latch the write enable */
-#define AT25_WRDI 0x04 /* reset the write enable */
-#define AT25_RDSR 0x05 /* read status register */
-#define AT25_WRSR 0x01 /* write status register */
-#define AT25_READ 0x03 /* read byte(s) */
-#define AT25_WRITE 0x02 /* write byte(s)/sector */
-
-#define AT25_SR_nRDY 0x01 /* nRDY = write-in-progress */
-#define AT25_SR_WEN 0x02 /* write enable (latched) */
-#define AT25_SR_BP0 0x04 /* BP for software writeprotect */
-#define AT25_SR_BP1 0x08
-#define AT25_SR_WPEN 0x80 /* writeprotect enable */
-
-
-#define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */
-
-/* Specs often allow 5 msec for a page write, sometimes 20 msec;
- * it's important to recover from write timeouts.
- */
-#define EE_TIMEOUT 25
-
-/*-------------------------------------------------------------------------*/
-
-#define io_limit PAGE_SIZE /* bytes */
-
-static ssize_t
-at25_ee_read(
- struct at25_data *at25,
- char *buf,
- unsigned offset,
- size_t count
-)
-{
- u8 command[EE_MAXADDRLEN + 1];
- u8 *cp;
- ssize_t status;
- struct spi_transfer t[2];
- struct spi_message m;
-
- if (unlikely(offset >= at25->bin.size))
- return 0;
- if ((offset + count) > at25->bin.size)
- count = at25->bin.size - offset;
- if (unlikely(!count))
- return count;
-
- cp = command;
- *cp++ = AT25_READ;
-
- /* 8/16/24-bit address is written MSB first */
- switch (at25->addrlen) {
- default: /* case 3 */
- *cp++ = offset >> 16;
- case 2:
- *cp++ = offset >> 8;
- case 1:
- case 0: /* can't happen: for better codegen */
- *cp++ = offset >> 0;
- }
-
- spi_message_init(&m);
- memset(t, 0, sizeof t);
-
- t[0].tx_buf = command;
- t[0].len = at25->addrlen + 1;
- spi_message_add_tail(&t[0], &m);
-
- t[1].rx_buf = buf;
- t[1].len = count;
- spi_message_add_tail(&t[1], &m);
-
- mutex_lock(&at25->lock);
-
- /* Read it all at once.
- *
- * REVISIT that's potentially a problem with large chips, if
- * other devices on the bus need to be accessed regularly or
- * this chip is clocked very slowly
- */
- status = spi_sync(at25->spi, &m);
- dev_dbg(&at25->spi->dev,
- "read %Zd bytes at %d --> %d\n",
- count, offset, (int) status);
-
- mutex_unlock(&at25->lock);
- return status ? status : count;
-}
-
-static ssize_t
-at25_bin_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- struct device *dev;
- struct at25_data *at25;
-
- dev = container_of(kobj, struct device, kobj);
- at25 = dev_get_drvdata(dev);
-
- return at25_ee_read(at25, buf, off, count);
-}
-
-
-static ssize_t
-at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
- size_t count)
-{
- ssize_t status = 0;
- unsigned written = 0;
- unsigned buf_size;
- u8 *bounce;
-
- if (unlikely(off >= at25->bin.size))
- return -EFBIG;
- if ((off + count) > at25->bin.size)
- count = at25->bin.size - off;
- if (unlikely(!count))
- return count;
-
- /* Temp buffer starts with command and address */
- buf_size = at25->chip.page_size;
- if (buf_size > io_limit)
- buf_size = io_limit;
- bounce = kmalloc(buf_size + at25->addrlen + 1, GFP_KERNEL);
- if (!bounce)
- return -ENOMEM;
-
- /* For write, rollover is within the page ... so we write at
- * most one page, then manually roll over to the next page.
- */
- bounce[0] = AT25_WRITE;
- mutex_lock(&at25->lock);
- do {
- unsigned long timeout, retries;
- unsigned segment;
- unsigned offset = (unsigned) off;
- u8 *cp = bounce + 1;
- int sr;
-
- *cp = AT25_WREN;
- status = spi_write(at25->spi, cp, 1);
- if (status < 0) {
- dev_dbg(&at25->spi->dev, "WREN --> %d\n",
- (int) status);
- break;
- }
-
- /* 8/16/24-bit address is written MSB first */
- switch (at25->addrlen) {
- default: /* case 3 */
- *cp++ = offset >> 16;
- case 2:
- *cp++ = offset >> 8;
- case 1:
- case 0: /* can't happen: for better codegen */
- *cp++ = offset >> 0;
- }
-
- /* Write as much of a page as we can */
- segment = buf_size - (offset % buf_size);
- if (segment > count)
- segment = count;
- memcpy(cp, buf, segment);
- status = spi_write(at25->spi, bounce,
- segment + at25->addrlen + 1);
- dev_dbg(&at25->spi->dev,
- "write %u bytes at %u --> %d\n",
- segment, offset, (int) status);
- if (status < 0)
- break;
-
- /* REVISIT this should detect (or prevent) failed writes
- * to readonly sections of the EEPROM...
- */
-
- /* Wait for non-busy status */
- timeout = jiffies + msecs_to_jiffies(EE_TIMEOUT);
- retries = 0;
- do {
-
- sr = spi_w8r8(at25->spi, AT25_RDSR);
- if (sr < 0 || (sr & AT25_SR_nRDY)) {
- dev_dbg(&at25->spi->dev,
- "rdsr --> %d (%02x)\n", sr, sr);
- /* at HZ=100, this is sloooow */
- msleep(1);
- continue;
- }
- if (!(sr & AT25_SR_nRDY))
- break;
- } while (retries++ < 3 || time_before_eq(jiffies, timeout));
-
- if ((sr < 0) || (sr & AT25_SR_nRDY)) {
- dev_err(&at25->spi->dev,
- "write %d bytes offset %d, "
- "timeout after %u msecs\n",
- segment, offset,
- jiffies_to_msecs(jiffies -
- (timeout - EE_TIMEOUT)));
- status = -ETIMEDOUT;
- break;
- }
-
- off += segment;
- buf += segment;
- count -= segment;
- written += segment;
-
- } while (count > 0);
-
- mutex_unlock(&at25->lock);
-
- kfree(bounce);
- return written ? written : status;
-}
-
-static ssize_t
-at25_bin_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- struct device *dev;
- struct at25_data *at25;
-
- dev = container_of(kobj, struct device, kobj);
- at25 = dev_get_drvdata(dev);
-
- return at25_ee_write(at25, buf, off, count);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* Let in-kernel code access the eeprom data. */
-
-static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf,
- off_t offset, size_t count)
-{
- struct at25_data *at25 = container_of(mem, struct at25_data, mem);
-
- return at25_ee_read(at25, buf, offset, count);
-}
-
-static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
- off_t offset, size_t count)
-{
- struct at25_data *at25 = container_of(mem, struct at25_data, mem);
-
- return at25_ee_write(at25, buf, offset, count);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int at25_probe(struct spi_device *spi)
-{
- struct at25_data *at25 = NULL;
- const struct spi_eeprom *chip;
- int err;
- int sr;
- int addrlen;
-
- /* Chip description */
- chip = spi->dev.platform_data;
- if (!chip) {
- dev_dbg(&spi->dev, "no chip description\n");
- err = -ENODEV;
- goto fail;
- }
-
- /* For now we only support 8/16/24 bit addressing */
- if (chip->flags & EE_ADDR1)
- addrlen = 1;
- else if (chip->flags & EE_ADDR2)
- addrlen = 2;
- else if (chip->flags & EE_ADDR3)
- addrlen = 3;
- else {
- dev_dbg(&spi->dev, "unsupported address type\n");
- err = -EINVAL;
- goto fail;
- }
-
- /* Ping the chip ... the status register is pretty portable,
- * unlike probing manufacturer IDs. We do expect that system
- * firmware didn't write it in the past few milliseconds!
- */
- sr = spi_w8r8(spi, AT25_RDSR);
- if (sr < 0 || sr & AT25_SR_nRDY) {
- dev_dbg(&spi->dev, "rdsr --> %d (%02x)\n", sr, sr);
- err = -ENXIO;
- goto fail;
- }
-
- if (!(at25 = kzalloc(sizeof *at25, GFP_KERNEL))) {
- err = -ENOMEM;
- goto fail;
- }
-
- mutex_init(&at25->lock);
- at25->chip = *chip;
- at25->spi = spi_dev_get(spi);
- dev_set_drvdata(&spi->dev, at25);
- at25->addrlen = addrlen;
-
- /* Export the EEPROM bytes through sysfs, since that's convenient.
- * And maybe to other kernel code; it might hold a board's Ethernet
- * address, or board-specific calibration data generated on the
- * manufacturing floor.
- *
- * Default to root-only access to the data; EEPROMs often hold data
- * that's sensitive for read and/or write, like ethernet addresses,
- * security codes, board-specific manufacturing calibrations, etc.
- */
- sysfs_bin_attr_init(&at25->bin);
- at25->bin.attr.name = "eeprom";
- at25->bin.attr.mode = S_IRUSR;
- at25->bin.read = at25_bin_read;
- at25->mem.read = at25_mem_read;
-
- at25->bin.size = at25->chip.byte_len;
- if (!(chip->flags & EE_READONLY)) {
- at25->bin.write = at25_bin_write;
- at25->bin.attr.mode |= S_IWUSR;
- at25->mem.write = at25_mem_write;
- }
-
- err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin);
- if (err)
- goto fail;
-
- if (chip->setup)
- chip->setup(&at25->mem, chip->context);
-
- dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n",
- (at25->bin.size < 1024)
- ? at25->bin.size
- : (at25->bin.size / 1024),
- (at25->bin.size < 1024) ? "Byte" : "KByte",
- at25->chip.name,
- (chip->flags & EE_READONLY) ? " (readonly)" : "",
- at25->chip.page_size);
- return 0;
-fail:
- dev_dbg(&spi->dev, "probe err %d\n", err);
- kfree(at25);
- return err;
-}
-
-static int __devexit at25_remove(struct spi_device *spi)
-{
- struct at25_data *at25;
-
- at25 = dev_get_drvdata(&spi->dev);
- sysfs_remove_bin_file(&spi->dev.kobj, &at25->bin);
- kfree(at25);
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static struct spi_driver at25_driver = {
- .driver = {
- .name = "at25",
- .owner = THIS_MODULE,
- },
- .probe = at25_probe,
- .remove = __devexit_p(at25_remove),
-};
-
-module_spi_driver(at25_driver);
-
-MODULE_DESCRIPTION("Driver for most SPI EEPROMs");
-MODULE_AUTHOR("David Brownell");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("spi:at25");
diff --git a/ANDROID_3.4.5/drivers/misc/eeprom/digsy_mtc_eeprom.c b/ANDROID_3.4.5/drivers/misc/eeprom/digsy_mtc_eeprom.c
deleted file mode 100644
index 66d9e1ba..00000000
--- a/ANDROID_3.4.5/drivers/misc/eeprom/digsy_mtc_eeprom.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * EEPROMs access control driver for display configuration EEPROMs
- * on DigsyMTC board.
- *
- * (C) 2011 DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_gpio.h>
-#include <linux/eeprom_93xx46.h>
-
-#define GPIO_EEPROM_CLK 216
-#define GPIO_EEPROM_CS 210
-#define GPIO_EEPROM_DI 217
-#define GPIO_EEPROM_DO 249
-#define GPIO_EEPROM_OE 255
-#define EE_SPI_BUS_NUM 1
-
-static void digsy_mtc_op_prepare(void *p)
-{
- /* enable */
- gpio_set_value(GPIO_EEPROM_OE, 0);
-}
-
-static void digsy_mtc_op_finish(void *p)
-{
- /* disable */
- gpio_set_value(GPIO_EEPROM_OE, 1);
-}
-
-struct eeprom_93xx46_platform_data digsy_mtc_eeprom_data = {
- .flags = EE_ADDR8,
- .prepare = digsy_mtc_op_prepare,
- .finish = digsy_mtc_op_finish,
-};
-
-static struct spi_gpio_platform_data eeprom_spi_gpio_data = {
- .sck = GPIO_EEPROM_CLK,
- .mosi = GPIO_EEPROM_DI,
- .miso = GPIO_EEPROM_DO,
- .num_chipselect = 1,
-};
-
-static struct platform_device digsy_mtc_eeprom = {
- .name = "spi_gpio",
- .id = EE_SPI_BUS_NUM,
- .dev = {
- .platform_data = &eeprom_spi_gpio_data,
- },
-};
-
-static struct spi_board_info digsy_mtc_eeprom_info[] __initdata = {
- {
- .modalias = "93xx46",
- .max_speed_hz = 1000000,
- .bus_num = EE_SPI_BUS_NUM,
- .chip_select = 0,
- .mode = SPI_MODE_0,
- .controller_data = (void *)GPIO_EEPROM_CS,
- .platform_data = &digsy_mtc_eeprom_data,
- },
-};
-
-static int __init digsy_mtc_eeprom_devices_init(void)
-{
- int ret;
-
- ret = gpio_request_one(GPIO_EEPROM_OE, GPIOF_OUT_INIT_HIGH,
- "93xx46 EEPROMs OE");
- if (ret) {
- pr_err("can't request gpio %d\n", GPIO_EEPROM_OE);
- return ret;
- }
- spi_register_board_info(digsy_mtc_eeprom_info,
- ARRAY_SIZE(digsy_mtc_eeprom_info));
- return platform_device_register(&digsy_mtc_eeprom);
-}
-device_initcall(digsy_mtc_eeprom_devices_init);
diff --git a/ANDROID_3.4.5/drivers/misc/eeprom/eeprom.c b/ANDROID_3.4.5/drivers/misc/eeprom/eeprom.c
deleted file mode 100644
index c169e076..00000000
--- a/ANDROID_3.4.5/drivers/misc/eeprom/eeprom.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
- * Philip Edelbrock <phil@netroedge.com>
- * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2003 IBM Corp.
- * Copyright (C) 2004 Jean Delvare <khali@linux-fr.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/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
- 0x55, 0x56, 0x57, I2C_CLIENT_END };
-
-
-/* Size of EEPROM in bytes */
-#define EEPROM_SIZE 256
-
-/* possible types of eeprom devices */
-enum eeprom_nature {
- UNKNOWN,
- VAIO,
-};
-
-/* Each client has this additional data */
-struct eeprom_data {
- struct mutex update_lock;
- u8 valid; /* bitfield, bit!=0 if slice is valid */
- unsigned long last_updated[8]; /* In jiffies, 8 slices */
- u8 data[EEPROM_SIZE]; /* Register values */
- enum eeprom_nature nature;
-};
-
-
-static void eeprom_update_client(struct i2c_client *client, u8 slice)
-{
- struct eeprom_data *data = i2c_get_clientdata(client);
- int i;
-
- mutex_lock(&data->update_lock);
-
- if (!(data->valid & (1 << slice)) ||
- time_after(jiffies, data->last_updated[slice] + 300 * HZ)) {
- dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice);
-
- if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
- for (i = slice << 5; i < (slice + 1) << 5; i += 32)
- if (i2c_smbus_read_i2c_block_data(client, i,
- 32, data->data + i)
- != 32)
- goto exit;
- } else {
- for (i = slice << 5; i < (slice + 1) << 5; i += 2) {
- int word = i2c_smbus_read_word_data(client, i);
- if (word < 0)
- goto exit;
- data->data[i] = word & 0xff;
- data->data[i + 1] = word >> 8;
- }
- }
- data->last_updated[slice] = jiffies;
- data->valid |= (1 << slice);
- }
-exit:
- mutex_unlock(&data->update_lock);
-}
-
-static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
- struct eeprom_data *data = i2c_get_clientdata(client);
- u8 slice;
-
- if (off > EEPROM_SIZE)
- return 0;
- if (off + count > EEPROM_SIZE)
- count = EEPROM_SIZE - off;
-
- /* Only refresh slices which contain requested bytes */
- for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++)
- eeprom_update_client(client, slice);
-
- /* Hide Vaio private settings to regular users:
- - BIOS passwords: bytes 0x00 to 0x0f
- - UUID: bytes 0x10 to 0x1f
- - Serial number: 0xc0 to 0xdf */
- if (data->nature == VAIO && !capable(CAP_SYS_ADMIN)) {
- int i;
-
- for (i = 0; i < count; i++) {
- if ((off + i <= 0x1f) ||
- (off + i >= 0xc0 && off + i <= 0xdf))
- buf[i] = 0;
- else
- buf[i] = data->data[off + i];
- }
- } else {
- memcpy(buf, &data->data[off], count);
- }
-
- return count;
-}
-
-static struct bin_attribute eeprom_attr = {
- .attr = {
- .name = "eeprom",
- .mode = S_IRUGO,
- },
- .size = EEPROM_SIZE,
- .read = eeprom_read,
-};
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int eeprom_detect(struct i2c_client *client, struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
-
- /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all
- addresses 0x50-0x57, but we only care about 0x50. So decline
- attaching to addresses >= 0x51 on DDC buses */
- if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51)
- return -ENODEV;
-
- /* There are four ways we can read the EEPROM data:
- (1) I2C block reads (faster, but unsupported by most adapters)
- (2) Word reads (128% overhead)
- (3) Consecutive byte reads (88% overhead, unsafe)
- (4) Regular byte data reads (265% overhead)
- The third and fourth methods are not implemented by this driver
- because all known adapters support one of the first two. */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)
- && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK))
- return -ENODEV;
-
- strlcpy(info->type, "eeprom", I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int eeprom_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = client->adapter;
- struct eeprom_data *data;
- int err;
-
- if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- memset(data->data, 0xff, EEPROM_SIZE);
- i2c_set_clientdata(client, data);
- mutex_init(&data->update_lock);
- data->nature = UNKNOWN;
-
- /* Detect the Vaio nature of EEPROMs.
- We use the "PCG-" or "VGN-" prefix as the signature. */
- if (client->addr == 0x57
- && i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
- char name[4];
-
- name[0] = i2c_smbus_read_byte_data(client, 0x80);
- name[1] = i2c_smbus_read_byte_data(client, 0x81);
- name[2] = i2c_smbus_read_byte_data(client, 0x82);
- name[3] = i2c_smbus_read_byte_data(client, 0x83);
-
- if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) {
- dev_info(&client->dev, "Vaio EEPROM detected, "
- "enabling privacy protection\n");
- data->nature = VAIO;
- }
- }
-
- /* create the sysfs eeprom file */
- err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr);
- if (err)
- goto exit_kfree;
-
- return 0;
-
-exit_kfree:
- kfree(data);
-exit:
- return err;
-}
-
-static int eeprom_remove(struct i2c_client *client)
-{
- sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr);
- kfree(i2c_get_clientdata(client));
-
- return 0;
-}
-
-static const struct i2c_device_id eeprom_id[] = {
- { "eeprom", 0 },
- { }
-};
-
-static struct i2c_driver eeprom_driver = {
- .driver = {
- .name = "eeprom",
- },
- .probe = eeprom_probe,
- .remove = eeprom_remove,
- .id_table = eeprom_id,
-
- .class = I2C_CLASS_DDC | I2C_CLASS_SPD,
- .detect = eeprom_detect,
- .address_list = normal_i2c,
-};
-
-module_i2c_driver(eeprom_driver);
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
- "Philip Edelbrock <phil@netroedge.com> and "
- "Greg Kroah-Hartman <greg@kroah.com>");
-MODULE_DESCRIPTION("I2C EEPROM driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/eeprom/eeprom_93cx6.c b/ANDROID_3.4.5/drivers/misc/eeprom/eeprom_93cx6.c
deleted file mode 100644
index 0ff4b021..00000000
--- a/ANDROID_3.4.5/drivers/misc/eeprom/eeprom_93cx6.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
- * <http://rt2x00.serialmonkey.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.
- *
- * Module: eeprom_93cx6
- * Abstract: EEPROM reader routines for 93cx6 chipsets.
- * Supported chipsets: 93c46 & 93c66.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/eeprom_93cx6.h>
-
-MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
-MODULE_VERSION("1.0");
-MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
-MODULE_LICENSE("GPL");
-
-static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
-{
- eeprom->reg_data_clock = 1;
- eeprom->register_write(eeprom);
-
- /*
- * Add a short delay for the pulse to work.
- * According to the specifications the "maximum minimum"
- * time should be 450ns.
- */
- ndelay(450);
-}
-
-static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
-{
- eeprom->reg_data_clock = 0;
- eeprom->register_write(eeprom);
-
- /*
- * Add a short delay for the pulse to work.
- * According to the specifications the "maximum minimum"
- * time should be 450ns.
- */
- ndelay(450);
-}
-
-static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
-{
- /*
- * Clear all flags, and enable chip select.
- */
- eeprom->register_read(eeprom);
- eeprom->reg_data_in = 0;
- eeprom->reg_data_out = 0;
- eeprom->reg_data_clock = 0;
- eeprom->reg_chip_select = 1;
- eeprom->drive_data = 1;
- eeprom->register_write(eeprom);
-
- /*
- * kick a pulse.
- */
- eeprom_93cx6_pulse_high(eeprom);
- eeprom_93cx6_pulse_low(eeprom);
-}
-
-static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
-{
- /*
- * Clear chip_select and data_in flags.
- */
- eeprom->register_read(eeprom);
- eeprom->reg_data_in = 0;
- eeprom->reg_chip_select = 0;
- eeprom->register_write(eeprom);
-
- /*
- * kick a pulse.
- */
- eeprom_93cx6_pulse_high(eeprom);
- eeprom_93cx6_pulse_low(eeprom);
-}
-
-static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
- const u16 data, const u16 count)
-{
- unsigned int i;
-
- eeprom->register_read(eeprom);
-
- /*
- * Clear data flags.
- */
- eeprom->reg_data_in = 0;
- eeprom->reg_data_out = 0;
- eeprom->drive_data = 1;
-
- /*
- * Start writing all bits.
- */
- for (i = count; i > 0; i--) {
- /*
- * Check if this bit needs to be set.
- */
- eeprom->reg_data_in = !!(data & (1 << (i - 1)));
-
- /*
- * Write the bit to the eeprom register.
- */
- eeprom->register_write(eeprom);
-
- /*
- * Kick a pulse.
- */
- eeprom_93cx6_pulse_high(eeprom);
- eeprom_93cx6_pulse_low(eeprom);
- }
-
- eeprom->reg_data_in = 0;
- eeprom->register_write(eeprom);
-}
-
-static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
- u16 *data, const u16 count)
-{
- unsigned int i;
- u16 buf = 0;
-
- eeprom->register_read(eeprom);
-
- /*
- * Clear data flags.
- */
- eeprom->reg_data_in = 0;
- eeprom->reg_data_out = 0;
- eeprom->drive_data = 0;
-
- /*
- * Start reading all bits.
- */
- for (i = count; i > 0; i--) {
- eeprom_93cx6_pulse_high(eeprom);
-
- eeprom->register_read(eeprom);
-
- /*
- * Clear data_in flag.
- */
- eeprom->reg_data_in = 0;
-
- /*
- * Read if the bit has been set.
- */
- if (eeprom->reg_data_out)
- buf |= (1 << (i - 1));
-
- eeprom_93cx6_pulse_low(eeprom);
- }
-
- *data = buf;
-}
-
-/**
- * eeprom_93cx6_read - Read multiple words from eeprom
- * @eeprom: Pointer to eeprom structure
- * @word: Word index from where we should start reading
- * @data: target pointer where the information will have to be stored
- *
- * This function will read the eeprom data as host-endian word
- * into the given data pointer.
- */
-void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
- u16 *data)
-{
- u16 command;
-
- /*
- * Initialize the eeprom register
- */
- eeprom_93cx6_startup(eeprom);
-
- /*
- * Select the read opcode and the word to be read.
- */
- command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
- eeprom_93cx6_write_bits(eeprom, command,
- PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
-
- /*
- * Read the requested 16 bits.
- */
- eeprom_93cx6_read_bits(eeprom, data, 16);
-
- /*
- * Cleanup eeprom register.
- */
- eeprom_93cx6_cleanup(eeprom);
-}
-EXPORT_SYMBOL_GPL(eeprom_93cx6_read);
-
-/**
- * eeprom_93cx6_multiread - Read multiple words from eeprom
- * @eeprom: Pointer to eeprom structure
- * @word: Word index from where we should start reading
- * @data: target pointer where the information will have to be stored
- * @words: Number of words that should be read.
- *
- * This function will read all requested words from the eeprom,
- * this is done by calling eeprom_93cx6_read() multiple times.
- * But with the additional change that while the eeprom_93cx6_read
- * will return host ordered bytes, this method will return little
- * endian words.
- */
-void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
- __le16 *data, const u16 words)
-{
- unsigned int i;
- u16 tmp;
-
- for (i = 0; i < words; i++) {
- tmp = 0;
- eeprom_93cx6_read(eeprom, word + i, &tmp);
- data[i] = cpu_to_le16(tmp);
- }
-}
-EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
-
-/**
- * eeprom_93cx6_wren - set the write enable state
- * @eeprom: Pointer to eeprom structure
- * @enable: true to enable writes, otherwise disable writes
- *
- * Set the EEPROM write enable state to either allow or deny
- * writes depending on the @enable value.
- */
-void eeprom_93cx6_wren(struct eeprom_93cx6 *eeprom, bool enable)
-{
- u16 command;
-
- /* start the command */
- eeprom_93cx6_startup(eeprom);
-
- /* create command to enable/disable */
-
- command = enable ? PCI_EEPROM_EWEN_OPCODE : PCI_EEPROM_EWDS_OPCODE;
- command <<= (eeprom->width - 2);
-
- eeprom_93cx6_write_bits(eeprom, command,
- PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
-
- eeprom_93cx6_cleanup(eeprom);
-}
-EXPORT_SYMBOL_GPL(eeprom_93cx6_wren);
-
-/**
- * eeprom_93cx6_write - write data to the EEPROM
- * @eeprom: Pointer to eeprom structure
- * @addr: Address to write data to.
- * @data: The data to write to address @addr.
- *
- * Write the @data to the specified @addr in the EEPROM and
- * waiting for the device to finish writing.
- *
- * Note, since we do not expect large number of write operations
- * we delay in between parts of the operation to avoid using excessive
- * amounts of CPU time busy waiting.
- */
-void eeprom_93cx6_write(struct eeprom_93cx6 *eeprom, u8 addr, u16 data)
-{
- int timeout = 100;
- u16 command;
-
- /* start the command */
- eeprom_93cx6_startup(eeprom);
-
- command = PCI_EEPROM_WRITE_OPCODE << eeprom->width;
- command |= addr;
-
- /* send write command */
- eeprom_93cx6_write_bits(eeprom, command,
- PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
-
- /* send data */
- eeprom_93cx6_write_bits(eeprom, data, 16);
-
- /* get ready to check for busy */
- eeprom->drive_data = 0;
- eeprom->reg_chip_select = 1;
- eeprom->register_write(eeprom);
-
- /* wait at-least 250ns to get DO to be the busy signal */
- usleep_range(1000, 2000);
-
- /* wait for DO to go high to signify finish */
-
- while (true) {
- eeprom->register_read(eeprom);
-
- if (eeprom->reg_data_out)
- break;
-
- usleep_range(1000, 2000);
-
- if (--timeout <= 0) {
- printk(KERN_ERR "%s: timeout\n", __func__);
- break;
- }
- }
-
- eeprom_93cx6_cleanup(eeprom);
-}
-EXPORT_SYMBOL_GPL(eeprom_93cx6_write);
diff --git a/ANDROID_3.4.5/drivers/misc/eeprom/eeprom_93xx46.c b/ANDROID_3.4.5/drivers/misc/eeprom/eeprom_93xx46.c
deleted file mode 100644
index ce3fe363..00000000
--- a/ANDROID_3.4.5/drivers/misc/eeprom/eeprom_93xx46.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Driver for 93xx46 EEPROMs
- *
- * (C) 2011 DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/spi/spi.h>
-#include <linux/sysfs.h>
-#include <linux/eeprom_93xx46.h>
-
-#define OP_START 0x4
-#define OP_WRITE (OP_START | 0x1)
-#define OP_READ (OP_START | 0x2)
-#define ADDR_EWDS 0x00
-#define ADDR_ERAL 0x20
-#define ADDR_EWEN 0x30
-
-struct eeprom_93xx46_dev {
- struct spi_device *spi;
- struct eeprom_93xx46_platform_data *pdata;
- struct bin_attribute bin;
- struct mutex lock;
- int addrlen;
-};
-
-static ssize_t
-eeprom_93xx46_bin_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- struct eeprom_93xx46_dev *edev;
- struct device *dev;
- struct spi_message m;
- struct spi_transfer t[2];
- int bits, ret;
- u16 cmd_addr;
-
- dev = container_of(kobj, struct device, kobj);
- edev = dev_get_drvdata(dev);
-
- if (unlikely(off >= edev->bin.size))
- return 0;
- if ((off + count) > edev->bin.size)
- count = edev->bin.size - off;
- if (unlikely(!count))
- return count;
-
- cmd_addr = OP_READ << edev->addrlen;
-
- if (edev->addrlen == 7) {
- cmd_addr |= off & 0x7f;
- bits = 10;
- } else {
- cmd_addr |= off & 0x3f;
- bits = 9;
- }
-
- dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n",
- cmd_addr, edev->spi->max_speed_hz);
-
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
-
- t[0].tx_buf = (char *)&cmd_addr;
- t[0].len = 2;
- t[0].bits_per_word = bits;
- spi_message_add_tail(&t[0], &m);
-
- t[1].rx_buf = buf;
- t[1].len = count;
- t[1].bits_per_word = 8;
- spi_message_add_tail(&t[1], &m);
-
- mutex_lock(&edev->lock);
-
- if (edev->pdata->prepare)
- edev->pdata->prepare(edev);
-
- ret = spi_sync(edev->spi, &m);
- /* have to wait at least Tcsl ns */
- ndelay(250);
- if (ret) {
- dev_err(&edev->spi->dev, "read %zu bytes at %d: err. %d\n",
- count, (int)off, ret);
- }
-
- if (edev->pdata->finish)
- edev->pdata->finish(edev);
-
- mutex_unlock(&edev->lock);
- return ret ? : count;
-}
-
-static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on)
-{
- struct spi_message m;
- struct spi_transfer t;
- int bits, ret;
- u16 cmd_addr;
-
- cmd_addr = OP_START << edev->addrlen;
- if (edev->addrlen == 7) {
- cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS) << 1;
- bits = 10;
- } else {
- cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS);
- bits = 9;
- }
-
- dev_dbg(&edev->spi->dev, "ew cmd 0x%04x\n", cmd_addr);
-
- spi_message_init(&m);
- memset(&t, 0, sizeof(t));
-
- t.tx_buf = &cmd_addr;
- t.len = 2;
- t.bits_per_word = bits;
- spi_message_add_tail(&t, &m);
-
- mutex_lock(&edev->lock);
-
- if (edev->pdata->prepare)
- edev->pdata->prepare(edev);
-
- ret = spi_sync(edev->spi, &m);
- /* have to wait at least Tcsl ns */
- ndelay(250);
- if (ret)
- dev_err(&edev->spi->dev, "erase/write %sable error %d\n",
- is_on ? "en" : "dis", ret);
-
- if (edev->pdata->finish)
- edev->pdata->finish(edev);
-
- mutex_unlock(&edev->lock);
- return ret;
-}
-
-static ssize_t
-eeprom_93xx46_write_word(struct eeprom_93xx46_dev *edev,
- const char *buf, unsigned off)
-{
- struct spi_message m;
- struct spi_transfer t[2];
- int bits, data_len, ret;
- u16 cmd_addr;
-
- cmd_addr = OP_WRITE << edev->addrlen;
-
- if (edev->addrlen == 7) {
- cmd_addr |= off & 0x7f;
- bits = 10;
- data_len = 1;
- } else {
- cmd_addr |= off & 0x3f;
- bits = 9;
- data_len = 2;
- }
-
- dev_dbg(&edev->spi->dev, "write cmd 0x%x\n", cmd_addr);
-
- spi_message_init(&m);
- memset(t, 0, sizeof(t));
-
- t[0].tx_buf = (char *)&cmd_addr;
- t[0].len = 2;
- t[0].bits_per_word = bits;
- spi_message_add_tail(&t[0], &m);
-
- t[1].tx_buf = buf;
- t[1].len = data_len;
- t[1].bits_per_word = 8;
- spi_message_add_tail(&t[1], &m);
-
- ret = spi_sync(edev->spi, &m);
- /* have to wait program cycle time Twc ms */
- mdelay(6);
- return ret;
-}
-
-static ssize_t
-eeprom_93xx46_bin_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- struct eeprom_93xx46_dev *edev;
- struct device *dev;
- int i, ret, step = 1;
-
- dev = container_of(kobj, struct device, kobj);
- edev = dev_get_drvdata(dev);
-
- if (unlikely(off >= edev->bin.size))
- return 0;
- if ((off + count) > edev->bin.size)
- count = edev->bin.size - off;
- if (unlikely(!count))
- return count;
-
- /* only write even number of bytes on 16-bit devices */
- if (edev->addrlen == 6) {
- step = 2;
- count &= ~1;
- }
-
- /* erase/write enable */
- ret = eeprom_93xx46_ew(edev, 1);
- if (ret)
- return ret;
-
- mutex_lock(&edev->lock);
-
- if (edev->pdata->prepare)
- edev->pdata->prepare(edev);
-
- for (i = 0; i < count; i += step) {
- ret = eeprom_93xx46_write_word(edev, &buf[i], off + i);
- if (ret) {
- dev_err(&edev->spi->dev, "write failed at %d: %d\n",
- (int)off + i, ret);
- break;
- }
- }
-
- if (edev->pdata->finish)
- edev->pdata->finish(edev);
-
- mutex_unlock(&edev->lock);
-
- /* erase/write disable */
- eeprom_93xx46_ew(edev, 0);
- return ret ? : count;
-}
-
-static int eeprom_93xx46_eral(struct eeprom_93xx46_dev *edev)
-{
- struct eeprom_93xx46_platform_data *pd = edev->pdata;
- struct spi_message m;
- struct spi_transfer t;
- int bits, ret;
- u16 cmd_addr;
-
- cmd_addr = OP_START << edev->addrlen;
- if (edev->addrlen == 7) {
- cmd_addr |= ADDR_ERAL << 1;
- bits = 10;
- } else {
- cmd_addr |= ADDR_ERAL;
- bits = 9;
- }
-
- spi_message_init(&m);
- memset(&t, 0, sizeof(t));
-
- t.tx_buf = &cmd_addr;
- t.len = 2;
- t.bits_per_word = bits;
- spi_message_add_tail(&t, &m);
-
- mutex_lock(&edev->lock);
-
- if (edev->pdata->prepare)
- edev->pdata->prepare(edev);
-
- ret = spi_sync(edev->spi, &m);
- if (ret)
- dev_err(&edev->spi->dev, "erase error %d\n", ret);
- /* have to wait erase cycle time Tec ms */
- mdelay(6);
-
- if (pd->finish)
- pd->finish(edev);
-
- mutex_unlock(&edev->lock);
- return ret;
-}
-
-static ssize_t eeprom_93xx46_store_erase(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct eeprom_93xx46_dev *edev = dev_get_drvdata(dev);
- int erase = 0, ret;
-
- sscanf(buf, "%d", &erase);
- if (erase) {
- ret = eeprom_93xx46_ew(edev, 1);
- if (ret)
- return ret;
- ret = eeprom_93xx46_eral(edev);
- if (ret)
- return ret;
- ret = eeprom_93xx46_ew(edev, 0);
- if (ret)
- return ret;
- }
- return count;
-}
-static DEVICE_ATTR(erase, S_IWUSR, NULL, eeprom_93xx46_store_erase);
-
-static int __devinit eeprom_93xx46_probe(struct spi_device *spi)
-{
- struct eeprom_93xx46_platform_data *pd;
- struct eeprom_93xx46_dev *edev;
- int err;
-
- pd = spi->dev.platform_data;
- if (!pd) {
- dev_err(&spi->dev, "missing platform data\n");
- return -ENODEV;
- }
-
- edev = kzalloc(sizeof(*edev), GFP_KERNEL);
- if (!edev)
- return -ENOMEM;
-
- if (pd->flags & EE_ADDR8)
- edev->addrlen = 7;
- else if (pd->flags & EE_ADDR16)
- edev->addrlen = 6;
- else {
- dev_err(&spi->dev, "unspecified address type\n");
- err = -EINVAL;
- goto fail;
- }
-
- mutex_init(&edev->lock);
-
- edev->spi = spi_dev_get(spi);
- edev->pdata = pd;
-
- sysfs_bin_attr_init(&edev->bin);
- edev->bin.attr.name = "eeprom";
- edev->bin.attr.mode = S_IRUSR;
- edev->bin.read = eeprom_93xx46_bin_read;
- edev->bin.size = 128;
- if (!(pd->flags & EE_READONLY)) {
- edev->bin.write = eeprom_93xx46_bin_write;
- edev->bin.attr.mode |= S_IWUSR;
- }
-
- err = sysfs_create_bin_file(&spi->dev.kobj, &edev->bin);
- if (err)
- goto fail;
-
- dev_info(&spi->dev, "%d-bit eeprom %s\n",
- (pd->flags & EE_ADDR8) ? 8 : 16,
- (pd->flags & EE_READONLY) ? "(readonly)" : "");
-
- if (!(pd->flags & EE_READONLY)) {
- if (device_create_file(&spi->dev, &dev_attr_erase))
- dev_err(&spi->dev, "can't create erase interface\n");
- }
-
- dev_set_drvdata(&spi->dev, edev);
- return 0;
-fail:
- kfree(edev);
- return err;
-}
-
-static int __devexit eeprom_93xx46_remove(struct spi_device *spi)
-{
- struct eeprom_93xx46_dev *edev = dev_get_drvdata(&spi->dev);
-
- if (!(edev->pdata->flags & EE_READONLY))
- device_remove_file(&spi->dev, &dev_attr_erase);
-
- sysfs_remove_bin_file(&spi->dev.kobj, &edev->bin);
- dev_set_drvdata(&spi->dev, NULL);
- kfree(edev);
- return 0;
-}
-
-static struct spi_driver eeprom_93xx46_driver = {
- .driver = {
- .name = "93xx46",
- .owner = THIS_MODULE,
- },
- .probe = eeprom_93xx46_probe,
- .remove = __devexit_p(eeprom_93xx46_remove),
-};
-
-module_spi_driver(eeprom_93xx46_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs");
-MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");
-MODULE_ALIAS("spi:93xx46");
diff --git a/ANDROID_3.4.5/drivers/misc/eeprom/max6875.c b/ANDROID_3.4.5/drivers/misc/eeprom/max6875.c
deleted file mode 100644
index e36157d5..00000000
--- a/ANDROID_3.4.5/drivers/misc/eeprom/max6875.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * max6875.c - driver for MAX6874/MAX6875
- *
- * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
- *
- * Based on eeprom.c
- *
- * The MAX6875 has a bank of registers and two banks of EEPROM.
- * Address ranges are defined as follows:
- * * 0x0000 - 0x0046 = configuration registers
- * * 0x8000 - 0x8046 = configuration EEPROM
- * * 0x8100 - 0x82FF = user EEPROM
- *
- * This driver makes the user EEPROM available for read.
- *
- * The registers & config EEPROM should be accessed via i2c-dev.
- *
- * The MAX6875 ignores the lowest address bit, so each chip responds to
- * two addresses - 0x50/0x51 and 0x52/0x53.
- *
- * Note that the MAX6875 uses i2c_smbus_write_byte_data() to set the read
- * address, so this driver is destructive if loaded for the wrong EEPROM chip.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-/* The MAX6875 can only read/write 16 bytes at a time */
-#define SLICE_SIZE 16
-#define SLICE_BITS 4
-
-/* USER EEPROM is at addresses 0x8100 - 0x82FF */
-#define USER_EEPROM_BASE 0x8100
-#define USER_EEPROM_SIZE 0x0200
-#define USER_EEPROM_SLICES 32
-
-/* MAX6875 commands */
-#define MAX6875_CMD_BLK_READ 0x84
-
-/* Each client has this additional data */
-struct max6875_data {
- struct i2c_client *fake_client;
- struct mutex update_lock;
-
- u32 valid;
- u8 data[USER_EEPROM_SIZE];
- unsigned long last_updated[USER_EEPROM_SLICES];
-};
-
-static void max6875_update_slice(struct i2c_client *client, int slice)
-{
- struct max6875_data *data = i2c_get_clientdata(client);
- int i, j, addr;
- u8 *buf;
-
- if (slice >= USER_EEPROM_SLICES)
- return;
-
- mutex_lock(&data->update_lock);
-
- buf = &data->data[slice << SLICE_BITS];
-
- if (!(data->valid & (1 << slice)) ||
- time_after(jiffies, data->last_updated[slice])) {
-
- dev_dbg(&client->dev, "Starting update of slice %u\n", slice);
-
- data->valid &= ~(1 << slice);
-
- addr = USER_EEPROM_BASE + (slice << SLICE_BITS);
-
- /* select the eeprom address */
- if (i2c_smbus_write_byte_data(client, addr >> 8, addr & 0xFF)) {
- dev_err(&client->dev, "address set failed\n");
- goto exit_up;
- }
-
- if (i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
- if (i2c_smbus_read_i2c_block_data(client,
- MAX6875_CMD_BLK_READ,
- SLICE_SIZE,
- buf) != SLICE_SIZE) {
- goto exit_up;
- }
- } else {
- for (i = 0; i < SLICE_SIZE; i++) {
- j = i2c_smbus_read_byte(client);
- if (j < 0) {
- goto exit_up;
- }
- buf[i] = j;
- }
- }
- data->last_updated[slice] = jiffies;
- data->valid |= (1 << slice);
- }
-exit_up:
- mutex_unlock(&data->update_lock);
-}
-
-static ssize_t max6875_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- struct i2c_client *client = kobj_to_i2c_client(kobj);
- struct max6875_data *data = i2c_get_clientdata(client);
- int slice, max_slice;
-
- if (off > USER_EEPROM_SIZE)
- return 0;
-
- if (off + count > USER_EEPROM_SIZE)
- count = USER_EEPROM_SIZE - off;
-
- /* refresh slices which contain requested bytes */
- max_slice = (off + count - 1) >> SLICE_BITS;
- for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++)
- max6875_update_slice(client, slice);
-
- memcpy(buf, &data->data[off], count);
-
- return count;
-}
-
-static struct bin_attribute user_eeprom_attr = {
- .attr = {
- .name = "eeprom",
- .mode = S_IRUGO,
- },
- .size = USER_EEPROM_SIZE,
- .read = max6875_read,
-};
-
-static int max6875_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = client->adapter;
- struct max6875_data *data;
- int err;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
- | I2C_FUNC_SMBUS_READ_BYTE))
- return -ENODEV;
-
- /* Only bind to even addresses */
- if (client->addr & 1)
- return -ENODEV;
-
- if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
- return -ENOMEM;
-
- /* A fake client is created on the odd address */
- data->fake_client = i2c_new_dummy(client->adapter, client->addr + 1);
- if (!data->fake_client) {
- err = -ENOMEM;
- goto exit_kfree;
- }
-
- /* Init real i2c_client */
- i2c_set_clientdata(client, data);
- mutex_init(&data->update_lock);
-
- err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr);
- if (err)
- goto exit_remove_fake;
-
- return 0;
-
-exit_remove_fake:
- i2c_unregister_device(data->fake_client);
-exit_kfree:
- kfree(data);
- return err;
-}
-
-static int max6875_remove(struct i2c_client *client)
-{
- struct max6875_data *data = i2c_get_clientdata(client);
-
- i2c_unregister_device(data->fake_client);
-
- sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
- kfree(data);
-
- return 0;
-}
-
-static const struct i2c_device_id max6875_id[] = {
- { "max6875", 0 },
- { }
-};
-
-static struct i2c_driver max6875_driver = {
- .driver = {
- .name = "max6875",
- },
- .probe = max6875_probe,
- .remove = max6875_remove,
- .id_table = max6875_id,
-};
-
-module_i2c_driver(max6875_driver);
-
-MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
-MODULE_DESCRIPTION("MAX6875 driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/enclosure.c b/ANDROID_3.4.5/drivers/misc/enclosure.c
deleted file mode 100644
index 00e5fcac..00000000
--- a/ANDROID_3.4.5/drivers/misc/enclosure.c
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Enclosure Services
- *
- * Copyright (C) 2008 James Bottomley <James.Bottomley@HansenPartnership.com>
- *
-**-----------------------------------------------------------------------------
-**
-** This program is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public License
-** version 2 as published by the Free Software Foundation.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-**
-**-----------------------------------------------------------------------------
-*/
-#include <linux/device.h>
-#include <linux/enclosure.h>
-#include <linux/err.h>
-#include <linux/list.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-static LIST_HEAD(container_list);
-static DEFINE_MUTEX(container_list_lock);
-static struct class enclosure_class;
-
-/**
- * enclosure_find - find an enclosure given a parent device
- * @dev: the parent to match against
- * @start: Optional enclosure device to start from (NULL if none)
- *
- * Looks through the list of registered enclosures to find all those
- * with @dev as a parent. Returns NULL if no enclosure is
- * found. @start can be used as a starting point to obtain multiple
- * enclosures per parent (should begin with NULL and then be set to
- * each returned enclosure device). Obtains a reference to the
- * enclosure class device which must be released with device_put().
- * If @start is not NULL, a reference must be taken on it which is
- * released before returning (this allows a loop through all
- * enclosures to exit with only the reference on the enclosure of
- * interest held). Note that the @dev may correspond to the actual
- * device housing the enclosure, in which case no iteration via @start
- * is required.
- */
-struct enclosure_device *enclosure_find(struct device *dev,
- struct enclosure_device *start)
-{
- struct enclosure_device *edev;
-
- mutex_lock(&container_list_lock);
- edev = list_prepare_entry(start, &container_list, node);
- if (start)
- put_device(&start->edev);
-
- list_for_each_entry_continue(edev, &container_list, node) {
- struct device *parent = edev->edev.parent;
- /* parent might not be immediate, so iterate up to
- * the root of the tree if necessary */
- while (parent) {
- if (parent == dev) {
- get_device(&edev->edev);
- mutex_unlock(&container_list_lock);
- return edev;
- }
- parent = parent->parent;
- }
- }
- mutex_unlock(&container_list_lock);
-
- return NULL;
-}
-EXPORT_SYMBOL_GPL(enclosure_find);
-
-/**
- * enclosure_for_each_device - calls a function for each enclosure
- * @fn: the function to call
- * @data: the data to pass to each call
- *
- * Loops over all the enclosures calling the function.
- *
- * Note, this function uses a mutex which will be held across calls to
- * @fn, so it must have non atomic context, and @fn may (although it
- * should not) sleep or otherwise cause the mutex to be held for
- * indefinite periods
- */
-int enclosure_for_each_device(int (*fn)(struct enclosure_device *, void *),
- void *data)
-{
- int error = 0;
- struct enclosure_device *edev;
-
- mutex_lock(&container_list_lock);
- list_for_each_entry(edev, &container_list, node) {
- error = fn(edev, data);
- if (error)
- break;
- }
- mutex_unlock(&container_list_lock);
-
- return error;
-}
-EXPORT_SYMBOL_GPL(enclosure_for_each_device);
-
-/**
- * enclosure_register - register device as an enclosure
- *
- * @dev: device containing the enclosure
- * @components: number of components in the enclosure
- *
- * This sets up the device for being an enclosure. Note that @dev does
- * not have to be a dedicated enclosure device. It may be some other type
- * of device that additionally responds to enclosure services
- */
-struct enclosure_device *
-enclosure_register(struct device *dev, const char *name, int components,
- struct enclosure_component_callbacks *cb)
-{
- struct enclosure_device *edev =
- kzalloc(sizeof(struct enclosure_device) +
- sizeof(struct enclosure_component)*components,
- GFP_KERNEL);
- int err, i;
-
- BUG_ON(!cb);
-
- if (!edev)
- return ERR_PTR(-ENOMEM);
-
- edev->components = components;
-
- edev->edev.class = &enclosure_class;
- edev->edev.parent = get_device(dev);
- edev->cb = cb;
- dev_set_name(&edev->edev, "%s", name);
- err = device_register(&edev->edev);
- if (err)
- goto err;
-
- for (i = 0; i < components; i++)
- edev->component[i].number = -1;
-
- mutex_lock(&container_list_lock);
- list_add_tail(&edev->node, &container_list);
- mutex_unlock(&container_list_lock);
-
- return edev;
-
- err:
- put_device(edev->edev.parent);
- kfree(edev);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL_GPL(enclosure_register);
-
-static struct enclosure_component_callbacks enclosure_null_callbacks;
-
-/**
- * enclosure_unregister - remove an enclosure
- *
- * @edev: the registered enclosure to remove;
- */
-void enclosure_unregister(struct enclosure_device *edev)
-{
- int i;
-
- mutex_lock(&container_list_lock);
- list_del(&edev->node);
- mutex_unlock(&container_list_lock);
-
- for (i = 0; i < edev->components; i++)
- if (edev->component[i].number != -1)
- device_unregister(&edev->component[i].cdev);
-
- /* prevent any callbacks into service user */
- edev->cb = &enclosure_null_callbacks;
- device_unregister(&edev->edev);
-}
-EXPORT_SYMBOL_GPL(enclosure_unregister);
-
-#define ENCLOSURE_NAME_SIZE 64
-
-static void enclosure_link_name(struct enclosure_component *cdev, char *name)
-{
- strcpy(name, "enclosure_device:");
- strcat(name, dev_name(&cdev->cdev));
-}
-
-static void enclosure_remove_links(struct enclosure_component *cdev)
-{
- char name[ENCLOSURE_NAME_SIZE];
-
- enclosure_link_name(cdev, name);
- sysfs_remove_link(&cdev->dev->kobj, name);
- sysfs_remove_link(&cdev->cdev.kobj, "device");
-}
-
-static int enclosure_add_links(struct enclosure_component *cdev)
-{
- int error;
- char name[ENCLOSURE_NAME_SIZE];
-
- error = sysfs_create_link(&cdev->cdev.kobj, &cdev->dev->kobj, "device");
- if (error)
- return error;
-
- enclosure_link_name(cdev, name);
- error = sysfs_create_link(&cdev->dev->kobj, &cdev->cdev.kobj, name);
- if (error)
- sysfs_remove_link(&cdev->cdev.kobj, "device");
-
- return error;
-}
-
-static void enclosure_release(struct device *cdev)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev);
-
- put_device(cdev->parent);
- kfree(edev);
-}
-
-static void enclosure_component_release(struct device *dev)
-{
- struct enclosure_component *cdev = to_enclosure_component(dev);
-
- if (cdev->dev) {
- enclosure_remove_links(cdev);
- put_device(cdev->dev);
- }
- put_device(dev->parent);
-}
-
-static const struct attribute_group *enclosure_groups[];
-
-/**
- * enclosure_component_register - add a particular component to an enclosure
- * @edev: the enclosure to add the component
- * @num: the device number
- * @type: the type of component being added
- * @name: an optional name to appear in sysfs (leave NULL if none)
- *
- * Registers the component. The name is optional for enclosures that
- * give their components a unique name. If not, leave the field NULL
- * and a name will be assigned.
- *
- * Returns a pointer to the enclosure component or an error.
- */
-struct enclosure_component *
-enclosure_component_register(struct enclosure_device *edev,
- unsigned int number,
- enum enclosure_component_type type,
- const char *name)
-{
- struct enclosure_component *ecomp;
- struct device *cdev;
- int err;
-
- if (number >= edev->components)
- return ERR_PTR(-EINVAL);
-
- ecomp = &edev->component[number];
-
- if (ecomp->number != -1)
- return ERR_PTR(-EINVAL);
-
- ecomp->type = type;
- ecomp->number = number;
- cdev = &ecomp->cdev;
- cdev->parent = get_device(&edev->edev);
- if (name && name[0])
- dev_set_name(cdev, "%s", name);
- else
- dev_set_name(cdev, "%u", number);
-
- cdev->release = enclosure_component_release;
- cdev->groups = enclosure_groups;
-
- err = device_register(cdev);
- if (err) {
- ecomp->number = -1;
- put_device(cdev);
- return ERR_PTR(err);
- }
-
- return ecomp;
-}
-EXPORT_SYMBOL_GPL(enclosure_component_register);
-
-/**
- * enclosure_add_device - add a device as being part of an enclosure
- * @edev: the enclosure device being added to.
- * @num: the number of the component
- * @dev: the device being added
- *
- * Declares a real device to reside in slot (or identifier) @num of an
- * enclosure. This will cause the relevant sysfs links to appear.
- * This function may also be used to change a device associated with
- * an enclosure without having to call enclosure_remove_device() in
- * between.
- *
- * Returns zero on success or an error.
- */
-int enclosure_add_device(struct enclosure_device *edev, int component,
- struct device *dev)
-{
- struct enclosure_component *cdev;
-
- if (!edev || component >= edev->components)
- return -EINVAL;
-
- cdev = &edev->component[component];
-
- if (cdev->dev == dev)
- return -EEXIST;
-
- if (cdev->dev)
- enclosure_remove_links(cdev);
-
- put_device(cdev->dev);
- cdev->dev = get_device(dev);
- return enclosure_add_links(cdev);
-}
-EXPORT_SYMBOL_GPL(enclosure_add_device);
-
-/**
- * enclosure_remove_device - remove a device from an enclosure
- * @edev: the enclosure device
- * @num: the number of the component to remove
- *
- * Returns zero on success or an error.
- *
- */
-int enclosure_remove_device(struct enclosure_device *edev, struct device *dev)
-{
- struct enclosure_component *cdev;
- int i;
-
- if (!edev || !dev)
- return -EINVAL;
-
- for (i = 0; i < edev->components; i++) {
- cdev = &edev->component[i];
- if (cdev->dev == dev) {
- enclosure_remove_links(cdev);
- device_del(&cdev->cdev);
- put_device(dev);
- cdev->dev = NULL;
- return device_add(&cdev->cdev);
- }
- }
- return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(enclosure_remove_device);
-
-/*
- * sysfs pieces below
- */
-
-static ssize_t enclosure_show_components(struct device *cdev,
- struct device_attribute *attr,
- char *buf)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev);
-
- return snprintf(buf, 40, "%d\n", edev->components);
-}
-
-static struct device_attribute enclosure_attrs[] = {
- __ATTR(components, S_IRUGO, enclosure_show_components, NULL),
- __ATTR_NULL
-};
-
-static struct class enclosure_class = {
- .name = "enclosure",
- .owner = THIS_MODULE,
- .dev_release = enclosure_release,
- .dev_attrs = enclosure_attrs,
-};
-
-static const char *const enclosure_status [] = {
- [ENCLOSURE_STATUS_UNSUPPORTED] = "unsupported",
- [ENCLOSURE_STATUS_OK] = "OK",
- [ENCLOSURE_STATUS_CRITICAL] = "critical",
- [ENCLOSURE_STATUS_NON_CRITICAL] = "non-critical",
- [ENCLOSURE_STATUS_UNRECOVERABLE] = "unrecoverable",
- [ENCLOSURE_STATUS_NOT_INSTALLED] = "not installed",
- [ENCLOSURE_STATUS_UNKNOWN] = "unknown",
- [ENCLOSURE_STATUS_UNAVAILABLE] = "unavailable",
- [ENCLOSURE_STATUS_MAX] = NULL,
-};
-
-static const char *const enclosure_type [] = {
- [ENCLOSURE_COMPONENT_DEVICE] = "device",
- [ENCLOSURE_COMPONENT_ARRAY_DEVICE] = "array device",
-};
-
-static ssize_t get_component_fault(struct device *cdev,
- struct device_attribute *attr, char *buf)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev->parent);
- struct enclosure_component *ecomp = to_enclosure_component(cdev);
-
- if (edev->cb->get_fault)
- edev->cb->get_fault(edev, ecomp);
- return snprintf(buf, 40, "%d\n", ecomp->fault);
-}
-
-static ssize_t set_component_fault(struct device *cdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev->parent);
- struct enclosure_component *ecomp = to_enclosure_component(cdev);
- int val = simple_strtoul(buf, NULL, 0);
-
- if (edev->cb->set_fault)
- edev->cb->set_fault(edev, ecomp, val);
- return count;
-}
-
-static ssize_t get_component_status(struct device *cdev,
- struct device_attribute *attr,char *buf)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev->parent);
- struct enclosure_component *ecomp = to_enclosure_component(cdev);
-
- if (edev->cb->get_status)
- edev->cb->get_status(edev, ecomp);
- return snprintf(buf, 40, "%s\n", enclosure_status[ecomp->status]);
-}
-
-static ssize_t set_component_status(struct device *cdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev->parent);
- struct enclosure_component *ecomp = to_enclosure_component(cdev);
- int i;
-
- for (i = 0; enclosure_status[i]; i++) {
- if (strncmp(buf, enclosure_status[i],
- strlen(enclosure_status[i])) == 0 &&
- (buf[strlen(enclosure_status[i])] == '\n' ||
- buf[strlen(enclosure_status[i])] == '\0'))
- break;
- }
-
- if (enclosure_status[i] && edev->cb->set_status) {
- edev->cb->set_status(edev, ecomp, i);
- return count;
- } else
- return -EINVAL;
-}
-
-static ssize_t get_component_active(struct device *cdev,
- struct device_attribute *attr, char *buf)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev->parent);
- struct enclosure_component *ecomp = to_enclosure_component(cdev);
-
- if (edev->cb->get_active)
- edev->cb->get_active(edev, ecomp);
- return snprintf(buf, 40, "%d\n", ecomp->active);
-}
-
-static ssize_t set_component_active(struct device *cdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev->parent);
- struct enclosure_component *ecomp = to_enclosure_component(cdev);
- int val = simple_strtoul(buf, NULL, 0);
-
- if (edev->cb->set_active)
- edev->cb->set_active(edev, ecomp, val);
- return count;
-}
-
-static ssize_t get_component_locate(struct device *cdev,
- struct device_attribute *attr, char *buf)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev->parent);
- struct enclosure_component *ecomp = to_enclosure_component(cdev);
-
- if (edev->cb->get_locate)
- edev->cb->get_locate(edev, ecomp);
- return snprintf(buf, 40, "%d\n", ecomp->locate);
-}
-
-static ssize_t set_component_locate(struct device *cdev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct enclosure_device *edev = to_enclosure_device(cdev->parent);
- struct enclosure_component *ecomp = to_enclosure_component(cdev);
- int val = simple_strtoul(buf, NULL, 0);
-
- if (edev->cb->set_locate)
- edev->cb->set_locate(edev, ecomp, val);
- return count;
-}
-
-static ssize_t get_component_type(struct device *cdev,
- struct device_attribute *attr, char *buf)
-{
- struct enclosure_component *ecomp = to_enclosure_component(cdev);
-
- return snprintf(buf, 40, "%s\n", enclosure_type[ecomp->type]);
-}
-
-
-static DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault,
- set_component_fault);
-static DEVICE_ATTR(status, S_IRUGO | S_IWUSR, get_component_status,
- set_component_status);
-static DEVICE_ATTR(active, S_IRUGO | S_IWUSR, get_component_active,
- set_component_active);
-static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate,
- set_component_locate);
-static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL);
-
-static struct attribute *enclosure_component_attrs[] = {
- &dev_attr_fault.attr,
- &dev_attr_status.attr,
- &dev_attr_active.attr,
- &dev_attr_locate.attr,
- &dev_attr_type.attr,
- NULL
-};
-
-static struct attribute_group enclosure_group = {
- .attrs = enclosure_component_attrs,
-};
-
-static const struct attribute_group *enclosure_groups[] = {
- &enclosure_group,
- NULL
-};
-
-static int __init enclosure_init(void)
-{
- int err;
-
- err = class_register(&enclosure_class);
- if (err)
- return err;
-
- return 0;
-}
-
-static void __exit enclosure_exit(void)
-{
- class_unregister(&enclosure_class);
-}
-
-module_init(enclosure_init);
-module_exit(enclosure_exit);
-
-MODULE_AUTHOR("James Bottomley");
-MODULE_DESCRIPTION("Enclosure Services");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/misc/ep93xx_pwm.c b/ANDROID_3.4.5/drivers/misc/ep93xx_pwm.c
deleted file mode 100644
index 16d7179e..00000000
--- a/ANDROID_3.4.5/drivers/misc/ep93xx_pwm.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Simple PWM driver for EP93XX
- *
- * (c) Copyright 2009 Matthieu Crapet <mcrapet@gmail.com>
- * (c) Copyright 2009 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.
- *
- * EP9307 has only one channel:
- * - PWMOUT
- *
- * EP9301/02/12/15 have two channels:
- * - PWMOUT
- * - PWMOUT1 (alternate function for EGPIO14)
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
-#include <mach/platform.h>
-
-#define EP93XX_PWMx_TERM_COUNT 0x00
-#define EP93XX_PWMx_DUTY_CYCLE 0x04
-#define EP93XX_PWMx_ENABLE 0x08
-#define EP93XX_PWMx_INVERT 0x0C
-
-#define EP93XX_PWM_MAX_COUNT 0xFFFF
-
-struct ep93xx_pwm {
- void __iomem *mmio_base;
- struct clk *clk;
- u32 duty_percent;
-};
-
-static inline void ep93xx_pwm_writel(struct ep93xx_pwm *pwm,
- unsigned int val, unsigned int off)
-{
- __raw_writel(val, pwm->mmio_base + off);
-}
-
-static inline unsigned int ep93xx_pwm_readl(struct ep93xx_pwm *pwm,
- unsigned int off)
-{
- return __raw_readl(pwm->mmio_base + off);
-}
-
-static inline void ep93xx_pwm_write_tc(struct ep93xx_pwm *pwm, u16 value)
-{
- ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_TERM_COUNT);
-}
-
-static inline u16 ep93xx_pwm_read_tc(struct ep93xx_pwm *pwm)
-{
- return ep93xx_pwm_readl(pwm, EP93XX_PWMx_TERM_COUNT);
-}
-
-static inline void ep93xx_pwm_write_dc(struct ep93xx_pwm *pwm, u16 value)
-{
- ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_DUTY_CYCLE);
-}
-
-static inline void ep93xx_pwm_enable(struct ep93xx_pwm *pwm)
-{
- ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_ENABLE);
-}
-
-static inline void ep93xx_pwm_disable(struct ep93xx_pwm *pwm)
-{
- ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_ENABLE);
-}
-
-static inline int ep93xx_pwm_is_enabled(struct ep93xx_pwm *pwm)
-{
- return ep93xx_pwm_readl(pwm, EP93XX_PWMx_ENABLE) & 0x1;
-}
-
-static inline void ep93xx_pwm_invert(struct ep93xx_pwm *pwm)
-{
- ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_INVERT);
-}
-
-static inline void ep93xx_pwm_normal(struct ep93xx_pwm *pwm)
-{
- ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_INVERT);
-}
-
-static inline int ep93xx_pwm_is_inverted(struct ep93xx_pwm *pwm)
-{
- return ep93xx_pwm_readl(pwm, EP93XX_PWMx_INVERT) & 0x1;
-}
-
-/*
- * /sys/devices/platform/ep93xx-pwm.N
- * /min_freq read-only minimum pwm output frequency
- * /max_req read-only maximum pwm output frequency
- * /freq read-write pwm output frequency (0 = disable output)
- * /duty_percent read-write pwm duty cycle percent (1..99)
- * /invert read-write invert pwm output
- */
-
-static ssize_t ep93xx_pwm_get_min_freq(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
- unsigned long rate = clk_get_rate(pwm->clk);
-
- return sprintf(buf, "%ld\n", rate / (EP93XX_PWM_MAX_COUNT + 1));
-}
-
-static ssize_t ep93xx_pwm_get_max_freq(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
- unsigned long rate = clk_get_rate(pwm->clk);
-
- return sprintf(buf, "%ld\n", rate / 2);
-}
-
-static ssize_t ep93xx_pwm_get_freq(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
-
- if (ep93xx_pwm_is_enabled(pwm)) {
- unsigned long rate = clk_get_rate(pwm->clk);
- u16 term = ep93xx_pwm_read_tc(pwm);
-
- return sprintf(buf, "%ld\n", rate / (term + 1));
- } else {
- return sprintf(buf, "disabled\n");
- }
-}
-
-static ssize_t ep93xx_pwm_set_freq(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
- long val;
- int err;
-
- err = strict_strtol(buf, 10, &val);
- if (err)
- return -EINVAL;
-
- if (val == 0) {
- ep93xx_pwm_disable(pwm);
- } else if (val <= (clk_get_rate(pwm->clk) / 2)) {
- u32 term, duty;
-
- val = (clk_get_rate(pwm->clk) / val) - 1;
- if (val > EP93XX_PWM_MAX_COUNT)
- val = EP93XX_PWM_MAX_COUNT;
- if (val < 1)
- val = 1;
-
- term = ep93xx_pwm_read_tc(pwm);
- duty = ((val + 1) * pwm->duty_percent / 100) - 1;
-
- /* If pwm is running, order is important */
- if (val > term) {
- ep93xx_pwm_write_tc(pwm, val);
- ep93xx_pwm_write_dc(pwm, duty);
- } else {
- ep93xx_pwm_write_dc(pwm, duty);
- ep93xx_pwm_write_tc(pwm, val);
- }
-
- if (!ep93xx_pwm_is_enabled(pwm))
- ep93xx_pwm_enable(pwm);
- } else {
- return -EINVAL;
- }
-
- return count;
-}
-
-static ssize_t ep93xx_pwm_get_duty_percent(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
-
- return sprintf(buf, "%d\n", pwm->duty_percent);
-}
-
-static ssize_t ep93xx_pwm_set_duty_percent(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
- long val;
- int err;
-
- err = strict_strtol(buf, 10, &val);
- if (err)
- return -EINVAL;
-
- if (val > 0 && val < 100) {
- u32 term = ep93xx_pwm_read_tc(pwm);
- ep93xx_pwm_write_dc(pwm, ((term + 1) * val / 100) - 1);
- pwm->duty_percent = val;
- return count;
- }
-
- return -EINVAL;
-}
-
-static ssize_t ep93xx_pwm_get_invert(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
-
- return sprintf(buf, "%d\n", ep93xx_pwm_is_inverted(pwm));
-}
-
-static ssize_t ep93xx_pwm_set_invert(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
- long val;
- int err;
-
- err = strict_strtol(buf, 10, &val);
- if (err)
- return -EINVAL;
-
- if (val == 0)
- ep93xx_pwm_normal(pwm);
- else if (val == 1)
- ep93xx_pwm_invert(pwm);
- else
- return -EINVAL;
-
- return count;
-}
-
-static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL);
-static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL);
-static DEVICE_ATTR(freq, S_IWUSR | S_IRUGO,
- ep93xx_pwm_get_freq, ep93xx_pwm_set_freq);
-static DEVICE_ATTR(duty_percent, S_IWUSR | S_IRUGO,
- ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent);
-static DEVICE_ATTR(invert, S_IWUSR | S_IRUGO,
- ep93xx_pwm_get_invert, ep93xx_pwm_set_invert);
-
-static struct attribute *ep93xx_pwm_attrs[] = {
- &dev_attr_min_freq.attr,
- &dev_attr_max_freq.attr,
- &dev_attr_freq.attr,
- &dev_attr_duty_percent.attr,
- &dev_attr_invert.attr,
- NULL
-};
-
-static const struct attribute_group ep93xx_pwm_sysfs_files = {
- .attrs = ep93xx_pwm_attrs,
-};
-
-static int __init ep93xx_pwm_probe(struct platform_device *pdev)
-{
- struct ep93xx_pwm *pwm;
- struct resource *res;
- int err;
-
- err = ep93xx_pwm_acquire_gpio(pdev);
- if (err)
- return err;
-
- pwm = kzalloc(sizeof(struct ep93xx_pwm), GFP_KERNEL);
- if (!pwm) {
- err = -ENOMEM;
- goto fail_no_mem;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- err = -ENXIO;
- goto fail_no_mem_resource;
- }
-
- res = request_mem_region(res->start, resource_size(res), pdev->name);
- if (res == NULL) {
- err = -EBUSY;
- goto fail_no_mem_resource;
- }
-
- pwm->mmio_base = ioremap(res->start, resource_size(res));
- if (pwm->mmio_base == NULL) {
- err = -ENXIO;
- goto fail_no_ioremap;
- }
-
- err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
- if (err)
- goto fail_no_sysfs;
-
- pwm->clk = clk_get(&pdev->dev, "pwm_clk");
- if (IS_ERR(pwm->clk)) {
- err = PTR_ERR(pwm->clk);
- goto fail_no_clk;
- }
-
- pwm->duty_percent = 50;
-
- platform_set_drvdata(pdev, pwm);
-
- /* disable pwm at startup. Avoids zero value. */
- ep93xx_pwm_disable(pwm);
- ep93xx_pwm_write_tc(pwm, EP93XX_PWM_MAX_COUNT);
- ep93xx_pwm_write_dc(pwm, EP93XX_PWM_MAX_COUNT / 2);
-
- clk_enable(pwm->clk);
-
- return 0;
-
-fail_no_clk:
- sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
-fail_no_sysfs:
- iounmap(pwm->mmio_base);
-fail_no_ioremap:
- release_mem_region(res->start, resource_size(res));
-fail_no_mem_resource:
- kfree(pwm);
-fail_no_mem:
- ep93xx_pwm_release_gpio(pdev);
- return err;
-}
-
-static int __exit ep93xx_pwm_remove(struct platform_device *pdev)
-{
- struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
- struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- ep93xx_pwm_disable(pwm);
- clk_disable(pwm->clk);
- clk_put(pwm->clk);
- platform_set_drvdata(pdev, NULL);
- sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
- iounmap(pwm->mmio_base);
- release_mem_region(res->start, resource_size(res));
- kfree(pwm);
- ep93xx_pwm_release_gpio(pdev);
-
- return 0;
-}
-
-static struct platform_driver ep93xx_pwm_driver = {
- .driver = {
- .name = "ep93xx-pwm",
- .owner = THIS_MODULE,
- },
- .remove = __exit_p(ep93xx_pwm_remove),
-};
-
-static int __init ep93xx_pwm_init(void)
-{
- return platform_driver_probe(&ep93xx_pwm_driver, ep93xx_pwm_probe);
-}
-
-static void __exit ep93xx_pwm_exit(void)
-{
- platform_driver_unregister(&ep93xx_pwm_driver);
-}
-
-module_init(ep93xx_pwm_init);
-module_exit(ep93xx_pwm_exit);
-
-MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, "
- "H Hartley Sweeten <hsweeten@visionengravers.com>");
-MODULE_DESCRIPTION("EP93xx PWM driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:ep93xx-pwm");
diff --git a/ANDROID_3.4.5/drivers/misc/fsa9480.c b/ANDROID_3.4.5/drivers/misc/fsa9480.c
deleted file mode 100644
index ac96c3a4..00000000
--- a/ANDROID_3.4.5/drivers/misc/fsa9480.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * fsa9480.c - FSA9480 micro USB switch device driver
- *
- * Copyright (C) 2010 Samsung Electronics
- * Minkyu Kang <mk7.kang@samsung.com>
- * Wonguk Jeong <wonguk.jeong@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/platform_data/fsa9480.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
-
-/* FSA9480 I2C registers */
-#define FSA9480_REG_DEVID 0x01
-#define FSA9480_REG_CTRL 0x02
-#define FSA9480_REG_INT1 0x03
-#define FSA9480_REG_INT2 0x04
-#define FSA9480_REG_INT1_MASK 0x05
-#define FSA9480_REG_INT2_MASK 0x06
-#define FSA9480_REG_ADC 0x07
-#define FSA9480_REG_TIMING1 0x08
-#define FSA9480_REG_TIMING2 0x09
-#define FSA9480_REG_DEV_T1 0x0a
-#define FSA9480_REG_DEV_T2 0x0b
-#define FSA9480_REG_BTN1 0x0c
-#define FSA9480_REG_BTN2 0x0d
-#define FSA9480_REG_CK 0x0e
-#define FSA9480_REG_CK_INT1 0x0f
-#define FSA9480_REG_CK_INT2 0x10
-#define FSA9480_REG_CK_INTMASK1 0x11
-#define FSA9480_REG_CK_INTMASK2 0x12
-#define FSA9480_REG_MANSW1 0x13
-#define FSA9480_REG_MANSW2 0x14
-
-/* Control */
-#define CON_SWITCH_OPEN (1 << 4)
-#define CON_RAW_DATA (1 << 3)
-#define CON_MANUAL_SW (1 << 2)
-#define CON_WAIT (1 << 1)
-#define CON_INT_MASK (1 << 0)
-#define CON_MASK (CON_SWITCH_OPEN | CON_RAW_DATA | \
- CON_MANUAL_SW | CON_WAIT)
-
-/* Device Type 1 */
-#define DEV_USB_OTG (1 << 7)
-#define DEV_DEDICATED_CHG (1 << 6)
-#define DEV_USB_CHG (1 << 5)
-#define DEV_CAR_KIT (1 << 4)
-#define DEV_UART (1 << 3)
-#define DEV_USB (1 << 2)
-#define DEV_AUDIO_2 (1 << 1)
-#define DEV_AUDIO_1 (1 << 0)
-
-#define DEV_T1_USB_MASK (DEV_USB_OTG | DEV_USB)
-#define DEV_T1_UART_MASK (DEV_UART)
-#define DEV_T1_CHARGER_MASK (DEV_DEDICATED_CHG | DEV_USB_CHG)
-
-/* Device Type 2 */
-#define DEV_AV (1 << 6)
-#define DEV_TTY (1 << 5)
-#define DEV_PPD (1 << 4)
-#define DEV_JIG_UART_OFF (1 << 3)
-#define DEV_JIG_UART_ON (1 << 2)
-#define DEV_JIG_USB_OFF (1 << 1)
-#define DEV_JIG_USB_ON (1 << 0)
-
-#define DEV_T2_USB_MASK (DEV_JIG_USB_OFF | DEV_JIG_USB_ON)
-#define DEV_T2_UART_MASK (DEV_JIG_UART_OFF | DEV_JIG_UART_ON)
-#define DEV_T2_JIG_MASK (DEV_JIG_USB_OFF | DEV_JIG_USB_ON | \
- DEV_JIG_UART_OFF | DEV_JIG_UART_ON)
-
-/*
- * Manual Switch
- * D- [7:5] / D+ [4:2]
- * 000: Open all / 001: USB / 010: AUDIO / 011: UART / 100: V_AUDIO
- */
-#define SW_VAUDIO ((4 << 5) | (4 << 2))
-#define SW_UART ((3 << 5) | (3 << 2))
-#define SW_AUDIO ((2 << 5) | (2 << 2))
-#define SW_DHOST ((1 << 5) | (1 << 2))
-#define SW_AUTO ((0 << 5) | (0 << 2))
-
-/* Interrupt 1 */
-#define INT_DETACH (1 << 1)
-#define INT_ATTACH (1 << 0)
-
-struct fsa9480_usbsw {
- struct i2c_client *client;
- struct fsa9480_platform_data *pdata;
- int dev1;
- int dev2;
- int mansw;
-};
-
-static struct fsa9480_usbsw *chip;
-
-static int fsa9480_write_reg(struct i2c_client *client,
- int reg, int value)
-{
- int ret;
-
- ret = i2c_smbus_write_byte_data(client, reg, value);
-
- if (ret < 0)
- dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
- return ret;
-}
-
-static int fsa9480_read_reg(struct i2c_client *client, int reg)
-{
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, reg);
-
- if (ret < 0)
- dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
- return ret;
-}
-
-static int fsa9480_read_irq(struct i2c_client *client, int *value)
-{
- int ret;
-
- ret = i2c_smbus_read_i2c_block_data(client,
- FSA9480_REG_INT1, 2, (u8 *)value);
- *value &= 0xffff;
-
- if (ret < 0)
- dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
- return ret;
-}
-
-static void fsa9480_set_switch(const char *buf)
-{
- struct fsa9480_usbsw *usbsw = chip;
- struct i2c_client *client = usbsw->client;
- unsigned int value;
- unsigned int path = 0;
-
- value = fsa9480_read_reg(client, FSA9480_REG_CTRL);
-
- if (!strncmp(buf, "VAUDIO", 6)) {
- path = SW_VAUDIO;
- value &= ~CON_MANUAL_SW;
- } else if (!strncmp(buf, "UART", 4)) {
- path = SW_UART;
- value &= ~CON_MANUAL_SW;
- } else if (!strncmp(buf, "AUDIO", 5)) {
- path = SW_AUDIO;
- value &= ~CON_MANUAL_SW;
- } else if (!strncmp(buf, "DHOST", 5)) {
- path = SW_DHOST;
- value &= ~CON_MANUAL_SW;
- } else if (!strncmp(buf, "AUTO", 4)) {
- path = SW_AUTO;
- value |= CON_MANUAL_SW;
- } else {
- printk(KERN_ERR "Wrong command\n");
- return;
- }
-
- usbsw->mansw = path;
- fsa9480_write_reg(client, FSA9480_REG_MANSW1, path);
- fsa9480_write_reg(client, FSA9480_REG_CTRL, value);
-}
-
-static ssize_t fsa9480_get_switch(char *buf)
-{
- struct fsa9480_usbsw *usbsw = chip;
- struct i2c_client *client = usbsw->client;
- unsigned int value;
-
- value = fsa9480_read_reg(client, FSA9480_REG_MANSW1);
-
- if (value == SW_VAUDIO)
- return sprintf(buf, "VAUDIO\n");
- else if (value == SW_UART)
- return sprintf(buf, "UART\n");
- else if (value == SW_AUDIO)
- return sprintf(buf, "AUDIO\n");
- else if (value == SW_DHOST)
- return sprintf(buf, "DHOST\n");
- else if (value == SW_AUTO)
- return sprintf(buf, "AUTO\n");
- else
- return sprintf(buf, "%x", value);
-}
-
-static ssize_t fsa9480_show_device(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct fsa9480_usbsw *usbsw = dev_get_drvdata(dev);
- struct i2c_client *client = usbsw->client;
- int dev1, dev2;
-
- dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1);
- dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2);
-
- if (!dev1 && !dev2)
- return sprintf(buf, "NONE\n");
-
- /* USB */
- if (dev1 & DEV_T1_USB_MASK || dev2 & DEV_T2_USB_MASK)
- return sprintf(buf, "USB\n");
-
- /* UART */
- if (dev1 & DEV_T1_UART_MASK || dev2 & DEV_T2_UART_MASK)
- return sprintf(buf, "UART\n");
-
- /* CHARGER */
- if (dev1 & DEV_T1_CHARGER_MASK)
- return sprintf(buf, "CHARGER\n");
-
- /* JIG */
- if (dev2 & DEV_T2_JIG_MASK)
- return sprintf(buf, "JIG\n");
-
- return sprintf(buf, "UNKNOWN\n");
-}
-
-static ssize_t fsa9480_show_manualsw(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return fsa9480_get_switch(buf);
-
-}
-
-static ssize_t fsa9480_set_manualsw(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- fsa9480_set_switch(buf);
-
- return count;
-}
-
-static DEVICE_ATTR(device, S_IRUGO, fsa9480_show_device, NULL);
-static DEVICE_ATTR(switch, S_IRUGO | S_IWUSR,
- fsa9480_show_manualsw, fsa9480_set_manualsw);
-
-static struct attribute *fsa9480_attributes[] = {
- &dev_attr_device.attr,
- &dev_attr_switch.attr,
- NULL
-};
-
-static const struct attribute_group fsa9480_group = {
- .attrs = fsa9480_attributes,
-};
-
-static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw, int intr)
-{
- int val1, val2, ctrl;
- struct fsa9480_platform_data *pdata = usbsw->pdata;
- struct i2c_client *client = usbsw->client;
-
- val1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1);
- val2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2);
- ctrl = fsa9480_read_reg(client, FSA9480_REG_CTRL);
-
- dev_info(&client->dev, "intr: 0x%x, dev1: 0x%x, dev2: 0x%x\n",
- intr, val1, val2);
-
- if (!intr)
- goto out;
-
- if (intr & INT_ATTACH) { /* Attached */
- /* USB */
- if (val1 & DEV_T1_USB_MASK || val2 & DEV_T2_USB_MASK) {
- if (pdata->usb_cb)
- pdata->usb_cb(FSA9480_ATTACHED);
-
- if (usbsw->mansw) {
- fsa9480_write_reg(client,
- FSA9480_REG_MANSW1, usbsw->mansw);
- }
- }
-
- /* UART */
- if (val1 & DEV_T1_UART_MASK || val2 & DEV_T2_UART_MASK) {
- if (pdata->uart_cb)
- pdata->uart_cb(FSA9480_ATTACHED);
-
- if (!(ctrl & CON_MANUAL_SW)) {
- fsa9480_write_reg(client,
- FSA9480_REG_MANSW1, SW_UART);
- }
- }
-
- /* CHARGER */
- if (val1 & DEV_T1_CHARGER_MASK) {
- if (pdata->charger_cb)
- pdata->charger_cb(FSA9480_ATTACHED);
- }
-
- /* JIG */
- if (val2 & DEV_T2_JIG_MASK) {
- if (pdata->jig_cb)
- pdata->jig_cb(FSA9480_ATTACHED);
- }
- } else if (intr & INT_DETACH) { /* Detached */
- /* USB */
- if (usbsw->dev1 & DEV_T1_USB_MASK ||
- usbsw->dev2 & DEV_T2_USB_MASK) {
- if (pdata->usb_cb)
- pdata->usb_cb(FSA9480_DETACHED);
- }
-
- /* UART */
- if (usbsw->dev1 & DEV_T1_UART_MASK ||
- usbsw->dev2 & DEV_T2_UART_MASK) {
- if (pdata->uart_cb)
- pdata->uart_cb(FSA9480_DETACHED);
- }
-
- /* CHARGER */
- if (usbsw->dev1 & DEV_T1_CHARGER_MASK) {
- if (pdata->charger_cb)
- pdata->charger_cb(FSA9480_DETACHED);
- }
-
- /* JIG */
- if (usbsw->dev2 & DEV_T2_JIG_MASK) {
- if (pdata->jig_cb)
- pdata->jig_cb(FSA9480_DETACHED);
- }
- }
-
- usbsw->dev1 = val1;
- usbsw->dev2 = val2;
-
-out:
- ctrl &= ~CON_INT_MASK;
- fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl);
-}
-
-static irqreturn_t fsa9480_irq_handler(int irq, void *data)
-{
- struct fsa9480_usbsw *usbsw = data;
- struct i2c_client *client = usbsw->client;
- int intr;
-
- /* clear interrupt */
- fsa9480_read_irq(client, &intr);
-
- /* device detection */
- fsa9480_detect_dev(usbsw, intr);
-
- return IRQ_HANDLED;
-}
-
-static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw)
-{
- struct fsa9480_platform_data *pdata = usbsw->pdata;
- struct i2c_client *client = usbsw->client;
- int ret;
- int intr;
- unsigned int ctrl = CON_MASK;
-
- /* clear interrupt */
- fsa9480_read_irq(client, &intr);
-
- /* unmask interrupt (attach/detach only) */
- fsa9480_write_reg(client, FSA9480_REG_INT1_MASK, 0xfc);
- fsa9480_write_reg(client, FSA9480_REG_INT2_MASK, 0x1f);
-
- usbsw->mansw = fsa9480_read_reg(client, FSA9480_REG_MANSW1);
-
- if (usbsw->mansw)
- ctrl &= ~CON_MANUAL_SW; /* Manual Switching Mode */
-
- fsa9480_write_reg(client, FSA9480_REG_CTRL, ctrl);
-
- if (pdata && pdata->cfg_gpio)
- pdata->cfg_gpio();
-
- if (client->irq) {
- ret = request_threaded_irq(client->irq, NULL,
- fsa9480_irq_handler,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
- "fsa9480 micro USB", usbsw);
- if (ret) {
- dev_err(&client->dev, "failed to reqeust IRQ\n");
- return ret;
- }
-
- if (pdata)
- device_init_wakeup(&client->dev, pdata->wakeup);
- }
-
- return 0;
-}
-
-static int __devinit fsa9480_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct fsa9480_usbsw *usbsw;
- int ret = 0;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EIO;
-
- usbsw = kzalloc(sizeof(struct fsa9480_usbsw), GFP_KERNEL);
- if (!usbsw) {
- dev_err(&client->dev, "failed to allocate driver data\n");
- return -ENOMEM;
- }
-
- usbsw->client = client;
- usbsw->pdata = client->dev.platform_data;
-
- chip = usbsw;
-
- i2c_set_clientdata(client, usbsw);
-
- ret = fsa9480_irq_init(usbsw);
- if (ret)
- goto fail1;
-
- ret = sysfs_create_group(&client->dev.kobj, &fsa9480_group);
- if (ret) {
- dev_err(&client->dev,
- "failed to create fsa9480 attribute group\n");
- goto fail2;
- }
-
- /* ADC Detect Time: 500ms */
- fsa9480_write_reg(client, FSA9480_REG_TIMING1, 0x6);
-
- if (chip->pdata->reset_cb)
- chip->pdata->reset_cb();
-
- /* device detection */
- fsa9480_detect_dev(usbsw, INT_ATTACH);
-
- pm_runtime_set_active(&client->dev);
-
- return 0;
-
-fail2:
- if (client->irq)
- free_irq(client->irq, usbsw);
-fail1:
- kfree(usbsw);
- return ret;
-}
-
-static int __devexit fsa9480_remove(struct i2c_client *client)
-{
- struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
- if (client->irq)
- free_irq(client->irq, usbsw);
-
- sysfs_remove_group(&client->dev.kobj, &fsa9480_group);
- device_init_wakeup(&client->dev, 0);
- kfree(usbsw);
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int fsa9480_suspend(struct i2c_client *client, pm_message_t state)
-{
- struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
- struct fsa9480_platform_data *pdata = usbsw->pdata;
-
- if (device_may_wakeup(&client->dev) && client->irq)
- enable_irq_wake(client->irq);
-
- if (pdata->usb_power)
- pdata->usb_power(0);
-
- return 0;
-}
-
-static int fsa9480_resume(struct i2c_client *client)
-{
- struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client);
- int dev1, dev2;
-
- if (device_may_wakeup(&client->dev) && client->irq)
- disable_irq_wake(client->irq);
-
- /*
- * Clear Pending interrupt. Note that detect_dev does what
- * the interrupt handler does. So, we don't miss pending and
- * we reenable interrupt if there is one.
- */
- fsa9480_read_reg(client, FSA9480_REG_INT1);
- fsa9480_read_reg(client, FSA9480_REG_INT2);
-
- dev1 = fsa9480_read_reg(client, FSA9480_REG_DEV_T1);
- dev2 = fsa9480_read_reg(client, FSA9480_REG_DEV_T2);
-
- /* device detection */
- fsa9480_detect_dev(usbsw, (dev1 || dev2) ? INT_ATTACH : INT_DETACH);
-
- return 0;
-}
-
-#else
-
-#define fsa9480_suspend NULL
-#define fsa9480_resume NULL
-
-#endif /* CONFIG_PM */
-
-static const struct i2c_device_id fsa9480_id[] = {
- {"fsa9480", 0},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, fsa9480_id);
-
-static struct i2c_driver fsa9480_i2c_driver = {
- .driver = {
- .name = "fsa9480",
- },
- .probe = fsa9480_probe,
- .remove = __devexit_p(fsa9480_remove),
- .resume = fsa9480_resume,
- .suspend = fsa9480_suspend,
- .id_table = fsa9480_id,
-};
-
-module_i2c_driver(fsa9480_i2c_driver);
-
-MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
-MODULE_DESCRIPTION("FSA9480 USB Switch driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/hmc6352.c b/ANDROID_3.4.5/drivers/misc/hmc6352.c
deleted file mode 100644
index 423cd40f..00000000
--- a/ANDROID_3.4.5/drivers/misc/hmc6352.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * hmc6352.c - Honeywell Compass Driver
- *
- * Copyright (C) 2009 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; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/sysfs.h>
-
-static DEFINE_MUTEX(compass_mutex);
-
-static int compass_command(struct i2c_client *c, u8 cmd)
-{
- int ret = i2c_master_send(c, &cmd, 1);
- if (ret < 0)
- dev_warn(&c->dev, "command '%c' failed.\n", cmd);
- return ret;
-}
-
-static int compass_store(struct device *dev, const char *buf, size_t count,
- const char *map)
-{
- struct i2c_client *c = to_i2c_client(dev);
- int ret;
- unsigned long val;
-
- if (strict_strtoul(buf, 10, &val))
- return -EINVAL;
- if (val >= strlen(map))
- return -EINVAL;
- mutex_lock(&compass_mutex);
- ret = compass_command(c, map[val]);
- mutex_unlock(&compass_mutex);
- if (ret < 0)
- return ret;
- return count;
-}
-
-static ssize_t compass_calibration_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- return compass_store(dev, buf, count, "EC");
-}
-
-static ssize_t compass_power_mode_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- return compass_store(dev, buf, count, "SW");
-}
-
-static ssize_t compass_heading_data_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- unsigned char i2c_data[2];
- int ret;
-
- mutex_lock(&compass_mutex);
- ret = compass_command(client, 'A');
- if (ret != 1) {
- mutex_unlock(&compass_mutex);
- return ret;
- }
- msleep(10); /* sending 'A' cmd we need to wait for 7-10 millisecs */
- ret = i2c_master_recv(client, i2c_data, 2);
- mutex_unlock(&compass_mutex);
- if (ret < 0) {
- dev_warn(dev, "i2c read data cmd failed\n");
- return ret;
- }
- ret = (i2c_data[0] << 8) | i2c_data[1];
- return sprintf(buf, "%d.%d\n", ret/10, ret%10);
-}
-
-
-static DEVICE_ATTR(heading0_input, S_IRUGO, compass_heading_data_show, NULL);
-static DEVICE_ATTR(calibration, S_IWUSR, NULL, compass_calibration_store);
-static DEVICE_ATTR(power_state, S_IWUSR, NULL, compass_power_mode_store);
-
-static struct attribute *mid_att_compass[] = {
- &dev_attr_heading0_input.attr,
- &dev_attr_calibration.attr,
- &dev_attr_power_state.attr,
- NULL
-};
-
-static const struct attribute_group m_compass_gr = {
- .name = "hmc6352",
- .attrs = mid_att_compass
-};
-
-static int hmc6352_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int res;
-
- res = sysfs_create_group(&client->dev.kobj, &m_compass_gr);
- if (res) {
- dev_err(&client->dev, "device_create_file failed\n");
- return res;
- }
- dev_info(&client->dev, "%s HMC6352 compass chip found\n",
- client->name);
- return 0;
-}
-
-static int hmc6352_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &m_compass_gr);
- return 0;
-}
-
-static struct i2c_device_id hmc6352_id[] = {
- { "hmc6352", 0 },
- { }
-};
-
-MODULE_DEVICE_TABLE(i2c, hmc6352_id);
-
-static struct i2c_driver hmc6352_driver = {
- .driver = {
- .name = "hmc6352",
- },
- .probe = hmc6352_probe,
- .remove = hmc6352_remove,
- .id_table = hmc6352_id,
-};
-
-module_i2c_driver(hmc6352_driver);
-
-MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
-MODULE_DESCRIPTION("hmc6352 Compass Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/misc/hpilo.c b/ANDROID_3.4.5/drivers/misc/hpilo.c
deleted file mode 100644
index fffc2271..00000000
--- a/ANDROID_3.4.5/drivers/misc/hpilo.c
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * Driver for the HP iLO management processor.
- *
- * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
- * David Altobelli <david.altobelli@hp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/file.h>
-#include <linux/cdev.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <linux/wait.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include "hpilo.h"
-
-static struct class *ilo_class;
-static unsigned int ilo_major;
-static char ilo_hwdev[MAX_ILO_DEV];
-
-static inline int get_entry_id(int entry)
-{
- return (entry & ENTRY_MASK_DESCRIPTOR) >> ENTRY_BITPOS_DESCRIPTOR;
-}
-
-static inline int get_entry_len(int entry)
-{
- return ((entry & ENTRY_MASK_QWORDS) >> ENTRY_BITPOS_QWORDS) << 3;
-}
-
-static inline int mk_entry(int id, int len)
-{
- int qlen = len & 7 ? (len >> 3) + 1 : len >> 3;
- return id << ENTRY_BITPOS_DESCRIPTOR | qlen << ENTRY_BITPOS_QWORDS;
-}
-
-static inline int desc_mem_sz(int nr_entry)
-{
- return nr_entry << L2_QENTRY_SZ;
-}
-
-/*
- * FIFO queues, shared with hardware.
- *
- * If a queue has empty slots, an entry is added to the queue tail,
- * and that entry is marked as occupied.
- * Entries can be dequeued from the head of the list, when the device
- * has marked the entry as consumed.
- *
- * Returns true on successful queue/dequeue, false on failure.
- */
-static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry)
-{
- struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&hw->fifo_lock, flags);
- if (!(fifo_q->fifobar[(fifo_q->tail + 1) & fifo_q->imask]
- & ENTRY_MASK_O)) {
- fifo_q->fifobar[fifo_q->tail & fifo_q->imask] |=
- (entry & ENTRY_MASK_NOSTATE) | fifo_q->merge;
- fifo_q->tail += 1;
- ret = 1;
- }
- spin_unlock_irqrestore(&hw->fifo_lock, flags);
-
- return ret;
-}
-
-static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry)
-{
- struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
- unsigned long flags;
- int ret = 0;
- u64 c;
-
- spin_lock_irqsave(&hw->fifo_lock, flags);
- c = fifo_q->fifobar[fifo_q->head & fifo_q->imask];
- if (c & ENTRY_MASK_C) {
- if (entry)
- *entry = c & ENTRY_MASK_NOSTATE;
-
- fifo_q->fifobar[fifo_q->head & fifo_q->imask] =
- (c | ENTRY_MASK) + 1;
- fifo_q->head += 1;
- ret = 1;
- }
- spin_unlock_irqrestore(&hw->fifo_lock, flags);
-
- return ret;
-}
-
-static int fifo_check_recv(struct ilo_hwinfo *hw, char *fifobar)
-{
- struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
- unsigned long flags;
- int ret = 0;
- u64 c;
-
- spin_lock_irqsave(&hw->fifo_lock, flags);
- c = fifo_q->fifobar[fifo_q->head & fifo_q->imask];
- if (c & ENTRY_MASK_C)
- ret = 1;
- spin_unlock_irqrestore(&hw->fifo_lock, flags);
-
- return ret;
-}
-
-static int ilo_pkt_enqueue(struct ilo_hwinfo *hw, struct ccb *ccb,
- int dir, int id, int len)
-{
- char *fifobar;
- int entry;
-
- if (dir == SENDQ)
- fifobar = ccb->ccb_u1.send_fifobar;
- else
- fifobar = ccb->ccb_u3.recv_fifobar;
-
- entry = mk_entry(id, len);
- return fifo_enqueue(hw, fifobar, entry);
-}
-
-static int ilo_pkt_dequeue(struct ilo_hwinfo *hw, struct ccb *ccb,
- int dir, int *id, int *len, void **pkt)
-{
- char *fifobar, *desc;
- int entry = 0, pkt_id = 0;
- int ret;
-
- if (dir == SENDQ) {
- fifobar = ccb->ccb_u1.send_fifobar;
- desc = ccb->ccb_u2.send_desc;
- } else {
- fifobar = ccb->ccb_u3.recv_fifobar;
- desc = ccb->ccb_u4.recv_desc;
- }
-
- ret = fifo_dequeue(hw, fifobar, &entry);
- if (ret) {
- pkt_id = get_entry_id(entry);
- if (id)
- *id = pkt_id;
- if (len)
- *len = get_entry_len(entry);
- if (pkt)
- *pkt = (void *)(desc + desc_mem_sz(pkt_id));
- }
-
- return ret;
-}
-
-static int ilo_pkt_recv(struct ilo_hwinfo *hw, struct ccb *ccb)
-{
- char *fifobar = ccb->ccb_u3.recv_fifobar;
-
- return fifo_check_recv(hw, fifobar);
-}
-
-static inline void doorbell_set(struct ccb *ccb)
-{
- iowrite8(1, ccb->ccb_u5.db_base);
-}
-
-static inline void doorbell_clr(struct ccb *ccb)
-{
- iowrite8(2, ccb->ccb_u5.db_base);
-}
-
-static inline int ctrl_set(int l2sz, int idxmask, int desclim)
-{
- int active = 0, go = 1;
- return l2sz << CTRL_BITPOS_L2SZ |
- idxmask << CTRL_BITPOS_FIFOINDEXMASK |
- desclim << CTRL_BITPOS_DESCLIMIT |
- active << CTRL_BITPOS_A |
- go << CTRL_BITPOS_G;
-}
-
-static void ctrl_setup(struct ccb *ccb, int nr_desc, int l2desc_sz)
-{
- /* for simplicity, use the same parameters for send and recv ctrls */
- ccb->send_ctrl = ctrl_set(l2desc_sz, nr_desc-1, nr_desc-1);
- ccb->recv_ctrl = ctrl_set(l2desc_sz, nr_desc-1, nr_desc-1);
-}
-
-static inline int fifo_sz(int nr_entry)
-{
- /* size of a fifo is determined by the number of entries it contains */
- return (nr_entry * sizeof(u64)) + FIFOHANDLESIZE;
-}
-
-static void fifo_setup(void *base_addr, int nr_entry)
-{
- struct fifo *fifo_q = base_addr;
- int i;
-
- /* set up an empty fifo */
- fifo_q->head = 0;
- fifo_q->tail = 0;
- fifo_q->reset = 0;
- fifo_q->nrents = nr_entry;
- fifo_q->imask = nr_entry - 1;
- fifo_q->merge = ENTRY_MASK_O;
-
- for (i = 0; i < nr_entry; i++)
- fifo_q->fifobar[i] = 0;
-}
-
-static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
-{
- struct ccb *driver_ccb = &data->driver_ccb;
- struct ccb __iomem *device_ccb = data->mapped_ccb;
- int retries;
-
- /* complicated dance to tell the hw we are stopping */
- doorbell_clr(driver_ccb);
- iowrite32(ioread32(&device_ccb->send_ctrl) & ~(1 << CTRL_BITPOS_G),
- &device_ccb->send_ctrl);
- iowrite32(ioread32(&device_ccb->recv_ctrl) & ~(1 << CTRL_BITPOS_G),
- &device_ccb->recv_ctrl);
-
- /* give iLO some time to process stop request */
- for (retries = MAX_WAIT; retries > 0; retries--) {
- doorbell_set(driver_ccb);
- udelay(WAIT_TIME);
- if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
- &&
- !(ioread32(&device_ccb->recv_ctrl) & (1 << CTRL_BITPOS_A)))
- break;
- }
- if (retries == 0)
- dev_err(&pdev->dev, "Closing, but controller still active\n");
-
- /* clear the hw ccb */
- memset_io(device_ccb, 0, sizeof(struct ccb));
-
- /* free resources used to back send/recv queues */
- pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
-}
-
-static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
-{
- char *dma_va;
- dma_addr_t dma_pa;
- struct ccb *driver_ccb, *ilo_ccb;
-
- driver_ccb = &data->driver_ccb;
- ilo_ccb = &data->ilo_ccb;
-
- data->dma_size = 2 * fifo_sz(NR_QENTRY) +
- 2 * desc_mem_sz(NR_QENTRY) +
- ILO_START_ALIGN + ILO_CACHE_SZ;
-
- data->dma_va = pci_alloc_consistent(hw->ilo_dev, data->dma_size,
- &data->dma_pa);
- if (!data->dma_va)
- return -ENOMEM;
-
- dma_va = (char *)data->dma_va;
- dma_pa = data->dma_pa;
-
- memset(dma_va, 0, data->dma_size);
-
- dma_va = (char *)roundup((unsigned long)dma_va, ILO_START_ALIGN);
- dma_pa = roundup(dma_pa, ILO_START_ALIGN);
-
- /*
- * Create two ccb's, one with virt addrs, one with phys addrs.
- * Copy the phys addr ccb to device shared mem.
- */
- ctrl_setup(driver_ccb, NR_QENTRY, L2_QENTRY_SZ);
- ctrl_setup(ilo_ccb, NR_QENTRY, L2_QENTRY_SZ);
-
- fifo_setup(dma_va, NR_QENTRY);
- driver_ccb->ccb_u1.send_fifobar = dma_va + FIFOHANDLESIZE;
- ilo_ccb->ccb_u1.send_fifobar_pa = dma_pa + FIFOHANDLESIZE;
- dma_va += fifo_sz(NR_QENTRY);
- dma_pa += fifo_sz(NR_QENTRY);
-
- dma_va = (char *)roundup((unsigned long)dma_va, ILO_CACHE_SZ);
- dma_pa = roundup(dma_pa, ILO_CACHE_SZ);
-
- fifo_setup(dma_va, NR_QENTRY);
- driver_ccb->ccb_u3.recv_fifobar = dma_va + FIFOHANDLESIZE;
- ilo_ccb->ccb_u3.recv_fifobar_pa = dma_pa + FIFOHANDLESIZE;
- dma_va += fifo_sz(NR_QENTRY);
- dma_pa += fifo_sz(NR_QENTRY);
-
- driver_ccb->ccb_u2.send_desc = dma_va;
- ilo_ccb->ccb_u2.send_desc_pa = dma_pa;
- dma_pa += desc_mem_sz(NR_QENTRY);
- dma_va += desc_mem_sz(NR_QENTRY);
-
- driver_ccb->ccb_u4.recv_desc = dma_va;
- ilo_ccb->ccb_u4.recv_desc_pa = dma_pa;
-
- driver_ccb->channel = slot;
- ilo_ccb->channel = slot;
-
- driver_ccb->ccb_u5.db_base = hw->db_vaddr + (slot << L2_DB_SIZE);
- ilo_ccb->ccb_u5.db_base = NULL; /* hw ccb's doorbell is not used */
-
- return 0;
-}
-
-static void ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
-{
- int pkt_id, pkt_sz;
- struct ccb *driver_ccb = &data->driver_ccb;
-
- /* copy the ccb with physical addrs to device memory */
- data->mapped_ccb = (struct ccb __iomem *)
- (hw->ram_vaddr + (slot * ILOHW_CCB_SZ));
- memcpy_toio(data->mapped_ccb, &data->ilo_ccb, sizeof(struct ccb));
-
- /* put packets on the send and receive queues */
- pkt_sz = 0;
- for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++) {
- ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, pkt_sz);
- doorbell_set(driver_ccb);
- }
-
- pkt_sz = desc_mem_sz(1);
- for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++)
- ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, pkt_sz);
-
- /* the ccb is ready to use */
- doorbell_clr(driver_ccb);
-}
-
-static int ilo_ccb_verify(struct ilo_hwinfo *hw, struct ccb_data *data)
-{
- int pkt_id, i;
- struct ccb *driver_ccb = &data->driver_ccb;
-
- /* make sure iLO is really handling requests */
- for (i = MAX_WAIT; i > 0; i--) {
- if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
- break;
- udelay(WAIT_TIME);
- }
-
- if (i == 0) {
- dev_err(&hw->ilo_dev->dev, "Open could not dequeue a packet\n");
- return -EBUSY;
- }
-
- ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0);
- doorbell_set(driver_ccb);
- return 0;
-}
-
-static inline int is_channel_reset(struct ccb *ccb)
-{
- /* check for this particular channel needing a reset */
- return FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset;
-}
-
-static inline void set_channel_reset(struct ccb *ccb)
-{
- /* set a flag indicating this channel needs a reset */
- FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset = 1;
-}
-
-static inline int get_device_outbound(struct ilo_hwinfo *hw)
-{
- return ioread32(&hw->mmio_vaddr[DB_OUT]);
-}
-
-static inline int is_db_reset(int db_out)
-{
- return db_out & (1 << DB_RESET);
-}
-
-static inline int is_device_reset(struct ilo_hwinfo *hw)
-{
- /* check for global reset condition */
- return is_db_reset(get_device_outbound(hw));
-}
-
-static inline void clear_pending_db(struct ilo_hwinfo *hw, int clr)
-{
- iowrite32(clr, &hw->mmio_vaddr[DB_OUT]);
-}
-
-static inline void clear_device(struct ilo_hwinfo *hw)
-{
- /* clear the device (reset bits, pending channel entries) */
- clear_pending_db(hw, -1);
-}
-
-static inline void ilo_enable_interrupts(struct ilo_hwinfo *hw)
-{
- iowrite8(ioread8(&hw->mmio_vaddr[DB_IRQ]) | 1, &hw->mmio_vaddr[DB_IRQ]);
-}
-
-static inline void ilo_disable_interrupts(struct ilo_hwinfo *hw)
-{
- iowrite8(ioread8(&hw->mmio_vaddr[DB_IRQ]) & ~1,
- &hw->mmio_vaddr[DB_IRQ]);
-}
-
-static void ilo_set_reset(struct ilo_hwinfo *hw)
-{
- int slot;
-
- /*
- * Mapped memory is zeroed on ilo reset, so set a per ccb flag
- * to indicate that this ccb needs to be closed and reopened.
- */
- for (slot = 0; slot < MAX_CCB; slot++) {
- if (!hw->ccb_alloc[slot])
- continue;
- set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb);
- }
-}
-
-static ssize_t ilo_read(struct file *fp, char __user *buf,
- size_t len, loff_t *off)
-{
- int err, found, cnt, pkt_id, pkt_len;
- struct ccb_data *data = fp->private_data;
- struct ccb *driver_ccb = &data->driver_ccb;
- struct ilo_hwinfo *hw = data->ilo_hw;
- void *pkt;
-
- if (is_channel_reset(driver_ccb)) {
- /*
- * If the device has been reset, applications
- * need to close and reopen all ccbs.
- */
- return -ENODEV;
- }
-
- /*
- * This function is to be called when data is expected
- * in the channel, and will return an error if no packet is found
- * during the loop below. The sleep/retry logic is to allow
- * applications to call read() immediately post write(),
- * and give iLO some time to process the sent packet.
- */
- cnt = 20;
- do {
- /* look for a received packet */
- found = ilo_pkt_dequeue(hw, driver_ccb, RECVQ, &pkt_id,
- &pkt_len, &pkt);
- if (found)
- break;
- cnt--;
- msleep(100);
- } while (!found && cnt);
-
- if (!found)
- return -EAGAIN;
-
- /* only copy the length of the received packet */
- if (pkt_len < len)
- len = pkt_len;
-
- err = copy_to_user(buf, pkt, len);
-
- /* return the received packet to the queue */
- ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, desc_mem_sz(1));
-
- return err ? -EFAULT : len;
-}
-
-static ssize_t ilo_write(struct file *fp, const char __user *buf,
- size_t len, loff_t *off)
-{
- int err, pkt_id, pkt_len;
- struct ccb_data *data = fp->private_data;
- struct ccb *driver_ccb = &data->driver_ccb;
- struct ilo_hwinfo *hw = data->ilo_hw;
- void *pkt;
-
- if (is_channel_reset(driver_ccb))
- return -ENODEV;
-
- /* get a packet to send the user command */
- if (!ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, &pkt_len, &pkt))
- return -EBUSY;
-
- /* limit the length to the length of the packet */
- if (pkt_len < len)
- len = pkt_len;
-
- /* on failure, set the len to 0 to return empty packet to the device */
- err = copy_from_user(pkt, buf, len);
- if (err)
- len = 0;
-
- /* send the packet */
- ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, len);
- doorbell_set(driver_ccb);
-
- return err ? -EFAULT : len;
-}
-
-static unsigned int ilo_poll(struct file *fp, poll_table *wait)
-{
- struct ccb_data *data = fp->private_data;
- struct ccb *driver_ccb = &data->driver_ccb;
-
- poll_wait(fp, &data->ccb_waitq, wait);
-
- if (is_channel_reset(driver_ccb))
- return POLLERR;
- else if (ilo_pkt_recv(data->ilo_hw, driver_ccb))
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
-
-static int ilo_close(struct inode *ip, struct file *fp)
-{
- int slot;
- struct ccb_data *data;
- struct ilo_hwinfo *hw;
- unsigned long flags;
-
- slot = iminor(ip) % MAX_CCB;
- hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
-
- spin_lock(&hw->open_lock);
-
- if (hw->ccb_alloc[slot]->ccb_cnt == 1) {
-
- data = fp->private_data;
-
- spin_lock_irqsave(&hw->alloc_lock, flags);
- hw->ccb_alloc[slot] = NULL;
- spin_unlock_irqrestore(&hw->alloc_lock, flags);
-
- ilo_ccb_close(hw->ilo_dev, data);
-
- kfree(data);
- } else
- hw->ccb_alloc[slot]->ccb_cnt--;
-
- spin_unlock(&hw->open_lock);
-
- return 0;
-}
-
-static int ilo_open(struct inode *ip, struct file *fp)
-{
- int slot, error;
- struct ccb_data *data;
- struct ilo_hwinfo *hw;
- unsigned long flags;
-
- slot = iminor(ip) % MAX_CCB;
- hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
-
- /* new ccb allocation */
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- spin_lock(&hw->open_lock);
-
- /* each fd private_data holds sw/hw view of ccb */
- if (hw->ccb_alloc[slot] == NULL) {
- /* create a channel control block for this minor */
- error = ilo_ccb_setup(hw, data, slot);
- if (error) {
- kfree(data);
- goto out;
- }
-
- data->ccb_cnt = 1;
- data->ccb_excl = fp->f_flags & O_EXCL;
- data->ilo_hw = hw;
- init_waitqueue_head(&data->ccb_waitq);
-
- /* write the ccb to hw */
- spin_lock_irqsave(&hw->alloc_lock, flags);
- ilo_ccb_open(hw, data, slot);
- hw->ccb_alloc[slot] = data;
- spin_unlock_irqrestore(&hw->alloc_lock, flags);
-
- /* make sure the channel is functional */
- error = ilo_ccb_verify(hw, data);
- if (error) {
-
- spin_lock_irqsave(&hw->alloc_lock, flags);
- hw->ccb_alloc[slot] = NULL;
- spin_unlock_irqrestore(&hw->alloc_lock, flags);
-
- ilo_ccb_close(hw->ilo_dev, data);
-
- kfree(data);
- goto out;
- }
-
- } else {
- kfree(data);
- if (fp->f_flags & O_EXCL || hw->ccb_alloc[slot]->ccb_excl) {
- /*
- * The channel exists, and either this open
- * or a previous open of this channel wants
- * exclusive access.
- */
- error = -EBUSY;
- } else {
- hw->ccb_alloc[slot]->ccb_cnt++;
- error = 0;
- }
- }
-out:
- spin_unlock(&hw->open_lock);
-
- if (!error)
- fp->private_data = hw->ccb_alloc[slot];
-
- return error;
-}
-
-static const struct file_operations ilo_fops = {
- .owner = THIS_MODULE,
- .read = ilo_read,
- .write = ilo_write,
- .poll = ilo_poll,
- .open = ilo_open,
- .release = ilo_close,
- .llseek = noop_llseek,
-};
-
-static irqreturn_t ilo_isr(int irq, void *data)
-{
- struct ilo_hwinfo *hw = data;
- int pending, i;
-
- spin_lock(&hw->alloc_lock);
-
- /* check for ccbs which have data */
- pending = get_device_outbound(hw);
- if (!pending) {
- spin_unlock(&hw->alloc_lock);
- return IRQ_NONE;
- }
-
- if (is_db_reset(pending)) {
- /* wake up all ccbs if the device was reset */
- pending = -1;
- ilo_set_reset(hw);
- }
-
- for (i = 0; i < MAX_CCB; i++) {
- if (!hw->ccb_alloc[i])
- continue;
- if (pending & (1 << i))
- wake_up_interruptible(&hw->ccb_alloc[i]->ccb_waitq);
- }
-
- /* clear the device of the channels that have been handled */
- clear_pending_db(hw, pending);
-
- spin_unlock(&hw->alloc_lock);
-
- return IRQ_HANDLED;
-}
-
-static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
-{
- pci_iounmap(pdev, hw->db_vaddr);
- pci_iounmap(pdev, hw->ram_vaddr);
- pci_iounmap(pdev, hw->mmio_vaddr);
-}
-
-static int __devinit ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
-{
- int error = -ENOMEM;
-
- /* map the memory mapped i/o registers */
- hw->mmio_vaddr = pci_iomap(pdev, 1, 0);
- if (hw->mmio_vaddr == NULL) {
- dev_err(&pdev->dev, "Error mapping mmio\n");
- goto out;
- }
-
- /* map the adapter shared memory region */
- hw->ram_vaddr = pci_iomap(pdev, 2, MAX_CCB * ILOHW_CCB_SZ);
- if (hw->ram_vaddr == NULL) {
- dev_err(&pdev->dev, "Error mapping shared mem\n");
- goto mmio_free;
- }
-
- /* map the doorbell aperture */
- hw->db_vaddr = pci_iomap(pdev, 3, MAX_CCB * ONE_DB_SIZE);
- if (hw->db_vaddr == NULL) {
- dev_err(&pdev->dev, "Error mapping doorbell\n");
- goto ram_free;
- }
-
- return 0;
-ram_free:
- pci_iounmap(pdev, hw->ram_vaddr);
-mmio_free:
- pci_iounmap(pdev, hw->mmio_vaddr);
-out:
- return error;
-}
-
-static void ilo_remove(struct pci_dev *pdev)
-{
- int i, minor;
- struct ilo_hwinfo *ilo_hw = pci_get_drvdata(pdev);
-
- clear_device(ilo_hw);
-
- minor = MINOR(ilo_hw->cdev.dev);
- for (i = minor; i < minor + MAX_CCB; i++)
- device_destroy(ilo_class, MKDEV(ilo_major, i));
-
- cdev_del(&ilo_hw->cdev);
- ilo_disable_interrupts(ilo_hw);
- free_irq(pdev->irq, ilo_hw);
- ilo_unmap_device(pdev, ilo_hw);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- kfree(ilo_hw);
- ilo_hwdev[(minor / MAX_CCB)] = 0;
-}
-
-static int __devinit ilo_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- int devnum, minor, start, error;
- struct ilo_hwinfo *ilo_hw;
-
- /* find a free range for device files */
- for (devnum = 0; devnum < MAX_ILO_DEV; devnum++) {
- if (ilo_hwdev[devnum] == 0) {
- ilo_hwdev[devnum] = 1;
- break;
- }
- }
-
- if (devnum == MAX_ILO_DEV) {
- dev_err(&pdev->dev, "Error finding free device\n");
- return -ENODEV;
- }
-
- /* track global allocations for this device */
- error = -ENOMEM;
- ilo_hw = kzalloc(sizeof(*ilo_hw), GFP_KERNEL);
- if (!ilo_hw)
- goto out;
-
- ilo_hw->ilo_dev = pdev;
- spin_lock_init(&ilo_hw->alloc_lock);
- spin_lock_init(&ilo_hw->fifo_lock);
- spin_lock_init(&ilo_hw->open_lock);
-
- error = pci_enable_device(pdev);
- if (error)
- goto free;
-
- pci_set_master(pdev);
-
- error = pci_request_regions(pdev, ILO_NAME);
- if (error)
- goto disable;
-
- error = ilo_map_device(pdev, ilo_hw);
- if (error)
- goto free_regions;
-
- pci_set_drvdata(pdev, ilo_hw);
- clear_device(ilo_hw);
-
- error = request_irq(pdev->irq, ilo_isr, IRQF_SHARED, "hpilo", ilo_hw);
- if (error)
- goto unmap;
-
- ilo_enable_interrupts(ilo_hw);
-
- cdev_init(&ilo_hw->cdev, &ilo_fops);
- ilo_hw->cdev.owner = THIS_MODULE;
- start = devnum * MAX_CCB;
- error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), MAX_CCB);
- if (error) {
- dev_err(&pdev->dev, "Could not add cdev\n");
- goto remove_isr;
- }
-
- for (minor = 0 ; minor < MAX_CCB; minor++) {
- struct device *dev;
- dev = device_create(ilo_class, &pdev->dev,
- MKDEV(ilo_major, minor), NULL,
- "hpilo!d%dccb%d", devnum, minor);
- if (IS_ERR(dev))
- dev_err(&pdev->dev, "Could not create files\n");
- }
-
- return 0;
-remove_isr:
- ilo_disable_interrupts(ilo_hw);
- free_irq(pdev->irq, ilo_hw);
-unmap:
- ilo_unmap_device(pdev, ilo_hw);
-free_regions:
- pci_release_regions(pdev);
-disable:
- pci_disable_device(pdev);
-free:
- kfree(ilo_hw);
-out:
- ilo_hwdev[devnum] = 0;
- return error;
-}
-
-static struct pci_device_id ilo_devices[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) },
- { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3307) },
- { }
-};
-MODULE_DEVICE_TABLE(pci, ilo_devices);
-
-static struct pci_driver ilo_driver = {
- .name = ILO_NAME,
- .id_table = ilo_devices,
- .probe = ilo_probe,
- .remove = __devexit_p(ilo_remove),
-};
-
-static int __init ilo_init(void)
-{
- int error;
- dev_t dev;
-
- ilo_class = class_create(THIS_MODULE, "iLO");
- if (IS_ERR(ilo_class)) {
- error = PTR_ERR(ilo_class);
- goto out;
- }
-
- error = alloc_chrdev_region(&dev, 0, MAX_OPEN, ILO_NAME);
- if (error)
- goto class_destroy;
-
- ilo_major = MAJOR(dev);
-
- error = pci_register_driver(&ilo_driver);
- if (error)
- goto chr_remove;
-
- return 0;
-chr_remove:
- unregister_chrdev_region(dev, MAX_OPEN);
-class_destroy:
- class_destroy(ilo_class);
-out:
- return error;
-}
-
-static void __exit ilo_exit(void)
-{
- pci_unregister_driver(&ilo_driver);
- unregister_chrdev_region(MKDEV(ilo_major, 0), MAX_OPEN);
- class_destroy(ilo_class);
-}
-
-MODULE_VERSION("1.2");
-MODULE_ALIAS(ILO_NAME);
-MODULE_DESCRIPTION(ILO_NAME);
-MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
-MODULE_LICENSE("GPL v2");
-
-module_init(ilo_init);
-module_exit(ilo_exit);
diff --git a/ANDROID_3.4.5/drivers/misc/hpilo.h b/ANDROID_3.4.5/drivers/misc/hpilo.h
deleted file mode 100644
index 54e43adb..00000000
--- a/ANDROID_3.4.5/drivers/misc/hpilo.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * linux/drivers/char/hpilo.h
- *
- * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
- * David Altobelli <david.altobelli@hp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __HPILO_H
-#define __HPILO_H
-
-#define ILO_NAME "hpilo"
-
-/* max number of open channel control blocks per device, hw limited to 32 */
-#define MAX_CCB 8
-/* max number of supported devices */
-#define MAX_ILO_DEV 1
-/* max number of files */
-#define MAX_OPEN (MAX_CCB * MAX_ILO_DEV)
-/* total wait time in usec */
-#define MAX_WAIT_TIME 10000
-/* per spin wait time in usec */
-#define WAIT_TIME 10
-/* spin counter for open/close delay */
-#define MAX_WAIT (MAX_WAIT_TIME / WAIT_TIME)
-
-/*
- * Per device, used to track global memory allocations.
- */
-struct ilo_hwinfo {
- /* mmio registers on device */
- char __iomem *mmio_vaddr;
-
- /* doorbell registers on device */
- char __iomem *db_vaddr;
-
- /* shared memory on device used for channel control blocks */
- char __iomem *ram_vaddr;
-
- /* files corresponding to this device */
- struct ccb_data *ccb_alloc[MAX_CCB];
-
- struct pci_dev *ilo_dev;
-
- /*
- * open_lock serializes ccb_cnt during open and close
- * [ irq disabled ]
- * -> alloc_lock used when adding/removing/searching ccb_alloc,
- * which represents all ccbs open on the device
- * --> fifo_lock controls access to fifo queues shared with hw
- *
- * Locks must be taken in this order, but open_lock and alloc_lock
- * are optional, they do not need to be held in order to take a
- * lower level lock.
- */
- spinlock_t open_lock;
- spinlock_t alloc_lock;
- spinlock_t fifo_lock;
-
- struct cdev cdev;
-};
-
-/* offset from mmio_vaddr for enabling doorbell interrupts */
-#define DB_IRQ 0xB2
-/* offset from mmio_vaddr for outbound communications */
-#define DB_OUT 0xD4
-/* DB_OUT reset bit */
-#define DB_RESET 26
-
-/*
- * Channel control block. Used to manage hardware queues.
- * The format must match hw's version. The hw ccb is 128 bytes,
- * but the context area shouldn't be touched by the driver.
- */
-#define ILOSW_CCB_SZ 64
-#define ILOHW_CCB_SZ 128
-struct ccb {
- union {
- char *send_fifobar;
- u64 send_fifobar_pa;
- } ccb_u1;
- union {
- char *send_desc;
- u64 send_desc_pa;
- } ccb_u2;
- u64 send_ctrl;
-
- union {
- char *recv_fifobar;
- u64 recv_fifobar_pa;
- } ccb_u3;
- union {
- char *recv_desc;
- u64 recv_desc_pa;
- } ccb_u4;
- u64 recv_ctrl;
-
- union {
- char __iomem *db_base;
- u64 padding5;
- } ccb_u5;
-
- u64 channel;
-
- /* unused context area (64 bytes) */
-};
-
-/* ccb queue parameters */
-#define SENDQ 1
-#define RECVQ 2
-#define NR_QENTRY 4
-#define L2_QENTRY_SZ 12
-
-/* ccb ctrl bitfields */
-#define CTRL_BITPOS_L2SZ 0
-#define CTRL_BITPOS_FIFOINDEXMASK 4
-#define CTRL_BITPOS_DESCLIMIT 18
-#define CTRL_BITPOS_A 30
-#define CTRL_BITPOS_G 31
-
-/* ccb doorbell macros */
-#define L2_DB_SIZE 14
-#define ONE_DB_SIZE (1 << L2_DB_SIZE)
-
-/*
- * Per fd structure used to track the ccb allocated to that dev file.
- */
-struct ccb_data {
- /* software version of ccb, using virtual addrs */
- struct ccb driver_ccb;
-
- /* hardware version of ccb, using physical addrs */
- struct ccb ilo_ccb;
-
- /* hardware ccb is written to this shared mapped device memory */
- struct ccb __iomem *mapped_ccb;
-
- /* dma'able memory used for send/recv queues */
- void *dma_va;
- dma_addr_t dma_pa;
- size_t dma_size;
-
- /* pointer to hardware device info */
- struct ilo_hwinfo *ilo_hw;
-
- /* queue for this ccb to wait for recv data */
- wait_queue_head_t ccb_waitq;
-
- /* usage count, to allow for shared ccb's */
- int ccb_cnt;
-
- /* open wanted exclusive access to this ccb */
- int ccb_excl;
-};
-
-/*
- * FIFO queue structure, shared with hw.
- */
-#define ILO_START_ALIGN 4096
-#define ILO_CACHE_SZ 128
-struct fifo {
- u64 nrents; /* user requested number of fifo entries */
- u64 imask; /* mask to extract valid fifo index */
- u64 merge; /* O/C bits to merge in during enqueue operation */
- u64 reset; /* set to non-zero when the target device resets */
- u8 pad_0[ILO_CACHE_SZ - (sizeof(u64) * 4)];
-
- u64 head;
- u8 pad_1[ILO_CACHE_SZ - (sizeof(u64))];
-
- u64 tail;
- u8 pad_2[ILO_CACHE_SZ - (sizeof(u64))];
-
- u64 fifobar[1];
-};
-
-/* convert between struct fifo, and the fifobar, which is saved in the ccb */
-#define FIFOHANDLESIZE (sizeof(struct fifo) - sizeof(u64))
-#define FIFOBARTOHANDLE(_fifo) \
- ((struct fifo *)(((char *)(_fifo)) - FIFOHANDLESIZE))
-
-/* the number of qwords to consume from the entry descriptor */
-#define ENTRY_BITPOS_QWORDS 0
-/* descriptor index number (within a specified queue) */
-#define ENTRY_BITPOS_DESCRIPTOR 10
-/* state bit, fifo entry consumed by consumer */
-#define ENTRY_BITPOS_C 22
-/* state bit, fifo entry is occupied */
-#define ENTRY_BITPOS_O 23
-
-#define ENTRY_BITS_QWORDS 10
-#define ENTRY_BITS_DESCRIPTOR 12
-#define ENTRY_BITS_C 1
-#define ENTRY_BITS_O 1
-#define ENTRY_BITS_TOTAL \
- (ENTRY_BITS_C + ENTRY_BITS_O + \
- ENTRY_BITS_QWORDS + ENTRY_BITS_DESCRIPTOR)
-
-/* extract various entry fields */
-#define ENTRY_MASK ((1 << ENTRY_BITS_TOTAL) - 1)
-#define ENTRY_MASK_C (((1 << ENTRY_BITS_C) - 1) << ENTRY_BITPOS_C)
-#define ENTRY_MASK_O (((1 << ENTRY_BITS_O) - 1) << ENTRY_BITPOS_O)
-#define ENTRY_MASK_QWORDS \
- (((1 << ENTRY_BITS_QWORDS) - 1) << ENTRY_BITPOS_QWORDS)
-#define ENTRY_MASK_DESCRIPTOR \
- (((1 << ENTRY_BITS_DESCRIPTOR) - 1) << ENTRY_BITPOS_DESCRIPTOR)
-
-#define ENTRY_MASK_NOSTATE (ENTRY_MASK >> (ENTRY_BITS_C + ENTRY_BITS_O))
-
-#endif /* __HPILO_H */
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/Makefile b/ANDROID_3.4.5/drivers/misc/ibmasm/Makefile
deleted file mode 100644
index 9e63ade5..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-
-obj-$(CONFIG_IBM_ASM) := ibmasm.o
-
-ibmasm-y := module.o \
- ibmasmfs.o \
- event.o \
- command.o \
- remote.o \
- heartbeat.o \
- r_heartbeat.o \
- dot_command.o \
- lowlevel.o
-
-ibmasm-$(CONFIG_SERIAL_8250) += uart.o
-
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/command.c b/ANDROID_3.4.5/drivers/misc/ibmasm/command.c
deleted file mode 100644
index 7d56f45d..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/command.c
+++ /dev/null
@@ -1,187 +0,0 @@
-
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include "ibmasm.h"
-#include "lowlevel.h"
-
-static void exec_next_command(struct service_processor *sp);
-
-static atomic_t command_count = ATOMIC_INIT(0);
-
-struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size)
-{
- struct command *cmd;
-
- if (buffer_size > IBMASM_CMD_MAX_BUFFER_SIZE)
- return NULL;
-
- cmd = kzalloc(sizeof(struct command), GFP_KERNEL);
- if (cmd == NULL)
- return NULL;
-
-
- cmd->buffer = kzalloc(buffer_size, GFP_KERNEL);
- if (cmd->buffer == NULL) {
- kfree(cmd);
- return NULL;
- }
- cmd->buffer_size = buffer_size;
-
- kref_init(&cmd->kref);
- cmd->lock = &sp->lock;
-
- cmd->status = IBMASM_CMD_PENDING;
- init_waitqueue_head(&cmd->wait);
- INIT_LIST_HEAD(&cmd->queue_node);
-
- atomic_inc(&command_count);
- dbg("command count: %d\n", atomic_read(&command_count));
-
- return cmd;
-}
-
-void ibmasm_free_command(struct kref *kref)
-{
- struct command *cmd = to_command(kref);
-
- list_del(&cmd->queue_node);
- atomic_dec(&command_count);
- dbg("command count: %d\n", atomic_read(&command_count));
- kfree(cmd->buffer);
- kfree(cmd);
-}
-
-static void enqueue_command(struct service_processor *sp, struct command *cmd)
-{
- list_add_tail(&cmd->queue_node, &sp->command_queue);
-}
-
-static struct command *dequeue_command(struct service_processor *sp)
-{
- struct command *cmd;
- struct list_head *next;
-
- if (list_empty(&sp->command_queue))
- return NULL;
-
- next = sp->command_queue.next;
- list_del_init(next);
- cmd = list_entry(next, struct command, queue_node);
-
- return cmd;
-}
-
-static inline void do_exec_command(struct service_processor *sp)
-{
- char tsbuf[32];
-
- dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf));
-
- if (ibmasm_send_i2o_message(sp)) {
- sp->current_command->status = IBMASM_CMD_FAILED;
- wake_up(&sp->current_command->wait);
- command_put(sp->current_command);
- exec_next_command(sp);
- }
-}
-
-/**
- * exec_command
- * send a command to a service processor
- * Commands are executed sequentially. One command (sp->current_command)
- * is sent to the service processor. Once the interrupt handler gets a
- * message of type command_response, the message is copied into
- * the current commands buffer,
- */
-void ibmasm_exec_command(struct service_processor *sp, struct command *cmd)
-{
- unsigned long flags;
- char tsbuf[32];
-
- dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf));
-
- spin_lock_irqsave(&sp->lock, flags);
-
- if (!sp->current_command) {
- sp->current_command = cmd;
- command_get(sp->current_command);
- spin_unlock_irqrestore(&sp->lock, flags);
- do_exec_command(sp);
- } else {
- enqueue_command(sp, cmd);
- spin_unlock_irqrestore(&sp->lock, flags);
- }
-}
-
-static void exec_next_command(struct service_processor *sp)
-{
- unsigned long flags;
- char tsbuf[32];
-
- dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf));
-
- spin_lock_irqsave(&sp->lock, flags);
- sp->current_command = dequeue_command(sp);
- if (sp->current_command) {
- command_get(sp->current_command);
- spin_unlock_irqrestore(&sp->lock, flags);
- do_exec_command(sp);
- } else {
- spin_unlock_irqrestore(&sp->lock, flags);
- }
-}
-
-/**
- * Sleep until a command has failed or a response has been received
- * and the command status been updated by the interrupt handler.
- * (see receive_response).
- */
-void ibmasm_wait_for_response(struct command *cmd, int timeout)
-{
- wait_event_interruptible_timeout(cmd->wait,
- cmd->status == IBMASM_CMD_COMPLETE ||
- cmd->status == IBMASM_CMD_FAILED,
- timeout * HZ);
-}
-
-/**
- * receive_command_response
- * called by the interrupt handler when a dot command of type command_response
- * was received.
- */
-void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size)
-{
- struct command *cmd = sp->current_command;
-
- if (!sp->current_command)
- return;
-
- memcpy_fromio(cmd->buffer, response, min(size, cmd->buffer_size));
- cmd->status = IBMASM_CMD_COMPLETE;
- wake_up(&sp->current_command->wait);
- command_put(sp->current_command);
- exec_next_command(sp);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/dot_command.c b/ANDROID_3.4.5/drivers/misc/ibmasm/dot_command.c
deleted file mode 100644
index d7b2ca35..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/dot_command.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#include "ibmasm.h"
-#include "dot_command.h"
-
-/**
- * Dispatch an incoming message to the specific handler for the message.
- * Called from interrupt context.
- */
-void ibmasm_receive_message(struct service_processor *sp, void *message, int message_size)
-{
- u32 size;
- struct dot_command_header *header = (struct dot_command_header *)message;
-
- if (message_size == 0)
- return;
-
- size = get_dot_command_size(message);
- if (size == 0)
- return;
-
- if (size > message_size)
- size = message_size;
-
- switch (header->type) {
- case sp_event:
- ibmasm_receive_event(sp, message, size);
- break;
- case sp_command_response:
- ibmasm_receive_command_response(sp, message, size);
- break;
- case sp_heartbeat:
- ibmasm_receive_heartbeat(sp, message, size);
- break;
- default:
- dev_err(sp->dev, "Received unknown message from service processor\n");
- }
-}
-
-
-#define INIT_BUFFER_SIZE 32
-
-
-/**
- * send the 4.3.5.10 dot command (driver VPD) to the service processor
- */
-int ibmasm_send_driver_vpd(struct service_processor *sp)
-{
- struct command *command;
- struct dot_command_header *header;
- u8 *vpd_command;
- u8 *vpd_data;
- int result = 0;
-
- command = ibmasm_new_command(sp, INIT_BUFFER_SIZE);
- if (command == NULL)
- return -ENOMEM;
-
- header = (struct dot_command_header *)command->buffer;
- header->type = sp_write;
- header->command_size = 4;
- header->data_size = 16;
- header->status = 0;
- header->reserved = 0;
-
- vpd_command = command->buffer + sizeof(struct dot_command_header);
- vpd_command[0] = 0x4;
- vpd_command[1] = 0x3;
- vpd_command[2] = 0x5;
- vpd_command[3] = 0xa;
-
- vpd_data = vpd_command + header->command_size;
- vpd_data[0] = 0;
- strcat(vpd_data, IBMASM_DRIVER_VPD);
- vpd_data[10] = 0;
- vpd_data[15] = 0;
-
- ibmasm_exec_command(sp, command);
- ibmasm_wait_for_response(command, IBMASM_CMD_TIMEOUT_NORMAL);
-
- if (command->status != IBMASM_CMD_COMPLETE)
- result = -ENODEV;
-
- command_put(command);
-
- return result;
-}
-
-struct os_state_command {
- struct dot_command_header header;
- unsigned char command[3];
- unsigned char data;
-};
-
-/**
- * send the 4.3.6 dot command (os state) to the service processor
- * During driver init this function is called with os state "up".
- * This causes the service processor to start sending heartbeats the
- * driver.
- * During driver exit the function is called with os state "down",
- * causing the service processor to stop the heartbeats.
- */
-int ibmasm_send_os_state(struct service_processor *sp, int os_state)
-{
- struct command *cmd;
- struct os_state_command *os_state_cmd;
- int result = 0;
-
- cmd = ibmasm_new_command(sp, sizeof(struct os_state_command));
- if (cmd == NULL)
- return -ENOMEM;
-
- os_state_cmd = (struct os_state_command *)cmd->buffer;
- os_state_cmd->header.type = sp_write;
- os_state_cmd->header.command_size = 3;
- os_state_cmd->header.data_size = 1;
- os_state_cmd->header.status = 0;
- os_state_cmd->command[0] = 4;
- os_state_cmd->command[1] = 3;
- os_state_cmd->command[2] = 6;
- os_state_cmd->data = os_state;
-
- ibmasm_exec_command(sp, cmd);
- ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
-
- if (cmd->status != IBMASM_CMD_COMPLETE)
- result = -ENODEV;
-
- command_put(cmd);
- return result;
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/dot_command.h b/ANDROID_3.4.5/drivers/misc/ibmasm/dot_command.h
deleted file mode 100644
index fc9fc9d4..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/dot_command.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#ifndef __DOT_COMMAND_H__
-#define __DOT_COMMAND_H__
-
-/*
- * dot commands are the protocol used to communicate with the service
- * processor.
- * They consist of header, a command of variable length and data of
- * variable length.
- */
-
-/* dot command types */
-#define sp_write 0
-#define sp_write_next 1
-#define sp_read 2
-#define sp_read_next 3
-#define sp_command_response 4
-#define sp_event 5
-#define sp_heartbeat 6
-
-#pragma pack(1)
-struct dot_command_header {
- u8 type;
- u8 command_size;
- u16 data_size;
- u8 status;
- u8 reserved;
-};
-#pragma pack()
-
-static inline size_t get_dot_command_size(void *buffer)
-{
- struct dot_command_header *cmd = (struct dot_command_header *)buffer;
- return sizeof(struct dot_command_header) + cmd->command_size + cmd->data_size;
-}
-
-static inline unsigned int get_dot_command_timeout(void *buffer)
-{
- struct dot_command_header *header = (struct dot_command_header *)buffer;
- unsigned char *cmd = buffer + sizeof(struct dot_command_header);
-
- /* dot commands 6.3.1, 7.1 and 8.x need a longer timeout */
-
- if (header->command_size == 3) {
- if ((cmd[0] == 6) && (cmd[1] == 3) && (cmd[2] == 1))
- return IBMASM_CMD_TIMEOUT_EXTRA;
- } else if (header->command_size == 2) {
- if ((cmd[0] == 7) && (cmd[1] == 1))
- return IBMASM_CMD_TIMEOUT_EXTRA;
- if (cmd[0] == 8)
- return IBMASM_CMD_TIMEOUT_EXTRA;
- }
- return IBMASM_CMD_TIMEOUT_NORMAL;
-}
-
-#endif /* __DOT_COMMAND_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/event.c b/ANDROID_3.4.5/drivers/misc/ibmasm/event.c
deleted file mode 100644
index 8e540f4e..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/event.c
+++ /dev/null
@@ -1,177 +0,0 @@
-
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include "ibmasm.h"
-#include "lowlevel.h"
-
-/*
- * ASM service processor event handling routines.
- *
- * Events are signalled to the device drivers through interrupts.
- * They have the format of dot commands, with the type field set to
- * sp_event.
- * The driver does not interpret the events, it simply stores them in a
- * circular buffer.
- */
-
-static void wake_up_event_readers(struct service_processor *sp)
-{
- struct event_reader *reader;
-
- list_for_each_entry(reader, &sp->event_buffer->readers, node)
- wake_up_interruptible(&reader->wait);
-}
-
-/**
- * receive_event
- * Called by the interrupt handler when a dot command of type sp_event is
- * received.
- * Store the event in the circular event buffer, wake up any sleeping
- * event readers.
- * There is no reader marker in the buffer, therefore readers are
- * responsible for keeping up with the writer, or they will lose events.
- */
-void ibmasm_receive_event(struct service_processor *sp, void *data, unsigned int data_size)
-{
- struct event_buffer *buffer = sp->event_buffer;
- struct ibmasm_event *event;
- unsigned long flags;
-
- data_size = min(data_size, IBMASM_EVENT_MAX_SIZE);
-
- spin_lock_irqsave(&sp->lock, flags);
- /* copy the event into the next slot in the circular buffer */
- event = &buffer->events[buffer->next_index];
- memcpy_fromio(event->data, data, data_size);
- event->data_size = data_size;
- event->serial_number = buffer->next_serial_number;
-
- /* advance indices in the buffer */
- buffer->next_index = (buffer->next_index + 1) % IBMASM_NUM_EVENTS;
- buffer->next_serial_number++;
- spin_unlock_irqrestore(&sp->lock, flags);
-
- wake_up_event_readers(sp);
-}
-
-static inline int event_available(struct event_buffer *b, struct event_reader *r)
-{
- return (r->next_serial_number < b->next_serial_number);
-}
-
-/**
- * get_next_event
- * Called by event readers (initiated from user space through the file
- * system).
- * Sleeps until a new event is available.
- */
-int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader)
-{
- struct event_buffer *buffer = sp->event_buffer;
- struct ibmasm_event *event;
- unsigned int index;
- unsigned long flags;
-
- reader->cancelled = 0;
-
- if (wait_event_interruptible(reader->wait,
- event_available(buffer, reader) || reader->cancelled))
- return -ERESTARTSYS;
-
- if (!event_available(buffer, reader))
- return 0;
-
- spin_lock_irqsave(&sp->lock, flags);
-
- index = buffer->next_index;
- event = &buffer->events[index];
- while (event->serial_number < reader->next_serial_number) {
- index = (index + 1) % IBMASM_NUM_EVENTS;
- event = &buffer->events[index];
- }
- memcpy(reader->data, event->data, event->data_size);
- reader->data_size = event->data_size;
- reader->next_serial_number = event->serial_number + 1;
-
- spin_unlock_irqrestore(&sp->lock, flags);
-
- return event->data_size;
-}
-
-void ibmasm_cancel_next_event(struct event_reader *reader)
-{
- reader->cancelled = 1;
- wake_up_interruptible(&reader->wait);
-}
-
-void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader)
-{
- unsigned long flags;
-
- reader->next_serial_number = sp->event_buffer->next_serial_number;
- init_waitqueue_head(&reader->wait);
- spin_lock_irqsave(&sp->lock, flags);
- list_add(&reader->node, &sp->event_buffer->readers);
- spin_unlock_irqrestore(&sp->lock, flags);
-}
-
-void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&sp->lock, flags);
- list_del(&reader->node);
- spin_unlock_irqrestore(&sp->lock, flags);
-}
-
-int ibmasm_event_buffer_init(struct service_processor *sp)
-{
- struct event_buffer *buffer;
- struct ibmasm_event *event;
- int i;
-
- buffer = kmalloc(sizeof(struct event_buffer), GFP_KERNEL);
- if (!buffer)
- return 1;
-
- buffer->next_index = 0;
- buffer->next_serial_number = 1;
-
- event = buffer->events;
- for (i=0; i<IBMASM_NUM_EVENTS; i++, event++)
- event->serial_number = 0;
-
- INIT_LIST_HEAD(&buffer->readers);
-
- sp->event_buffer = buffer;
-
- return 0;
-}
-
-void ibmasm_event_buffer_exit(struct service_processor *sp)
-{
- kfree(sp->event_buffer);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/heartbeat.c b/ANDROID_3.4.5/drivers/misc/ibmasm/heartbeat.c
deleted file mode 100644
index 90746378..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/heartbeat.c
+++ /dev/null
@@ -1,101 +0,0 @@
-
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#include <linux/notifier.h>
-#include "ibmasm.h"
-#include "dot_command.h"
-#include "lowlevel.h"
-
-static int suspend_heartbeats = 0;
-
-/*
- * Once the driver indicates to the service processor that it is running
- * - see send_os_state() - the service processor sends periodic heartbeats
- * to the driver. The driver must respond to the heartbeats or else the OS
- * will be rebooted.
- * In the case of a panic the interrupt handler continues to work and thus
- * continues to respond to heartbeats, making the service processor believe
- * the OS is still running and thus preventing a reboot.
- * To prevent this from happening a callback is added the panic_notifier_list.
- * Before responding to a heartbeat the driver checks if a panic has happened,
- * if yes it suspends heartbeat, causing the service processor to reboot as
- * expected.
- */
-static int panic_happened(struct notifier_block *n, unsigned long val, void *v)
-{
- suspend_heartbeats = 1;
- return 0;
-}
-
-static struct notifier_block panic_notifier = { panic_happened, NULL, 1 };
-
-void ibmasm_register_panic_notifier(void)
-{
- atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier);
-}
-
-void ibmasm_unregister_panic_notifier(void)
-{
- atomic_notifier_chain_unregister(&panic_notifier_list,
- &panic_notifier);
-}
-
-
-int ibmasm_heartbeat_init(struct service_processor *sp)
-{
- sp->heartbeat = ibmasm_new_command(sp, HEARTBEAT_BUFFER_SIZE);
- if (sp->heartbeat == NULL)
- return -ENOMEM;
-
- return 0;
-}
-
-void ibmasm_heartbeat_exit(struct service_processor *sp)
-{
- char tsbuf[32];
-
- dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf));
- ibmasm_wait_for_response(sp->heartbeat, IBMASM_CMD_TIMEOUT_NORMAL);
- dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf));
- suspend_heartbeats = 1;
- command_put(sp->heartbeat);
-}
-
-void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size_t size)
-{
- struct command *cmd = sp->heartbeat;
- struct dot_command_header *header = (struct dot_command_header *)cmd->buffer;
- char tsbuf[32];
-
- dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf));
- if (suspend_heartbeats)
- return;
-
- /* return the received dot command to sender */
- cmd->status = IBMASM_CMD_PENDING;
- size = min(size, cmd->buffer_size);
- memcpy_fromio(cmd->buffer, message, size);
- header->type = sp_write;
- ibmasm_exec_command(sp, cmd);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/i2o.h b/ANDROID_3.4.5/drivers/misc/ibmasm/i2o.h
deleted file mode 100644
index 2e9566da..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/i2o.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#pragma pack(1)
-struct i2o_header {
- u8 version;
- u8 message_flags;
- u16 message_size;
- u8 target;
- u8 initiator_and_target;
- u8 initiator;
- u8 function;
- u32 initiator_context;
-};
-#pragma pack()
-
-#define I2O_HEADER_TEMPLATE \
- { .version = 0x01, \
- .message_flags = 0x00, \
- .function = 0xFF, \
- .initiator = 0x00, \
- .initiator_and_target = 0x40, \
- .target = 0x00, \
- .initiator_context = 0x0 }
-
-#define I2O_MESSAGE_SIZE 0x1000
-#define I2O_COMMAND_SIZE (I2O_MESSAGE_SIZE - sizeof(struct i2o_header))
-
-#pragma pack(1)
-struct i2o_message {
- struct i2o_header header;
- void *data;
-};
-#pragma pack()
-
-static inline unsigned short outgoing_message_size(unsigned int data_size)
-{
- unsigned int size;
- unsigned short i2o_size;
-
- if (data_size > I2O_COMMAND_SIZE)
- data_size = I2O_COMMAND_SIZE;
-
- size = sizeof(struct i2o_header) + data_size;
-
- i2o_size = size / sizeof(u32);
-
- if (size % sizeof(u32))
- i2o_size++;
-
- return i2o_size;
-}
-
-static inline u32 incoming_data_size(struct i2o_message *i2o_message)
-{
- return (sizeof(u32) * i2o_message->header.message_size);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/ibmasm.h b/ANDROID_3.4.5/drivers/misc/ibmasm/ibmasm.h
deleted file mode 100644
index 9b083448..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/ibmasm.h
+++ /dev/null
@@ -1,220 +0,0 @@
-
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/list.h>
-#include <linux/wait.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/kref.h>
-#include <linux/device.h>
-#include <linux/input.h>
-
-/* Driver identification */
-#define DRIVER_NAME "ibmasm"
-#define DRIVER_VERSION "1.0"
-#define DRIVER_AUTHOR "Max Asbock <masbock@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"
-#define DRIVER_DESC "IBM ASM Service Processor Driver"
-
-#define err(msg) printk(KERN_ERR "%s: " msg "\n", DRIVER_NAME)
-#define info(msg) printk(KERN_INFO "%s: " msg "\n", DRIVER_NAME)
-
-extern int ibmasm_debug;
-#define dbg(STR, ARGS...) \
- do { \
- if (ibmasm_debug) \
- printk(KERN_DEBUG STR , ##ARGS); \
- } while (0)
-
-static inline char *get_timestamp(char *buf)
-{
- struct timeval now;
- do_gettimeofday(&now);
- sprintf(buf, "%lu.%lu", now.tv_sec, now.tv_usec);
- return buf;
-}
-
-#define IBMASM_CMD_PENDING 0
-#define IBMASM_CMD_COMPLETE 1
-#define IBMASM_CMD_FAILED 2
-
-#define IBMASM_CMD_TIMEOUT_NORMAL 45
-#define IBMASM_CMD_TIMEOUT_EXTRA 240
-
-#define IBMASM_CMD_MAX_BUFFER_SIZE 0x8000
-
-#define REVERSE_HEARTBEAT_TIMEOUT 120
-
-#define HEARTBEAT_BUFFER_SIZE 0x400
-
-#ifdef IA64
-#define IBMASM_DRIVER_VPD "Lin64 6.08 "
-#else
-#define IBMASM_DRIVER_VPD "Lin32 6.08 "
-#endif
-
-#define SYSTEM_STATE_OS_UP 5
-#define SYSTEM_STATE_OS_DOWN 4
-
-#define IBMASM_NAME_SIZE 16
-
-#define IBMASM_NUM_EVENTS 10
-#define IBMASM_EVENT_MAX_SIZE 2048u
-
-
-struct command {
- struct list_head queue_node;
- wait_queue_head_t wait;
- unsigned char *buffer;
- size_t buffer_size;
- int status;
- struct kref kref;
- spinlock_t *lock;
-};
-#define to_command(c) container_of(c, struct command, kref)
-
-void ibmasm_free_command(struct kref *kref);
-static inline void command_put(struct command *cmd)
-{
- unsigned long flags;
- spinlock_t *lock = cmd->lock;
-
- spin_lock_irqsave(lock, flags);
- kref_put(&cmd->kref, ibmasm_free_command);
- spin_unlock_irqrestore(lock, flags);
-}
-
-static inline void command_get(struct command *cmd)
-{
- kref_get(&cmd->kref);
-}
-
-
-struct ibmasm_event {
- unsigned int serial_number;
- unsigned int data_size;
- unsigned char data[IBMASM_EVENT_MAX_SIZE];
-};
-
-struct event_buffer {
- struct ibmasm_event events[IBMASM_NUM_EVENTS];
- unsigned int next_serial_number;
- unsigned int next_index;
- struct list_head readers;
-};
-
-struct event_reader {
- int cancelled;
- unsigned int next_serial_number;
- wait_queue_head_t wait;
- struct list_head node;
- unsigned int data_size;
- unsigned char data[IBMASM_EVENT_MAX_SIZE];
-};
-
-struct reverse_heartbeat {
- wait_queue_head_t wait;
- unsigned int stopped;
-};
-
-struct ibmasm_remote {
- struct input_dev *keybd_dev;
- struct input_dev *mouse_dev;
-};
-
-struct service_processor {
- struct list_head node;
- spinlock_t lock;
- void __iomem *base_address;
- unsigned int irq;
- struct command *current_command;
- struct command *heartbeat;
- struct list_head command_queue;
- struct event_buffer *event_buffer;
- char dirname[IBMASM_NAME_SIZE];
- char devname[IBMASM_NAME_SIZE];
- unsigned int number;
- struct ibmasm_remote remote;
- int serial_line;
- struct device *dev;
-};
-
-/* command processing */
-struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_size);
-void ibmasm_exec_command(struct service_processor *sp, struct command *cmd);
-void ibmasm_wait_for_response(struct command *cmd, int timeout);
-void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size);
-
-/* event processing */
-int ibmasm_event_buffer_init(struct service_processor *sp);
-void ibmasm_event_buffer_exit(struct service_processor *sp);
-void ibmasm_receive_event(struct service_processor *sp, void *data, unsigned int data_size);
-void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader);
-void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader);
-int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader);
-void ibmasm_cancel_next_event(struct event_reader *reader);
-
-/* heartbeat - from SP to OS */
-void ibmasm_register_panic_notifier(void);
-void ibmasm_unregister_panic_notifier(void);
-int ibmasm_heartbeat_init(struct service_processor *sp);
-void ibmasm_heartbeat_exit(struct service_processor *sp);
-void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size_t size);
-
-/* reverse heartbeat - from OS to SP */
-void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb);
-int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb);
-void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb);
-
-/* dot commands */
-void ibmasm_receive_message(struct service_processor *sp, void *data, int data_size);
-int ibmasm_send_driver_vpd(struct service_processor *sp);
-int ibmasm_send_os_state(struct service_processor *sp, int os_state);
-
-/* low level message processing */
-int ibmasm_send_i2o_message(struct service_processor *sp);
-irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id);
-
-/* remote console */
-void ibmasm_handle_mouse_interrupt(struct service_processor *sp);
-int ibmasm_init_remote_input_dev(struct service_processor *sp);
-void ibmasm_free_remote_input_dev(struct service_processor *sp);
-
-/* file system */
-int ibmasmfs_register(void);
-void ibmasmfs_unregister(void);
-void ibmasmfs_add_sp(struct service_processor *sp);
-
-/* uart */
-#ifdef CONFIG_SERIAL_8250
-void ibmasm_register_uart(struct service_processor *sp);
-void ibmasm_unregister_uart(struct service_processor *sp);
-#else
-#define ibmasm_register_uart(sp) do { } while(0)
-#define ibmasm_unregister_uart(sp) do { } while(0)
-#endif
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/ibmasmfs.c b/ANDROID_3.4.5/drivers/misc/ibmasm/ibmasmfs.c
deleted file mode 100644
index 6673e578..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/ibmasmfs.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-/*
- * Parts of this code are based on an article by Jonathan Corbet
- * that appeared in Linux Weekly News.
- */
-
-
-/*
- * The IBMASM file virtual filesystem. It creates the following hierarchy
- * dynamically when mounted from user space:
- *
- * /ibmasm
- * |-- 0
- * | |-- command
- * | |-- event
- * | |-- reverse_heartbeat
- * | `-- remote_video
- * | |-- depth
- * | |-- height
- * | `-- width
- * .
- * .
- * .
- * `-- n
- * |-- command
- * |-- event
- * |-- reverse_heartbeat
- * `-- remote_video
- * |-- depth
- * |-- height
- * `-- width
- *
- * For each service processor the following files are created:
- *
- * command: execute dot commands
- * write: execute a dot command on the service processor
- * read: return the result of a previously executed dot command
- *
- * events: listen for service processor events
- * read: sleep (interruptible) until an event occurs
- * write: wakeup sleeping event listener
- *
- * reverse_heartbeat: send a heartbeat to the service processor
- * read: sleep (interruptible) until the reverse heartbeat fails
- * write: wakeup sleeping heartbeat listener
- *
- * remote_video/width
- * remote_video/height
- * remote_video/width: control remote display settings
- * write: set value
- * read: read value
- */
-
-#include <linux/fs.h>
-#include <linux/pagemap.h>
-#include <linux/slab.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include "ibmasm.h"
-#include "remote.h"
-#include "dot_command.h"
-
-#define IBMASMFS_MAGIC 0x66726f67
-
-static LIST_HEAD(service_processors);
-
-static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode);
-static void ibmasmfs_create_files (struct super_block *sb);
-static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent);
-
-
-static struct dentry *ibmasmfs_mount(struct file_system_type *fst,
- int flags, const char *name, void *data)
-{
- return mount_single(fst, flags, data, ibmasmfs_fill_super);
-}
-
-static const struct super_operations ibmasmfs_s_ops = {
- .statfs = simple_statfs,
- .drop_inode = generic_delete_inode,
-};
-
-static const struct file_operations *ibmasmfs_dir_ops = &simple_dir_operations;
-
-static struct file_system_type ibmasmfs_type = {
- .owner = THIS_MODULE,
- .name = "ibmasmfs",
- .mount = ibmasmfs_mount,
- .kill_sb = kill_litter_super,
-};
-
-static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
-{
- struct inode *root;
-
- sb->s_blocksize = PAGE_CACHE_SIZE;
- sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
- sb->s_magic = IBMASMFS_MAGIC;
- sb->s_op = &ibmasmfs_s_ops;
- sb->s_time_gran = 1;
-
- root = ibmasmfs_make_inode (sb, S_IFDIR | 0500);
- if (!root)
- return -ENOMEM;
-
- root->i_op = &simple_dir_inode_operations;
- root->i_fop = ibmasmfs_dir_ops;
-
- sb->s_root = d_make_root(root);
- if (!sb->s_root)
- return -ENOMEM;
-
- ibmasmfs_create_files(sb);
- return 0;
-}
-
-static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode)
-{
- struct inode *ret = new_inode(sb);
-
- if (ret) {
- ret->i_ino = get_next_ino();
- ret->i_mode = mode;
- ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
- }
- return ret;
-}
-
-static struct dentry *ibmasmfs_create_file (struct super_block *sb,
- struct dentry *parent,
- const char *name,
- const struct file_operations *fops,
- void *data,
- int mode)
-{
- struct dentry *dentry;
- struct inode *inode;
-
- dentry = d_alloc_name(parent, name);
- if (!dentry)
- return NULL;
-
- inode = ibmasmfs_make_inode(sb, S_IFREG | mode);
- if (!inode) {
- dput(dentry);
- return NULL;
- }
-
- inode->i_fop = fops;
- inode->i_private = data;
-
- d_add(dentry, inode);
- return dentry;
-}
-
-static struct dentry *ibmasmfs_create_dir (struct super_block *sb,
- struct dentry *parent,
- const char *name)
-{
- struct dentry *dentry;
- struct inode *inode;
-
- dentry = d_alloc_name(parent, name);
- if (!dentry)
- return NULL;
-
- inode = ibmasmfs_make_inode(sb, S_IFDIR | 0500);
- if (!inode) {
- dput(dentry);
- return NULL;
- }
-
- inode->i_op = &simple_dir_inode_operations;
- inode->i_fop = ibmasmfs_dir_ops;
-
- d_add(dentry, inode);
- return dentry;
-}
-
-int ibmasmfs_register(void)
-{
- return register_filesystem(&ibmasmfs_type);
-}
-
-void ibmasmfs_unregister(void)
-{
- unregister_filesystem(&ibmasmfs_type);
-}
-
-void ibmasmfs_add_sp(struct service_processor *sp)
-{
- list_add(&sp->node, &service_processors);
-}
-
-/* struct to save state between command file operations */
-struct ibmasmfs_command_data {
- struct service_processor *sp;
- struct command *command;
-};
-
-/* struct to save state between event file operations */
-struct ibmasmfs_event_data {
- struct service_processor *sp;
- struct event_reader reader;
- int active;
-};
-
-/* struct to save state between reverse heartbeat file operations */
-struct ibmasmfs_heartbeat_data {
- struct service_processor *sp;
- struct reverse_heartbeat heartbeat;
- int active;
-};
-
-static int command_file_open(struct inode *inode, struct file *file)
-{
- struct ibmasmfs_command_data *command_data;
-
- if (!inode->i_private)
- return -ENODEV;
-
- command_data = kmalloc(sizeof(struct ibmasmfs_command_data), GFP_KERNEL);
- if (!command_data)
- return -ENOMEM;
-
- command_data->command = NULL;
- command_data->sp = inode->i_private;
- file->private_data = command_data;
- return 0;
-}
-
-static int command_file_close(struct inode *inode, struct file *file)
-{
- struct ibmasmfs_command_data *command_data = file->private_data;
-
- if (command_data->command)
- command_put(command_data->command);
-
- kfree(command_data);
- return 0;
-}
-
-static ssize_t command_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
-{
- struct ibmasmfs_command_data *command_data = file->private_data;
- struct command *cmd;
- int len;
- unsigned long flags;
-
- if (*offset < 0)
- return -EINVAL;
- if (count == 0 || count > IBMASM_CMD_MAX_BUFFER_SIZE)
- return 0;
- if (*offset != 0)
- return 0;
-
- spin_lock_irqsave(&command_data->sp->lock, flags);
- cmd = command_data->command;
- if (cmd == NULL) {
- spin_unlock_irqrestore(&command_data->sp->lock, flags);
- return 0;
- }
- command_data->command = NULL;
- spin_unlock_irqrestore(&command_data->sp->lock, flags);
-
- if (cmd->status != IBMASM_CMD_COMPLETE) {
- command_put(cmd);
- return -EIO;
- }
- len = min(count, cmd->buffer_size);
- if (copy_to_user(buf, cmd->buffer, len)) {
- command_put(cmd);
- return -EFAULT;
- }
- command_put(cmd);
-
- return len;
-}
-
-static ssize_t command_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset)
-{
- struct ibmasmfs_command_data *command_data = file->private_data;
- struct command *cmd;
- unsigned long flags;
-
- if (*offset < 0)
- return -EINVAL;
- if (count == 0 || count > IBMASM_CMD_MAX_BUFFER_SIZE)
- return 0;
- if (*offset != 0)
- return 0;
-
- /* commands are executed sequentially, only one command at a time */
- if (command_data->command)
- return -EAGAIN;
-
- cmd = ibmasm_new_command(command_data->sp, count);
- if (!cmd)
- return -ENOMEM;
-
- if (copy_from_user(cmd->buffer, ubuff, count)) {
- command_put(cmd);
- return -EFAULT;
- }
-
- spin_lock_irqsave(&command_data->sp->lock, flags);
- if (command_data->command) {
- spin_unlock_irqrestore(&command_data->sp->lock, flags);
- command_put(cmd);
- return -EAGAIN;
- }
- command_data->command = cmd;
- spin_unlock_irqrestore(&command_data->sp->lock, flags);
-
- ibmasm_exec_command(command_data->sp, cmd);
- ibmasm_wait_for_response(cmd, get_dot_command_timeout(cmd->buffer));
-
- return count;
-}
-
-static int event_file_open(struct inode *inode, struct file *file)
-{
- struct ibmasmfs_event_data *event_data;
- struct service_processor *sp;
-
- if (!inode->i_private)
- return -ENODEV;
-
- sp = inode->i_private;
-
- event_data = kmalloc(sizeof(struct ibmasmfs_event_data), GFP_KERNEL);
- if (!event_data)
- return -ENOMEM;
-
- ibmasm_event_reader_register(sp, &event_data->reader);
-
- event_data->sp = sp;
- event_data->active = 0;
- file->private_data = event_data;
- return 0;
-}
-
-static int event_file_close(struct inode *inode, struct file *file)
-{
- struct ibmasmfs_event_data *event_data = file->private_data;
-
- ibmasm_event_reader_unregister(event_data->sp, &event_data->reader);
- kfree(event_data);
- return 0;
-}
-
-static ssize_t event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
-{
- struct ibmasmfs_event_data *event_data = file->private_data;
- struct event_reader *reader = &event_data->reader;
- struct service_processor *sp = event_data->sp;
- int ret;
- unsigned long flags;
-
- if (*offset < 0)
- return -EINVAL;
- if (count == 0 || count > IBMASM_EVENT_MAX_SIZE)
- return 0;
- if (*offset != 0)
- return 0;
-
- spin_lock_irqsave(&sp->lock, flags);
- if (event_data->active) {
- spin_unlock_irqrestore(&sp->lock, flags);
- return -EBUSY;
- }
- event_data->active = 1;
- spin_unlock_irqrestore(&sp->lock, flags);
-
- ret = ibmasm_get_next_event(sp, reader);
- if (ret <= 0)
- goto out;
-
- if (count < reader->data_size) {
- ret = -EINVAL;
- goto out;
- }
-
- if (copy_to_user(buf, reader->data, reader->data_size)) {
- ret = -EFAULT;
- goto out;
- }
- ret = reader->data_size;
-
-out:
- event_data->active = 0;
- return ret;
-}
-
-static ssize_t event_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
-{
- struct ibmasmfs_event_data *event_data = file->private_data;
-
- if (*offset < 0)
- return -EINVAL;
- if (count != 1)
- return 0;
- if (*offset != 0)
- return 0;
-
- ibmasm_cancel_next_event(&event_data->reader);
- return 0;
-}
-
-static int r_heartbeat_file_open(struct inode *inode, struct file *file)
-{
- struct ibmasmfs_heartbeat_data *rhbeat;
-
- if (!inode->i_private)
- return -ENODEV;
-
- rhbeat = kmalloc(sizeof(struct ibmasmfs_heartbeat_data), GFP_KERNEL);
- if (!rhbeat)
- return -ENOMEM;
-
- rhbeat->sp = inode->i_private;
- rhbeat->active = 0;
- ibmasm_init_reverse_heartbeat(rhbeat->sp, &rhbeat->heartbeat);
- file->private_data = rhbeat;
- return 0;
-}
-
-static int r_heartbeat_file_close(struct inode *inode, struct file *file)
-{
- struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
-
- kfree(rhbeat);
- return 0;
-}
-
-static ssize_t r_heartbeat_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
-{
- struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
- unsigned long flags;
- int result;
-
- if (*offset < 0)
- return -EINVAL;
- if (count == 0 || count > 1024)
- return 0;
- if (*offset != 0)
- return 0;
-
- /* allow only one reverse heartbeat per process */
- spin_lock_irqsave(&rhbeat->sp->lock, flags);
- if (rhbeat->active) {
- spin_unlock_irqrestore(&rhbeat->sp->lock, flags);
- return -EBUSY;
- }
- rhbeat->active = 1;
- spin_unlock_irqrestore(&rhbeat->sp->lock, flags);
-
- result = ibmasm_start_reverse_heartbeat(rhbeat->sp, &rhbeat->heartbeat);
- rhbeat->active = 0;
-
- return result;
-}
-
-static ssize_t r_heartbeat_file_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
-{
- struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
-
- if (*offset < 0)
- return -EINVAL;
- if (count != 1)
- return 0;
- if (*offset != 0)
- return 0;
-
- if (rhbeat->active)
- ibmasm_stop_reverse_heartbeat(&rhbeat->heartbeat);
-
- return 1;
-}
-
-static int remote_settings_file_close(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-static ssize_t remote_settings_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
-{
- void __iomem *address = (void __iomem *)file->private_data;
- unsigned char *page;
- int retval;
- int len = 0;
- unsigned int value;
-
- if (*offset < 0)
- return -EINVAL;
- if (count == 0 || count > 1024)
- return 0;
- if (*offset != 0)
- return 0;
-
- page = (unsigned char *)__get_free_page(GFP_KERNEL);
- if (!page)
- return -ENOMEM;
-
- value = readl(address);
- len = sprintf(page, "%d\n", value);
-
- if (copy_to_user(buf, page, len)) {
- retval = -EFAULT;
- goto exit;
- }
- *offset += len;
- retval = len;
-
-exit:
- free_page((unsigned long)page);
- return retval;
-}
-
-static ssize_t remote_settings_file_write(struct file *file, const char __user *ubuff, size_t count, loff_t *offset)
-{
- void __iomem *address = (void __iomem *)file->private_data;
- char *buff;
- unsigned int value;
-
- if (*offset < 0)
- return -EINVAL;
- if (count == 0 || count > 1024)
- return 0;
- if (*offset != 0)
- return 0;
-
- buff = kzalloc (count + 1, GFP_KERNEL);
- if (!buff)
- return -ENOMEM;
-
-
- if (copy_from_user(buff, ubuff, count)) {
- kfree(buff);
- return -EFAULT;
- }
-
- value = simple_strtoul(buff, NULL, 10);
- writel(value, address);
- kfree(buff);
-
- return count;
-}
-
-static const struct file_operations command_fops = {
- .open = command_file_open,
- .release = command_file_close,
- .read = command_file_read,
- .write = command_file_write,
- .llseek = generic_file_llseek,
-};
-
-static const struct file_operations event_fops = {
- .open = event_file_open,
- .release = event_file_close,
- .read = event_file_read,
- .write = event_file_write,
- .llseek = generic_file_llseek,
-};
-
-static const struct file_operations r_heartbeat_fops = {
- .open = r_heartbeat_file_open,
- .release = r_heartbeat_file_close,
- .read = r_heartbeat_file_read,
- .write = r_heartbeat_file_write,
- .llseek = generic_file_llseek,
-};
-
-static const struct file_operations remote_settings_fops = {
- .open = simple_open,
- .release = remote_settings_file_close,
- .read = remote_settings_file_read,
- .write = remote_settings_file_write,
- .llseek = generic_file_llseek,
-};
-
-
-static void ibmasmfs_create_files (struct super_block *sb)
-{
- struct list_head *entry;
- struct service_processor *sp;
-
- list_for_each(entry, &service_processors) {
- struct dentry *dir;
- struct dentry *remote_dir;
- sp = list_entry(entry, struct service_processor, node);
- dir = ibmasmfs_create_dir(sb, sb->s_root, sp->dirname);
- if (!dir)
- continue;
-
- ibmasmfs_create_file(sb, dir, "command", &command_fops, sp, S_IRUSR|S_IWUSR);
- ibmasmfs_create_file(sb, dir, "event", &event_fops, sp, S_IRUSR|S_IWUSR);
- ibmasmfs_create_file(sb, dir, "reverse_heartbeat", &r_heartbeat_fops, sp, S_IRUSR|S_IWUSR);
-
- remote_dir = ibmasmfs_create_dir(sb, dir, "remote_video");
- if (!remote_dir)
- continue;
-
- ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR);
- ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR);
- ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR);
- }
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/lowlevel.c b/ANDROID_3.4.5/drivers/misc/ibmasm/lowlevel.c
deleted file mode 100644
index 5319ea26..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/lowlevel.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#include "ibmasm.h"
-#include "lowlevel.h"
-#include "i2o.h"
-#include "dot_command.h"
-#include "remote.h"
-
-static struct i2o_header header = I2O_HEADER_TEMPLATE;
-
-
-int ibmasm_send_i2o_message(struct service_processor *sp)
-{
- u32 mfa;
- unsigned int command_size;
- struct i2o_message *message;
- struct command *command = sp->current_command;
-
- mfa = get_mfa_inbound(sp->base_address);
- if (!mfa)
- return 1;
-
- command_size = get_dot_command_size(command->buffer);
- header.message_size = outgoing_message_size(command_size);
-
- message = get_i2o_message(sp->base_address, mfa);
-
- memcpy_toio(&message->header, &header, sizeof(struct i2o_header));
- memcpy_toio(&message->data, command->buffer, command_size);
-
- set_mfa_inbound(sp->base_address, mfa);
-
- return 0;
-}
-
-irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id)
-{
- u32 mfa;
- struct service_processor *sp = (struct service_processor *)dev_id;
- void __iomem *base_address = sp->base_address;
- char tsbuf[32];
-
- if (!sp_interrupt_pending(base_address))
- return IRQ_NONE;
-
- dbg("respond to interrupt at %s\n", get_timestamp(tsbuf));
-
- if (mouse_interrupt_pending(sp)) {
- ibmasm_handle_mouse_interrupt(sp);
- clear_mouse_interrupt(sp);
- }
-
- mfa = get_mfa_outbound(base_address);
- if (valid_mfa(mfa)) {
- struct i2o_message *msg = get_i2o_message(base_address, mfa);
- ibmasm_receive_message(sp, &msg->data, incoming_data_size(msg));
- } else
- dbg("didn't get a valid MFA\n");
-
- set_mfa_outbound(base_address, mfa);
- dbg("finished interrupt at %s\n", get_timestamp(tsbuf));
-
- return IRQ_HANDLED;
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/lowlevel.h b/ANDROID_3.4.5/drivers/misc/ibmasm/lowlevel.h
deleted file mode 100644
index e97848f5..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/lowlevel.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-/* Condor service processor specific hardware definitions */
-
-#ifndef __IBMASM_CONDOR_H__
-#define __IBMASM_CONDOR_H__
-
-#include <asm/io.h>
-
-#define VENDORID_IBM 0x1014
-#define DEVICEID_RSA 0x010F
-
-#define GET_MFA_ADDR(x) (x & 0xFFFFFF00)
-
-#define MAILBOX_FULL(x) (x & 0x00000001)
-
-#define NO_MFAS_AVAILABLE 0xFFFFFFFF
-
-
-#define INBOUND_QUEUE_PORT 0x40 /* contains address of next free MFA */
-#define OUTBOUND_QUEUE_PORT 0x44 /* contains address of posted MFA */
-
-#define SP_INTR_MASK 0x00000008
-#define UART_INTR_MASK 0x00000010
-
-#define INTR_STATUS_REGISTER 0x13A0
-#define INTR_CONTROL_REGISTER 0x13A4
-
-#define SCOUT_COM_A_BASE 0x0000
-#define SCOUT_COM_B_BASE 0x0100
-#define SCOUT_COM_C_BASE 0x0200
-#define SCOUT_COM_D_BASE 0x0300
-
-static inline int sp_interrupt_pending(void __iomem *base_address)
-{
- return SP_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER);
-}
-
-static inline int uart_interrupt_pending(void __iomem *base_address)
-{
- return UART_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER);
-}
-
-static inline void ibmasm_enable_interrupts(void __iomem *base_address, int mask)
-{
- void __iomem *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
- writel( readl(ctrl_reg) & ~mask, ctrl_reg);
-}
-
-static inline void ibmasm_disable_interrupts(void __iomem *base_address, int mask)
-{
- void __iomem *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
- writel( readl(ctrl_reg) | mask, ctrl_reg);
-}
-
-static inline void enable_sp_interrupts(void __iomem *base_address)
-{
- ibmasm_enable_interrupts(base_address, SP_INTR_MASK);
-}
-
-static inline void disable_sp_interrupts(void __iomem *base_address)
-{
- ibmasm_disable_interrupts(base_address, SP_INTR_MASK);
-}
-
-static inline void enable_uart_interrupts(void __iomem *base_address)
-{
- ibmasm_enable_interrupts(base_address, UART_INTR_MASK);
-}
-
-static inline void disable_uart_interrupts(void __iomem *base_address)
-{
- ibmasm_disable_interrupts(base_address, UART_INTR_MASK);
-}
-
-#define valid_mfa(mfa) ( (mfa) != NO_MFAS_AVAILABLE )
-
-static inline u32 get_mfa_outbound(void __iomem *base_address)
-{
- int retry;
- u32 mfa;
-
- for (retry=0; retry<=10; retry++) {
- mfa = readl(base_address + OUTBOUND_QUEUE_PORT);
- if (valid_mfa(mfa))
- break;
- }
- return mfa;
-}
-
-static inline void set_mfa_outbound(void __iomem *base_address, u32 mfa)
-{
- writel(mfa, base_address + OUTBOUND_QUEUE_PORT);
-}
-
-static inline u32 get_mfa_inbound(void __iomem *base_address)
-{
- u32 mfa = readl(base_address + INBOUND_QUEUE_PORT);
-
- if (MAILBOX_FULL(mfa))
- return 0;
-
- return mfa;
-}
-
-static inline void set_mfa_inbound(void __iomem *base_address, u32 mfa)
-{
- writel(mfa, base_address + INBOUND_QUEUE_PORT);
-}
-
-static inline struct i2o_message *get_i2o_message(void __iomem *base_address, u32 mfa)
-{
- return (struct i2o_message *)(GET_MFA_ADDR(mfa) + base_address);
-}
-
-#endif /* __IBMASM_CONDOR_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/module.c b/ANDROID_3.4.5/drivers/misc/ibmasm/module.c
deleted file mode 100644
index 168d8008..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/module.c
+++ /dev/null
@@ -1,237 +0,0 @@
-
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- * This driver is based on code originally written by Pete Reynolds
- * and others.
- *
- */
-
-/*
- * The ASM device driver does the following things:
- *
- * 1) When loaded it sends a message to the service processor,
- * indicating that an OS is * running. This causes the service processor
- * to send periodic heartbeats to the OS.
- *
- * 2) Answers the periodic heartbeats sent by the service processor.
- * Failure to do so would result in system reboot.
- *
- * 3) Acts as a pass through for dot commands sent from user applications.
- * The interface for this is the ibmasmfs file system.
- *
- * 4) Allows user applications to register for event notification. Events
- * are sent to the driver through interrupts. They can be read from user
- * space through the ibmasmfs file system.
- *
- * 5) Allows user space applications to send heartbeats to the service
- * processor (aka reverse heartbeats). Again this happens through ibmasmfs.
- *
- * 6) Handles remote mouse and keyboard event interrupts and makes them
- * available to user applications through ibmasmfs.
- *
- */
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include "ibmasm.h"
-#include "lowlevel.h"
-#include "remote.h"
-
-int ibmasm_debug = 0;
-module_param(ibmasm_debug, int , S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(ibmasm_debug, " Set debug mode on or off");
-
-
-static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- int result;
- struct service_processor *sp;
-
- if ((result = pci_enable_device(pdev))) {
- dev_err(&pdev->dev, "Failed to enable PCI device\n");
- return result;
- }
- if ((result = pci_request_regions(pdev, DRIVER_NAME))) {
- dev_err(&pdev->dev, "Failed to allocate PCI resources\n");
- goto error_resources;
- }
- /* vnc client won't work without bus-mastering */
- pci_set_master(pdev);
-
- sp = kzalloc(sizeof(struct service_processor), GFP_KERNEL);
- if (sp == NULL) {
- dev_err(&pdev->dev, "Failed to allocate memory\n");
- result = -ENOMEM;
- goto error_kmalloc;
- }
-
- spin_lock_init(&sp->lock);
- INIT_LIST_HEAD(&sp->command_queue);
-
- pci_set_drvdata(pdev, (void *)sp);
- sp->dev = &pdev->dev;
- sp->number = pdev->bus->number;
- snprintf(sp->dirname, IBMASM_NAME_SIZE, "%d", sp->number);
- snprintf(sp->devname, IBMASM_NAME_SIZE, "%s%d", DRIVER_NAME, sp->number);
-
- if (ibmasm_event_buffer_init(sp)) {
- dev_err(sp->dev, "Failed to allocate event buffer\n");
- goto error_eventbuffer;
- }
-
- if (ibmasm_heartbeat_init(sp)) {
- dev_err(sp->dev, "Failed to allocate heartbeat command\n");
- goto error_heartbeat;
- }
-
- sp->irq = pdev->irq;
- sp->base_address = pci_ioremap_bar(pdev, 0);
- if (!sp->base_address) {
- dev_err(sp->dev, "Failed to ioremap pci memory\n");
- result = -ENODEV;
- goto error_ioremap;
- }
-
- result = request_irq(sp->irq, ibmasm_interrupt_handler, IRQF_SHARED, sp->devname, (void*)sp);
- if (result) {
- dev_err(sp->dev, "Failed to register interrupt handler\n");
- goto error_request_irq;
- }
-
- enable_sp_interrupts(sp->base_address);
-
- result = ibmasm_init_remote_input_dev(sp);
- if (result) {
- dev_err(sp->dev, "Failed to initialize remote queue\n");
- goto error_send_message;
- }
-
- result = ibmasm_send_driver_vpd(sp);
- if (result) {
- dev_err(sp->dev, "Failed to send driver VPD to service processor\n");
- goto error_send_message;
- }
- result = ibmasm_send_os_state(sp, SYSTEM_STATE_OS_UP);
- if (result) {
- dev_err(sp->dev, "Failed to send OS state to service processor\n");
- goto error_send_message;
- }
- ibmasmfs_add_sp(sp);
-
- ibmasm_register_uart(sp);
-
- return 0;
-
-error_send_message:
- disable_sp_interrupts(sp->base_address);
- ibmasm_free_remote_input_dev(sp);
- free_irq(sp->irq, (void *)sp);
-error_request_irq:
- iounmap(sp->base_address);
-error_ioremap:
- ibmasm_heartbeat_exit(sp);
-error_heartbeat:
- ibmasm_event_buffer_exit(sp);
-error_eventbuffer:
- pci_set_drvdata(pdev, NULL);
- kfree(sp);
-error_kmalloc:
- pci_release_regions(pdev);
-error_resources:
- pci_disable_device(pdev);
-
- return result;
-}
-
-static void __devexit ibmasm_remove_one(struct pci_dev *pdev)
-{
- struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev);
-
- dbg("Unregistering UART\n");
- ibmasm_unregister_uart(sp);
- dbg("Sending OS down message\n");
- if (ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN))
- err("failed to get repsonse to 'Send OS State' command\n");
- dbg("Disabling heartbeats\n");
- ibmasm_heartbeat_exit(sp);
- dbg("Disabling interrupts\n");
- disable_sp_interrupts(sp->base_address);
- dbg("Freeing SP irq\n");
- free_irq(sp->irq, (void *)sp);
- dbg("Cleaning up\n");
- ibmasm_free_remote_input_dev(sp);
- iounmap(sp->base_address);
- ibmasm_event_buffer_exit(sp);
- pci_set_drvdata(pdev, NULL);
- kfree(sp);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
-}
-
-static struct pci_device_id ibmasm_pci_table[] =
-{
- { PCI_DEVICE(VENDORID_IBM, DEVICEID_RSA) },
- {},
-};
-
-static struct pci_driver ibmasm_driver = {
- .name = DRIVER_NAME,
- .id_table = ibmasm_pci_table,
- .probe = ibmasm_init_one,
- .remove = __devexit_p(ibmasm_remove_one),
-};
-
-static void __exit ibmasm_exit (void)
-{
- ibmasm_unregister_panic_notifier();
- ibmasmfs_unregister();
- pci_unregister_driver(&ibmasm_driver);
- info(DRIVER_DESC " version " DRIVER_VERSION " unloaded");
-}
-
-static int __init ibmasm_init(void)
-{
- int result = pci_register_driver(&ibmasm_driver);
- if (result)
- return result;
-
- result = ibmasmfs_register();
- if (result) {
- pci_unregister_driver(&ibmasm_driver);
- err("Failed to register ibmasmfs file system");
- return result;
- }
-
- ibmasm_register_panic_notifier();
- info(DRIVER_DESC " version " DRIVER_VERSION " loaded");
- return 0;
-}
-
-module_init(ibmasm_init);
-module_exit(ibmasm_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, ibmasm_pci_table);
-
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/r_heartbeat.c b/ANDROID_3.4.5/drivers/misc/ibmasm/r_heartbeat.c
deleted file mode 100644
index 232034f5..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/r_heartbeat.c
+++ /dev/null
@@ -1,99 +0,0 @@
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#include <linux/sched.h>
-#include "ibmasm.h"
-#include "dot_command.h"
-
-/*
- * Reverse Heartbeat, i.e. heartbeats sent from the driver to the
- * service processor.
- * These heartbeats are initiated by user level programs.
- */
-
-/* the reverse heartbeat dot command */
-#pragma pack(1)
-static struct {
- struct dot_command_header header;
- unsigned char command[3];
-} rhb_dot_cmd = {
- .header = {
- .type = sp_read,
- .command_size = 3,
- .data_size = 0,
- .status = 0
- },
- .command = { 4, 3, 6 }
-};
-#pragma pack()
-
-void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
-{
- init_waitqueue_head(&rhb->wait);
- rhb->stopped = 0;
-}
-
-/**
- * start_reverse_heartbeat
- * Loop forever, sending a reverse heartbeat dot command to the service
- * processor, then sleeping. The loop comes to an end if the service
- * processor fails to respond 3 times or we were interrupted.
- */
-int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
-{
- struct command *cmd;
- int times_failed = 0;
- int result = 1;
-
- cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd);
- if (!cmd)
- return -ENOMEM;
-
- while (times_failed < 3) {
- memcpy(cmd->buffer, (void *)&rhb_dot_cmd, sizeof rhb_dot_cmd);
- cmd->status = IBMASM_CMD_PENDING;
- ibmasm_exec_command(sp, cmd);
- ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
-
- if (cmd->status != IBMASM_CMD_COMPLETE)
- times_failed++;
-
- wait_event_interruptible_timeout(rhb->wait,
- rhb->stopped,
- REVERSE_HEARTBEAT_TIMEOUT * HZ);
-
- if (signal_pending(current) || rhb->stopped) {
- result = -EINTR;
- break;
- }
- }
- command_put(cmd);
- rhb->stopped = 0;
-
- return result;
-}
-
-void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb)
-{
- rhb->stopped = 1;
- wake_up_interruptible(&rhb->wait);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/remote.c b/ANDROID_3.4.5/drivers/misc/ibmasm/remote.c
deleted file mode 100644
index 477bb43c..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/remote.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Authors: Max Asböck <amax@us.ibm.com>
- * Vernon Mauery <vernux@us.ibm.com>
- *
- */
-
-/* Remote mouse and keyboard event handling functions */
-
-#include <linux/pci.h>
-#include "ibmasm.h"
-#include "remote.h"
-
-#define MOUSE_X_MAX 1600
-#define MOUSE_Y_MAX 1200
-
-static const unsigned short xlate_high[XLATE_SIZE] = {
- [KEY_SYM_ENTER & 0xff] = KEY_ENTER,
- [KEY_SYM_KPSLASH & 0xff] = KEY_KPSLASH,
- [KEY_SYM_KPSTAR & 0xff] = KEY_KPASTERISK,
- [KEY_SYM_KPMINUS & 0xff] = KEY_KPMINUS,
- [KEY_SYM_KPDOT & 0xff] = KEY_KPDOT,
- [KEY_SYM_KPPLUS & 0xff] = KEY_KPPLUS,
- [KEY_SYM_KP0 & 0xff] = KEY_KP0,
- [KEY_SYM_KP1 & 0xff] = KEY_KP1,
- [KEY_SYM_KP2 & 0xff] = KEY_KP2, [KEY_SYM_KPDOWN & 0xff] = KEY_KP2,
- [KEY_SYM_KP3 & 0xff] = KEY_KP3,
- [KEY_SYM_KP4 & 0xff] = KEY_KP4, [KEY_SYM_KPLEFT & 0xff] = KEY_KP4,
- [KEY_SYM_KP5 & 0xff] = KEY_KP5,
- [KEY_SYM_KP6 & 0xff] = KEY_KP6, [KEY_SYM_KPRIGHT & 0xff] = KEY_KP6,
- [KEY_SYM_KP7 & 0xff] = KEY_KP7,
- [KEY_SYM_KP8 & 0xff] = KEY_KP8, [KEY_SYM_KPUP & 0xff] = KEY_KP8,
- [KEY_SYM_KP9 & 0xff] = KEY_KP9,
- [KEY_SYM_BK_SPC & 0xff] = KEY_BACKSPACE,
- [KEY_SYM_TAB & 0xff] = KEY_TAB,
- [KEY_SYM_CTRL & 0xff] = KEY_LEFTCTRL,
- [KEY_SYM_ALT & 0xff] = KEY_LEFTALT,
- [KEY_SYM_INSERT & 0xff] = KEY_INSERT,
- [KEY_SYM_DELETE & 0xff] = KEY_DELETE,
- [KEY_SYM_SHIFT & 0xff] = KEY_LEFTSHIFT,
- [KEY_SYM_UARROW & 0xff] = KEY_UP,
- [KEY_SYM_DARROW & 0xff] = KEY_DOWN,
- [KEY_SYM_LARROW & 0xff] = KEY_LEFT,
- [KEY_SYM_RARROW & 0xff] = KEY_RIGHT,
- [KEY_SYM_ESCAPE & 0xff] = KEY_ESC,
- [KEY_SYM_PAGEUP & 0xff] = KEY_PAGEUP,
- [KEY_SYM_PAGEDOWN & 0xff] = KEY_PAGEDOWN,
- [KEY_SYM_HOME & 0xff] = KEY_HOME,
- [KEY_SYM_END & 0xff] = KEY_END,
- [KEY_SYM_F1 & 0xff] = KEY_F1,
- [KEY_SYM_F2 & 0xff] = KEY_F2,
- [KEY_SYM_F3 & 0xff] = KEY_F3,
- [KEY_SYM_F4 & 0xff] = KEY_F4,
- [KEY_SYM_F5 & 0xff] = KEY_F5,
- [KEY_SYM_F6 & 0xff] = KEY_F6,
- [KEY_SYM_F7 & 0xff] = KEY_F7,
- [KEY_SYM_F8 & 0xff] = KEY_F8,
- [KEY_SYM_F9 & 0xff] = KEY_F9,
- [KEY_SYM_F10 & 0xff] = KEY_F10,
- [KEY_SYM_F11 & 0xff] = KEY_F11,
- [KEY_SYM_F12 & 0xff] = KEY_F12,
- [KEY_SYM_CAP_LOCK & 0xff] = KEY_CAPSLOCK,
- [KEY_SYM_NUM_LOCK & 0xff] = KEY_NUMLOCK,
- [KEY_SYM_SCR_LOCK & 0xff] = KEY_SCROLLLOCK,
-};
-
-static const unsigned short xlate[XLATE_SIZE] = {
- [NO_KEYCODE] = KEY_RESERVED,
- [KEY_SYM_SPACE] = KEY_SPACE,
- [KEY_SYM_TILDE] = KEY_GRAVE, [KEY_SYM_BKTIC] = KEY_GRAVE,
- [KEY_SYM_ONE] = KEY_1, [KEY_SYM_BANG] = KEY_1,
- [KEY_SYM_TWO] = KEY_2, [KEY_SYM_AT] = KEY_2,
- [KEY_SYM_THREE] = KEY_3, [KEY_SYM_POUND] = KEY_3,
- [KEY_SYM_FOUR] = KEY_4, [KEY_SYM_DOLLAR] = KEY_4,
- [KEY_SYM_FIVE] = KEY_5, [KEY_SYM_PERCENT] = KEY_5,
- [KEY_SYM_SIX] = KEY_6, [KEY_SYM_CARAT] = KEY_6,
- [KEY_SYM_SEVEN] = KEY_7, [KEY_SYM_AMPER] = KEY_7,
- [KEY_SYM_EIGHT] = KEY_8, [KEY_SYM_STAR] = KEY_8,
- [KEY_SYM_NINE] = KEY_9, [KEY_SYM_LPAREN] = KEY_9,
- [KEY_SYM_ZERO] = KEY_0, [KEY_SYM_RPAREN] = KEY_0,
- [KEY_SYM_MINUS] = KEY_MINUS, [KEY_SYM_USCORE] = KEY_MINUS,
- [KEY_SYM_EQUAL] = KEY_EQUAL, [KEY_SYM_PLUS] = KEY_EQUAL,
- [KEY_SYM_LBRKT] = KEY_LEFTBRACE, [KEY_SYM_LCURLY] = KEY_LEFTBRACE,
- [KEY_SYM_RBRKT] = KEY_RIGHTBRACE, [KEY_SYM_RCURLY] = KEY_RIGHTBRACE,
- [KEY_SYM_SLASH] = KEY_BACKSLASH, [KEY_SYM_PIPE] = KEY_BACKSLASH,
- [KEY_SYM_TIC] = KEY_APOSTROPHE, [KEY_SYM_QUOTE] = KEY_APOSTROPHE,
- [KEY_SYM_SEMIC] = KEY_SEMICOLON, [KEY_SYM_COLON] = KEY_SEMICOLON,
- [KEY_SYM_COMMA] = KEY_COMMA, [KEY_SYM_LT] = KEY_COMMA,
- [KEY_SYM_PERIOD] = KEY_DOT, [KEY_SYM_GT] = KEY_DOT,
- [KEY_SYM_BSLASH] = KEY_SLASH, [KEY_SYM_QMARK] = KEY_SLASH,
- [KEY_SYM_A] = KEY_A, [KEY_SYM_a] = KEY_A,
- [KEY_SYM_B] = KEY_B, [KEY_SYM_b] = KEY_B,
- [KEY_SYM_C] = KEY_C, [KEY_SYM_c] = KEY_C,
- [KEY_SYM_D] = KEY_D, [KEY_SYM_d] = KEY_D,
- [KEY_SYM_E] = KEY_E, [KEY_SYM_e] = KEY_E,
- [KEY_SYM_F] = KEY_F, [KEY_SYM_f] = KEY_F,
- [KEY_SYM_G] = KEY_G, [KEY_SYM_g] = KEY_G,
- [KEY_SYM_H] = KEY_H, [KEY_SYM_h] = KEY_H,
- [KEY_SYM_I] = KEY_I, [KEY_SYM_i] = KEY_I,
- [KEY_SYM_J] = KEY_J, [KEY_SYM_j] = KEY_J,
- [KEY_SYM_K] = KEY_K, [KEY_SYM_k] = KEY_K,
- [KEY_SYM_L] = KEY_L, [KEY_SYM_l] = KEY_L,
- [KEY_SYM_M] = KEY_M, [KEY_SYM_m] = KEY_M,
- [KEY_SYM_N] = KEY_N, [KEY_SYM_n] = KEY_N,
- [KEY_SYM_O] = KEY_O, [KEY_SYM_o] = KEY_O,
- [KEY_SYM_P] = KEY_P, [KEY_SYM_p] = KEY_P,
- [KEY_SYM_Q] = KEY_Q, [KEY_SYM_q] = KEY_Q,
- [KEY_SYM_R] = KEY_R, [KEY_SYM_r] = KEY_R,
- [KEY_SYM_S] = KEY_S, [KEY_SYM_s] = KEY_S,
- [KEY_SYM_T] = KEY_T, [KEY_SYM_t] = KEY_T,
- [KEY_SYM_U] = KEY_U, [KEY_SYM_u] = KEY_U,
- [KEY_SYM_V] = KEY_V, [KEY_SYM_v] = KEY_V,
- [KEY_SYM_W] = KEY_W, [KEY_SYM_w] = KEY_W,
- [KEY_SYM_X] = KEY_X, [KEY_SYM_x] = KEY_X,
- [KEY_SYM_Y] = KEY_Y, [KEY_SYM_y] = KEY_Y,
- [KEY_SYM_Z] = KEY_Z, [KEY_SYM_z] = KEY_Z,
-};
-
-static void print_input(struct remote_input *input)
-{
- if (input->type == INPUT_TYPE_MOUSE) {
- unsigned char buttons = input->mouse_buttons;
- dbg("remote mouse movement: (x,y)=(%d,%d)%s%s%s%s\n",
- input->data.mouse.x, input->data.mouse.y,
- (buttons) ? " -- buttons:" : "",
- (buttons & REMOTE_BUTTON_LEFT) ? "left " : "",
- (buttons & REMOTE_BUTTON_MIDDLE) ? "middle " : "",
- (buttons & REMOTE_BUTTON_RIGHT) ? "right" : ""
- );
- } else {
- dbg("remote keypress (code, flag, down):"
- "%d (0x%x) [0x%x] [0x%x]\n",
- input->data.keyboard.key_code,
- input->data.keyboard.key_code,
- input->data.keyboard.key_flag,
- input->data.keyboard.key_down
- );
- }
-}
-
-static void send_mouse_event(struct input_dev *dev, struct remote_input *input)
-{
- unsigned char buttons = input->mouse_buttons;
-
- input_report_abs(dev, ABS_X, input->data.mouse.x);
- input_report_abs(dev, ABS_Y, input->data.mouse.y);
- input_report_key(dev, BTN_LEFT, buttons & REMOTE_BUTTON_LEFT);
- input_report_key(dev, BTN_MIDDLE, buttons & REMOTE_BUTTON_MIDDLE);
- input_report_key(dev, BTN_RIGHT, buttons & REMOTE_BUTTON_RIGHT);
- input_sync(dev);
-}
-
-static void send_keyboard_event(struct input_dev *dev,
- struct remote_input *input)
-{
- unsigned int key;
- unsigned short code = input->data.keyboard.key_code;
-
- if (code & 0xff00)
- key = xlate_high[code & 0xff];
- else
- key = xlate[code];
- input_report_key(dev, key, input->data.keyboard.key_down);
- input_sync(dev);
-}
-
-void ibmasm_handle_mouse_interrupt(struct service_processor *sp)
-{
- unsigned long reader;
- unsigned long writer;
- struct remote_input input;
-
- reader = get_queue_reader(sp);
- writer = get_queue_writer(sp);
-
- while (reader != writer) {
- memcpy_fromio(&input, get_queue_entry(sp, reader),
- sizeof(struct remote_input));
-
- print_input(&input);
- if (input.type == INPUT_TYPE_MOUSE) {
- send_mouse_event(sp->remote.mouse_dev, &input);
- } else if (input.type == INPUT_TYPE_KEYBOARD) {
- send_keyboard_event(sp->remote.keybd_dev, &input);
- } else
- break;
-
- reader = advance_queue_reader(sp, reader);
- writer = get_queue_writer(sp);
- }
-}
-
-int ibmasm_init_remote_input_dev(struct service_processor *sp)
-{
- /* set up the mouse input device */
- struct input_dev *mouse_dev, *keybd_dev;
- struct pci_dev *pdev = to_pci_dev(sp->dev);
- int error = -ENOMEM;
- int i;
-
- sp->remote.mouse_dev = mouse_dev = input_allocate_device();
- sp->remote.keybd_dev = keybd_dev = input_allocate_device();
-
- if (!mouse_dev || !keybd_dev)
- goto err_free_devices;
-
- mouse_dev->id.bustype = BUS_PCI;
- mouse_dev->id.vendor = pdev->vendor;
- mouse_dev->id.product = pdev->device;
- mouse_dev->id.version = 1;
- mouse_dev->dev.parent = sp->dev;
- mouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- mouse_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
- BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
- set_bit(BTN_TOUCH, mouse_dev->keybit);
- mouse_dev->name = "ibmasm RSA I remote mouse";
- input_set_abs_params(mouse_dev, ABS_X, 0, MOUSE_X_MAX, 0, 0);
- input_set_abs_params(mouse_dev, ABS_Y, 0, MOUSE_Y_MAX, 0, 0);
-
- keybd_dev->id.bustype = BUS_PCI;
- keybd_dev->id.vendor = pdev->vendor;
- keybd_dev->id.product = pdev->device;
- keybd_dev->id.version = 2;
- keybd_dev->dev.parent = sp->dev;
- keybd_dev->evbit[0] = BIT_MASK(EV_KEY);
- keybd_dev->name = "ibmasm RSA I remote keyboard";
-
- for (i = 0; i < XLATE_SIZE; i++) {
- if (xlate_high[i])
- set_bit(xlate_high[i], keybd_dev->keybit);
- if (xlate[i])
- set_bit(xlate[i], keybd_dev->keybit);
- }
-
- error = input_register_device(mouse_dev);
- if (error)
- goto err_free_devices;
-
- error = input_register_device(keybd_dev);
- if (error)
- goto err_unregister_mouse_dev;
-
- enable_mouse_interrupts(sp);
-
- printk(KERN_INFO "ibmasm remote responding to events on RSA card %d\n", sp->number);
-
- return 0;
-
- err_unregister_mouse_dev:
- input_unregister_device(mouse_dev);
- mouse_dev = NULL; /* so we don't try to free it again below */
- err_free_devices:
- input_free_device(mouse_dev);
- input_free_device(keybd_dev);
-
- return error;
-}
-
-void ibmasm_free_remote_input_dev(struct service_processor *sp)
-{
- disable_mouse_interrupts(sp);
- input_unregister_device(sp->remote.mouse_dev);
- input_unregister_device(sp->remote.keybd_dev);
-}
-
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/remote.h b/ANDROID_3.4.5/drivers/misc/ibmasm/remote.h
deleted file mode 100644
index a7729ef7..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/remote.h
+++ /dev/null
@@ -1,270 +0,0 @@
-
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- * Originally written by Pete Reynolds
- */
-
-#ifndef _IBMASM_REMOTE_H_
-#define _IBMASM_REMOTE_H_
-
-#include <asm/io.h>
-
-/* pci offsets */
-#define CONDOR_MOUSE_DATA 0x000AC000
-#define CONDOR_MOUSE_ISR_CONTROL 0x00
-#define CONDOR_MOUSE_ISR_STATUS 0x04
-#define CONDOR_MOUSE_Q_READER 0x08
-#define CONDOR_MOUSE_Q_WRITER 0x0C
-#define CONDOR_MOUSE_Q_BEGIN 0x10
-#define CONDOR_MOUSE_MAX_X 0x14
-#define CONDOR_MOUSE_MAX_Y 0x18
-
-#define CONDOR_INPUT_DESKTOP_INFO 0x1F0
-#define CONDOR_INPUT_DISPLAY_RESX 0x1F4
-#define CONDOR_INPUT_DISPLAY_RESY 0x1F8
-#define CONDOR_INPUT_DISPLAY_BITS 0x1FC
-#define CONDOR_OUTPUT_VNC_STATUS 0x200
-
-#define CONDOR_MOUSE_INTR_STATUS_MASK 0x00000001
-
-#define INPUT_TYPE_MOUSE 0x1
-#define INPUT_TYPE_KEYBOARD 0x2
-
-
-/* mouse button states received from SP */
-#define REMOTE_DOUBLE_CLICK 0xF0
-#define REMOTE_BUTTON_LEFT 0x01
-#define REMOTE_BUTTON_MIDDLE 0x02
-#define REMOTE_BUTTON_RIGHT 0x04
-
-/* size of keysym/keycode translation matricies */
-#define XLATE_SIZE 256
-
-struct mouse_input {
- unsigned short y;
- unsigned short x;
-};
-
-
-struct keyboard_input {
- unsigned short key_code;
- unsigned char key_flag;
- unsigned char key_down;
-};
-
-
-
-struct remote_input {
- union {
- struct mouse_input mouse;
- struct keyboard_input keyboard;
- } data;
-
- unsigned char type;
- unsigned char pad1;
- unsigned char mouse_buttons;
- unsigned char pad3;
-};
-
-#define mouse_addr(sp) (sp->base_address + CONDOR_MOUSE_DATA)
-#define display_width(sp) (mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESX)
-#define display_height(sp) (mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESY)
-#define display_depth(sp) (mouse_addr(sp) + CONDOR_INPUT_DISPLAY_BITS)
-#define desktop_info(sp) (mouse_addr(sp) + CONDOR_INPUT_DESKTOP_INFO)
-#define vnc_status(sp) (mouse_addr(sp) + CONDOR_OUTPUT_VNC_STATUS)
-#define isr_control(sp) (mouse_addr(sp) + CONDOR_MOUSE_ISR_CONTROL)
-
-#define mouse_interrupt_pending(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS)
-#define clear_mouse_interrupt(sp) writel(0, mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS)
-#define enable_mouse_interrupts(sp) writel(1, mouse_addr(sp) + CONDOR_MOUSE_ISR_CONTROL)
-#define disable_mouse_interrupts(sp) writel(0, mouse_addr(sp) + CONDOR_MOUSE_ISR_CONTROL)
-
-/* remote input queue operations */
-#define REMOTE_QUEUE_SIZE 60
-
-#define get_queue_writer(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_Q_WRITER)
-#define get_queue_reader(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_Q_READER)
-#define set_queue_reader(sp, reader) writel(reader, mouse_addr(sp) + CONDOR_MOUSE_Q_READER)
-
-#define queue_begin (mouse_addr(sp) + CONDOR_MOUSE_Q_BEGIN)
-
-#define get_queue_entry(sp, read_index) \
- ((void*)(queue_begin + read_index * sizeof(struct remote_input)))
-
-static inline int advance_queue_reader(struct service_processor *sp, unsigned long reader)
-{
- reader++;
- if (reader == REMOTE_QUEUE_SIZE)
- reader = 0;
-
- set_queue_reader(sp, reader);
- return reader;
-}
-
-#define NO_KEYCODE 0
-#define KEY_SYM_BK_SPC 0xFF08
-#define KEY_SYM_TAB 0xFF09
-#define KEY_SYM_ENTER 0xFF0D
-#define KEY_SYM_SCR_LOCK 0xFF14
-#define KEY_SYM_ESCAPE 0xFF1B
-#define KEY_SYM_HOME 0xFF50
-#define KEY_SYM_LARROW 0xFF51
-#define KEY_SYM_UARROW 0xFF52
-#define KEY_SYM_RARROW 0xFF53
-#define KEY_SYM_DARROW 0xFF54
-#define KEY_SYM_PAGEUP 0xFF55
-#define KEY_SYM_PAGEDOWN 0xFF56
-#define KEY_SYM_END 0xFF57
-#define KEY_SYM_INSERT 0xFF63
-#define KEY_SYM_NUM_LOCK 0xFF7F
-#define KEY_SYM_KPSTAR 0xFFAA
-#define KEY_SYM_KPPLUS 0xFFAB
-#define KEY_SYM_KPMINUS 0xFFAD
-#define KEY_SYM_KPDOT 0xFFAE
-#define KEY_SYM_KPSLASH 0xFFAF
-#define KEY_SYM_KPRIGHT 0xFF96
-#define KEY_SYM_KPUP 0xFF97
-#define KEY_SYM_KPLEFT 0xFF98
-#define KEY_SYM_KPDOWN 0xFF99
-#define KEY_SYM_KP0 0xFFB0
-#define KEY_SYM_KP1 0xFFB1
-#define KEY_SYM_KP2 0xFFB2
-#define KEY_SYM_KP3 0xFFB3
-#define KEY_SYM_KP4 0xFFB4
-#define KEY_SYM_KP5 0xFFB5
-#define KEY_SYM_KP6 0xFFB6
-#define KEY_SYM_KP7 0xFFB7
-#define KEY_SYM_KP8 0xFFB8
-#define KEY_SYM_KP9 0xFFB9
-#define KEY_SYM_F1 0xFFBE // 1B 5B 5B 41
-#define KEY_SYM_F2 0xFFBF // 1B 5B 5B 42
-#define KEY_SYM_F3 0xFFC0 // 1B 5B 5B 43
-#define KEY_SYM_F4 0xFFC1 // 1B 5B 5B 44
-#define KEY_SYM_F5 0xFFC2 // 1B 5B 5B 45
-#define KEY_SYM_F6 0xFFC3 // 1B 5B 31 37 7E
-#define KEY_SYM_F7 0xFFC4 // 1B 5B 31 38 7E
-#define KEY_SYM_F8 0xFFC5 // 1B 5B 31 39 7E
-#define KEY_SYM_F9 0xFFC6 // 1B 5B 32 30 7E
-#define KEY_SYM_F10 0xFFC7 // 1B 5B 32 31 7E
-#define KEY_SYM_F11 0xFFC8 // 1B 5B 32 33 7E
-#define KEY_SYM_F12 0xFFC9 // 1B 5B 32 34 7E
-#define KEY_SYM_SHIFT 0xFFE1
-#define KEY_SYM_CTRL 0xFFE3
-#define KEY_SYM_ALT 0xFFE9
-#define KEY_SYM_CAP_LOCK 0xFFE5
-#define KEY_SYM_DELETE 0xFFFF
-#define KEY_SYM_TILDE 0x60
-#define KEY_SYM_BKTIC 0x7E
-#define KEY_SYM_ONE 0x31
-#define KEY_SYM_BANG 0x21
-#define KEY_SYM_TWO 0x32
-#define KEY_SYM_AT 0x40
-#define KEY_SYM_THREE 0x33
-#define KEY_SYM_POUND 0x23
-#define KEY_SYM_FOUR 0x34
-#define KEY_SYM_DOLLAR 0x24
-#define KEY_SYM_FIVE 0x35
-#define KEY_SYM_PERCENT 0x25
-#define KEY_SYM_SIX 0x36
-#define KEY_SYM_CARAT 0x5E
-#define KEY_SYM_SEVEN 0x37
-#define KEY_SYM_AMPER 0x26
-#define KEY_SYM_EIGHT 0x38
-#define KEY_SYM_STAR 0x2A
-#define KEY_SYM_NINE 0x39
-#define KEY_SYM_LPAREN 0x28
-#define KEY_SYM_ZERO 0x30
-#define KEY_SYM_RPAREN 0x29
-#define KEY_SYM_MINUS 0x2D
-#define KEY_SYM_USCORE 0x5F
-#define KEY_SYM_EQUAL 0x2B
-#define KEY_SYM_PLUS 0x3D
-#define KEY_SYM_LBRKT 0x5B
-#define KEY_SYM_LCURLY 0x7B
-#define KEY_SYM_RBRKT 0x5D
-#define KEY_SYM_RCURLY 0x7D
-#define KEY_SYM_SLASH 0x5C
-#define KEY_SYM_PIPE 0x7C
-#define KEY_SYM_TIC 0x27
-#define KEY_SYM_QUOTE 0x22
-#define KEY_SYM_SEMIC 0x3B
-#define KEY_SYM_COLON 0x3A
-#define KEY_SYM_COMMA 0x2C
-#define KEY_SYM_LT 0x3C
-#define KEY_SYM_PERIOD 0x2E
-#define KEY_SYM_GT 0x3E
-#define KEY_SYM_BSLASH 0x2F
-#define KEY_SYM_QMARK 0x3F
-#define KEY_SYM_A 0x41
-#define KEY_SYM_B 0x42
-#define KEY_SYM_C 0x43
-#define KEY_SYM_D 0x44
-#define KEY_SYM_E 0x45
-#define KEY_SYM_F 0x46
-#define KEY_SYM_G 0x47
-#define KEY_SYM_H 0x48
-#define KEY_SYM_I 0x49
-#define KEY_SYM_J 0x4A
-#define KEY_SYM_K 0x4B
-#define KEY_SYM_L 0x4C
-#define KEY_SYM_M 0x4D
-#define KEY_SYM_N 0x4E
-#define KEY_SYM_O 0x4F
-#define KEY_SYM_P 0x50
-#define KEY_SYM_Q 0x51
-#define KEY_SYM_R 0x52
-#define KEY_SYM_S 0x53
-#define KEY_SYM_T 0x54
-#define KEY_SYM_U 0x55
-#define KEY_SYM_V 0x56
-#define KEY_SYM_W 0x57
-#define KEY_SYM_X 0x58
-#define KEY_SYM_Y 0x59
-#define KEY_SYM_Z 0x5A
-#define KEY_SYM_a 0x61
-#define KEY_SYM_b 0x62
-#define KEY_SYM_c 0x63
-#define KEY_SYM_d 0x64
-#define KEY_SYM_e 0x65
-#define KEY_SYM_f 0x66
-#define KEY_SYM_g 0x67
-#define KEY_SYM_h 0x68
-#define KEY_SYM_i 0x69
-#define KEY_SYM_j 0x6A
-#define KEY_SYM_k 0x6B
-#define KEY_SYM_l 0x6C
-#define KEY_SYM_m 0x6D
-#define KEY_SYM_n 0x6E
-#define KEY_SYM_o 0x6F
-#define KEY_SYM_p 0x70
-#define KEY_SYM_q 0x71
-#define KEY_SYM_r 0x72
-#define KEY_SYM_s 0x73
-#define KEY_SYM_t 0x74
-#define KEY_SYM_u 0x75
-#define KEY_SYM_v 0x76
-#define KEY_SYM_w 0x77
-#define KEY_SYM_x 0x78
-#define KEY_SYM_y 0x79
-#define KEY_SYM_z 0x7A
-#define KEY_SYM_SPACE 0x20
-#endif /* _IBMASM_REMOTE_H_ */
diff --git a/ANDROID_3.4.5/drivers/misc/ibmasm/uart.c b/ANDROID_3.4.5/drivers/misc/ibmasm/uart.c
deleted file mode 100644
index 1dcb9ae1..00000000
--- a/ANDROID_3.4.5/drivers/misc/ibmasm/uart.c
+++ /dev/null
@@ -1,72 +0,0 @@
-
-/*
- * IBM ASM Service Processor Device Driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2004
- *
- * Author: Max Asböck <amax@us.ibm.com>
- *
- */
-
-#include <linux/termios.h>
-#include <linux/tty.h>
-#include <linux/serial_core.h>
-#include <linux/serial_reg.h>
-#include <linux/serial_8250.h>
-#include "ibmasm.h"
-#include "lowlevel.h"
-
-
-void ibmasm_register_uart(struct service_processor *sp)
-{
- struct uart_port uport;
- void __iomem *iomem_base;
-
- iomem_base = sp->base_address + SCOUT_COM_B_BASE;
-
- /* read the uart scratch register to determine if the UART
- * is dedicated to the service processor or if the OS can use it
- */
- if (0 == readl(iomem_base + UART_SCR)) {
- dev_info(sp->dev, "IBM SP UART not registered, owned by service processor\n");
- sp->serial_line = -1;
- return;
- }
-
- memset(&uport, 0, sizeof(struct uart_port));
- uport.irq = sp->irq;
- uport.uartclk = 3686400;
- uport.flags = UPF_SHARE_IRQ;
- uport.iotype = UPIO_MEM;
- uport.membase = iomem_base;
-
- sp->serial_line = serial8250_register_port(&uport);
- if (sp->serial_line < 0) {
- dev_err(sp->dev, "Failed to register serial port\n");
- return;
- }
- enable_uart_interrupts(sp->base_address);
-}
-
-void ibmasm_unregister_uart(struct service_processor *sp)
-{
- if (sp->serial_line < 0)
- return;
-
- disable_uart_interrupts(sp->base_address);
- serial8250_unregister_port(sp->serial_line);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ics932s401.c b/ANDROID_3.4.5/drivers/misc/ics932s401.c
deleted file mode 100644
index 00295367..00000000
--- a/ANDROID_3.4.5/drivers/misc/ics932s401.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * A driver for the Integrated Circuits ICS932S401
- * Copyright (C) 2008 IBM
- *
- * Author: Darrick J. Wong <djwong@us.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/log2.h>
-#include <linux/slab.h>
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END };
-
-/* ICS932S401 registers */
-#define ICS932S401_REG_CFG2 0x01
-#define ICS932S401_CFG1_SPREAD 0x01
-#define ICS932S401_REG_CFG7 0x06
-#define ICS932S401_FS_MASK 0x07
-#define ICS932S401_REG_VENDOR_REV 0x07
-#define ICS932S401_VENDOR 1
-#define ICS932S401_VENDOR_MASK 0x0F
-#define ICS932S401_REV 4
-#define ICS932S401_REV_SHIFT 4
-#define ICS932S401_REG_DEVICE 0x09
-#define ICS932S401_DEVICE 11
-#define ICS932S401_REG_CTRL 0x0A
-#define ICS932S401_MN_ENABLED 0x80
-#define ICS932S401_CPU_ALT 0x04
-#define ICS932S401_SRC_ALT 0x08
-#define ICS932S401_REG_CPU_M_CTRL 0x0B
-#define ICS932S401_M_MASK 0x3F
-#define ICS932S401_REG_CPU_N_CTRL 0x0C
-#define ICS932S401_REG_CPU_SPREAD1 0x0D
-#define ICS932S401_REG_CPU_SPREAD2 0x0E
-#define ICS932S401_SPREAD_MASK 0x7FFF
-#define ICS932S401_REG_SRC_M_CTRL 0x0F
-#define ICS932S401_REG_SRC_N_CTRL 0x10
-#define ICS932S401_REG_SRC_SPREAD1 0x11
-#define ICS932S401_REG_SRC_SPREAD2 0x12
-#define ICS932S401_REG_CPU_DIVISOR 0x13
-#define ICS932S401_CPU_DIVISOR_SHIFT 4
-#define ICS932S401_REG_PCISRC_DIVISOR 0x14
-#define ICS932S401_SRC_DIVISOR_MASK 0x0F
-#define ICS932S401_PCI_DIVISOR_SHIFT 4
-
-/* Base clock is 14.318MHz */
-#define BASE_CLOCK 14318
-
-#define NUM_REGS 21
-#define NUM_MIRRORED_REGS 15
-
-static int regs_to_copy[NUM_MIRRORED_REGS] = {
- ICS932S401_REG_CFG2,
- ICS932S401_REG_CFG7,
- ICS932S401_REG_VENDOR_REV,
- ICS932S401_REG_DEVICE,
- ICS932S401_REG_CTRL,
- ICS932S401_REG_CPU_M_CTRL,
- ICS932S401_REG_CPU_N_CTRL,
- ICS932S401_REG_CPU_SPREAD1,
- ICS932S401_REG_CPU_SPREAD2,
- ICS932S401_REG_SRC_M_CTRL,
- ICS932S401_REG_SRC_N_CTRL,
- ICS932S401_REG_SRC_SPREAD1,
- ICS932S401_REG_SRC_SPREAD2,
- ICS932S401_REG_CPU_DIVISOR,
- ICS932S401_REG_PCISRC_DIVISOR,
-};
-
-/* How often do we reread sensors values? (In jiffies) */
-#define SENSOR_REFRESH_INTERVAL (2 * HZ)
-
-/* How often do we reread sensor limit values? (In jiffies) */
-#define LIMIT_REFRESH_INTERVAL (60 * HZ)
-
-struct ics932s401_data {
- struct attribute_group attrs;
- struct mutex lock;
- char sensors_valid;
- unsigned long sensors_last_updated; /* In jiffies */
-
- u8 regs[NUM_REGS];
-};
-
-static int ics932s401_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int ics932s401_detect(struct i2c_client *client,
- struct i2c_board_info *info);
-static int ics932s401_remove(struct i2c_client *client);
-
-static const struct i2c_device_id ics932s401_id[] = {
- { "ics932s401", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ics932s401_id);
-
-static struct i2c_driver ics932s401_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "ics932s401",
- },
- .probe = ics932s401_probe,
- .remove = ics932s401_remove,
- .id_table = ics932s401_id,
- .detect = ics932s401_detect,
- .address_list = normal_i2c,
-};
-
-static struct ics932s401_data *ics932s401_update_device(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct ics932s401_data *data = i2c_get_clientdata(client);
- unsigned long local_jiffies = jiffies;
- int i, temp;
-
- mutex_lock(&data->lock);
- if (time_before(local_jiffies, data->sensors_last_updated +
- SENSOR_REFRESH_INTERVAL)
- && data->sensors_valid)
- goto out;
-
- /*
- * Each register must be read as a word and then right shifted 8 bits.
- * Not really sure why this is; setting the "byte count programming"
- * register to 1 does not fix this problem.
- */
- for (i = 0; i < NUM_MIRRORED_REGS; i++) {
- temp = i2c_smbus_read_word_data(client, regs_to_copy[i]);
- data->regs[regs_to_copy[i]] = temp >> 8;
- }
-
- data->sensors_last_updated = local_jiffies;
- data->sensors_valid = 1;
-
-out:
- mutex_unlock(&data->lock);
- return data;
-}
-
-static ssize_t show_spread_enabled(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct ics932s401_data *data = ics932s401_update_device(dev);
-
- if (data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD)
- return sprintf(buf, "1\n");
-
- return sprintf(buf, "0\n");
-}
-
-/* bit to cpu khz map */
-static const int fs_speeds[] = {
- 266666,
- 133333,
- 200000,
- 166666,
- 333333,
- 100000,
- 400000,
- 0,
-};
-
-/* clock divisor map */
-static const int divisors[] = {2, 3, 5, 15, 4, 6, 10, 30, 8, 12, 20, 60, 16,
- 24, 40, 120};
-
-/* Calculate CPU frequency from the M/N registers. */
-static int calculate_cpu_freq(struct ics932s401_data *data)
-{
- int m, n, freq;
-
- m = data->regs[ICS932S401_REG_CPU_M_CTRL] & ICS932S401_M_MASK;
- n = data->regs[ICS932S401_REG_CPU_N_CTRL];
-
- /* Pull in bits 8 & 9 from the M register */
- n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x80) << 1;
- n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x40) << 3;
-
- freq = BASE_CLOCK * (n + 8) / (m + 2);
- freq /= divisors[data->regs[ICS932S401_REG_CPU_DIVISOR] >>
- ICS932S401_CPU_DIVISOR_SHIFT];
-
- return freq;
-}
-
-static ssize_t show_cpu_clock(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct ics932s401_data *data = ics932s401_update_device(dev);
-
- return sprintf(buf, "%d\n", calculate_cpu_freq(data));
-}
-
-static ssize_t show_cpu_clock_sel(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct ics932s401_data *data = ics932s401_update_device(dev);
- int freq;
-
- if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)
- freq = calculate_cpu_freq(data);
- else {
- /* Freq is neatly wrapped up for us */
- int fid = data->regs[ICS932S401_REG_CFG7] & ICS932S401_FS_MASK;
- freq = fs_speeds[fid];
- if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT) {
- switch (freq) {
- case 166666:
- freq = 160000;
- break;
- case 333333:
- freq = 320000;
- break;
- }
- }
- }
-
- return sprintf(buf, "%d\n", freq);
-}
-
-/* Calculate SRC frequency from the M/N registers. */
-static int calculate_src_freq(struct ics932s401_data *data)
-{
- int m, n, freq;
-
- m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK;
- n = data->regs[ICS932S401_REG_SRC_N_CTRL];
-
- /* Pull in bits 8 & 9 from the M register */
- n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1;
- n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3;
-
- freq = BASE_CLOCK * (n + 8) / (m + 2);
- freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] &
- ICS932S401_SRC_DIVISOR_MASK];
-
- return freq;
-}
-
-static ssize_t show_src_clock(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct ics932s401_data *data = ics932s401_update_device(dev);
-
- return sprintf(buf, "%d\n", calculate_src_freq(data));
-}
-
-static ssize_t show_src_clock_sel(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct ics932s401_data *data = ics932s401_update_device(dev);
- int freq;
-
- if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)
- freq = calculate_src_freq(data);
- else
- /* Freq is neatly wrapped up for us */
- if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT &&
- data->regs[ICS932S401_REG_CTRL] & ICS932S401_SRC_ALT)
- freq = 96000;
- else
- freq = 100000;
-
- return sprintf(buf, "%d\n", freq);
-}
-
-/* Calculate PCI frequency from the SRC M/N registers. */
-static int calculate_pci_freq(struct ics932s401_data *data)
-{
- int m, n, freq;
-
- m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK;
- n = data->regs[ICS932S401_REG_SRC_N_CTRL];
-
- /* Pull in bits 8 & 9 from the M register */
- n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1;
- n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3;
-
- freq = BASE_CLOCK * (n + 8) / (m + 2);
- freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] >>
- ICS932S401_PCI_DIVISOR_SHIFT];
-
- return freq;
-}
-
-static ssize_t show_pci_clock(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct ics932s401_data *data = ics932s401_update_device(dev);
-
- return sprintf(buf, "%d\n", calculate_pci_freq(data));
-}
-
-static ssize_t show_pci_clock_sel(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct ics932s401_data *data = ics932s401_update_device(dev);
- int freq;
-
- if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED)
- freq = calculate_pci_freq(data);
- else
- freq = 33333;
-
- return sprintf(buf, "%d\n", freq);
-}
-
-static ssize_t show_value(struct device *dev,
- struct device_attribute *devattr,
- char *buf);
-
-static ssize_t show_spread(struct device *dev,
- struct device_attribute *devattr,
- char *buf);
-
-static DEVICE_ATTR(spread_enabled, S_IRUGO, show_spread_enabled, NULL);
-static DEVICE_ATTR(cpu_clock_selection, S_IRUGO, show_cpu_clock_sel, NULL);
-static DEVICE_ATTR(cpu_clock, S_IRUGO, show_cpu_clock, NULL);
-static DEVICE_ATTR(src_clock_selection, S_IRUGO, show_src_clock_sel, NULL);
-static DEVICE_ATTR(src_clock, S_IRUGO, show_src_clock, NULL);
-static DEVICE_ATTR(pci_clock_selection, S_IRUGO, show_pci_clock_sel, NULL);
-static DEVICE_ATTR(pci_clock, S_IRUGO, show_pci_clock, NULL);
-static DEVICE_ATTR(usb_clock, S_IRUGO, show_value, NULL);
-static DEVICE_ATTR(ref_clock, S_IRUGO, show_value, NULL);
-static DEVICE_ATTR(cpu_spread, S_IRUGO, show_spread, NULL);
-static DEVICE_ATTR(src_spread, S_IRUGO, show_spread, NULL);
-
-static struct attribute *ics932s401_attr[] =
-{
- &dev_attr_spread_enabled.attr,
- &dev_attr_cpu_clock_selection.attr,
- &dev_attr_cpu_clock.attr,
- &dev_attr_src_clock_selection.attr,
- &dev_attr_src_clock.attr,
- &dev_attr_pci_clock_selection.attr,
- &dev_attr_pci_clock.attr,
- &dev_attr_usb_clock.attr,
- &dev_attr_ref_clock.attr,
- &dev_attr_cpu_spread.attr,
- &dev_attr_src_spread.attr,
- NULL
-};
-
-static ssize_t show_value(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- int x;
-
- if (devattr == &dev_attr_usb_clock)
- x = 48000;
- else if (devattr == &dev_attr_ref_clock)
- x = BASE_CLOCK;
- else
- BUG();
-
- return sprintf(buf, "%d\n", x);
-}
-
-static ssize_t show_spread(struct device *dev,
- struct device_attribute *devattr,
- char *buf)
-{
- struct ics932s401_data *data = ics932s401_update_device(dev);
- int reg;
- unsigned long val;
-
- if (!(data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD))
- return sprintf(buf, "0%%\n");
-
- if (devattr == &dev_attr_src_spread)
- reg = ICS932S401_REG_SRC_SPREAD1;
- else if (devattr == &dev_attr_cpu_spread)
- reg = ICS932S401_REG_CPU_SPREAD1;
- else
- BUG();
-
- val = data->regs[reg] | (data->regs[reg + 1] << 8);
- val &= ICS932S401_SPREAD_MASK;
-
- /* Scale 0..2^14 to -0.5. */
- val = 500000 * val / 16384;
- return sprintf(buf, "-0.%lu%%\n", val);
-}
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int ics932s401_detect(struct i2c_client *client,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
- int vendor, device, revision;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- vendor = i2c_smbus_read_word_data(client, ICS932S401_REG_VENDOR_REV);
- vendor >>= 8;
- revision = vendor >> ICS932S401_REV_SHIFT;
- vendor &= ICS932S401_VENDOR_MASK;
- if (vendor != ICS932S401_VENDOR)
- return -ENODEV;
-
- device = i2c_smbus_read_word_data(client, ICS932S401_REG_DEVICE);
- device >>= 8;
- if (device != ICS932S401_DEVICE)
- return -ENODEV;
-
- if (revision != ICS932S401_REV)
- dev_info(&adapter->dev, "Unknown revision %d\n", revision);
-
- strlcpy(info->type, "ics932s401", I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int ics932s401_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct ics932s401_data *data;
- int err;
-
- data = kzalloc(sizeof(struct ics932s401_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
-
- i2c_set_clientdata(client, data);
- mutex_init(&data->lock);
-
- dev_info(&client->dev, "%s chip found\n", client->name);
-
- /* Register sysfs hooks */
- data->attrs.attrs = ics932s401_attr;
- err = sysfs_create_group(&client->dev.kobj, &data->attrs);
- if (err)
- goto exit_free;
-
- return 0;
-
-exit_free:
- kfree(data);
-exit:
- return err;
-}
-
-static int ics932s401_remove(struct i2c_client *client)
-{
- struct ics932s401_data *data = i2c_get_clientdata(client);
-
- sysfs_remove_group(&client->dev.kobj, &data->attrs);
- kfree(data);
- return 0;
-}
-
-module_i2c_driver(ics932s401_driver);
-
-MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
-MODULE_DESCRIPTION("ICS932S401 driver");
-MODULE_LICENSE("GPL");
-
-/* IBM IntelliStation Z30 */
-MODULE_ALIAS("dmi:bvnIBM:*:rn9228:*");
-MODULE_ALIAS("dmi:bvnIBM:*:rn9232:*");
-
-/* IBM x3650/x3550 */
-MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650*");
-MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550*");
diff --git a/ANDROID_3.4.5/drivers/misc/ioc4.c b/ANDROID_3.4.5/drivers/misc/ioc4.c
deleted file mode 100644
index df03dd3b..00000000
--- a/ANDROID_3.4.5/drivers/misc/ioc4.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2005-2006 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/* This file contains the master driver module for use by SGI IOC4 subdrivers.
- *
- * It allocates any resources shared between multiple subdevices, and
- * provides accessor functions (where needed) and the like for those
- * resources. It also provides a mechanism for the subdevice modules
- * to support loading and unloading.
- *
- * Non-shared resources (e.g. external interrupt A_INT_OUT register page
- * alias, serial port and UART registers) are handled by the subdevice
- * modules themselves.
- *
- * This is all necessary because IOC4 is not implemented as a multi-function
- * PCI device, but an amalgamation of disparate registers for several
- * types of device (ATA, serial, external interrupts). The normal
- * resource management in the kernel doesn't have quite the right interfaces
- * to handle this situation (e.g. multiple modules can't claim the same
- * PCI ID), thus this IOC4 master module.
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/ioc4.h>
-#include <linux/ktime.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/time.h>
-#include <asm/io.h>
-
-/***************
- * Definitions *
- ***************/
-
-/* Tweakable values */
-
-/* PCI bus speed detection/calibration */
-#define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */
-#define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */
-#define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */
-#define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */
-#define IOC4_CALIBRATE_HIGH_MHZ 75 /* Upper bound on bus speed sanity */
-#define IOC4_CALIBRATE_DEFAULT_MHZ 66 /* Assumed if sanity check fails */
-
-/************************
- * Submodule management *
- ************************/
-
-static DEFINE_MUTEX(ioc4_mutex);
-
-static LIST_HEAD(ioc4_devices);
-static LIST_HEAD(ioc4_submodules);
-
-/* Register an IOC4 submodule */
-int
-ioc4_register_submodule(struct ioc4_submodule *is)
-{
- struct ioc4_driver_data *idd;
-
- mutex_lock(&ioc4_mutex);
- list_add(&is->is_list, &ioc4_submodules);
-
- /* Initialize submodule for each IOC4 */
- if (!is->is_probe)
- goto out;
-
- list_for_each_entry(idd, &ioc4_devices, idd_list) {
- if (is->is_probe(idd)) {
- printk(KERN_WARNING
- "%s: IOC4 submodule %s probe failed "
- "for pci_dev %s",
- __func__, module_name(is->is_owner),
- pci_name(idd->idd_pdev));
- }
- }
- out:
- mutex_unlock(&ioc4_mutex);
- return 0;
-}
-
-/* Unregister an IOC4 submodule */
-void
-ioc4_unregister_submodule(struct ioc4_submodule *is)
-{
- struct ioc4_driver_data *idd;
-
- mutex_lock(&ioc4_mutex);
- list_del(&is->is_list);
-
- /* Remove submodule for each IOC4 */
- if (!is->is_remove)
- goto out;
-
- list_for_each_entry(idd, &ioc4_devices, idd_list) {
- if (is->is_remove(idd)) {
- printk(KERN_WARNING
- "%s: IOC4 submodule %s remove failed "
- "for pci_dev %s.\n",
- __func__, module_name(is->is_owner),
- pci_name(idd->idd_pdev));
- }
- }
- out:
- mutex_unlock(&ioc4_mutex);
-}
-
-/*********************
- * Device management *
- *********************/
-
-#define IOC4_CALIBRATE_LOW_LIMIT \
- (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_LOW_MHZ)
-#define IOC4_CALIBRATE_HIGH_LIMIT \
- (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_HIGH_MHZ)
-#define IOC4_CALIBRATE_DEFAULT \
- (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_DEFAULT_MHZ)
-
-#define IOC4_CALIBRATE_END \
- (IOC4_CALIBRATE_CYCLES + IOC4_CALIBRATE_DISCARD)
-
-#define IOC4_INT_OUT_MODE_TOGGLE 0x7 /* Toggle INT_OUT every COUNT+1 ticks */
-
-/* Determines external interrupt output clock period of the PCI bus an
- * IOC4 is attached to. This value can be used to determine the PCI
- * bus speed.
- *
- * IOC4 has a design feature that various internal timers are derived from
- * the PCI bus clock. This causes IOC4 device drivers to need to take the
- * bus speed into account when setting various register values (e.g. INT_OUT
- * register COUNT field, UART divisors, etc). Since this information is
- * needed by several subdrivers, it is determined by the main IOC4 driver,
- * even though the following code utilizes external interrupt registers
- * to perform the speed calculation.
- */
-static void __devinit
-ioc4_clock_calibrate(struct ioc4_driver_data *idd)
-{
- union ioc4_int_out int_out;
- union ioc4_gpcr gpcr;
- unsigned int state, last_state = 1;
- struct timespec start_ts, end_ts;
- uint64_t start, end, period;
- unsigned int count = 0;
-
- /* Enable output */
- gpcr.raw = 0;
- gpcr.fields.dir = IOC4_GPCR_DIR_0;
- gpcr.fields.int_out_en = 1;
- writel(gpcr.raw, &idd->idd_misc_regs->gpcr_s.raw);
-
- /* Reset to power-on state */
- writel(0, &idd->idd_misc_regs->int_out.raw);
- mmiowb();
-
- /* Set up square wave */
- int_out.raw = 0;
- int_out.fields.count = IOC4_CALIBRATE_COUNT;
- int_out.fields.mode = IOC4_INT_OUT_MODE_TOGGLE;
- int_out.fields.diag = 0;
- writel(int_out.raw, &idd->idd_misc_regs->int_out.raw);
- mmiowb();
-
- /* Check square wave period averaged over some number of cycles */
- do {
- int_out.raw = readl(&idd->idd_misc_regs->int_out.raw);
- state = int_out.fields.int_out;
- if (!last_state && state) {
- count++;
- if (count == IOC4_CALIBRATE_END) {
- ktime_get_ts(&end_ts);
- break;
- } else if (count == IOC4_CALIBRATE_DISCARD)
- ktime_get_ts(&start_ts);
- }
- last_state = state;
- } while (1);
-
- /* Calculation rearranged to preserve intermediate precision.
- * Logically:
- * 1. "end - start" gives us the measurement period over all
- * the square wave cycles.
- * 2. Divide by number of square wave cycles to get the period
- * of a square wave cycle.
- * 3. Divide by 2*(int_out.fields.count+1), which is the formula
- * by which the IOC4 generates the square wave, to get the
- * period of an IOC4 INT_OUT count.
- */
- end = end_ts.tv_sec * NSEC_PER_SEC + end_ts.tv_nsec;
- start = start_ts.tv_sec * NSEC_PER_SEC + start_ts.tv_nsec;
- period = (end - start) /
- (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1));
-
- /* Bounds check the result. */
- if (period > IOC4_CALIBRATE_LOW_LIMIT ||
- period < IOC4_CALIBRATE_HIGH_LIMIT) {
- printk(KERN_INFO
- "IOC4 %s: Clock calibration failed. Assuming"
- "PCI clock is %d ns.\n",
- pci_name(idd->idd_pdev),
- IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR);
- period = IOC4_CALIBRATE_DEFAULT;
- } else {
- u64 ns = period;
-
- do_div(ns, IOC4_EXTINT_COUNT_DIVISOR);
- printk(KERN_DEBUG
- "IOC4 %s: PCI clock is %llu ns.\n",
- pci_name(idd->idd_pdev), (unsigned long long)ns);
- }
-
- /* Remember results. We store the extint clock period rather
- * than the PCI clock period so that greater precision is
- * retained. Divide by IOC4_EXTINT_COUNT_DIVISOR to get
- * PCI clock period.
- */
- idd->count_period = period;
-}
-
-/* There are three variants of IOC4 cards: IO9, IO10, and PCI-RT.
- * Each brings out different combinations of IOC4 signals, thus.
- * the IOC4 subdrivers need to know to which we're attached.
- *
- * We look for the presence of a SCSI (IO9) or SATA (IO10) controller
- * on the same PCI bus at slot number 3 to differentiate IO9 from IO10.
- * If neither is present, it's a PCI-RT.
- */
-static unsigned int __devinit
-ioc4_variant(struct ioc4_driver_data *idd)
-{
- struct pci_dev *pdev = NULL;
- int found = 0;
-
- /* IO9: Look for a QLogic ISP 12160 at the same bus and slot 3. */
- do {
- pdev = pci_get_device(PCI_VENDOR_ID_QLOGIC,
- PCI_DEVICE_ID_QLOGIC_ISP12160, pdev);
- if (pdev &&
- idd->idd_pdev->bus->number == pdev->bus->number &&
- 3 == PCI_SLOT(pdev->devfn))
- found = 1;
- } while (pdev && !found);
- if (NULL != pdev) {
- pci_dev_put(pdev);
- return IOC4_VARIANT_IO9;
- }
-
- /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */
- pdev = NULL;
- do {
- pdev = pci_get_device(PCI_VENDOR_ID_VITESSE,
- PCI_DEVICE_ID_VITESSE_VSC7174, pdev);
- if (pdev &&
- idd->idd_pdev->bus->number == pdev->bus->number &&
- 3 == PCI_SLOT(pdev->devfn))
- found = 1;
- } while (pdev && !found);
- if (NULL != pdev) {
- pci_dev_put(pdev);
- return IOC4_VARIANT_IO10;
- }
-
- /* PCI-RT: No SCSI/SATA controller will be present */
- return IOC4_VARIANT_PCI_RT;
-}
-
-static void
-ioc4_load_modules(struct work_struct *work)
-{
- request_module("sgiioc4");
-}
-
-static DECLARE_WORK(ioc4_load_modules_work, ioc4_load_modules);
-
-/* Adds a new instance of an IOC4 card */
-static int __devinit
-ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
-{
- struct ioc4_driver_data *idd;
- struct ioc4_submodule *is;
- uint32_t pcmd;
- int ret;
-
- /* Enable IOC4 and take ownership of it */
- if ((ret = pci_enable_device(pdev))) {
- printk(KERN_WARNING
- "%s: Failed to enable IOC4 device for pci_dev %s.\n",
- __func__, pci_name(pdev));
- goto out;
- }
- pci_set_master(pdev);
-
- /* Set up per-IOC4 data */
- idd = kmalloc(sizeof(struct ioc4_driver_data), GFP_KERNEL);
- if (!idd) {
- printk(KERN_WARNING
- "%s: Failed to allocate IOC4 data for pci_dev %s.\n",
- __func__, pci_name(pdev));
- ret = -ENODEV;
- goto out_idd;
- }
- idd->idd_pdev = pdev;
- idd->idd_pci_id = pci_id;
-
- /* Map IOC4 misc registers. These are shared between subdevices
- * so the main IOC4 module manages them.
- */
- idd->idd_bar0 = pci_resource_start(idd->idd_pdev, 0);
- if (!idd->idd_bar0) {
- printk(KERN_WARNING
- "%s: Unable to find IOC4 misc resource "
- "for pci_dev %s.\n",
- __func__, pci_name(idd->idd_pdev));
- ret = -ENODEV;
- goto out_pci;
- }
- if (!request_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
- "ioc4_misc")) {
- printk(KERN_WARNING
- "%s: Unable to request IOC4 misc region "
- "for pci_dev %s.\n",
- __func__, pci_name(idd->idd_pdev));
- ret = -ENODEV;
- goto out_pci;
- }
- idd->idd_misc_regs = ioremap(idd->idd_bar0,
- sizeof(struct ioc4_misc_regs));
- if (!idd->idd_misc_regs) {
- printk(KERN_WARNING
- "%s: Unable to remap IOC4 misc region "
- "for pci_dev %s.\n",
- __func__, pci_name(idd->idd_pdev));
- ret = -ENODEV;
- goto out_misc_region;
- }
-
- /* Failsafe portion of per-IOC4 initialization */
-
- /* Detect card variant */
- idd->idd_variant = ioc4_variant(idd);
- printk(KERN_INFO "IOC4 %s: %s card detected.\n", pci_name(pdev),
- idd->idd_variant == IOC4_VARIANT_IO9 ? "IO9" :
- idd->idd_variant == IOC4_VARIANT_PCI_RT ? "PCI-RT" :
- idd->idd_variant == IOC4_VARIANT_IO10 ? "IO10" : "unknown");
-
- /* Initialize IOC4 */
- pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd);
- pci_write_config_dword(idd->idd_pdev, PCI_COMMAND,
- pcmd | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
-
- /* Determine PCI clock */
- ioc4_clock_calibrate(idd);
-
- /* Disable/clear all interrupts. Need to do this here lest
- * one submodule request the shared IOC4 IRQ, but interrupt
- * is generated by a different subdevice.
- */
- /* Disable */
- writel(~0, &idd->idd_misc_regs->other_iec.raw);
- writel(~0, &idd->idd_misc_regs->sio_iec);
- /* Clear (i.e. acknowledge) */
- writel(~0, &idd->idd_misc_regs->other_ir.raw);
- writel(~0, &idd->idd_misc_regs->sio_ir);
-
- /* Track PCI-device specific data */
- idd->idd_serial_data = NULL;
- pci_set_drvdata(idd->idd_pdev, idd);
-
- mutex_lock(&ioc4_mutex);
- list_add_tail(&idd->idd_list, &ioc4_devices);
-
- /* Add this IOC4 to all submodules */
- list_for_each_entry(is, &ioc4_submodules, is_list) {
- if (is->is_probe && is->is_probe(idd)) {
- printk(KERN_WARNING
- "%s: IOC4 submodule 0x%s probe failed "
- "for pci_dev %s.\n",
- __func__, module_name(is->is_owner),
- pci_name(idd->idd_pdev));
- }
- }
- mutex_unlock(&ioc4_mutex);
-
- /* Request sgiioc4 IDE driver on boards that bring that functionality
- * off of IOC4. The root filesystem may be hosted on a drive connected
- * to IOC4, so we need to make sure the sgiioc4 driver is loaded as it
- * won't be picked up by modprobes due to the ioc4 module owning the
- * PCI device.
- */
- if (idd->idd_variant != IOC4_VARIANT_PCI_RT) {
- /* Request the module from a work procedure as the modprobe
- * goes out to a userland helper and that will hang if done
- * directly from ioc4_probe().
- */
- printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n");
- schedule_work(&ioc4_load_modules_work);
- }
-
- return 0;
-
-out_misc_region:
- release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
-out_pci:
- kfree(idd);
-out_idd:
- pci_disable_device(pdev);
-out:
- return ret;
-}
-
-/* Removes a particular instance of an IOC4 card. */
-static void __devexit
-ioc4_remove(struct pci_dev *pdev)
-{
- struct ioc4_submodule *is;
- struct ioc4_driver_data *idd;
-
- idd = pci_get_drvdata(pdev);
-
- /* Remove this IOC4 from all submodules */
- mutex_lock(&ioc4_mutex);
- list_for_each_entry(is, &ioc4_submodules, is_list) {
- if (is->is_remove && is->is_remove(idd)) {
- printk(KERN_WARNING
- "%s: IOC4 submodule 0x%s remove failed "
- "for pci_dev %s.\n",
- __func__, module_name(is->is_owner),
- pci_name(idd->idd_pdev));
- }
- }
- mutex_unlock(&ioc4_mutex);
-
- /* Release resources */
- iounmap(idd->idd_misc_regs);
- if (!idd->idd_bar0) {
- printk(KERN_WARNING
- "%s: Unable to get IOC4 misc mapping for pci_dev %s. "
- "Device removal may be incomplete.\n",
- __func__, pci_name(idd->idd_pdev));
- }
- release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
-
- /* Disable IOC4 and relinquish */
- pci_disable_device(pdev);
-
- /* Remove and free driver data */
- mutex_lock(&ioc4_mutex);
- list_del(&idd->idd_list);
- mutex_unlock(&ioc4_mutex);
- kfree(idd);
-}
-
-static struct pci_device_id ioc4_id_table[] = {
- {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID,
- PCI_ANY_ID, 0x0b4000, 0xFFFFFF},
- {0}
-};
-
-static struct pci_driver ioc4_driver = {
- .name = "IOC4",
- .id_table = ioc4_id_table,
- .probe = ioc4_probe,
- .remove = __devexit_p(ioc4_remove),
-};
-
-MODULE_DEVICE_TABLE(pci, ioc4_id_table);
-
-/*********************
- * Module management *
- *********************/
-
-/* Module load */
-static int __init
-ioc4_init(void)
-{
- return pci_register_driver(&ioc4_driver);
-}
-
-/* Module unload */
-static void __exit
-ioc4_exit(void)
-{
- /* Ensure ioc4_load_modules() has completed before exiting */
- flush_work_sync(&ioc4_load_modules_work);
- pci_unregister_driver(&ioc4_driver);
-}
-
-module_init(ioc4_init);
-module_exit(ioc4_exit);
-
-MODULE_AUTHOR("Brent Casavant - Silicon Graphics, Inc. <bcasavan@sgi.com>");
-MODULE_DESCRIPTION("PCI driver master module for SGI IOC4 Base-IO Card");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(ioc4_register_submodule);
-EXPORT_SYMBOL(ioc4_unregister_submodule);
diff --git a/ANDROID_3.4.5/drivers/misc/isl29003.c b/ANDROID_3.4.5/drivers/misc/isl29003.c
deleted file mode 100644
index eb5de2e2..00000000
--- a/ANDROID_3.4.5/drivers/misc/isl29003.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * isl29003.c - Linux kernel module for
- * Intersil ISL29003 ambient light sensor
- *
- * See file:Documentation/misc-devices/isl29003
- *
- * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- * Based on code written by
- * Rodolfo Giometti <giometti@linux.it>
- * Eurotech S.p.A. <info@eurotech.it>
- *
- * This program is free software; you can redistribute 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/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-
-#define ISL29003_DRV_NAME "isl29003"
-#define DRIVER_VERSION "1.0"
-
-#define ISL29003_REG_COMMAND 0x00
-#define ISL29003_ADC_ENABLED (1 << 7)
-#define ISL29003_ADC_PD (1 << 6)
-#define ISL29003_TIMING_INT (1 << 5)
-#define ISL29003_MODE_SHIFT (2)
-#define ISL29003_MODE_MASK (0x3 << ISL29003_MODE_SHIFT)
-#define ISL29003_RES_SHIFT (0)
-#define ISL29003_RES_MASK (0x3 << ISL29003_RES_SHIFT)
-
-#define ISL29003_REG_CONTROL 0x01
-#define ISL29003_INT_FLG (1 << 5)
-#define ISL29003_RANGE_SHIFT (2)
-#define ISL29003_RANGE_MASK (0x3 << ISL29003_RANGE_SHIFT)
-#define ISL29003_INT_PERSISTS_SHIFT (0)
-#define ISL29003_INT_PERSISTS_MASK (0xf << ISL29003_INT_PERSISTS_SHIFT)
-
-#define ISL29003_REG_IRQ_THRESH_HI 0x02
-#define ISL29003_REG_IRQ_THRESH_LO 0x03
-#define ISL29003_REG_LSB_SENSOR 0x04
-#define ISL29003_REG_MSB_SENSOR 0x05
-#define ISL29003_REG_LSB_TIMER 0x06
-#define ISL29003_REG_MSB_TIMER 0x07
-
-#define ISL29003_NUM_CACHABLE_REGS 4
-
-struct isl29003_data {
- struct i2c_client *client;
- struct mutex lock;
- u8 reg_cache[ISL29003_NUM_CACHABLE_REGS];
- u8 power_state_before_suspend;
-};
-
-static int gain_range[] = {
- 1000, 4000, 16000, 64000
-};
-
-/*
- * register access helpers
- */
-
-static int __isl29003_read_reg(struct i2c_client *client,
- u32 reg, u8 mask, u8 shift)
-{
- struct isl29003_data *data = i2c_get_clientdata(client);
- return (data->reg_cache[reg] & mask) >> shift;
-}
-
-static int __isl29003_write_reg(struct i2c_client *client,
- u32 reg, u8 mask, u8 shift, u8 val)
-{
- struct isl29003_data *data = i2c_get_clientdata(client);
- int ret = 0;
- u8 tmp;
-
- if (reg >= ISL29003_NUM_CACHABLE_REGS)
- return -EINVAL;
-
- mutex_lock(&data->lock);
-
- tmp = data->reg_cache[reg];
- tmp &= ~mask;
- tmp |= val << shift;
-
- ret = i2c_smbus_write_byte_data(client, reg, tmp);
- if (!ret)
- data->reg_cache[reg] = tmp;
-
- mutex_unlock(&data->lock);
- return ret;
-}
-
-/*
- * internally used functions
- */
-
-/* range */
-static int isl29003_get_range(struct i2c_client *client)
-{
- return __isl29003_read_reg(client, ISL29003_REG_CONTROL,
- ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT);
-}
-
-static int isl29003_set_range(struct i2c_client *client, int range)
-{
- return __isl29003_write_reg(client, ISL29003_REG_CONTROL,
- ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT, range);
-}
-
-/* resolution */
-static int isl29003_get_resolution(struct i2c_client *client)
-{
- return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
- ISL29003_RES_MASK, ISL29003_RES_SHIFT);
-}
-
-static int isl29003_set_resolution(struct i2c_client *client, int res)
-{
- return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
- ISL29003_RES_MASK, ISL29003_RES_SHIFT, res);
-}
-
-/* mode */
-static int isl29003_get_mode(struct i2c_client *client)
-{
- return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
- ISL29003_RES_MASK, ISL29003_RES_SHIFT);
-}
-
-static int isl29003_set_mode(struct i2c_client *client, int mode)
-{
- return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
- ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode);
-}
-
-/* power_state */
-static int isl29003_set_power_state(struct i2c_client *client, int state)
-{
- return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
- ISL29003_ADC_ENABLED | ISL29003_ADC_PD, 0,
- state ? ISL29003_ADC_ENABLED : ISL29003_ADC_PD);
-}
-
-static int isl29003_get_power_state(struct i2c_client *client)
-{
- struct isl29003_data *data = i2c_get_clientdata(client);
- u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND];
- return ~cmdreg & ISL29003_ADC_PD;
-}
-
-static int isl29003_get_adc_value(struct i2c_client *client)
-{
- struct isl29003_data *data = i2c_get_clientdata(client);
- int lsb, msb, range, bitdepth;
-
- mutex_lock(&data->lock);
- lsb = i2c_smbus_read_byte_data(client, ISL29003_REG_LSB_SENSOR);
-
- if (lsb < 0) {
- mutex_unlock(&data->lock);
- return lsb;
- }
-
- msb = i2c_smbus_read_byte_data(client, ISL29003_REG_MSB_SENSOR);
- mutex_unlock(&data->lock);
-
- if (msb < 0)
- return msb;
-
- range = isl29003_get_range(client);
- bitdepth = (4 - isl29003_get_resolution(client)) * 4;
- return (((msb << 8) | lsb) * gain_range[range]) >> bitdepth;
-}
-
-/*
- * sysfs layer
- */
-
-/* range */
-static ssize_t isl29003_show_range(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- return sprintf(buf, "%i\n", isl29003_get_range(client));
-}
-
-static ssize_t isl29003_store_range(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- unsigned long val;
- int ret;
-
- if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
- return -EINVAL;
-
- ret = isl29003_set_range(client, val);
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(range, S_IWUSR | S_IRUGO,
- isl29003_show_range, isl29003_store_range);
-
-
-/* resolution */
-static ssize_t isl29003_show_resolution(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- return sprintf(buf, "%d\n", isl29003_get_resolution(client));
-}
-
-static ssize_t isl29003_store_resolution(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- unsigned long val;
- int ret;
-
- if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
- return -EINVAL;
-
- ret = isl29003_set_resolution(client, val);
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO,
- isl29003_show_resolution, isl29003_store_resolution);
-
-/* mode */
-static ssize_t isl29003_show_mode(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- return sprintf(buf, "%d\n", isl29003_get_mode(client));
-}
-
-static ssize_t isl29003_store_mode(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- unsigned long val;
- int ret;
-
- if ((strict_strtoul(buf, 10, &val) < 0) || (val > 2))
- return -EINVAL;
-
- ret = isl29003_set_mode(client, val);
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
- isl29003_show_mode, isl29003_store_mode);
-
-
-/* power state */
-static ssize_t isl29003_show_power_state(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- return sprintf(buf, "%d\n", isl29003_get_power_state(client));
-}
-
-static ssize_t isl29003_store_power_state(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- unsigned long val;
- int ret;
-
- if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1))
- return -EINVAL;
-
- ret = isl29003_set_power_state(client, val);
- return ret ? ret : count;
-}
-
-static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
- isl29003_show_power_state, isl29003_store_power_state);
-
-
-/* lux */
-static ssize_t isl29003_show_lux(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
-
- /* No LUX data if not operational */
- if (!isl29003_get_power_state(client))
- return -EBUSY;
-
- return sprintf(buf, "%d\n", isl29003_get_adc_value(client));
-}
-
-static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL);
-
-static struct attribute *isl29003_attributes[] = {
- &dev_attr_range.attr,
- &dev_attr_resolution.attr,
- &dev_attr_mode.attr,
- &dev_attr_power_state.attr,
- &dev_attr_lux.attr,
- NULL
-};
-
-static const struct attribute_group isl29003_attr_group = {
- .attrs = isl29003_attributes,
-};
-
-static int isl29003_init_client(struct i2c_client *client)
-{
- struct isl29003_data *data = i2c_get_clientdata(client);
- int i;
-
- /* read all the registers once to fill the cache.
- * if one of the reads fails, we consider the init failed */
- for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) {
- int v = i2c_smbus_read_byte_data(client, i);
- if (v < 0)
- return -ENODEV;
-
- data->reg_cache[i] = v;
- }
-
- /* set defaults */
- isl29003_set_range(client, 0);
- isl29003_set_resolution(client, 0);
- isl29003_set_mode(client, 0);
- isl29003_set_power_state(client, 0);
-
- return 0;
-}
-
-/*
- * I2C layer
- */
-
-static int __devinit isl29003_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct isl29003_data *data;
- int err = 0;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
- return -EIO;
-
- data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL);
- if (!data)
- return -ENOMEM;
-
- data->client = client;
- i2c_set_clientdata(client, data);
- mutex_init(&data->lock);
-
- /* initialize the ISL29003 chip */
- err = isl29003_init_client(client);
- if (err)
- goto exit_kfree;
-
- /* register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &isl29003_attr_group);
- if (err)
- goto exit_kfree;
-
- dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
- return 0;
-
-exit_kfree:
- kfree(data);
- return err;
-}
-
-static int __devexit isl29003_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group);
- isl29003_set_power_state(client, 0);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int isl29003_suspend(struct i2c_client *client, pm_message_t mesg)
-{
- struct isl29003_data *data = i2c_get_clientdata(client);
-
- data->power_state_before_suspend = isl29003_get_power_state(client);
- return isl29003_set_power_state(client, 0);
-}
-
-static int isl29003_resume(struct i2c_client *client)
-{
- int i;
- struct isl29003_data *data = i2c_get_clientdata(client);
-
- /* restore registers from cache */
- for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
- if (i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
- return -EIO;
-
- return isl29003_set_power_state(client,
- data->power_state_before_suspend);
-}
-
-#else
-#define isl29003_suspend NULL
-#define isl29003_resume NULL
-#endif /* CONFIG_PM */
-
-static const struct i2c_device_id isl29003_id[] = {
- { "isl29003", 0 },
- {}
-};
-MODULE_DEVICE_TABLE(i2c, isl29003_id);
-
-static struct i2c_driver isl29003_driver = {
- .driver = {
- .name = ISL29003_DRV_NAME,
- .owner = THIS_MODULE,
- },
- .suspend = isl29003_suspend,
- .resume = isl29003_resume,
- .probe = isl29003_probe,
- .remove = __devexit_p(isl29003_remove),
- .id_table = isl29003_id,
-};
-
-module_i2c_driver(isl29003_driver);
-
-MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("ISL29003 ambient light sensor driver");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRIVER_VERSION);
diff --git a/ANDROID_3.4.5/drivers/misc/isl29020.c b/ANDROID_3.4.5/drivers/misc/isl29020.c
deleted file mode 100644
index 0aa08c74..00000000
--- a/ANDROID_3.4.5/drivers/misc/isl29020.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * isl29020.c - Intersil ALS Driver
- *
- * 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; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Data sheet at: http://www.intersil.com/data/fn/fn6505.pdf
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/sysfs.h>
-#include <linux/pm_runtime.h>
-
-static DEFINE_MUTEX(mutex);
-
-static ssize_t als_sensing_range_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- int val;
-
- val = i2c_smbus_read_byte_data(client, 0x00);
-
- if (val < 0)
- return val;
- return sprintf(buf, "%d000\n", 1 << (2 * (val & 3)));
-
-}
-
-static ssize_t als_lux_input_data_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- int ret_val, val;
- unsigned long int lux;
- int temp;
-
- pm_runtime_get_sync(dev);
- msleep(100);
-
- mutex_lock(&mutex);
- temp = i2c_smbus_read_byte_data(client, 0x02); /* MSB data */
- if (temp < 0) {
- pm_runtime_put_sync(dev);
- mutex_unlock(&mutex);
- return temp;
- }
-
- ret_val = i2c_smbus_read_byte_data(client, 0x01); /* LSB data */
- mutex_unlock(&mutex);
-
- if (ret_val < 0) {
- pm_runtime_put_sync(dev);
- return ret_val;
- }
-
- ret_val |= temp << 8;
- val = i2c_smbus_read_byte_data(client, 0x00);
- pm_runtime_put_sync(dev);
- if (val < 0)
- return val;
- lux = ((((1 << (2 * (val & 3))))*1000) * ret_val) / 65536;
- return sprintf(buf, "%ld\n", lux);
-}
-
-static ssize_t als_sensing_range_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- int ret_val;
- unsigned long val;
-
- if (strict_strtoul(buf, 10, &val))
- return -EINVAL;
- if (val < 1 || val > 64000)
- return -EINVAL;
-
- /* Pick the smallest sensor range that will meet our requirements */
- if (val <= 1000)
- val = 1;
- else if (val <= 4000)
- val = 2;
- else if (val <= 16000)
- val = 3;
- else
- val = 4;
-
- ret_val = i2c_smbus_read_byte_data(client, 0x00);
- if (ret_val < 0)
- return ret_val;
-
- ret_val &= 0xFC; /*reset the bit before setting them */
- ret_val |= val - 1;
- ret_val = i2c_smbus_write_byte_data(client, 0x00, ret_val);
-
- if (ret_val < 0)
- return ret_val;
- return count;
-}
-
-static void als_set_power_state(struct i2c_client *client, int enable)
-{
- int ret_val;
-
- ret_val = i2c_smbus_read_byte_data(client, 0x00);
- if (ret_val < 0)
- return;
-
- if (enable)
- ret_val |= 0x80;
- else
- ret_val &= 0x7F;
-
- i2c_smbus_write_byte_data(client, 0x00, ret_val);
-}
-
-static DEVICE_ATTR(lux0_sensor_range, S_IRUGO | S_IWUSR,
- als_sensing_range_show, als_sensing_range_store);
-static DEVICE_ATTR(lux0_input, S_IRUGO, als_lux_input_data_show, NULL);
-
-static struct attribute *mid_att_als[] = {
- &dev_attr_lux0_sensor_range.attr,
- &dev_attr_lux0_input.attr,
- NULL
-};
-
-static struct attribute_group m_als_gr = {
- .name = "isl29020",
- .attrs = mid_att_als
-};
-
-static int als_set_default_config(struct i2c_client *client)
-{
- int retval;
-
- retval = i2c_smbus_write_byte_data(client, 0x00, 0xc0);
- if (retval < 0) {
- dev_err(&client->dev, "default write failed.");
- return retval;
- }
- return 0;
-}
-
-static int isl29020_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int res;
-
- res = als_set_default_config(client);
- if (res < 0)
- return res;
-
- res = sysfs_create_group(&client->dev.kobj, &m_als_gr);
- if (res) {
- dev_err(&client->dev, "isl29020: device create file failed\n");
- return res;
- }
- dev_info(&client->dev, "%s isl29020: ALS chip found\n", client->name);
- als_set_power_state(client, 0);
- pm_runtime_enable(&client->dev);
- return res;
-}
-
-static int isl29020_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &m_als_gr);
- return 0;
-}
-
-static struct i2c_device_id isl29020_id[] = {
- { "isl29020", 0 },
- { }
-};
-
-MODULE_DEVICE_TABLE(i2c, isl29020_id);
-
-#ifdef CONFIG_PM
-
-static int isl29020_runtime_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- als_set_power_state(client, 0);
- return 0;
-}
-
-static int isl29020_runtime_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- als_set_power_state(client, 1);
- return 0;
-}
-
-static const struct dev_pm_ops isl29020_pm_ops = {
- .runtime_suspend = isl29020_runtime_suspend,
- .runtime_resume = isl29020_runtime_resume,
-};
-
-#define ISL29020_PM_OPS (&isl29020_pm_ops)
-#else /* CONFIG_PM */
-#define ISL29020_PM_OPS NULL
-#endif /* CONFIG_PM */
-
-static struct i2c_driver isl29020_driver = {
- .driver = {
- .name = "isl29020",
- .pm = ISL29020_PM_OPS,
- },
- .probe = isl29020_probe,
- .remove = isl29020_remove,
- .id_table = isl29020_id,
-};
-
-module_i2c_driver(isl29020_driver);
-
-MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com>");
-MODULE_DESCRIPTION("Intersil isl29020 ALS Driver");
-MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/Kconfig b/ANDROID_3.4.5/drivers/misc/iwmc3200top/Kconfig
deleted file mode 100644
index 9e4b88fb..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-config IWMC3200TOP
- tristate "Intel Wireless MultiCom Top Driver"
- depends on MMC && EXPERIMENTAL
- select FW_LOADER
- ---help---
- Intel Wireless MultiCom 3200 Top driver is responsible for
- for firmware load and enabled coms enumeration
-
-config IWMC3200TOP_DEBUG
- bool "Enable full debug output of iwmc3200top Driver"
- depends on IWMC3200TOP
- ---help---
- Enable full debug output of iwmc3200top Driver
-
-config IWMC3200TOP_DEBUGFS
- bool "Enable Debugfs debugging interface for iwmc3200top"
- depends on IWMC3200TOP
- ---help---
- Enable creation of debugfs files for iwmc3200top
-
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/Makefile b/ANDROID_3.4.5/drivers/misc/iwmc3200top/Makefile
deleted file mode 100644
index fbf53fb4..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-# iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
-# drivers/misc/iwmc3200top/Makefile
-#
-# Copyright (C) 2009 Intel 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 version
-# 2 as published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-#
-# Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
-# -
-#
-#
-
-obj-$(CONFIG_IWMC3200TOP) += iwmc3200top.o
-iwmc3200top-objs := main.o fw-download.o
-iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUG) += log.o
-iwmc3200top-$(CONFIG_IWMC3200TOP_DEBUGFS) += debugfs.o
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/debugfs.c b/ANDROID_3.4.5/drivers/misc/iwmc3200top/debugfs.c
deleted file mode 100644
index 62fbaec4..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/debugfs.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/debufs.c
- *
- * Copyright (C) 2009 Intel 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 version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
- * -
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio.h>
-#include <linux/debugfs.h>
-
-#include "iwmc3200top.h"
-#include "fw-msg.h"
-#include "log.h"
-#include "debugfs.h"
-
-
-
-/* Constants definition */
-#define HEXADECIMAL_RADIX 16
-
-/* Functions definition */
-
-
-#define DEBUGFS_ADD(name, parent) do { \
- dbgfs->dbgfs_##parent##_files.file_##name = \
- debugfs_create_file(#name, 0644, dbgfs->dir_##parent, priv, \
- &iwmct_dbgfs_##name##_ops); \
-} while (0)
-
-#define DEBUGFS_RM(name) do { \
- debugfs_remove(name); \
- name = NULL; \
-} while (0)
-
-#define DEBUGFS_READ_FUNC(name) \
-ssize_t iwmct_dbgfs_##name##_read(struct file *file, \
- char __user *user_buf, \
- size_t count, loff_t *ppos);
-
-#define DEBUGFS_WRITE_FUNC(name) \
-ssize_t iwmct_dbgfs_##name##_write(struct file *file, \
- const char __user *user_buf, \
- size_t count, loff_t *ppos);
-
-#define DEBUGFS_READ_FILE_OPS(name) \
- DEBUGFS_READ_FUNC(name) \
- static const struct file_operations iwmct_dbgfs_##name##_ops = { \
- .read = iwmct_dbgfs_##name##_read, \
- .open = iwmct_dbgfs_open_file_generic, \
- .llseek = generic_file_llseek, \
- };
-
-#define DEBUGFS_WRITE_FILE_OPS(name) \
- DEBUGFS_WRITE_FUNC(name) \
- static const struct file_operations iwmct_dbgfs_##name##_ops = { \
- .write = iwmct_dbgfs_##name##_write, \
- .open = iwmct_dbgfs_open_file_generic, \
- .llseek = generic_file_llseek, \
- };
-
-#define DEBUGFS_READ_WRITE_FILE_OPS(name) \
- DEBUGFS_READ_FUNC(name) \
- DEBUGFS_WRITE_FUNC(name) \
- static const struct file_operations iwmct_dbgfs_##name##_ops = {\
- .write = iwmct_dbgfs_##name##_write, \
- .read = iwmct_dbgfs_##name##_read, \
- .open = iwmct_dbgfs_open_file_generic, \
- .llseek = generic_file_llseek, \
- };
-
-
-/* Debugfs file ops definitions */
-
-/*
- * Create the debugfs files and directories
- *
- */
-void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
-{
- struct iwmct_debugfs *dbgfs;
-
- dbgfs = kzalloc(sizeof(struct iwmct_debugfs), GFP_KERNEL);
- if (!dbgfs) {
- LOG_ERROR(priv, DEBUGFS, "failed to allocate %zd bytes\n",
- sizeof(struct iwmct_debugfs));
- return;
- }
-
- priv->dbgfs = dbgfs;
- dbgfs->name = name;
- dbgfs->dir_drv = debugfs_create_dir(name, NULL);
- if (!dbgfs->dir_drv) {
- LOG_ERROR(priv, DEBUGFS, "failed to create debugfs dir\n");
- return;
- }
-
- return;
-}
-
-/**
- * Remove the debugfs files and directories
- *
- */
-void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
-{
- if (!dbgfs)
- return;
-
- DEBUGFS_RM(dbgfs->dir_drv);
- kfree(dbgfs);
- dbgfs = NULL;
-}
-
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/debugfs.h b/ANDROID_3.4.5/drivers/misc/iwmc3200top/debugfs.h
deleted file mode 100644
index 71d45759..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/debugfs.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/debufs.h
- *
- * Copyright (C) 2009 Intel 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 version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
- * -
- *
- */
-
-#ifndef __DEBUGFS_H__
-#define __DEBUGFS_H__
-
-
-#ifdef CONFIG_IWMC3200TOP_DEBUGFS
-
-struct iwmct_debugfs {
- const char *name;
- struct dentry *dir_drv;
- struct dir_drv_files {
- } dbgfs_drv_files;
-};
-
-void iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name);
-void iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs);
-
-#else /* CONFIG_IWMC3200TOP_DEBUGFS */
-
-struct iwmct_debugfs;
-
-static inline void
-iwmct_dbgfs_register(struct iwmct_priv *priv, const char *name)
-{}
-
-static inline void
-iwmct_dbgfs_unregister(struct iwmct_debugfs *dbgfs)
-{}
-
-#endif /* CONFIG_IWMC3200TOP_DEBUGFS */
-
-#endif /* __DEBUGFS_H__ */
-
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/fw-download.c b/ANDROID_3.4.5/drivers/misc/iwmc3200top/fw-download.c
deleted file mode 100644
index e27afde6..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/fw-download.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/fw-download.c
- *
- * Copyright (C) 2009 Intel 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 version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
- * -
- *
- */
-
-#include <linux/firmware.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/slab.h>
-#include <asm/unaligned.h>
-
-#include "iwmc3200top.h"
-#include "log.h"
-#include "fw-msg.h"
-
-#define CHECKSUM_BYTES_NUM sizeof(u32)
-
-/**
- init parser struct with file
- */
-static int iwmct_fw_parser_init(struct iwmct_priv *priv, const u8 *file,
- size_t file_size, size_t block_size)
-{
- struct iwmct_parser *parser = &priv->parser;
- struct iwmct_fw_hdr *fw_hdr = &parser->versions;
-
- LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
-
- LOG_INFO(priv, FW_DOWNLOAD, "file_size=%zd\n", file_size);
-
- parser->file = file;
- parser->file_size = file_size;
- parser->cur_pos = 0;
- parser->entry_point = 0;
- parser->buf = kzalloc(block_size, GFP_KERNEL);
- if (!parser->buf) {
- LOG_ERROR(priv, FW_DOWNLOAD, "kzalloc error\n");
- return -ENOMEM;
- }
- parser->buf_size = block_size;
-
- /* extract fw versions */
- memcpy(fw_hdr, parser->file, sizeof(struct iwmct_fw_hdr));
- LOG_INFO(priv, FW_DOWNLOAD, "fw versions are:\n"
- "top %u.%u.%u gps %u.%u.%u bt %u.%u.%u tic %s\n",
- fw_hdr->top_major, fw_hdr->top_minor, fw_hdr->top_revision,
- fw_hdr->gps_major, fw_hdr->gps_minor, fw_hdr->gps_revision,
- fw_hdr->bt_major, fw_hdr->bt_minor, fw_hdr->bt_revision,
- fw_hdr->tic_name);
-
- parser->cur_pos += sizeof(struct iwmct_fw_hdr);
-
- LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
- return 0;
-}
-
-static bool iwmct_checksum(struct iwmct_priv *priv)
-{
- struct iwmct_parser *parser = &priv->parser;
- __le32 *file = (__le32 *)parser->file;
- int i, pad, steps;
- u32 accum = 0;
- u32 checksum;
- u32 mask = 0xffffffff;
-
- pad = (parser->file_size - CHECKSUM_BYTES_NUM) % 4;
- steps = (parser->file_size - CHECKSUM_BYTES_NUM) / 4;
-
- LOG_INFO(priv, FW_DOWNLOAD, "pad=%d steps=%d\n", pad, steps);
-
- for (i = 0; i < steps; i++)
- accum += le32_to_cpu(file[i]);
-
- if (pad) {
- mask <<= 8 * (4 - pad);
- accum += le32_to_cpu(file[steps]) & mask;
- }
-
- checksum = get_unaligned_le32((__le32 *)(parser->file +
- parser->file_size - CHECKSUM_BYTES_NUM));
-
- LOG_INFO(priv, FW_DOWNLOAD,
- "compare checksum accum=0x%x to checksum=0x%x\n",
- accum, checksum);
-
- return checksum == accum;
-}
-
-static int iwmct_parse_next_section(struct iwmct_priv *priv, const u8 **p_sec,
- size_t *sec_size, __le32 *sec_addr)
-{
- struct iwmct_parser *parser = &priv->parser;
- struct iwmct_dbg *dbg = &priv->dbg;
- struct iwmct_fw_sec_hdr *sec_hdr;
-
- LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
-
- while (parser->cur_pos + sizeof(struct iwmct_fw_sec_hdr)
- <= parser->file_size) {
-
- sec_hdr = (struct iwmct_fw_sec_hdr *)
- (parser->file + parser->cur_pos);
- parser->cur_pos += sizeof(struct iwmct_fw_sec_hdr);
-
- LOG_INFO(priv, FW_DOWNLOAD,
- "sec hdr: type=%s addr=0x%x size=%d\n",
- sec_hdr->type, sec_hdr->target_addr,
- sec_hdr->data_size);
-
- if (strcmp(sec_hdr->type, "ENT") == 0)
- parser->entry_point = le32_to_cpu(sec_hdr->target_addr);
- else if (strcmp(sec_hdr->type, "LBL") == 0)
- strcpy(dbg->label_fw, parser->file + parser->cur_pos);
- else if (((strcmp(sec_hdr->type, "TOP") == 0) &&
- (priv->barker & BARKER_DNLOAD_TOP_MSK)) ||
- ((strcmp(sec_hdr->type, "GPS") == 0) &&
- (priv->barker & BARKER_DNLOAD_GPS_MSK)) ||
- ((strcmp(sec_hdr->type, "BTH") == 0) &&
- (priv->barker & BARKER_DNLOAD_BT_MSK))) {
- *sec_addr = sec_hdr->target_addr;
- *sec_size = le32_to_cpu(sec_hdr->data_size);
- *p_sec = parser->file + parser->cur_pos;
- parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
- return 1;
- } else if (strcmp(sec_hdr->type, "LOG") != 0)
- LOG_WARNING(priv, FW_DOWNLOAD,
- "skipping section type %s\n",
- sec_hdr->type);
-
- parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
- LOG_INFO(priv, FW_DOWNLOAD,
- "finished with section cur_pos=%zd\n", parser->cur_pos);
- }
-
- LOG_TRACE(priv, INIT, "<--\n");
- return 0;
-}
-
-static int iwmct_download_section(struct iwmct_priv *priv, const u8 *p_sec,
- size_t sec_size, __le32 addr)
-{
- struct iwmct_parser *parser = &priv->parser;
- struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
- const u8 *cur_block = p_sec;
- size_t sent = 0;
- int cnt = 0;
- int ret = 0;
- u32 cmd = 0;
-
- LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
- LOG_INFO(priv, FW_DOWNLOAD, "Download address 0x%x size 0x%zx\n",
- addr, sec_size);
-
- while (sent < sec_size) {
- int i;
- u32 chksm = 0;
- u32 reset = atomic_read(&priv->reset);
- /* actual FW data */
- u32 data_size = min(parser->buf_size - sizeof(*hdr),
- sec_size - sent);
- /* Pad to block size */
- u32 trans_size = (data_size + sizeof(*hdr) +
- IWMC_SDIO_BLK_SIZE - 1) &
- ~(IWMC_SDIO_BLK_SIZE - 1);
- ++cnt;
-
- /* in case of reset, interrupt FW DOWNLAOD */
- if (reset) {
- LOG_INFO(priv, FW_DOWNLOAD,
- "Reset detected. Abort FW download!!!");
- ret = -ECANCELED;
- goto exit;
- }
-
- memset(parser->buf, 0, parser->buf_size);
- cmd |= IWMC_OPCODE_WRITE << CMD_HDR_OPCODE_POS;
- cmd |= IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
- cmd |= (priv->dbg.direct ? 1 : 0) << CMD_HDR_DIRECT_ACCESS_POS;
- cmd |= (priv->dbg.checksum ? 1 : 0) << CMD_HDR_USE_CHECKSUM_POS;
- hdr->data_size = cpu_to_le32(data_size);
- hdr->target_addr = addr;
-
- /* checksum is allowed for sizes divisible by 4 */
- if (data_size & 0x3)
- cmd &= ~CMD_HDR_USE_CHECKSUM_MSK;
-
- memcpy(hdr->data, cur_block, data_size);
-
-
- if (cmd & CMD_HDR_USE_CHECKSUM_MSK) {
-
- chksm = data_size + le32_to_cpu(addr) + cmd;
- for (i = 0; i < data_size >> 2; i++)
- chksm += ((u32 *)cur_block)[i];
-
- hdr->block_chksm = cpu_to_le32(chksm);
- LOG_INFO(priv, FW_DOWNLOAD, "Checksum = 0x%X\n",
- hdr->block_chksm);
- }
-
- LOG_INFO(priv, FW_DOWNLOAD, "trans#%d, len=%d, sent=%zd, "
- "sec_size=%zd, startAddress 0x%X\n",
- cnt, trans_size, sent, sec_size, addr);
-
- if (priv->dbg.dump)
- LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, trans_size);
-
-
- hdr->cmd = cpu_to_le32(cmd);
- /* send it down */
- /* TODO: add more proper sending and error checking */
- ret = iwmct_tx(priv, parser->buf, trans_size);
- if (ret != 0) {
- LOG_INFO(priv, FW_DOWNLOAD,
- "iwmct_tx returned %d\n", ret);
- goto exit;
- }
-
- addr = cpu_to_le32(le32_to_cpu(addr) + data_size);
- sent += data_size;
- cur_block = p_sec + sent;
-
- if (priv->dbg.blocks && (cnt + 1) >= priv->dbg.blocks) {
- LOG_INFO(priv, FW_DOWNLOAD,
- "Block number limit is reached [%d]\n",
- priv->dbg.blocks);
- break;
- }
- }
-
- if (sent < sec_size)
- ret = -EINVAL;
-exit:
- LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
- return ret;
-}
-
-static int iwmct_kick_fw(struct iwmct_priv *priv, bool jump)
-{
- struct iwmct_parser *parser = &priv->parser;
- struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
- int ret;
- u32 cmd;
-
- LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
-
- memset(parser->buf, 0, parser->buf_size);
- cmd = IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
- if (jump) {
- cmd |= IWMC_OPCODE_JUMP << CMD_HDR_OPCODE_POS;
- hdr->target_addr = cpu_to_le32(parser->entry_point);
- LOG_INFO(priv, FW_DOWNLOAD, "jump address 0x%x\n",
- parser->entry_point);
- } else {
- cmd |= IWMC_OPCODE_LAST_COMMAND << CMD_HDR_OPCODE_POS;
- LOG_INFO(priv, FW_DOWNLOAD, "last command\n");
- }
-
- hdr->cmd = cpu_to_le32(cmd);
-
- LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, sizeof(*hdr));
- /* send it down */
- /* TODO: add more proper sending and error checking */
- ret = iwmct_tx(priv, parser->buf, IWMC_SDIO_BLK_SIZE);
- if (ret)
- LOG_INFO(priv, FW_DOWNLOAD, "iwmct_tx returned %d", ret);
-
- LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
- return 0;
-}
-
-int iwmct_fw_load(struct iwmct_priv *priv)
-{
- const u8 *fw_name = FW_NAME(FW_API_VER);
- const struct firmware *raw;
- const u8 *pdata;
- size_t len;
- __le32 addr;
- int ret;
-
-
- LOG_INFO(priv, FW_DOWNLOAD, "barker download request 0x%x is:\n",
- priv->barker);
- LOG_INFO(priv, FW_DOWNLOAD, "******* Top FW %s requested ********\n",
- (priv->barker & BARKER_DNLOAD_TOP_MSK) ? "was" : "not");
- LOG_INFO(priv, FW_DOWNLOAD, "******* GPS FW %s requested ********\n",
- (priv->barker & BARKER_DNLOAD_GPS_MSK) ? "was" : "not");
- LOG_INFO(priv, FW_DOWNLOAD, "******* BT FW %s requested ********\n",
- (priv->barker & BARKER_DNLOAD_BT_MSK) ? "was" : "not");
-
-
- /* get the firmware */
- ret = request_firmware(&raw, fw_name, &priv->func->dev);
- if (ret < 0) {
- LOG_ERROR(priv, FW_DOWNLOAD, "%s request_firmware failed %d\n",
- fw_name, ret);
- goto exit;
- }
-
- if (raw->size < sizeof(struct iwmct_fw_sec_hdr)) {
- LOG_ERROR(priv, FW_DOWNLOAD, "%s smaller then (%zd) (%zd)\n",
- fw_name, sizeof(struct iwmct_fw_sec_hdr), raw->size);
- goto exit;
- }
-
- LOG_INFO(priv, FW_DOWNLOAD, "Read firmware '%s'\n", fw_name);
-
- /* clear parser struct */
- ret = iwmct_fw_parser_init(priv, raw->data, raw->size, priv->trans_len);
- if (ret < 0) {
- LOG_ERROR(priv, FW_DOWNLOAD,
- "iwmct_parser_init failed: Reason %d\n", ret);
- goto exit;
- }
-
- if (!iwmct_checksum(priv)) {
- LOG_ERROR(priv, FW_DOWNLOAD, "checksum error\n");
- ret = -EINVAL;
- goto exit;
- }
-
- /* download firmware to device */
- while (iwmct_parse_next_section(priv, &pdata, &len, &addr)) {
- ret = iwmct_download_section(priv, pdata, len, addr);
- if (ret) {
- LOG_ERROR(priv, FW_DOWNLOAD,
- "%s download section failed\n", fw_name);
- goto exit;
- }
- }
-
- ret = iwmct_kick_fw(priv, !!(priv->barker & BARKER_DNLOAD_JUMP_MSK));
-
-exit:
- kfree(priv->parser.buf);
- release_firmware(raw);
- return ret;
-}
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/fw-msg.h b/ANDROID_3.4.5/drivers/misc/iwmc3200top/fw-msg.h
deleted file mode 100644
index 9e26b75b..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/fw-msg.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/fw-msg.h
- *
- * Copyright (C) 2009 Intel 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 version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
- * -
- *
- */
-
-#ifndef __FWMSG_H__
-#define __FWMSG_H__
-
-#define COMM_TYPE_D2H 0xFF
-#define COMM_TYPE_H2D 0xEE
-
-#define COMM_CATEGORY_OPERATIONAL 0x00
-#define COMM_CATEGORY_DEBUG 0x01
-#define COMM_CATEGORY_TESTABILITY 0x02
-#define COMM_CATEGORY_DIAGNOSTICS 0x03
-
-#define OP_DBG_ZSTR_MSG cpu_to_le16(0x1A)
-
-#define FW_LOG_SRC_MAX 32
-#define FW_LOG_SRC_ALL 255
-
-#define FW_STRING_TABLE_ADDR cpu_to_le32(0x0C000000)
-
-#define CMD_DBG_LOG_LEVEL cpu_to_le16(0x0001)
-#define CMD_TST_DEV_RESET cpu_to_le16(0x0060)
-#define CMD_TST_FUNC_RESET cpu_to_le16(0x0062)
-#define CMD_TST_IFACE_RESET cpu_to_le16(0x0064)
-#define CMD_TST_CPU_UTILIZATION cpu_to_le16(0x0065)
-#define CMD_TST_TOP_DEEP_SLEEP cpu_to_le16(0x0080)
-#define CMD_TST_WAKEUP cpu_to_le16(0x0081)
-#define CMD_TST_FUNC_WAKEUP cpu_to_le16(0x0082)
-#define CMD_TST_FUNC_DEEP_SLEEP_REQUEST cpu_to_le16(0x0083)
-#define CMD_TST_GET_MEM_DUMP cpu_to_le16(0x0096)
-
-#define OP_OPR_ALIVE cpu_to_le16(0x0010)
-#define OP_OPR_CMD_ACK cpu_to_le16(0x001F)
-#define OP_OPR_CMD_NACK cpu_to_le16(0x0020)
-#define OP_TST_MEM_DUMP cpu_to_le16(0x0043)
-
-#define CMD_FLAG_PADDING_256 0x80
-
-#define FW_HCMD_BLOCK_SIZE 256
-
-struct msg_hdr {
- u8 type;
- u8 category;
- __le16 opcode;
- u8 seqnum;
- u8 flags;
- __le16 length;
-} __attribute__((__packed__));
-
-struct log_hdr {
- __le32 timestamp;
- u8 severity;
- u8 logsource;
- __le16 reserved;
-} __attribute__((__packed__));
-
-struct mdump_hdr {
- u8 dmpid;
- u8 frag;
- __le16 size;
- __le32 addr;
-} __attribute__((__packed__));
-
-struct top_msg {
- struct msg_hdr hdr;
- union {
- /* D2H messages */
- struct {
- struct log_hdr log_hdr;
- u8 data[1];
- } __attribute__((__packed__)) log;
-
- struct {
- struct log_hdr log_hdr;
- struct mdump_hdr md_hdr;
- u8 data[1];
- } __attribute__((__packed__)) mdump;
-
- /* H2D messages */
- struct {
- u8 logsource;
- u8 sevmask;
- } __attribute__((__packed__)) logdefs[FW_LOG_SRC_MAX];
- struct mdump_hdr mdump_req;
- } u;
-} __attribute__((__packed__));
-
-
-#endif /* __FWMSG_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/iwmc3200top.h b/ANDROID_3.4.5/drivers/misc/iwmc3200top/iwmc3200top.h
deleted file mode 100644
index 620973ed..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/iwmc3200top.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/iwmc3200top.h
- *
- * Copyright (C) 2009 Intel 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 version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
- * -
- *
- */
-
-#ifndef __IWMC3200TOP_H__
-#define __IWMC3200TOP_H__
-
-#include <linux/workqueue.h>
-
-#define DRV_NAME "iwmc3200top"
-#define FW_API_VER 1
-#define _FW_NAME(api) DRV_NAME "." #api ".fw"
-#define FW_NAME(api) _FW_NAME(api)
-
-#define IWMC_SDIO_BLK_SIZE 256
-#define IWMC_DEFAULT_TR_BLK 64
-#define IWMC_SDIO_DATA_ADDR 0x0
-#define IWMC_SDIO_INTR_ENABLE_ADDR 0x14
-#define IWMC_SDIO_INTR_STATUS_ADDR 0x13
-#define IWMC_SDIO_INTR_CLEAR_ADDR 0x13
-#define IWMC_SDIO_INTR_GET_SIZE_ADDR 0x2C
-
-#define COMM_HUB_HEADER_LENGTH 16
-#define LOGGER_HEADER_LENGTH 10
-
-
-#define BARKER_DNLOAD_BT_POS 0
-#define BARKER_DNLOAD_BT_MSK BIT(BARKER_DNLOAD_BT_POS)
-#define BARKER_DNLOAD_GPS_POS 1
-#define BARKER_DNLOAD_GPS_MSK BIT(BARKER_DNLOAD_GPS_POS)
-#define BARKER_DNLOAD_TOP_POS 2
-#define BARKER_DNLOAD_TOP_MSK BIT(BARKER_DNLOAD_TOP_POS)
-#define BARKER_DNLOAD_RESERVED1_POS 3
-#define BARKER_DNLOAD_RESERVED1_MSK BIT(BARKER_DNLOAD_RESERVED1_POS)
-#define BARKER_DNLOAD_JUMP_POS 4
-#define BARKER_DNLOAD_JUMP_MSK BIT(BARKER_DNLOAD_JUMP_POS)
-#define BARKER_DNLOAD_SYNC_POS 5
-#define BARKER_DNLOAD_SYNC_MSK BIT(BARKER_DNLOAD_SYNC_POS)
-#define BARKER_DNLOAD_RESERVED2_POS 6
-#define BARKER_DNLOAD_RESERVED2_MSK (0x3 << BARKER_DNLOAD_RESERVED2_POS)
-#define BARKER_DNLOAD_BARKER_POS 8
-#define BARKER_DNLOAD_BARKER_MSK (0xffffff << BARKER_DNLOAD_BARKER_POS)
-
-#define IWMC_BARKER_REBOOT (0xdeadbe << BARKER_DNLOAD_BARKER_POS)
-/* whole field barker */
-#define IWMC_BARKER_ACK 0xfeedbabe
-
-#define IWMC_CMD_SIGNATURE 0xcbbc
-
-#define CMD_HDR_OPCODE_POS 0
-#define CMD_HDR_OPCODE_MSK_MSK (0xf << CMD_HDR_OPCODE_MSK_POS)
-#define CMD_HDR_RESPONSE_CODE_POS 4
-#define CMD_HDR_RESPONSE_CODE_MSK (0xf << CMD_HDR_RESPONSE_CODE_POS)
-#define CMD_HDR_USE_CHECKSUM_POS 8
-#define CMD_HDR_USE_CHECKSUM_MSK BIT(CMD_HDR_USE_CHECKSUM_POS)
-#define CMD_HDR_RESPONSE_REQUIRED_POS 9
-#define CMD_HDR_RESPONSE_REQUIRED_MSK BIT(CMD_HDR_RESPONSE_REQUIRED_POS)
-#define CMD_HDR_DIRECT_ACCESS_POS 10
-#define CMD_HDR_DIRECT_ACCESS_MSK BIT(CMD_HDR_DIRECT_ACCESS_POS)
-#define CMD_HDR_RESERVED_POS 11
-#define CMD_HDR_RESERVED_MSK BIT(0x1f << CMD_HDR_RESERVED_POS)
-#define CMD_HDR_SIGNATURE_POS 16
-#define CMD_HDR_SIGNATURE_MSK BIT(0xffff << CMD_HDR_SIGNATURE_POS)
-
-enum {
- IWMC_OPCODE_PING = 0,
- IWMC_OPCODE_READ = 1,
- IWMC_OPCODE_WRITE = 2,
- IWMC_OPCODE_JUMP = 3,
- IWMC_OPCODE_REBOOT = 4,
- IWMC_OPCODE_PERSISTENT_WRITE = 5,
- IWMC_OPCODE_PERSISTENT_READ = 6,
- IWMC_OPCODE_READ_MODIFY_WRITE = 7,
- IWMC_OPCODE_LAST_COMMAND = 15
-};
-
-struct iwmct_fw_load_hdr {
- __le32 cmd;
- __le32 target_addr;
- __le32 data_size;
- __le32 block_chksm;
- u8 data[0];
-};
-
-/**
- * struct iwmct_fw_hdr
- * holds all sw components versions
- */
-struct iwmct_fw_hdr {
- u8 top_major;
- u8 top_minor;
- u8 top_revision;
- u8 gps_major;
- u8 gps_minor;
- u8 gps_revision;
- u8 bt_major;
- u8 bt_minor;
- u8 bt_revision;
- u8 tic_name[31];
-};
-
-/**
- * struct iwmct_fw_sec_hdr
- * @type: function type
- * @data_size: section's data size
- * @target_addr: download address
- */
-struct iwmct_fw_sec_hdr {
- u8 type[4];
- __le32 data_size;
- __le32 target_addr;
-};
-
-/**
- * struct iwmct_parser
- * @file: fw image
- * @file_size: fw size
- * @cur_pos: position in file
- * @buf: temp buf for download
- * @buf_size: size of buf
- * @entry_point: address to jump in fw kick-off
- */
-struct iwmct_parser {
- const u8 *file;
- size_t file_size;
- size_t cur_pos;
- u8 *buf;
- size_t buf_size;
- u32 entry_point;
- struct iwmct_fw_hdr versions;
-};
-
-
-struct iwmct_work_struct {
- struct list_head list;
- ssize_t iosize;
-};
-
-struct iwmct_dbg {
- int blocks;
- bool dump;
- bool jump;
- bool direct;
- bool checksum;
- bool fw_download;
- int block_size;
- int download_trans_blks;
-
- char label_fw[256];
-};
-
-struct iwmct_debugfs;
-
-struct iwmct_priv {
- struct sdio_func *func;
- struct iwmct_debugfs *dbgfs;
- struct iwmct_parser parser;
- atomic_t reset;
- atomic_t dev_sync;
- u32 trans_len;
- u32 barker;
- struct iwmct_dbg dbg;
-
- /* drivers work items */
- struct work_struct bus_rescan_worker;
- struct work_struct isr_worker;
-
- /* drivers wait queue */
- wait_queue_head_t wait_q;
-
- /* rx request list */
- struct list_head read_req_list;
-};
-
-extern int iwmct_tx(struct iwmct_priv *priv, void *src, int count);
-extern int iwmct_fw_load(struct iwmct_priv *priv);
-
-extern void iwmct_dbg_init_params(struct iwmct_priv *drv);
-extern void iwmct_dbg_init_drv_attrs(struct device_driver *drv);
-extern void iwmct_dbg_remove_drv_attrs(struct device_driver *drv);
-extern int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len);
-
-#endif /* __IWMC3200TOP_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/log.c b/ANDROID_3.4.5/drivers/misc/iwmc3200top/log.c
deleted file mode 100644
index a36a55a4..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/log.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/log.c
- *
- * Copyright (C) 2009 Intel 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 version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
- * -
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include "fw-msg.h"
-#include "iwmc3200top.h"
-#include "log.h"
-
-/* Maximal hexadecimal string size of the FW memdump message */
-#define LOG_MSG_SIZE_MAX 12400
-
-/* iwmct_logdefs is a global used by log macros */
-u8 iwmct_logdefs[LOG_SRC_MAX];
-static u8 iwmct_fw_logdefs[FW_LOG_SRC_MAX];
-
-
-static int _log_set_log_filter(u8 *logdefs, int size, u8 src, u8 logmask)
-{
- int i;
-
- if (src < size)
- logdefs[src] = logmask;
- else if (src == LOG_SRC_ALL)
- for (i = 0; i < size; i++)
- logdefs[i] = logmask;
- else
- return -1;
-
- return 0;
-}
-
-
-int iwmct_log_set_filter(u8 src, u8 logmask)
-{
- return _log_set_log_filter(iwmct_logdefs, LOG_SRC_MAX, src, logmask);
-}
-
-
-int iwmct_log_set_fw_filter(u8 src, u8 logmask)
-{
- return _log_set_log_filter(iwmct_fw_logdefs,
- FW_LOG_SRC_MAX, src, logmask);
-}
-
-
-static int log_msg_format_hex(char *str, int slen, u8 *ibuf,
- int ilen, char *pref)
-{
- int pos = 0;
- int i;
- int len;
-
- for (pos = 0, i = 0; pos < slen - 2 && pref[i] != '\0'; i++, pos++)
- str[pos] = pref[i];
-
- for (i = 0; pos < slen - 2 && i < ilen; pos += len, i++)
- len = snprintf(&str[pos], slen - pos - 1, " %2.2X", ibuf[i]);
-
- if (i < ilen)
- return -1;
-
- return 0;
-}
-
-/* NOTE: This function is not thread safe.
- Currently it's called only from sdio rx worker - no race there
-*/
-void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len)
-{
- struct top_msg *msg;
- static char logbuf[LOG_MSG_SIZE_MAX];
-
- msg = (struct top_msg *)buf;
-
- if (len < sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr)) {
- LOG_ERROR(priv, FW_MSG, "Log message from TOP "
- "is too short %d (expected %zd)\n",
- len, sizeof(msg->hdr) + sizeof(msg->u.log.log_hdr));
- return;
- }
-
- if (!(iwmct_fw_logdefs[msg->u.log.log_hdr.logsource] &
- BIT(msg->u.log.log_hdr.severity)) ||
- !(iwmct_logdefs[LOG_SRC_FW_MSG] & BIT(msg->u.log.log_hdr.severity)))
- return;
-
- switch (msg->hdr.category) {
- case COMM_CATEGORY_TESTABILITY:
- if (!(iwmct_logdefs[LOG_SRC_TST] &
- BIT(msg->u.log.log_hdr.severity)))
- return;
- if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
- le16_to_cpu(msg->hdr.length) +
- sizeof(msg->hdr), "<TST>"))
- LOG_WARNING(priv, TST,
- "TOP TST message is too long, truncating...");
- LOG_WARNING(priv, TST, "%s\n", logbuf);
- break;
- case COMM_CATEGORY_DEBUG:
- if (msg->hdr.opcode == OP_DBG_ZSTR_MSG)
- LOG_INFO(priv, FW_MSG, "%s %s", "<DBG>",
- ((u8 *)msg) + sizeof(msg->hdr)
- + sizeof(msg->u.log.log_hdr));
- else {
- if (log_msg_format_hex(logbuf, LOG_MSG_SIZE_MAX, buf,
- le16_to_cpu(msg->hdr.length)
- + sizeof(msg->hdr),
- "<DBG>"))
- LOG_WARNING(priv, FW_MSG,
- "TOP DBG message is too long,"
- "truncating...");
- LOG_WARNING(priv, FW_MSG, "%s\n", logbuf);
- }
- break;
- default:
- break;
- }
-}
-
-static int _log_get_filter_str(u8 *logdefs, int logdefsz, char *buf, int size)
-{
- int i, pos, len;
- for (i = 0, pos = 0; (pos < size-1) && (i < logdefsz); i++) {
- len = snprintf(&buf[pos], size - pos - 1, "0x%02X%02X,",
- i, logdefs[i]);
- pos += len;
- }
- buf[pos-1] = '\n';
- buf[pos] = '\0';
-
- if (i < logdefsz)
- return -1;
- return 0;
-}
-
-int log_get_filter_str(char *buf, int size)
-{
- return _log_get_filter_str(iwmct_logdefs, LOG_SRC_MAX, buf, size);
-}
-
-int log_get_fw_filter_str(char *buf, int size)
-{
- return _log_get_filter_str(iwmct_fw_logdefs, FW_LOG_SRC_MAX, buf, size);
-}
-
-#define HEXADECIMAL_RADIX 16
-#define LOG_SRC_FORMAT 7 /* log level is in format of "0xXXXX," */
-
-ssize_t show_iwmct_log_level(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- char *str_buf;
- int buf_size;
- ssize_t ret;
-
- buf_size = (LOG_SRC_FORMAT * LOG_SRC_MAX) + 1;
- str_buf = kzalloc(buf_size, GFP_KERNEL);
- if (!str_buf) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to allocate %d bytes\n", buf_size);
- ret = -ENOMEM;
- goto exit;
- }
-
- if (log_get_filter_str(str_buf, buf_size) < 0) {
- ret = -EINVAL;
- goto exit;
- }
-
- ret = sprintf(buf, "%s", str_buf);
-
-exit:
- kfree(str_buf);
- return ret;
-}
-
-ssize_t store_iwmct_log_level(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- char *token, *str_buf = NULL;
- long val;
- ssize_t ret = count;
- u8 src, mask;
-
- if (!count)
- goto exit;
-
- str_buf = kzalloc(count, GFP_KERNEL);
- if (!str_buf) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to allocate %zd bytes\n", count);
- ret = -ENOMEM;
- goto exit;
- }
-
- memcpy(str_buf, buf, count);
-
- while ((token = strsep(&str_buf, ",")) != NULL) {
- while (isspace(*token))
- ++token;
- if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to convert string to long %s\n",
- token);
- ret = -EINVAL;
- goto exit;
- }
-
- mask = val & 0xFF;
- src = (val & 0XFF00) >> 8;
- iwmct_log_set_filter(src, mask);
- }
-
-exit:
- kfree(str_buf);
- return ret;
-}
-
-ssize_t show_iwmct_log_level_fw(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- char *str_buf;
- int buf_size;
- ssize_t ret;
-
- buf_size = (LOG_SRC_FORMAT * FW_LOG_SRC_MAX) + 2;
-
- str_buf = kzalloc(buf_size, GFP_KERNEL);
- if (!str_buf) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to allocate %d bytes\n", buf_size);
- ret = -ENOMEM;
- goto exit;
- }
-
- if (log_get_fw_filter_str(str_buf, buf_size) < 0) {
- ret = -EINVAL;
- goto exit;
- }
-
- ret = sprintf(buf, "%s", str_buf);
-
-exit:
- kfree(str_buf);
- return ret;
-}
-
-ssize_t store_iwmct_log_level_fw(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- struct top_msg cmd;
- char *token, *str_buf = NULL;
- ssize_t ret = count;
- u16 cmdlen = 0;
- int i;
- long val;
- u8 src, mask;
-
- if (!count)
- goto exit;
-
- str_buf = kzalloc(count, GFP_KERNEL);
- if (!str_buf) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to allocate %zd bytes\n", count);
- ret = -ENOMEM;
- goto exit;
- }
-
- memcpy(str_buf, buf, count);
-
- cmd.hdr.type = COMM_TYPE_H2D;
- cmd.hdr.category = COMM_CATEGORY_DEBUG;
- cmd.hdr.opcode = CMD_DBG_LOG_LEVEL;
-
- for (i = 0; ((token = strsep(&str_buf, ",")) != NULL) &&
- (i < FW_LOG_SRC_MAX); i++) {
-
- while (isspace(*token))
- ++token;
-
- if (strict_strtol(token, HEXADECIMAL_RADIX, &val)) {
- LOG_ERROR(priv, DEBUGFS,
- "failed to convert string to long %s\n",
- token);
- ret = -EINVAL;
- goto exit;
- }
-
- mask = val & 0xFF; /* LSB */
- src = (val & 0XFF00) >> 8; /* 2nd least significant byte. */
- iwmct_log_set_fw_filter(src, mask);
-
- cmd.u.logdefs[i].logsource = src;
- cmd.u.logdefs[i].sevmask = mask;
- }
-
- cmd.hdr.length = cpu_to_le16(i * sizeof(cmd.u.logdefs[0]));
- cmdlen = (i * sizeof(cmd.u.logdefs[0]) + sizeof(cmd.hdr));
-
- ret = iwmct_send_hcmd(priv, (u8 *)&cmd, cmdlen);
- if (ret) {
- LOG_ERROR(priv, DEBUGFS,
- "Failed to send %d bytes of fwcmd, ret=%zd\n",
- cmdlen, ret);
- goto exit;
- } else
- LOG_INFO(priv, DEBUGFS, "fwcmd sent (%d bytes)\n", cmdlen);
-
- ret = count;
-
-exit:
- kfree(str_buf);
- return ret;
-}
-
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/log.h b/ANDROID_3.4.5/drivers/misc/iwmc3200top/log.h
deleted file mode 100644
index 4434bb16..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/log.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/log.h
- *
- * Copyright (C) 2009 Intel 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 version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
- * -
- *
- */
-
-#ifndef __LOG_H__
-#define __LOG_H__
-
-
-/* log severity:
- * The log levels here match FW log levels
- * so values need to stay as is */
-#define LOG_SEV_CRITICAL 0
-#define LOG_SEV_ERROR 1
-#define LOG_SEV_WARNING 2
-#define LOG_SEV_INFO 3
-#define LOG_SEV_INFOEX 4
-
-/* Log levels not defined for FW */
-#define LOG_SEV_TRACE 5
-#define LOG_SEV_DUMP 6
-
-#define LOG_SEV_FW_FILTER_ALL \
- (BIT(LOG_SEV_CRITICAL) | \
- BIT(LOG_SEV_ERROR) | \
- BIT(LOG_SEV_WARNING) | \
- BIT(LOG_SEV_INFO) | \
- BIT(LOG_SEV_INFOEX))
-
-#define LOG_SEV_FILTER_ALL \
- (BIT(LOG_SEV_CRITICAL) | \
- BIT(LOG_SEV_ERROR) | \
- BIT(LOG_SEV_WARNING) | \
- BIT(LOG_SEV_INFO) | \
- BIT(LOG_SEV_INFOEX) | \
- BIT(LOG_SEV_TRACE) | \
- BIT(LOG_SEV_DUMP))
-
-/* log source */
-#define LOG_SRC_INIT 0
-#define LOG_SRC_DEBUGFS 1
-#define LOG_SRC_FW_DOWNLOAD 2
-#define LOG_SRC_FW_MSG 3
-#define LOG_SRC_TST 4
-#define LOG_SRC_IRQ 5
-
-#define LOG_SRC_MAX 6
-#define LOG_SRC_ALL 0xFF
-
-/**
- * Default intitialization runtime log level
- */
-#ifndef LOG_SEV_FILTER_RUNTIME
-#define LOG_SEV_FILTER_RUNTIME \
- (BIT(LOG_SEV_CRITICAL) | \
- BIT(LOG_SEV_ERROR) | \
- BIT(LOG_SEV_WARNING))
-#endif
-
-#ifndef FW_LOG_SEV_FILTER_RUNTIME
-#define FW_LOG_SEV_FILTER_RUNTIME LOG_SEV_FILTER_ALL
-#endif
-
-#ifdef CONFIG_IWMC3200TOP_DEBUG
-/**
- * Log macros
- */
-
-#define priv2dev(priv) (&(priv->func)->dev)
-
-#define LOG_CRITICAL(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_CRITICAL)) \
- dev_crit(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_ERROR(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_ERROR)) \
- dev_err(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_WARNING(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_WARNING)) \
- dev_warn(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_INFO(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_INFO)) \
- dev_info(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_TRACE(priv, src, fmt, args...) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_TRACE)) \
- dev_dbg(priv2dev(priv), "%s %d: " fmt, \
- __func__, __LINE__, ##args); \
-} while (0)
-
-#define LOG_HEXDUMP(src, ptr, len) \
-do { \
- if (iwmct_logdefs[LOG_SRC_ ## src] & BIT(LOG_SEV_DUMP)) \
- print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE, \
- 16, 1, ptr, len, false); \
-} while (0)
-
-void iwmct_log_top_message(struct iwmct_priv *priv, u8 *buf, int len);
-
-extern u8 iwmct_logdefs[];
-
-int iwmct_log_set_filter(u8 src, u8 logmask);
-int iwmct_log_set_fw_filter(u8 src, u8 logmask);
-
-ssize_t show_iwmct_log_level(struct device *d,
- struct device_attribute *attr, char *buf);
-ssize_t store_iwmct_log_level(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count);
-ssize_t show_iwmct_log_level_fw(struct device *d,
- struct device_attribute *attr, char *buf);
-ssize_t store_iwmct_log_level_fw(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count);
-
-#else
-
-#define LOG_CRITICAL(priv, src, fmt, args...)
-#define LOG_ERROR(priv, src, fmt, args...)
-#define LOG_WARNING(priv, src, fmt, args...)
-#define LOG_INFO(priv, src, fmt, args...)
-#define LOG_TRACE(priv, src, fmt, args...)
-#define LOG_HEXDUMP(src, ptr, len)
-
-static inline void iwmct_log_top_message(struct iwmct_priv *priv,
- u8 *buf, int len) {}
-static inline int iwmct_log_set_filter(u8 src, u8 logmask) { return 0; }
-static inline int iwmct_log_set_fw_filter(u8 src, u8 logmask) { return 0; }
-
-#endif /* CONFIG_IWMC3200TOP_DEBUG */
-
-int log_get_filter_str(char *buf, int size);
-int log_get_fw_filter_str(char *buf, int size);
-
-#endif /* __LOG_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/iwmc3200top/main.c b/ANDROID_3.4.5/drivers/misc/iwmc3200top/main.c
deleted file mode 100644
index 701eb600..00000000
--- a/ANDROID_3.4.5/drivers/misc/iwmc3200top/main.c
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
- * drivers/misc/iwmc3200top/main.c
- *
- * Copyright (C) 2009 Intel 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 version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- *
- * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
- * -
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/debugfs.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio.h>
-
-#include "iwmc3200top.h"
-#include "log.h"
-#include "fw-msg.h"
-#include "debugfs.h"
-
-
-#define DRIVER_DESCRIPTION "Intel(R) IWMC 3200 Top Driver"
-#define DRIVER_COPYRIGHT "Copyright (c) 2008 Intel Corporation."
-
-#define DRIVER_VERSION "0.1.62"
-
-MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR(DRIVER_COPYRIGHT);
-MODULE_FIRMWARE(FW_NAME(FW_API_VER));
-
-
-static inline int __iwmct_tx(struct iwmct_priv *priv, void *src, int count)
-{
- return sdio_memcpy_toio(priv->func, IWMC_SDIO_DATA_ADDR, src, count);
-
-}
-int iwmct_tx(struct iwmct_priv *priv, void *src, int count)
-{
- int ret;
- sdio_claim_host(priv->func);
- ret = __iwmct_tx(priv, src, count);
- sdio_release_host(priv->func);
- return ret;
-}
-/*
- * This workers main task is to wait for OP_OPR_ALIVE
- * from TOP FW until ALIVE_MSG_TIMOUT timeout is elapsed.
- * When OP_OPR_ALIVE received it will issue
- * a call to "bus_rescan_devices".
- */
-static void iwmct_rescan_worker(struct work_struct *ws)
-{
- struct iwmct_priv *priv;
- int ret;
-
- priv = container_of(ws, struct iwmct_priv, bus_rescan_worker);
-
- LOG_INFO(priv, FW_MSG, "Calling bus_rescan\n");
-
- ret = bus_rescan_devices(priv->func->dev.bus);
- if (ret < 0)
- LOG_INFO(priv, INIT, "bus_rescan_devices FAILED!!!\n");
-}
-
-static void op_top_message(struct iwmct_priv *priv, struct top_msg *msg)
-{
- switch (msg->hdr.opcode) {
- case OP_OPR_ALIVE:
- LOG_INFO(priv, FW_MSG, "Got ALIVE from device, wake rescan\n");
- schedule_work(&priv->bus_rescan_worker);
- break;
- default:
- LOG_INFO(priv, FW_MSG, "Received msg opcode 0x%X\n",
- msg->hdr.opcode);
- break;
- }
-}
-
-
-static void handle_top_message(struct iwmct_priv *priv, u8 *buf, int len)
-{
- struct top_msg *msg;
-
- msg = (struct top_msg *)buf;
-
- if (msg->hdr.type != COMM_TYPE_D2H) {
- LOG_ERROR(priv, FW_MSG,
- "Message from TOP with invalid message type 0x%X\n",
- msg->hdr.type);
- return;
- }
-
- if (len < sizeof(msg->hdr)) {
- LOG_ERROR(priv, FW_MSG,
- "Message from TOP is too short for message header "
- "received %d bytes, expected at least %zd bytes\n",
- len, sizeof(msg->hdr));
- return;
- }
-
- if (len < le16_to_cpu(msg->hdr.length) + sizeof(msg->hdr)) {
- LOG_ERROR(priv, FW_MSG,
- "Message length (%d bytes) is shorter than "
- "in header (%d bytes)\n",
- len, le16_to_cpu(msg->hdr.length));
- return;
- }
-
- switch (msg->hdr.category) {
- case COMM_CATEGORY_OPERATIONAL:
- op_top_message(priv, (struct top_msg *)buf);
- break;
-
- case COMM_CATEGORY_DEBUG:
- case COMM_CATEGORY_TESTABILITY:
- case COMM_CATEGORY_DIAGNOSTICS:
- iwmct_log_top_message(priv, buf, len);
- break;
-
- default:
- LOG_ERROR(priv, FW_MSG,
- "Message from TOP with unknown category 0x%X\n",
- msg->hdr.category);
- break;
- }
-}
-
-int iwmct_send_hcmd(struct iwmct_priv *priv, u8 *cmd, u16 len)
-{
- int ret;
- u8 *buf;
-
- LOG_TRACE(priv, FW_MSG, "Sending hcmd:\n");
-
- /* add padding to 256 for IWMC */
- ((struct top_msg *)cmd)->hdr.flags |= CMD_FLAG_PADDING_256;
-
- LOG_HEXDUMP(FW_MSG, cmd, len);
-
- if (len > FW_HCMD_BLOCK_SIZE) {
- LOG_ERROR(priv, FW_MSG, "size %d exceeded hcmd max size %d\n",
- len, FW_HCMD_BLOCK_SIZE);
- return -1;
- }
-
- buf = kzalloc(FW_HCMD_BLOCK_SIZE, GFP_KERNEL);
- if (!buf) {
- LOG_ERROR(priv, FW_MSG, "kzalloc error, buf size %d\n",
- FW_HCMD_BLOCK_SIZE);
- return -1;
- }
-
- memcpy(buf, cmd, len);
- ret = iwmct_tx(priv, buf, FW_HCMD_BLOCK_SIZE);
-
- kfree(buf);
- return ret;
-}
-
-
-static void iwmct_irq_read_worker(struct work_struct *ws)
-{
- struct iwmct_priv *priv;
- struct iwmct_work_struct *read_req;
- __le32 *buf = NULL;
- int ret;
- int iosize;
- u32 barker;
- bool is_barker;
-
- priv = container_of(ws, struct iwmct_priv, isr_worker);
-
- LOG_TRACE(priv, IRQ, "enter iwmct_irq_read_worker %p\n", ws);
-
- /* --------------------- Handshake with device -------------------- */
- sdio_claim_host(priv->func);
-
- /* all list manipulations have to be protected by
- * sdio_claim_host/sdio_release_host */
- if (list_empty(&priv->read_req_list)) {
- LOG_ERROR(priv, IRQ, "read_req_list empty in read worker\n");
- goto exit_release;
- }
-
- read_req = list_entry(priv->read_req_list.next,
- struct iwmct_work_struct, list);
-
- list_del(&read_req->list);
- iosize = read_req->iosize;
- kfree(read_req);
-
- buf = kzalloc(iosize, GFP_KERNEL);
- if (!buf) {
- LOG_ERROR(priv, IRQ, "kzalloc error, buf size %d\n", iosize);
- goto exit_release;
- }
-
- LOG_INFO(priv, IRQ, "iosize=%d, buf=%p, func=%d\n",
- iosize, buf, priv->func->num);
-
- /* read from device */
- ret = sdio_memcpy_fromio(priv->func, buf, IWMC_SDIO_DATA_ADDR, iosize);
- if (ret) {
- LOG_ERROR(priv, IRQ, "error %d reading buffer\n", ret);
- goto exit_release;
- }
-
- LOG_HEXDUMP(IRQ, (u8 *)buf, iosize);
-
- barker = le32_to_cpu(buf[0]);
-
- /* Verify whether it's a barker and if not - treat as regular Rx */
- if (barker == IWMC_BARKER_ACK ||
- (barker & BARKER_DNLOAD_BARKER_MSK) == IWMC_BARKER_REBOOT) {
-
- /* Valid Barker is equal on first 4 dwords */
- is_barker = (buf[1] == buf[0]) &&
- (buf[2] == buf[0]) &&
- (buf[3] == buf[0]);
-
- if (!is_barker) {
- LOG_WARNING(priv, IRQ,
- "Potentially inconsistent barker "
- "%08X_%08X_%08X_%08X\n",
- le32_to_cpu(buf[0]), le32_to_cpu(buf[1]),
- le32_to_cpu(buf[2]), le32_to_cpu(buf[3]));
- }
- } else {
- is_barker = false;
- }
-
- /* Handle Top CommHub message */
- if (!is_barker) {
- sdio_release_host(priv->func);
- handle_top_message(priv, (u8 *)buf, iosize);
- goto exit;
- } else if (barker == IWMC_BARKER_ACK) { /* Handle barkers */
- if (atomic_read(&priv->dev_sync) == 0) {
- LOG_ERROR(priv, IRQ,
- "ACK barker arrived out-of-sync\n");
- goto exit_release;
- }
-
- /* Continuing to FW download (after Sync is completed)*/
- atomic_set(&priv->dev_sync, 0);
- LOG_INFO(priv, IRQ, "ACK barker arrived "
- "- starting FW download\n");
- } else { /* REBOOT barker */
- LOG_INFO(priv, IRQ, "Received reboot barker: %x\n", barker);
- priv->barker = barker;
-
- if (barker & BARKER_DNLOAD_SYNC_MSK) {
- /* Send the same barker back */
- ret = __iwmct_tx(priv, buf, iosize);
- if (ret) {
- LOG_ERROR(priv, IRQ,
- "error %d echoing barker\n", ret);
- goto exit_release;
- }
- LOG_INFO(priv, IRQ, "Echoing barker to device\n");
- atomic_set(&priv->dev_sync, 1);
- goto exit_release;
- }
-
- /* Continuing to FW download (without Sync) */
- LOG_INFO(priv, IRQ, "No sync requested "
- "- starting FW download\n");
- }
-
- sdio_release_host(priv->func);
-
- if (priv->dbg.fw_download)
- iwmct_fw_load(priv);
- else
- LOG_ERROR(priv, IRQ, "FW download not allowed\n");
-
- goto exit;
-
-exit_release:
- sdio_release_host(priv->func);
-exit:
- kfree(buf);
- LOG_TRACE(priv, IRQ, "exit iwmct_irq_read_worker\n");
-}
-
-static void iwmct_irq(struct sdio_func *func)
-{
- struct iwmct_priv *priv;
- int val, ret;
- int iosize;
- int addr = IWMC_SDIO_INTR_GET_SIZE_ADDR;
- struct iwmct_work_struct *read_req;
-
- priv = sdio_get_drvdata(func);
-
- LOG_TRACE(priv, IRQ, "enter iwmct_irq\n");
-
- /* read the function's status register */
- val = sdio_readb(func, IWMC_SDIO_INTR_STATUS_ADDR, &ret);
-
- LOG_TRACE(priv, IRQ, "iir value = %d, ret=%d\n", val, ret);
-
- if (!val) {
- LOG_ERROR(priv, IRQ, "iir = 0, exiting ISR\n");
- goto exit_clear_intr;
- }
-
-
- /*
- * read 2 bytes of the transaction size
- * IMPORTANT: sdio transaction size has to be read before clearing
- * sdio interrupt!!!
- */
- val = sdio_readb(priv->func, addr++, &ret);
- iosize = val;
- val = sdio_readb(priv->func, addr++, &ret);
- iosize += val << 8;
-
- LOG_INFO(priv, IRQ, "READ size %d\n", iosize);
-
- if (iosize == 0) {
- LOG_ERROR(priv, IRQ, "READ size %d, exiting ISR\n", iosize);
- goto exit_clear_intr;
- }
-
- /* allocate a work structure to pass iosize to the worker */
- read_req = kzalloc(sizeof(struct iwmct_work_struct), GFP_KERNEL);
- if (!read_req) {
- LOG_ERROR(priv, IRQ, "failed to allocate read_req, exit ISR\n");
- goto exit_clear_intr;
- }
-
- INIT_LIST_HEAD(&read_req->list);
- read_req->iosize = iosize;
-
- list_add_tail(&priv->read_req_list, &read_req->list);
-
- /* clear the function's interrupt request bit (write 1 to clear) */
- sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
-
- schedule_work(&priv->isr_worker);
-
- LOG_TRACE(priv, IRQ, "exit iwmct_irq\n");
-
- return;
-
-exit_clear_intr:
- /* clear the function's interrupt request bit (write 1 to clear) */
- sdio_writeb(func, 1, IWMC_SDIO_INTR_CLEAR_ADDR, &ret);
-}
-
-
-static int blocks;
-module_param(blocks, int, 0604);
-MODULE_PARM_DESC(blocks, "max_blocks_to_send");
-
-static bool dump;
-module_param(dump, bool, 0604);
-MODULE_PARM_DESC(dump, "dump_hex_content");
-
-static bool jump = 1;
-module_param(jump, bool, 0604);
-
-static bool direct = 1;
-module_param(direct, bool, 0604);
-
-static bool checksum = 1;
-module_param(checksum, bool, 0604);
-
-static bool fw_download = 1;
-module_param(fw_download, bool, 0604);
-
-static int block_size = IWMC_SDIO_BLK_SIZE;
-module_param(block_size, int, 0404);
-
-static int download_trans_blks = IWMC_DEFAULT_TR_BLK;
-module_param(download_trans_blks, int, 0604);
-
-static bool rubbish_barker;
-module_param(rubbish_barker, bool, 0604);
-
-#ifdef CONFIG_IWMC3200TOP_DEBUG
-static int log_level[LOG_SRC_MAX];
-static unsigned int log_level_argc;
-module_param_array(log_level, int, &log_level_argc, 0604);
-MODULE_PARM_DESC(log_level, "log_level");
-
-static int log_level_fw[FW_LOG_SRC_MAX];
-static unsigned int log_level_fw_argc;
-module_param_array(log_level_fw, int, &log_level_fw_argc, 0604);
-MODULE_PARM_DESC(log_level_fw, "log_level_fw");
-#endif
-
-void iwmct_dbg_init_params(struct iwmct_priv *priv)
-{
-#ifdef CONFIG_IWMC3200TOP_DEBUG
- int i;
-
- for (i = 0; i < log_level_argc; i++) {
- dev_notice(&priv->func->dev, "log_level[%d]=0x%X\n",
- i, log_level[i]);
- iwmct_log_set_filter((log_level[i] >> 8) & 0xFF,
- log_level[i] & 0xFF);
- }
- for (i = 0; i < log_level_fw_argc; i++) {
- dev_notice(&priv->func->dev, "log_level_fw[%d]=0x%X\n",
- i, log_level_fw[i]);
- iwmct_log_set_fw_filter((log_level_fw[i] >> 8) & 0xFF,
- log_level_fw[i] & 0xFF);
- }
-#endif
-
- priv->dbg.blocks = blocks;
- LOG_INFO(priv, INIT, "blocks=%d\n", blocks);
- priv->dbg.dump = (bool)dump;
- LOG_INFO(priv, INIT, "dump=%d\n", dump);
- priv->dbg.jump = (bool)jump;
- LOG_INFO(priv, INIT, "jump=%d\n", jump);
- priv->dbg.direct = (bool)direct;
- LOG_INFO(priv, INIT, "direct=%d\n", direct);
- priv->dbg.checksum = (bool)checksum;
- LOG_INFO(priv, INIT, "checksum=%d\n", checksum);
- priv->dbg.fw_download = (bool)fw_download;
- LOG_INFO(priv, INIT, "fw_download=%d\n", fw_download);
- priv->dbg.block_size = block_size;
- LOG_INFO(priv, INIT, "block_size=%d\n", block_size);
- priv->dbg.download_trans_blks = download_trans_blks;
- LOG_INFO(priv, INIT, "download_trans_blks=%d\n", download_trans_blks);
-}
-
-/*****************************************************************************
- *
- * sysfs attributes
- *
- *****************************************************************************/
-static ssize_t show_iwmct_fw_version(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwmct_priv *priv = dev_get_drvdata(d);
- return sprintf(buf, "%s\n", priv->dbg.label_fw);
-}
-static DEVICE_ATTR(cc_label_fw, S_IRUGO, show_iwmct_fw_version, NULL);
-
-#ifdef CONFIG_IWMC3200TOP_DEBUG
-static DEVICE_ATTR(log_level, S_IWUSR | S_IRUGO,
- show_iwmct_log_level, store_iwmct_log_level);
-static DEVICE_ATTR(log_level_fw, S_IWUSR | S_IRUGO,
- show_iwmct_log_level_fw, store_iwmct_log_level_fw);
-#endif
-
-static struct attribute *iwmct_sysfs_entries[] = {
- &dev_attr_cc_label_fw.attr,
-#ifdef CONFIG_IWMC3200TOP_DEBUG
- &dev_attr_log_level.attr,
- &dev_attr_log_level_fw.attr,
-#endif
- NULL
-};
-
-static struct attribute_group iwmct_attribute_group = {
- .name = NULL, /* put in device directory */
- .attrs = iwmct_sysfs_entries,
-};
-
-
-static int iwmct_probe(struct sdio_func *func,
- const struct sdio_device_id *id)
-{
- struct iwmct_priv *priv;
- int ret;
- int val = 1;
- int addr = IWMC_SDIO_INTR_ENABLE_ADDR;
-
- dev_dbg(&func->dev, "enter iwmct_probe\n");
-
- dev_dbg(&func->dev, "IRQ polling period id %u msecs, HZ is %d\n",
- jiffies_to_msecs(2147483647), HZ);
-
- priv = kzalloc(sizeof(struct iwmct_priv), GFP_KERNEL);
- if (!priv) {
- dev_err(&func->dev, "kzalloc error\n");
- return -ENOMEM;
- }
- priv->func = func;
- sdio_set_drvdata(func, priv);
-
- INIT_WORK(&priv->bus_rescan_worker, iwmct_rescan_worker);
- INIT_WORK(&priv->isr_worker, iwmct_irq_read_worker);
-
- init_waitqueue_head(&priv->wait_q);
-
- sdio_claim_host(func);
- /* FIXME: Remove after it is fixed in the Boot ROM upgrade */
- func->enable_timeout = 10;
-
- /* In our HW, setting the block size also wakes up the boot rom. */
- ret = sdio_set_block_size(func, priv->dbg.block_size);
- if (ret) {
- LOG_ERROR(priv, INIT,
- "sdio_set_block_size() failure: %d\n", ret);
- goto error_sdio_enable;
- }
-
- ret = sdio_enable_func(func);
- if (ret) {
- LOG_ERROR(priv, INIT, "sdio_enable_func() failure: %d\n", ret);
- goto error_sdio_enable;
- }
-
- /* init reset and dev_sync states */
- atomic_set(&priv->reset, 0);
- atomic_set(&priv->dev_sync, 0);
-
- /* init read req queue */
- INIT_LIST_HEAD(&priv->read_req_list);
-
- /* process configurable parameters */
- iwmct_dbg_init_params(priv);
- ret = sysfs_create_group(&func->dev.kobj, &iwmct_attribute_group);
- if (ret) {
- LOG_ERROR(priv, INIT, "Failed to register attributes and "
- "initialize module_params\n");
- goto error_dev_attrs;
- }
-
- iwmct_dbgfs_register(priv, DRV_NAME);
-
- if (!priv->dbg.direct && priv->dbg.download_trans_blks > 8) {
- LOG_INFO(priv, INIT,
- "Reducing transaction to 8 blocks = 2K (from %d)\n",
- priv->dbg.download_trans_blks);
- priv->dbg.download_trans_blks = 8;
- }
- priv->trans_len = priv->dbg.download_trans_blks * priv->dbg.block_size;
- LOG_INFO(priv, INIT, "Transaction length = %d\n", priv->trans_len);
-
- ret = sdio_claim_irq(func, iwmct_irq);
- if (ret) {
- LOG_ERROR(priv, INIT, "sdio_claim_irq() failure: %d\n", ret);
- goto error_claim_irq;
- }
-
-
- /* Enable function's interrupt */
- sdio_writeb(priv->func, val, addr, &ret);
- if (ret) {
- LOG_ERROR(priv, INIT, "Failure writing to "
- "Interrupt Enable Register (%d): %d\n", addr, ret);
- goto error_enable_int;
- }
-
- sdio_release_host(func);
-
- LOG_INFO(priv, INIT, "exit iwmct_probe\n");
-
- return ret;
-
-error_enable_int:
- sdio_release_irq(func);
-error_claim_irq:
- sdio_disable_func(func);
-error_dev_attrs:
- iwmct_dbgfs_unregister(priv->dbgfs);
- sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
-error_sdio_enable:
- sdio_release_host(func);
- return ret;
-}
-
-static void iwmct_remove(struct sdio_func *func)
-{
- struct iwmct_work_struct *read_req;
- struct iwmct_priv *priv = sdio_get_drvdata(func);
-
- LOG_INFO(priv, INIT, "enter\n");
-
- sdio_claim_host(func);
- sdio_release_irq(func);
- sdio_release_host(func);
-
- /* Make sure works are finished */
- flush_work_sync(&priv->bus_rescan_worker);
- flush_work_sync(&priv->isr_worker);
-
- sdio_claim_host(func);
- sdio_disable_func(func);
- sysfs_remove_group(&func->dev.kobj, &iwmct_attribute_group);
- iwmct_dbgfs_unregister(priv->dbgfs);
- sdio_release_host(func);
-
- /* free read requests */
- while (!list_empty(&priv->read_req_list)) {
- read_req = list_entry(priv->read_req_list.next,
- struct iwmct_work_struct, list);
-
- list_del(&read_req->list);
- kfree(read_req);
- }
-
- kfree(priv);
-}
-
-
-static const struct sdio_device_id iwmct_ids[] = {
- /* Intel Wireless MultiCom 3200 Top Driver */
- { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, 0x1404)},
- { }, /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(sdio, iwmct_ids);
-
-static struct sdio_driver iwmct_driver = {
- .probe = iwmct_probe,
- .remove = iwmct_remove,
- .name = DRV_NAME,
- .id_table = iwmct_ids,
-};
-
-static int __init iwmct_init(void)
-{
- int rc;
-
- /* Default log filter settings */
- iwmct_log_set_filter(LOG_SRC_ALL, LOG_SEV_FILTER_RUNTIME);
- iwmct_log_set_filter(LOG_SRC_FW_MSG, LOG_SEV_FW_FILTER_ALL);
- iwmct_log_set_fw_filter(LOG_SRC_ALL, FW_LOG_SEV_FILTER_RUNTIME);
-
- rc = sdio_register_driver(&iwmct_driver);
-
- return rc;
-}
-
-static void __exit iwmct_exit(void)
-{
- sdio_unregister_driver(&iwmct_driver);
-}
-
-module_init(iwmct_init);
-module_exit(iwmct_exit);
-
diff --git a/ANDROID_3.4.5/drivers/misc/kgdbts.c b/ANDROID_3.4.5/drivers/misc/kgdbts.c
deleted file mode 100644
index 3aa9a969..00000000
--- a/ANDROID_3.4.5/drivers/misc/kgdbts.c
+++ /dev/null
@@ -1,1187 +0,0 @@
-/*
- * kgdbts is a test suite for kgdb for the sole purpose of validating
- * that key pieces of the kgdb internals are working properly such as
- * HW/SW breakpoints, single stepping, and NMI.
- *
- * Created by: Jason Wessel <jason.wessel@windriver.com>
- *
- * Copyright (c) 2008 Wind River Systems, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-/* Information about the kgdb test suite.
- * -------------------------------------
- *
- * The kgdb test suite is designed as a KGDB I/O module which
- * simulates the communications that a debugger would have with kgdb.
- * The tests are broken up in to a line by line and referenced here as
- * a "get" which is kgdb requesting input and "put" which is kgdb
- * sending a response.
- *
- * The kgdb suite can be invoked from the kernel command line
- * arguments system or executed dynamically at run time. The test
- * suite uses the variable "kgdbts" to obtain the information about
- * which tests to run and to configure the verbosity level. The
- * following are the various characters you can use with the kgdbts=
- * line:
- *
- * When using the "kgdbts=" you only choose one of the following core
- * test types:
- * A = Run all the core tests silently
- * V1 = Run all the core tests with minimal output
- * V2 = Run all the core tests in debug mode
- *
- * You can also specify optional tests:
- * N## = Go to sleep with interrupts of for ## seconds
- * to test the HW NMI watchdog
- * F## = Break at do_fork for ## iterations
- * S## = Break at sys_open for ## iterations
- * I## = Run the single step test ## iterations
- *
- * NOTE: that the do_fork and sys_open tests are mutually exclusive.
- *
- * To invoke the kgdb test suite from boot you use a kernel start
- * argument as follows:
- * kgdbts=V1 kgdbwait
- * Or if you wanted to perform the NMI test for 6 seconds and do_fork
- * test for 100 forks, you could use:
- * kgdbts=V1N6F100 kgdbwait
- *
- * The test suite can also be invoked at run time with:
- * echo kgdbts=V1N6F100 > /sys/module/kgdbts/parameters/kgdbts
- * Or as another example:
- * echo kgdbts=V2 > /sys/module/kgdbts/parameters/kgdbts
- *
- * When developing a new kgdb arch specific implementation or
- * using these tests for the purpose of regression testing,
- * several invocations are required.
- *
- * 1) Boot with the test suite enabled by using the kernel arguments
- * "kgdbts=V1F100 kgdbwait"
- * ## If kgdb arch specific implementation has NMI use
- * "kgdbts=V1N6F100
- *
- * 2) After the system boot run the basic test.
- * echo kgdbts=V1 > /sys/module/kgdbts/parameters/kgdbts
- *
- * 3) Run the concurrency tests. It is best to use n+1
- * while loops where n is the number of cpus you have
- * in your system. The example below uses only two
- * loops.
- *
- * ## This tests break points on sys_open
- * while [ 1 ] ; do find / > /dev/null 2>&1 ; done &
- * while [ 1 ] ; do find / > /dev/null 2>&1 ; done &
- * echo kgdbts=V1S10000 > /sys/module/kgdbts/parameters/kgdbts
- * fg # and hit control-c
- * fg # and hit control-c
- * ## This tests break points on do_fork
- * while [ 1 ] ; do date > /dev/null ; done &
- * while [ 1 ] ; do date > /dev/null ; done &
- * echo kgdbts=V1F1000 > /sys/module/kgdbts/parameters/kgdbts
- * fg # and hit control-c
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/kgdb.h>
-#include <linux/ctype.h>
-#include <linux/uaccess.h>
-#include <linux/syscalls.h>
-#include <linux/nmi.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <linux/module.h>
-
-#define v1printk(a...) do { \
- if (verbose) \
- printk(KERN_INFO a); \
- } while (0)
-#define v2printk(a...) do { \
- if (verbose > 1) \
- printk(KERN_INFO a); \
- touch_nmi_watchdog(); \
- } while (0)
-#define eprintk(a...) do { \
- printk(KERN_ERR a); \
- WARN_ON(1); \
- } while (0)
-#define MAX_CONFIG_LEN 40
-
-static struct kgdb_io kgdbts_io_ops;
-static char get_buf[BUFMAX];
-static int get_buf_cnt;
-static char put_buf[BUFMAX];
-static int put_buf_cnt;
-static char scratch_buf[BUFMAX];
-static int verbose;
-static int repeat_test;
-static int test_complete;
-static int send_ack;
-static int final_ack;
-static int force_hwbrks;
-static int hwbreaks_ok;
-static int hw_break_val;
-static int hw_break_val2;
-static int cont_instead_of_sstep;
-static unsigned long cont_thread_id;
-static unsigned long sstep_thread_id;
-#if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC)
-static int arch_needs_sstep_emulation = 1;
-#else
-static int arch_needs_sstep_emulation;
-#endif
-static unsigned long cont_addr;
-static unsigned long sstep_addr;
-static int restart_from_top_after_write;
-static int sstep_state;
-
-/* Storage for the registers, in GDB format. */
-static unsigned long kgdbts_gdb_regs[(NUMREGBYTES +
- sizeof(unsigned long) - 1) /
- sizeof(unsigned long)];
-static struct pt_regs kgdbts_regs;
-
-/* -1 = init not run yet, 0 = unconfigured, 1 = configured. */
-static int configured = -1;
-
-#ifdef CONFIG_KGDB_TESTS_BOOT_STRING
-static char config[MAX_CONFIG_LEN] = CONFIG_KGDB_TESTS_BOOT_STRING;
-#else
-static char config[MAX_CONFIG_LEN];
-#endif
-static struct kparam_string kps = {
- .string = config,
- .maxlen = MAX_CONFIG_LEN,
-};
-
-static void fill_get_buf(char *buf);
-
-struct test_struct {
- char *get;
- char *put;
- void (*get_handler)(char *);
- int (*put_handler)(char *, char *);
-};
-
-struct test_state {
- char *name;
- struct test_struct *tst;
- int idx;
- int (*run_test) (int, int);
- int (*validate_put) (char *);
-};
-
-static struct test_state ts;
-
-static int kgdbts_unreg_thread(void *ptr)
-{
- /* Wait until the tests are complete and then ungresiter the I/O
- * driver.
- */
- while (!final_ack)
- msleep_interruptible(1500);
- /* Pause for any other threads to exit after final ack. */
- msleep_interruptible(1000);
- if (configured)
- kgdb_unregister_io_module(&kgdbts_io_ops);
- configured = 0;
-
- return 0;
-}
-
-/* This is noinline such that it can be used for a single location to
- * place a breakpoint
- */
-static noinline void kgdbts_break_test(void)
-{
- v2printk("kgdbts: breakpoint complete\n");
-}
-
-/* Lookup symbol info in the kernel */
-static unsigned long lookup_addr(char *arg)
-{
- unsigned long addr = 0;
-
- if (!strcmp(arg, "kgdbts_break_test"))
- addr = (unsigned long)kgdbts_break_test;
- else if (!strcmp(arg, "sys_open"))
- addr = (unsigned long)do_sys_open;
- else if (!strcmp(arg, "do_fork"))
- addr = (unsigned long)do_fork;
- else if (!strcmp(arg, "hw_break_val"))
- addr = (unsigned long)&hw_break_val;
- return addr;
-}
-
-static void break_helper(char *bp_type, char *arg, unsigned long vaddr)
-{
- unsigned long addr;
-
- if (arg)
- addr = lookup_addr(arg);
- else
- addr = vaddr;
-
- sprintf(scratch_buf, "%s,%lx,%i", bp_type, addr,
- BREAK_INSTR_SIZE);
- fill_get_buf(scratch_buf);
-}
-
-static void sw_break(char *arg)
-{
- break_helper(force_hwbrks ? "Z1" : "Z0", arg, 0);
-}
-
-static void sw_rem_break(char *arg)
-{
- break_helper(force_hwbrks ? "z1" : "z0", arg, 0);
-}
-
-static void hw_break(char *arg)
-{
- break_helper("Z1", arg, 0);
-}
-
-static void hw_rem_break(char *arg)
-{
- break_helper("z1", arg, 0);
-}
-
-static void hw_write_break(char *arg)
-{
- break_helper("Z2", arg, 0);
-}
-
-static void hw_rem_write_break(char *arg)
-{
- break_helper("z2", arg, 0);
-}
-
-static void hw_access_break(char *arg)
-{
- break_helper("Z4", arg, 0);
-}
-
-static void hw_rem_access_break(char *arg)
-{
- break_helper("z4", arg, 0);
-}
-
-static void hw_break_val_access(void)
-{
- hw_break_val2 = hw_break_val;
-}
-
-static void hw_break_val_write(void)
-{
- hw_break_val++;
-}
-
-static int get_thread_id_continue(char *put_str, char *arg)
-{
- char *ptr = &put_str[11];
-
- if (put_str[1] != 'T' || put_str[2] != '0')
- return 1;
- kgdb_hex2long(&ptr, &cont_thread_id);
- return 0;
-}
-
-static int check_and_rewind_pc(char *put_str, char *arg)
-{
- unsigned long addr = lookup_addr(arg);
- unsigned long ip;
- int offset = 0;
-
- kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
- NUMREGBYTES);
- gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
- ip = instruction_pointer(&kgdbts_regs);
- v2printk("Stopped at IP: %lx\n", ip);
-#ifdef GDB_ADJUSTS_BREAK_OFFSET
- /* On some arches, a breakpoint stop requires it to be decremented */
- if (addr + BREAK_INSTR_SIZE == ip)
- offset = -BREAK_INSTR_SIZE;
-#endif
-
- if (arch_needs_sstep_emulation && sstep_addr &&
- ip + offset == sstep_addr &&
- ((!strcmp(arg, "sys_open") || !strcmp(arg, "do_fork")))) {
- /* This is special case for emulated single step */
- v2printk("Emul: rewind hit single step bp\n");
- restart_from_top_after_write = 1;
- } else if (strcmp(arg, "silent") && ip + offset != addr) {
- eprintk("kgdbts: BP mismatch %lx expected %lx\n",
- ip + offset, addr);
- return 1;
- }
- /* Readjust the instruction pointer if needed */
- ip += offset;
- cont_addr = ip;
-#ifdef GDB_ADJUSTS_BREAK_OFFSET
- instruction_pointer_set(&kgdbts_regs, ip);
-#endif
- return 0;
-}
-
-static int check_single_step(char *put_str, char *arg)
-{
- unsigned long addr = lookup_addr(arg);
- static int matched_id;
-
- /*
- * From an arch indepent point of view the instruction pointer
- * should be on a different instruction
- */
- kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
- NUMREGBYTES);
- gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
- v2printk("Singlestep stopped at IP: %lx\n",
- instruction_pointer(&kgdbts_regs));
-
- if (sstep_thread_id != cont_thread_id) {
- /*
- * Ensure we stopped in the same thread id as before, else the
- * debugger should continue until the original thread that was
- * single stepped is scheduled again, emulating gdb's behavior.
- */
- v2printk("ThrID does not match: %lx\n", cont_thread_id);
- if (arch_needs_sstep_emulation) {
- if (matched_id &&
- instruction_pointer(&kgdbts_regs) != addr)
- goto continue_test;
- matched_id++;
- ts.idx -= 2;
- sstep_state = 0;
- return 0;
- }
- cont_instead_of_sstep = 1;
- ts.idx -= 4;
- return 0;
- }
-continue_test:
- matched_id = 0;
- if (instruction_pointer(&kgdbts_regs) == addr) {
- eprintk("kgdbts: SingleStep failed at %lx\n",
- instruction_pointer(&kgdbts_regs));
- return 1;
- }
-
- return 0;
-}
-
-static void write_regs(char *arg)
-{
- memset(scratch_buf, 0, sizeof(scratch_buf));
- scratch_buf[0] = 'G';
- pt_regs_to_gdb_regs(kgdbts_gdb_regs, &kgdbts_regs);
- kgdb_mem2hex((char *)kgdbts_gdb_regs, &scratch_buf[1], NUMREGBYTES);
- fill_get_buf(scratch_buf);
-}
-
-static void skip_back_repeat_test(char *arg)
-{
- int go_back = simple_strtol(arg, NULL, 10);
-
- repeat_test--;
- if (repeat_test <= 0)
- ts.idx++;
- else
- ts.idx -= go_back;
- fill_get_buf(ts.tst[ts.idx].get);
-}
-
-static int got_break(char *put_str, char *arg)
-{
- test_complete = 1;
- if (!strncmp(put_str+1, arg, 2)) {
- if (!strncmp(arg, "T0", 2))
- test_complete = 2;
- return 0;
- }
- return 1;
-}
-
-static void get_cont_catch(char *arg)
-{
- /* Always send detach because the test is completed at this point */
- fill_get_buf("D");
-}
-
-static int put_cont_catch(char *put_str, char *arg)
-{
- /* This is at the end of the test and we catch any and all input */
- v2printk("kgdbts: cleanup task: %lx\n", sstep_thread_id);
- ts.idx--;
- return 0;
-}
-
-static int emul_reset(char *put_str, char *arg)
-{
- if (strncmp(put_str, "$OK", 3))
- return 1;
- if (restart_from_top_after_write) {
- restart_from_top_after_write = 0;
- ts.idx = -1;
- }
- return 0;
-}
-
-static void emul_sstep_get(char *arg)
-{
- if (!arch_needs_sstep_emulation) {
- if (cont_instead_of_sstep) {
- cont_instead_of_sstep = 0;
- fill_get_buf("c");
- } else {
- fill_get_buf(arg);
- }
- return;
- }
- switch (sstep_state) {
- case 0:
- v2printk("Emulate single step\n");
- /* Start by looking at the current PC */
- fill_get_buf("g");
- break;
- case 1:
- /* set breakpoint */
- break_helper("Z0", NULL, sstep_addr);
- break;
- case 2:
- /* Continue */
- fill_get_buf("c");
- break;
- case 3:
- /* Clear breakpoint */
- break_helper("z0", NULL, sstep_addr);
- break;
- default:
- eprintk("kgdbts: ERROR failed sstep get emulation\n");
- }
- sstep_state++;
-}
-
-static int emul_sstep_put(char *put_str, char *arg)
-{
- if (!arch_needs_sstep_emulation) {
- char *ptr = &put_str[11];
- if (put_str[1] != 'T' || put_str[2] != '0')
- return 1;
- kgdb_hex2long(&ptr, &sstep_thread_id);
- return 0;
- }
- switch (sstep_state) {
- case 1:
- /* validate the "g" packet to get the IP */
- kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
- NUMREGBYTES);
- gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
- v2printk("Stopped at IP: %lx\n",
- instruction_pointer(&kgdbts_regs));
- /* Want to stop at IP + break instruction size by default */
- sstep_addr = cont_addr + BREAK_INSTR_SIZE;
- break;
- case 2:
- if (strncmp(put_str, "$OK", 3)) {
- eprintk("kgdbts: failed sstep break set\n");
- return 1;
- }
- break;
- case 3:
- if (strncmp(put_str, "$T0", 3)) {
- eprintk("kgdbts: failed continue sstep\n");
- return 1;
- } else {
- char *ptr = &put_str[11];
- kgdb_hex2long(&ptr, &sstep_thread_id);
- }
- break;
- case 4:
- if (strncmp(put_str, "$OK", 3)) {
- eprintk("kgdbts: failed sstep break unset\n");
- return 1;
- }
- /* Single step is complete so continue on! */
- sstep_state = 0;
- return 0;
- default:
- eprintk("kgdbts: ERROR failed sstep put emulation\n");
- }
-
- /* Continue on the same test line until emulation is complete */
- ts.idx--;
- return 0;
-}
-
-static int final_ack_set(char *put_str, char *arg)
-{
- if (strncmp(put_str+1, arg, 2))
- return 1;
- final_ack = 1;
- return 0;
-}
-/*
- * Test to plant a breakpoint and detach, which should clear out the
- * breakpoint and restore the original instruction.
- */
-static struct test_struct plant_and_detach_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
- { "D", "OK" }, /* Detach */
- { "", "" },
-};
-
-/*
- * Simple test to write in a software breakpoint, check for the
- * correct stop location and detach.
- */
-static struct test_struct sw_breakpoint_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
- { "c", "T0*", }, /* Continue */
- { "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
- { "write", "OK", write_regs },
- { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
- { "D", "OK" }, /* Detach */
- { "D", "OK", NULL, got_break }, /* On success we made it here */
- { "", "" },
-};
-
-/*
- * Test a known bad memory read location to test the fault handler and
- * read bytes 1-8 at the bad address
- */
-static struct test_struct bad_read_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "m0,1", "E*" }, /* read 1 byte at address 1 */
- { "m0,2", "E*" }, /* read 1 byte at address 2 */
- { "m0,3", "E*" }, /* read 1 byte at address 3 */
- { "m0,4", "E*" }, /* read 1 byte at address 4 */
- { "m0,5", "E*" }, /* read 1 byte at address 5 */
- { "m0,6", "E*" }, /* read 1 byte at address 6 */
- { "m0,7", "E*" }, /* read 1 byte at address 7 */
- { "m0,8", "E*" }, /* read 1 byte at address 8 */
- { "D", "OK" }, /* Detach which removes all breakpoints and continues */
- { "", "" },
-};
-
-/*
- * Test for hitting a breakpoint, remove it, single step, plant it
- * again and detach.
- */
-static struct test_struct singlestep_break_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
- { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
- { "kgdbts_break_test", "OK", sw_rem_break }, /*remove breakpoint */
- { "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
- { "write", "OK", write_regs }, /* Write registers */
- { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
- { "g", "kgdbts_break_test", NULL, check_single_step },
- { "kgdbts_break_test", "OK", sw_break, }, /* set sw breakpoint */
- { "c", "T0*", }, /* Continue */
- { "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
- { "write", "OK", write_regs }, /* Write registers */
- { "D", "OK" }, /* Remove all breakpoints and continues */
- { "", "" },
-};
-
-/*
- * Test for hitting a breakpoint at do_fork for what ever the number
- * of iterations required by the variable repeat_test.
- */
-static struct test_struct do_fork_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "do_fork", "OK", sw_break, }, /* set sw breakpoint */
- { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
- { "do_fork", "OK", sw_rem_break }, /*remove breakpoint */
- { "g", "do_fork", NULL, check_and_rewind_pc }, /* check location */
- { "write", "OK", write_regs, emul_reset }, /* Write registers */
- { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
- { "g", "do_fork", NULL, check_single_step },
- { "do_fork", "OK", sw_break, }, /* set sw breakpoint */
- { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
- { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */
- { "", "", get_cont_catch, put_cont_catch },
-};
-
-/* Test for hitting a breakpoint at sys_open for what ever the number
- * of iterations required by the variable repeat_test.
- */
-static struct test_struct sys_open_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
- { "c", "T0*", NULL, get_thread_id_continue }, /* Continue */
- { "sys_open", "OK", sw_rem_break }, /*remove breakpoint */
- { "g", "sys_open", NULL, check_and_rewind_pc }, /* check location */
- { "write", "OK", write_regs, emul_reset }, /* Write registers */
- { "s", "T0*", emul_sstep_get, emul_sstep_put }, /* Single step */
- { "g", "sys_open", NULL, check_single_step },
- { "sys_open", "OK", sw_break, }, /* set sw breakpoint */
- { "7", "T0*", skip_back_repeat_test }, /* Loop based on repeat_test */
- { "D", "OK", NULL, final_ack_set }, /* detach and unregister I/O */
- { "", "", get_cont_catch, put_cont_catch },
-};
-
-/*
- * Test for hitting a simple hw breakpoint
- */
-static struct test_struct hw_breakpoint_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "kgdbts_break_test", "OK", hw_break, }, /* set hw breakpoint */
- { "c", "T0*", }, /* Continue */
- { "g", "kgdbts_break_test", NULL, check_and_rewind_pc },
- { "write", "OK", write_regs },
- { "kgdbts_break_test", "OK", hw_rem_break }, /*remove breakpoint */
- { "D", "OK" }, /* Detach */
- { "D", "OK", NULL, got_break }, /* On success we made it here */
- { "", "" },
-};
-
-/*
- * Test for hitting a hw write breakpoint
- */
-static struct test_struct hw_write_break_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "hw_break_val", "OK", hw_write_break, }, /* set hw breakpoint */
- { "c", "T0*", NULL, got_break }, /* Continue */
- { "g", "silent", NULL, check_and_rewind_pc },
- { "write", "OK", write_regs },
- { "hw_break_val", "OK", hw_rem_write_break }, /*remove breakpoint */
- { "D", "OK" }, /* Detach */
- { "D", "OK", NULL, got_break }, /* On success we made it here */
- { "", "" },
-};
-
-/*
- * Test for hitting a hw access breakpoint
- */
-static struct test_struct hw_access_break_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "hw_break_val", "OK", hw_access_break, }, /* set hw breakpoint */
- { "c", "T0*", NULL, got_break }, /* Continue */
- { "g", "silent", NULL, check_and_rewind_pc },
- { "write", "OK", write_regs },
- { "hw_break_val", "OK", hw_rem_access_break }, /*remove breakpoint */
- { "D", "OK" }, /* Detach */
- { "D", "OK", NULL, got_break }, /* On success we made it here */
- { "", "" },
-};
-
-/*
- * Test for hitting a hw access breakpoint
- */
-static struct test_struct nmi_sleep_test[] = {
- { "?", "S0*" }, /* Clear break points */
- { "c", "T0*", NULL, got_break }, /* Continue */
- { "D", "OK" }, /* Detach */
- { "D", "OK", NULL, got_break }, /* On success we made it here */
- { "", "" },
-};
-
-static void fill_get_buf(char *buf)
-{
- unsigned char checksum = 0;
- int count = 0;
- char ch;
-
- strcpy(get_buf, "$");
- strcat(get_buf, buf);
- while ((ch = buf[count])) {
- checksum += ch;
- count++;
- }
- strcat(get_buf, "#");
- get_buf[count + 2] = hex_asc_hi(checksum);
- get_buf[count + 3] = hex_asc_lo(checksum);
- get_buf[count + 4] = '\0';
- v2printk("get%i: %s\n", ts.idx, get_buf);
-}
-
-static int validate_simple_test(char *put_str)
-{
- char *chk_str;
-
- if (ts.tst[ts.idx].put_handler)
- return ts.tst[ts.idx].put_handler(put_str,
- ts.tst[ts.idx].put);
-
- chk_str = ts.tst[ts.idx].put;
- if (*put_str == '$')
- put_str++;
-
- while (*chk_str != '\0' && *put_str != '\0') {
- /* If someone does a * to match the rest of the string, allow
- * it, or stop if the received string is complete.
- */
- if (*put_str == '#' || *chk_str == '*')
- return 0;
- if (*put_str != *chk_str)
- return 1;
-
- chk_str++;
- put_str++;
- }
- if (*chk_str == '\0' && (*put_str == '\0' || *put_str == '#'))
- return 0;
-
- return 1;
-}
-
-static int run_simple_test(int is_get_char, int chr)
-{
- int ret = 0;
- if (is_get_char) {
- /* Send an ACK on the get if a prior put completed and set the
- * send ack variable
- */
- if (send_ack) {
- send_ack = 0;
- return '+';
- }
- /* On the first get char, fill the transmit buffer and then
- * take from the get_string.
- */
- if (get_buf_cnt == 0) {
- if (ts.tst[ts.idx].get_handler)
- ts.tst[ts.idx].get_handler(ts.tst[ts.idx].get);
- else
- fill_get_buf(ts.tst[ts.idx].get);
- }
-
- if (get_buf[get_buf_cnt] == '\0') {
- eprintk("kgdbts: ERROR GET: EOB on '%s' at %i\n",
- ts.name, ts.idx);
- get_buf_cnt = 0;
- fill_get_buf("D");
- }
- ret = get_buf[get_buf_cnt];
- get_buf_cnt++;
- return ret;
- }
-
- /* This callback is a put char which is when kgdb sends data to
- * this I/O module.
- */
- if (ts.tst[ts.idx].get[0] == '\0' && ts.tst[ts.idx].put[0] == '\0' &&
- !ts.tst[ts.idx].get_handler) {
- eprintk("kgdbts: ERROR: beyond end of test on"
- " '%s' line %i\n", ts.name, ts.idx);
- return 0;
- }
-
- if (put_buf_cnt >= BUFMAX) {
- eprintk("kgdbts: ERROR: put buffer overflow on"
- " '%s' line %i\n", ts.name, ts.idx);
- put_buf_cnt = 0;
- return 0;
- }
- /* Ignore everything until the first valid packet start '$' */
- if (put_buf_cnt == 0 && chr != '$')
- return 0;
-
- put_buf[put_buf_cnt] = chr;
- put_buf_cnt++;
-
- /* End of packet == #XX so look for the '#' */
- if (put_buf_cnt > 3 && put_buf[put_buf_cnt - 3] == '#') {
- if (put_buf_cnt >= BUFMAX) {
- eprintk("kgdbts: ERROR: put buffer overflow on"
- " '%s' line %i\n", ts.name, ts.idx);
- put_buf_cnt = 0;
- return 0;
- }
- put_buf[put_buf_cnt] = '\0';
- v2printk("put%i: %s\n", ts.idx, put_buf);
- /* Trigger check here */
- if (ts.validate_put && ts.validate_put(put_buf)) {
- eprintk("kgdbts: ERROR PUT: end of test "
- "buffer on '%s' line %i expected %s got %s\n",
- ts.name, ts.idx, ts.tst[ts.idx].put, put_buf);
- }
- ts.idx++;
- put_buf_cnt = 0;
- get_buf_cnt = 0;
- send_ack = 1;
- }
- return 0;
-}
-
-static void init_simple_test(void)
-{
- memset(&ts, 0, sizeof(ts));
- ts.run_test = run_simple_test;
- ts.validate_put = validate_simple_test;
-}
-
-static void run_plant_and_detach_test(int is_early)
-{
- char before[BREAK_INSTR_SIZE];
- char after[BREAK_INSTR_SIZE];
-
- probe_kernel_read(before, (char *)kgdbts_break_test,
- BREAK_INSTR_SIZE);
- init_simple_test();
- ts.tst = plant_and_detach_test;
- ts.name = "plant_and_detach_test";
- /* Activate test with initial breakpoint */
- if (!is_early)
- kgdb_breakpoint();
- probe_kernel_read(after, (char *)kgdbts_break_test,
- BREAK_INSTR_SIZE);
- if (memcmp(before, after, BREAK_INSTR_SIZE)) {
- printk(KERN_CRIT "kgdbts: ERROR kgdb corrupted memory\n");
- panic("kgdb memory corruption");
- }
-
- /* complete the detach test */
- if (!is_early)
- kgdbts_break_test();
-}
-
-static void run_breakpoint_test(int is_hw_breakpoint)
-{
- test_complete = 0;
- init_simple_test();
- if (is_hw_breakpoint) {
- ts.tst = hw_breakpoint_test;
- ts.name = "hw_breakpoint_test";
- } else {
- ts.tst = sw_breakpoint_test;
- ts.name = "sw_breakpoint_test";
- }
- /* Activate test with initial breakpoint */
- kgdb_breakpoint();
- /* run code with the break point in it */
- kgdbts_break_test();
- kgdb_breakpoint();
-
- if (test_complete)
- return;
-
- eprintk("kgdbts: ERROR %s test failed\n", ts.name);
- if (is_hw_breakpoint)
- hwbreaks_ok = 0;
-}
-
-static void run_hw_break_test(int is_write_test)
-{
- test_complete = 0;
- init_simple_test();
- if (is_write_test) {
- ts.tst = hw_write_break_test;
- ts.name = "hw_write_break_test";
- } else {
- ts.tst = hw_access_break_test;
- ts.name = "hw_access_break_test";
- }
- /* Activate test with initial breakpoint */
- kgdb_breakpoint();
- hw_break_val_access();
- if (is_write_test) {
- if (test_complete == 2) {
- eprintk("kgdbts: ERROR %s broke on access\n",
- ts.name);
- hwbreaks_ok = 0;
- }
- hw_break_val_write();
- }
- kgdb_breakpoint();
-
- if (test_complete == 1)
- return;
-
- eprintk("kgdbts: ERROR %s test failed\n", ts.name);
- hwbreaks_ok = 0;
-}
-
-static void run_nmi_sleep_test(int nmi_sleep)
-{
- unsigned long flags;
-
- init_simple_test();
- ts.tst = nmi_sleep_test;
- ts.name = "nmi_sleep_test";
- /* Activate test with initial breakpoint */
- kgdb_breakpoint();
- local_irq_save(flags);
- mdelay(nmi_sleep*1000);
- touch_nmi_watchdog();
- local_irq_restore(flags);
- if (test_complete != 2)
- eprintk("kgdbts: ERROR nmi_test did not hit nmi\n");
- kgdb_breakpoint();
- if (test_complete == 1)
- return;
-
- eprintk("kgdbts: ERROR %s test failed\n", ts.name);
-}
-
-static void run_bad_read_test(void)
-{
- init_simple_test();
- ts.tst = bad_read_test;
- ts.name = "bad_read_test";
- /* Activate test with initial breakpoint */
- kgdb_breakpoint();
-}
-
-static void run_do_fork_test(void)
-{
- init_simple_test();
- ts.tst = do_fork_test;
- ts.name = "do_fork_test";
- /* Activate test with initial breakpoint */
- kgdb_breakpoint();
-}
-
-static void run_sys_open_test(void)
-{
- init_simple_test();
- ts.tst = sys_open_test;
- ts.name = "sys_open_test";
- /* Activate test with initial breakpoint */
- kgdb_breakpoint();
-}
-
-static void run_singlestep_break_test(void)
-{
- init_simple_test();
- ts.tst = singlestep_break_test;
- ts.name = "singlestep_breakpoint_test";
- /* Activate test with initial breakpoint */
- kgdb_breakpoint();
- kgdbts_break_test();
- kgdbts_break_test();
-}
-
-static void kgdbts_run_tests(void)
-{
- char *ptr;
- int fork_test = 0;
- int do_sys_open_test = 0;
- int sstep_test = 1000;
- int nmi_sleep = 0;
- int i;
-
- ptr = strchr(config, 'F');
- if (ptr)
- fork_test = simple_strtol(ptr + 1, NULL, 10);
- ptr = strchr(config, 'S');
- if (ptr)
- do_sys_open_test = simple_strtol(ptr + 1, NULL, 10);
- ptr = strchr(config, 'N');
- if (ptr)
- nmi_sleep = simple_strtol(ptr+1, NULL, 10);
- ptr = strchr(config, 'I');
- if (ptr)
- sstep_test = simple_strtol(ptr+1, NULL, 10);
-
- /* All HW break point tests */
- if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) {
- hwbreaks_ok = 1;
- v1printk("kgdbts:RUN hw breakpoint test\n");
- run_breakpoint_test(1);
- v1printk("kgdbts:RUN hw write breakpoint test\n");
- run_hw_break_test(1);
- v1printk("kgdbts:RUN access write breakpoint test\n");
- run_hw_break_test(0);
- }
-
- /* required internal KGDB tests */
- v1printk("kgdbts:RUN plant and detach test\n");
- run_plant_and_detach_test(0);
- v1printk("kgdbts:RUN sw breakpoint test\n");
- run_breakpoint_test(0);
- v1printk("kgdbts:RUN bad memory access test\n");
- run_bad_read_test();
- v1printk("kgdbts:RUN singlestep test %i iterations\n", sstep_test);
- for (i = 0; i < sstep_test; i++) {
- run_singlestep_break_test();
- if (i % 100 == 0)
- v1printk("kgdbts:RUN singlestep [%i/%i]\n",
- i, sstep_test);
- }
-
- /* ===Optional tests=== */
-
- if (nmi_sleep) {
- v1printk("kgdbts:RUN NMI sleep %i seconds test\n", nmi_sleep);
- run_nmi_sleep_test(nmi_sleep);
- }
-
- /* If the do_fork test is run it will be the last test that is
- * executed because a kernel thread will be spawned at the very
- * end to unregister the debug hooks.
- */
- if (fork_test) {
- repeat_test = fork_test;
- printk(KERN_INFO "kgdbts:RUN do_fork for %i breakpoints\n",
- repeat_test);
- kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg");
- run_do_fork_test();
- return;
- }
-
- /* If the sys_open test is run it will be the last test that is
- * executed because a kernel thread will be spawned at the very
- * end to unregister the debug hooks.
- */
- if (do_sys_open_test) {
- repeat_test = do_sys_open_test;
- printk(KERN_INFO "kgdbts:RUN sys_open for %i breakpoints\n",
- repeat_test);
- kthread_run(kgdbts_unreg_thread, NULL, "kgdbts_unreg");
- run_sys_open_test();
- return;
- }
- /* Shutdown and unregister */
- kgdb_unregister_io_module(&kgdbts_io_ops);
- configured = 0;
-}
-
-static int kgdbts_option_setup(char *opt)
-{
- if (strlen(opt) >= MAX_CONFIG_LEN) {
- printk(KERN_ERR "kgdbts: config string too long\n");
- return -ENOSPC;
- }
- strcpy(config, opt);
-
- verbose = 0;
- if (strstr(config, "V1"))
- verbose = 1;
- if (strstr(config, "V2"))
- verbose = 2;
-
- return 0;
-}
-
-__setup("kgdbts=", kgdbts_option_setup);
-
-static int configure_kgdbts(void)
-{
- int err = 0;
-
- if (!strlen(config) || isspace(config[0]))
- goto noconfig;
- err = kgdbts_option_setup(config);
- if (err)
- goto noconfig;
-
- final_ack = 0;
- run_plant_and_detach_test(1);
-
- err = kgdb_register_io_module(&kgdbts_io_ops);
- if (err) {
- configured = 0;
- return err;
- }
- configured = 1;
- kgdbts_run_tests();
-
- return err;
-
-noconfig:
- config[0] = 0;
- configured = 0;
-
- return err;
-}
-
-static int __init init_kgdbts(void)
-{
- /* Already configured? */
- if (configured == 1)
- return 0;
-
- return configure_kgdbts();
-}
-
-static int kgdbts_get_char(void)
-{
- int val = 0;
-
- if (ts.run_test)
- val = ts.run_test(1, 0);
-
- return val;
-}
-
-static void kgdbts_put_char(u8 chr)
-{
- if (ts.run_test)
- ts.run_test(0, chr);
-}
-
-static int param_set_kgdbts_var(const char *kmessage, struct kernel_param *kp)
-{
- int len = strlen(kmessage);
-
- if (len >= MAX_CONFIG_LEN) {
- printk(KERN_ERR "kgdbts: config string too long\n");
- return -ENOSPC;
- }
-
- /* Only copy in the string if the init function has not run yet */
- if (configured < 0) {
- strcpy(config, kmessage);
- return 0;
- }
-
- if (configured == 1) {
- printk(KERN_ERR "kgdbts: ERROR: Already configured and running.\n");
- return -EBUSY;
- }
-
- strcpy(config, kmessage);
- /* Chop out \n char as a result of echo */
- if (config[len - 1] == '\n')
- config[len - 1] = '\0';
-
- /* Go and configure with the new params. */
- return configure_kgdbts();
-}
-
-static void kgdbts_pre_exp_handler(void)
-{
- /* Increment the module count when the debugger is active */
- if (!kgdb_connected)
- try_module_get(THIS_MODULE);
-}
-
-static void kgdbts_post_exp_handler(void)
-{
- /* decrement the module count when the debugger detaches */
- if (!kgdb_connected)
- module_put(THIS_MODULE);
-}
-
-static struct kgdb_io kgdbts_io_ops = {
- .name = "kgdbts",
- .read_char = kgdbts_get_char,
- .write_char = kgdbts_put_char,
- .pre_exception = kgdbts_pre_exp_handler,
- .post_exception = kgdbts_post_exp_handler,
-};
-
-module_init(init_kgdbts);
-module_param_call(kgdbts, param_set_kgdbts_var, param_get_string, &kps, 0644);
-MODULE_PARM_DESC(kgdbts, "<A|V1|V2>[F#|S#][N#]");
-MODULE_DESCRIPTION("KGDB Test Suite");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Wind River Systems, Inc.");
-
diff --git a/ANDROID_3.4.5/drivers/misc/lis3lv02d/Kconfig b/ANDROID_3.4.5/drivers/misc/lis3lv02d/Kconfig
deleted file mode 100644
index 8f474e6f..00000000
--- a/ANDROID_3.4.5/drivers/misc/lis3lv02d/Kconfig
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# STMicroelectonics LIS3LV02D and similar accelerometers
-#
-
-config SENSORS_LIS3_SPI
- tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
- depends on !ACPI && SPI_MASTER && INPUT
- select SENSORS_LIS3LV02D
- default n
- help
- This driver provides support for the LIS3LV02Dx accelerometer connected
- via SPI. The accelerometer data is readable via
- /sys/devices/platform/lis3lv02d.
-
- This driver also provides an absolute input class device, allowing
- the laptop to act as a pinball machine-esque joystick.
-
- This driver can also be built as modules. If so, the core module
- will be called lis3lv02d and a specific module for the SPI transport
- is called lis3lv02d_spi.
-
-config SENSORS_LIS3_I2C
- tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (I2C)"
- depends on I2C && INPUT
- select SENSORS_LIS3LV02D
- default n
- help
- This driver provides support for the LIS3LV02Dx accelerometer connected
- via I2C. The accelerometer data is readable via
- /sys/devices/platform/lis3lv02d.
-
- This driver also provides an absolute input class device, allowing
- the device to act as a pinball machine-esque joystick.
-
- This driver can also be built as modules. If so, the core module
- will be called lis3lv02d and a specific module for the I2C transport
- is called lis3lv02d_i2c.
diff --git a/ANDROID_3.4.5/drivers/misc/lis3lv02d/Makefile b/ANDROID_3.4.5/drivers/misc/lis3lv02d/Makefile
deleted file mode 100644
index 4bf58b16..00000000
--- a/ANDROID_3.4.5/drivers/misc/lis3lv02d/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# STMicroelectonics LIS3LV02D and similar accelerometers
-#
-
-obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o
-obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d_spi.o
-obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d_i2c.o
diff --git a/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d.c b/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d.c
deleted file mode 100644
index a981e2a4..00000000
--- a/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d.c
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*
- * lis3lv02d.c - ST LIS3LV02DL accelerometer driver
- *
- * Copyright (C) 2007-2008 Yan Burman
- * Copyright (C) 2008 Eric Piel
- * Copyright (C) 2008-2009 Pavel Machek
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/dmi.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/input-polldev.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/freezer.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/pm_runtime.h>
-#include <linux/atomic.h>
-#include "lis3lv02d.h"
-
-#define DRIVER_NAME "lis3lv02d"
-
-/* joystick device poll interval in milliseconds */
-#define MDPS_POLL_INTERVAL 50
-#define MDPS_POLL_MIN 0
-#define MDPS_POLL_MAX 2000
-
-#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
-
-#define SELFTEST_OK 0
-#define SELFTEST_FAIL -1
-#define SELFTEST_IRQ -2
-
-#define IRQ_LINE0 0
-#define IRQ_LINE1 1
-
-/*
- * The sensor can also generate interrupts (DRDY) but it's pretty pointless
- * because they are generated even if the data do not change. So it's better
- * to keep the interrupt for the free-fall event. The values are updated at
- * 40Hz (at the lowest frequency), but as it can be pretty time consuming on
- * some low processor, we poll the sensor only at 20Hz... enough for the
- * joystick.
- */
-
-#define LIS3_PWRON_DELAY_WAI_12B (5000)
-#define LIS3_PWRON_DELAY_WAI_8B (3000)
-
-/*
- * LIS3LV02D spec says 1024 LSBs corresponds 1 G -> 1LSB is 1000/1024 mG
- * LIS302D spec says: 18 mG / digit
- * LIS3_ACCURACY is used to increase accuracy of the intermediate
- * calculation results.
- */
-#define LIS3_ACCURACY 1024
-/* Sensitivity values for -2G +2G scale */
-#define LIS3_SENSITIVITY_12B ((LIS3_ACCURACY * 1000) / 1024)
-#define LIS3_SENSITIVITY_8B (18 * LIS3_ACCURACY)
-
-#define LIS3_DEFAULT_FUZZ_12B 3
-#define LIS3_DEFAULT_FLAT_12B 3
-#define LIS3_DEFAULT_FUZZ_8B 1
-#define LIS3_DEFAULT_FLAT_8B 1
-
-struct lis3lv02d lis3_dev = {
- .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
-};
-EXPORT_SYMBOL_GPL(lis3_dev);
-
-/* just like param_set_int() but does sanity-check so that it won't point
- * over the axis array size
- */
-static int param_set_axis(const char *val, const struct kernel_param *kp)
-{
- int ret = param_set_int(val, kp);
- if (!ret) {
- int val = *(int *)kp->arg;
- if (val < 0)
- val = -val;
- if (!val || val > 3)
- return -EINVAL;
- }
- return ret;
-}
-
-static struct kernel_param_ops param_ops_axis = {
- .set = param_set_axis,
- .get = param_get_int,
-};
-
-#define param_check_axis(name, p) param_check_int(name, p)
-
-module_param_array_named(axes, lis3_dev.ac.as_array, axis, NULL, 0644);
-MODULE_PARM_DESC(axes, "Axis-mapping for x,y,z directions");
-
-static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg)
-{
- s8 lo;
- if (lis3->read(lis3, reg, &lo) < 0)
- return 0;
-
- return lo;
-}
-
-static s16 lis3lv02d_read_12(struct lis3lv02d *lis3, int reg)
-{
- u8 lo, hi;
-
- lis3->read(lis3, reg - 1, &lo);
- lis3->read(lis3, reg, &hi);
- /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
- return (s16)((hi << 8) | lo);
-}
-
-/**
- * lis3lv02d_get_axis - For the given axis, give the value converted
- * @axis: 1,2,3 - can also be negative
- * @hw_values: raw values returned by the hardware
- *
- * Returns the converted value.
- */
-static inline int lis3lv02d_get_axis(s8 axis, int hw_values[3])
-{
- if (axis > 0)
- return hw_values[axis - 1];
- else
- return -hw_values[-axis - 1];
-}
-
-/**
- * lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer
- * @lis3: pointer to the device struct
- * @x: where to store the X axis value
- * @y: where to store the Y axis value
- * @z: where to store the Z axis value
- *
- * Note that 40Hz input device can eat up about 10% CPU at 800MHZ
- */
-static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
-{
- int position[3];
- int i;
-
- if (lis3->blkread) {
- if (lis3->whoami == WAI_12B) {
- u16 data[3];
- lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
- for (i = 0; i < 3; i++)
- position[i] = (s16)le16_to_cpu(data[i]);
- } else {
- u8 data[5];
- /* Data: x, dummy, y, dummy, z */
- lis3->blkread(lis3, OUTX, 5, data);
- for (i = 0; i < 3; i++)
- position[i] = (s8)data[i * 2];
- }
- } else {
- position[0] = lis3->read_data(lis3, OUTX);
- position[1] = lis3->read_data(lis3, OUTY);
- position[2] = lis3->read_data(lis3, OUTZ);
- }
-
- for (i = 0; i < 3; i++)
- position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
-
- *x = lis3lv02d_get_axis(lis3->ac.x, position);
- *y = lis3lv02d_get_axis(lis3->ac.y, position);
- *z = lis3lv02d_get_axis(lis3->ac.z, position);
-}
-
-/* conversion btw sampling rate and the register values */
-static int lis3_12_rates[4] = {40, 160, 640, 2560};
-static int lis3_8_rates[2] = {100, 400};
-static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
-
-/* ODR is Output Data Rate */
-static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
-{
- u8 ctrl;
- int shift;
-
- lis3->read(lis3, CTRL_REG1, &ctrl);
- ctrl &= lis3->odr_mask;
- shift = ffs(lis3->odr_mask) - 1;
- return lis3->odrs[(ctrl >> shift)];
-}
-
-static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3)
-{
- int div = lis3lv02d_get_odr(lis3);
-
- if (WARN_ONCE(div == 0, "device returned spurious data"))
- return -ENXIO;
-
- /* LIS3 power on delay is quite long */
- msleep(lis3->pwron_delay / div);
- return 0;
-}
-
-static int lis3lv02d_set_odr(struct lis3lv02d *lis3, int rate)
-{
- u8 ctrl;
- int i, len, shift;
-
- if (!rate)
- return -EINVAL;
-
- lis3->read(lis3, CTRL_REG1, &ctrl);
- ctrl &= ~lis3->odr_mask;
- len = 1 << hweight_long(lis3->odr_mask); /* # of possible values */
- shift = ffs(lis3->odr_mask) - 1;
-
- for (i = 0; i < len; i++)
- if (lis3->odrs[i] == rate) {
- lis3->write(lis3, CTRL_REG1,
- ctrl | (i << shift));
- return 0;
- }
- return -EINVAL;
-}
-
-static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
-{
- u8 ctlreg, reg;
- s16 x, y, z;
- u8 selftest;
- int ret;
- u8 ctrl_reg_data;
- unsigned char irq_cfg;
-
- mutex_lock(&lis3->mutex);
-
- irq_cfg = lis3->irq_cfg;
- if (lis3->whoami == WAI_8B) {
- lis3->data_ready_count[IRQ_LINE0] = 0;
- lis3->data_ready_count[IRQ_LINE1] = 0;
-
- /* Change interrupt cfg to data ready for selftest */
- atomic_inc(&lis3->wake_thread);
- lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
- lis3->read(lis3, CTRL_REG3, &ctrl_reg_data);
- lis3->write(lis3, CTRL_REG3, (ctrl_reg_data &
- ~(LIS3_IRQ1_MASK | LIS3_IRQ2_MASK)) |
- (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
- }
-
- if (lis3->whoami == WAI_3DC) {
- ctlreg = CTRL_REG4;
- selftest = CTRL4_ST0;
- } else {
- ctlreg = CTRL_REG1;
- if (lis3->whoami == WAI_12B)
- selftest = CTRL1_ST;
- else
- selftest = CTRL1_STP;
- }
-
- lis3->read(lis3, ctlreg, &reg);
- lis3->write(lis3, ctlreg, (reg | selftest));
- ret = lis3lv02d_get_pwron_wait(lis3);
- if (ret)
- goto fail;
-
- /* Read directly to avoid axis remap */
- x = lis3->read_data(lis3, OUTX);
- y = lis3->read_data(lis3, OUTY);
- z = lis3->read_data(lis3, OUTZ);
-
- /* back to normal settings */
- lis3->write(lis3, ctlreg, reg);
- ret = lis3lv02d_get_pwron_wait(lis3);
- if (ret)
- goto fail;
-
- results[0] = x - lis3->read_data(lis3, OUTX);
- results[1] = y - lis3->read_data(lis3, OUTY);
- results[2] = z - lis3->read_data(lis3, OUTZ);
-
- ret = 0;
-
- if (lis3->whoami == WAI_8B) {
- /* Restore original interrupt configuration */
- atomic_dec(&lis3->wake_thread);
- lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
- lis3->irq_cfg = irq_cfg;
-
- if ((irq_cfg & LIS3_IRQ1_MASK) &&
- lis3->data_ready_count[IRQ_LINE0] < 2) {
- ret = SELFTEST_IRQ;
- goto fail;
- }
-
- if ((irq_cfg & LIS3_IRQ2_MASK) &&
- lis3->data_ready_count[IRQ_LINE1] < 2) {
- ret = SELFTEST_IRQ;
- goto fail;
- }
- }
-
- if (lis3->pdata) {
- int i;
- for (i = 0; i < 3; i++) {
- /* Check against selftest acceptance limits */
- if ((results[i] < lis3->pdata->st_min_limits[i]) ||
- (results[i] > lis3->pdata->st_max_limits[i])) {
- ret = SELFTEST_FAIL;
- goto fail;
- }
- }
- }
-
- /* test passed */
-fail:
- mutex_unlock(&lis3->mutex);
- return ret;
-}
-
-/*
- * Order of registers in the list affects to order of the restore process.
- * Perhaps it is a good idea to set interrupt enable register as a last one
- * after all other configurations
- */
-static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
- FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
- CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
- CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
- CTRL_REG1, CTRL_REG2, CTRL_REG3};
-
-static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
- FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
- DD_THSE_L, DD_THSE_H,
- CTRL_REG1, CTRL_REG3, CTRL_REG2};
-
-static inline void lis3_context_save(struct lis3lv02d *lis3)
-{
- int i;
- for (i = 0; i < lis3->regs_size; i++)
- lis3->read(lis3, lis3->regs[i], &lis3->reg_cache[i]);
- lis3->regs_stored = true;
-}
-
-static inline void lis3_context_restore(struct lis3lv02d *lis3)
-{
- int i;
- if (lis3->regs_stored)
- for (i = 0; i < lis3->regs_size; i++)
- lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
-}
-
-void lis3lv02d_poweroff(struct lis3lv02d *lis3)
-{
- if (lis3->reg_ctrl)
- lis3_context_save(lis3);
- /* disable X,Y,Z axis and power down */
- lis3->write(lis3, CTRL_REG1, 0x00);
- if (lis3->reg_ctrl)
- lis3->reg_ctrl(lis3, LIS3_REG_OFF);
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
-
-int lis3lv02d_poweron(struct lis3lv02d *lis3)
-{
- int err;
- u8 reg;
-
- lis3->init(lis3);
-
- /*
- * Common configuration
- * BDU: (12 bits sensors only) LSB and MSB values are not updated until
- * both have been read. So the value read will always be correct.
- * Set BOOT bit to refresh factory tuning values.
- */
- if (lis3->pdata) {
- lis3->read(lis3, CTRL_REG2, &reg);
- if (lis3->whoami == WAI_12B)
- reg |= CTRL2_BDU | CTRL2_BOOT;
- else
- reg |= CTRL2_BOOT_8B;
- lis3->write(lis3, CTRL_REG2, reg);
- }
-
- err = lis3lv02d_get_pwron_wait(lis3);
- if (err)
- return err;
-
- if (lis3->reg_ctrl)
- lis3_context_restore(lis3);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
-
-
-static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
-{
- struct lis3lv02d *lis3 = pidev->private;
- int x, y, z;
-
- mutex_lock(&lis3->mutex);
- lis3lv02d_get_xyz(lis3, &x, &y, &z);
- input_report_abs(pidev->input, ABS_X, x);
- input_report_abs(pidev->input, ABS_Y, y);
- input_report_abs(pidev->input, ABS_Z, z);
- input_sync(pidev->input);
- mutex_unlock(&lis3->mutex);
-}
-
-static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
-{
- struct lis3lv02d *lis3 = pidev->private;
-
- if (lis3->pm_dev)
- pm_runtime_get_sync(lis3->pm_dev);
-
- if (lis3->pdata && lis3->whoami == WAI_8B && lis3->idev)
- atomic_set(&lis3->wake_thread, 1);
- /*
- * Update coordinates for the case where poll interval is 0 and
- * the chip in running purely under interrupt control
- */
- lis3lv02d_joystick_poll(pidev);
-}
-
-static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
-{
- struct lis3lv02d *lis3 = pidev->private;
-
- atomic_set(&lis3->wake_thread, 0);
- if (lis3->pm_dev)
- pm_runtime_put(lis3->pm_dev);
-}
-
-static irqreturn_t lis302dl_interrupt(int irq, void *data)
-{
- struct lis3lv02d *lis3 = data;
-
- if (!test_bit(0, &lis3->misc_opened))
- goto out;
-
- /*
- * Be careful: on some HP laptops the bios force DD when on battery and
- * the lid is closed. This leads to interrupts as soon as a little move
- * is done.
- */
- atomic_inc(&lis3->count);
-
- wake_up_interruptible(&lis3->misc_wait);
- kill_fasync(&lis3->async_queue, SIGIO, POLL_IN);
-out:
- if (atomic_read(&lis3->wake_thread))
- return IRQ_WAKE_THREAD;
- return IRQ_HANDLED;
-}
-
-static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
-{
- struct input_dev *dev = lis3->idev->input;
- u8 click_src;
-
- mutex_lock(&lis3->mutex);
- lis3->read(lis3, CLICK_SRC, &click_src);
-
- if (click_src & CLICK_SINGLE_X) {
- input_report_key(dev, lis3->mapped_btns[0], 1);
- input_report_key(dev, lis3->mapped_btns[0], 0);
- }
-
- if (click_src & CLICK_SINGLE_Y) {
- input_report_key(dev, lis3->mapped_btns[1], 1);
- input_report_key(dev, lis3->mapped_btns[1], 0);
- }
-
- if (click_src & CLICK_SINGLE_Z) {
- input_report_key(dev, lis3->mapped_btns[2], 1);
- input_report_key(dev, lis3->mapped_btns[2], 0);
- }
- input_sync(dev);
- mutex_unlock(&lis3->mutex);
-}
-
-static inline void lis302dl_data_ready(struct lis3lv02d *lis3, int index)
-{
- int dummy;
-
- /* Dummy read to ack interrupt */
- lis3lv02d_get_xyz(lis3, &dummy, &dummy, &dummy);
- lis3->data_ready_count[index]++;
-}
-
-static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
-{
- struct lis3lv02d *lis3 = data;
- u8 irq_cfg = lis3->irq_cfg & LIS3_IRQ1_MASK;
-
- if (irq_cfg == LIS3_IRQ1_CLICK)
- lis302dl_interrupt_handle_click(lis3);
- else if (unlikely(irq_cfg == LIS3_IRQ1_DATA_READY))
- lis302dl_data_ready(lis3, IRQ_LINE0);
- else
- lis3lv02d_joystick_poll(lis3->idev);
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
-{
- struct lis3lv02d *lis3 = data;
- u8 irq_cfg = lis3->irq_cfg & LIS3_IRQ2_MASK;
-
- if (irq_cfg == LIS3_IRQ2_CLICK)
- lis302dl_interrupt_handle_click(lis3);
- else if (unlikely(irq_cfg == LIS3_IRQ2_DATA_READY))
- lis302dl_data_ready(lis3, IRQ_LINE1);
- else
- lis3lv02d_joystick_poll(lis3->idev);
-
- return IRQ_HANDLED;
-}
-
-static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
-{
- struct lis3lv02d *lis3 = container_of(file->private_data,
- struct lis3lv02d, miscdev);
-
- if (test_and_set_bit(0, &lis3->misc_opened))
- return -EBUSY; /* already open */
-
- if (lis3->pm_dev)
- pm_runtime_get_sync(lis3->pm_dev);
-
- atomic_set(&lis3->count, 0);
- return 0;
-}
-
-static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
-{
- struct lis3lv02d *lis3 = container_of(file->private_data,
- struct lis3lv02d, miscdev);
-
- fasync_helper(-1, file, 0, &lis3->async_queue);
- clear_bit(0, &lis3->misc_opened); /* release the device */
- if (lis3->pm_dev)
- pm_runtime_put(lis3->pm_dev);
- return 0;
-}
-
-static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
- size_t count, loff_t *pos)
-{
- struct lis3lv02d *lis3 = container_of(file->private_data,
- struct lis3lv02d, miscdev);
-
- DECLARE_WAITQUEUE(wait, current);
- u32 data;
- unsigned char byte_data;
- ssize_t retval = 1;
-
- if (count < 1)
- return -EINVAL;
-
- add_wait_queue(&lis3->misc_wait, &wait);
- while (true) {
- set_current_state(TASK_INTERRUPTIBLE);
- data = atomic_xchg(&lis3->count, 0);
- if (data)
- break;
-
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- goto out;
- }
-
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- goto out;
- }
-
- schedule();
- }
-
- if (data < 255)
- byte_data = data;
- else
- byte_data = 255;
-
- /* make sure we are not going into copy_to_user() with
- * TASK_INTERRUPTIBLE state */
- set_current_state(TASK_RUNNING);
- if (copy_to_user(buf, &byte_data, sizeof(byte_data)))
- retval = -EFAULT;
-
-out:
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&lis3->misc_wait, &wait);
-
- return retval;
-}
-
-static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
-{
- struct lis3lv02d *lis3 = container_of(file->private_data,
- struct lis3lv02d, miscdev);
-
- poll_wait(file, &lis3->misc_wait, wait);
- if (atomic_read(&lis3->count))
- return POLLIN | POLLRDNORM;
- return 0;
-}
-
-static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
-{
- struct lis3lv02d *lis3 = container_of(file->private_data,
- struct lis3lv02d, miscdev);
-
- return fasync_helper(fd, file, on, &lis3->async_queue);
-}
-
-static const struct file_operations lis3lv02d_misc_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = lis3lv02d_misc_read,
- .open = lis3lv02d_misc_open,
- .release = lis3lv02d_misc_release,
- .poll = lis3lv02d_misc_poll,
- .fasync = lis3lv02d_misc_fasync,
-};
-
-int lis3lv02d_joystick_enable(struct lis3lv02d *lis3)
-{
- struct input_dev *input_dev;
- int err;
- int max_val, fuzz, flat;
- int btns[] = {BTN_X, BTN_Y, BTN_Z};
-
- if (lis3->idev)
- return -EINVAL;
-
- lis3->idev = input_allocate_polled_device();
- if (!lis3->idev)
- return -ENOMEM;
-
- lis3->idev->poll = lis3lv02d_joystick_poll;
- lis3->idev->open = lis3lv02d_joystick_open;
- lis3->idev->close = lis3lv02d_joystick_close;
- lis3->idev->poll_interval = MDPS_POLL_INTERVAL;
- lis3->idev->poll_interval_min = MDPS_POLL_MIN;
- lis3->idev->poll_interval_max = MDPS_POLL_MAX;
- lis3->idev->private = lis3;
- input_dev = lis3->idev->input;
-
- input_dev->name = "ST LIS3LV02DL Accelerometer";
- input_dev->phys = DRIVER_NAME "/input0";
- input_dev->id.bustype = BUS_HOST;
- input_dev->id.vendor = 0;
- input_dev->dev.parent = &lis3->pdev->dev;
-
- set_bit(EV_ABS, input_dev->evbit);
- max_val = (lis3->mdps_max_val * lis3->scale) / LIS3_ACCURACY;
- if (lis3->whoami == WAI_12B) {
- fuzz = LIS3_DEFAULT_FUZZ_12B;
- flat = LIS3_DEFAULT_FLAT_12B;
- } else {
- fuzz = LIS3_DEFAULT_FUZZ_8B;
- flat = LIS3_DEFAULT_FLAT_8B;
- }
- fuzz = (fuzz * lis3->scale) / LIS3_ACCURACY;
- flat = (flat * lis3->scale) / LIS3_ACCURACY;
-
- input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
- input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
- input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);
-
- lis3->mapped_btns[0] = lis3lv02d_get_axis(abs(lis3->ac.x), btns);
- lis3->mapped_btns[1] = lis3lv02d_get_axis(abs(lis3->ac.y), btns);
- lis3->mapped_btns[2] = lis3lv02d_get_axis(abs(lis3->ac.z), btns);
-
- err = input_register_polled_device(lis3->idev);
- if (err) {
- input_free_polled_device(lis3->idev);
- lis3->idev = NULL;
- }
-
- return err;
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable);
-
-void lis3lv02d_joystick_disable(struct lis3lv02d *lis3)
-{
- if (lis3->irq)
- free_irq(lis3->irq, lis3);
- if (lis3->pdata && lis3->pdata->irq2)
- free_irq(lis3->pdata->irq2, lis3);
-
- if (!lis3->idev)
- return;
-
- if (lis3->irq)
- misc_deregister(&lis3->miscdev);
- input_unregister_polled_device(lis3->idev);
- input_free_polled_device(lis3->idev);
- lis3->idev = NULL;
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
-
-/* Sysfs stuff */
-static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
-{
- /*
- * SYSFS functions are fast visitors so put-call
- * immediately after the get-call. However, keep
- * chip running for a while and schedule delayed
- * suspend. This way periodic sysfs calls doesn't
- * suffer from relatively long power up time.
- */
-
- if (lis3->pm_dev) {
- pm_runtime_get_sync(lis3->pm_dev);
- pm_runtime_put_noidle(lis3->pm_dev);
- pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
- }
-}
-
-static ssize_t lis3lv02d_selftest_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lis3lv02d *lis3 = dev_get_drvdata(dev);
- s16 values[3];
-
- static const char ok[] = "OK";
- static const char fail[] = "FAIL";
- static const char irq[] = "FAIL_IRQ";
- const char *res;
-
- lis3lv02d_sysfs_poweron(lis3);
- switch (lis3lv02d_selftest(lis3, values)) {
- case SELFTEST_FAIL:
- res = fail;
- break;
- case SELFTEST_IRQ:
- res = irq;
- break;
- case SELFTEST_OK:
- default:
- res = ok;
- break;
- }
- return sprintf(buf, "%s %d %d %d\n", res,
- values[0], values[1], values[2]);
-}
-
-static ssize_t lis3lv02d_position_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lis3lv02d *lis3 = dev_get_drvdata(dev);
- int x, y, z;
-
- lis3lv02d_sysfs_poweron(lis3);
- mutex_lock(&lis3->mutex);
- lis3lv02d_get_xyz(lis3, &x, &y, &z);
- mutex_unlock(&lis3->mutex);
- return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
-}
-
-static ssize_t lis3lv02d_rate_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct lis3lv02d *lis3 = dev_get_drvdata(dev);
-
- lis3lv02d_sysfs_poweron(lis3);
- return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3));
-}
-
-static ssize_t lis3lv02d_rate_set(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t count)
-{
- struct lis3lv02d *lis3 = dev_get_drvdata(dev);
- unsigned long rate;
-
- if (strict_strtoul(buf, 0, &rate))
- return -EINVAL;
-
- lis3lv02d_sysfs_poweron(lis3);
- if (lis3lv02d_set_odr(lis3, rate))
- return -EINVAL;
-
- return count;
-}
-
-static DEVICE_ATTR(selftest, S_IRUSR, lis3lv02d_selftest_show, NULL);
-static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL);
-static DEVICE_ATTR(rate, S_IRUGO | S_IWUSR, lis3lv02d_rate_show,
- lis3lv02d_rate_set);
-
-static struct attribute *lis3lv02d_attributes[] = {
- &dev_attr_selftest.attr,
- &dev_attr_position.attr,
- &dev_attr_rate.attr,
- NULL
-};
-
-static struct attribute_group lis3lv02d_attribute_group = {
- .attrs = lis3lv02d_attributes
-};
-
-
-static int lis3lv02d_add_fs(struct lis3lv02d *lis3)
-{
- lis3->pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
- if (IS_ERR(lis3->pdev))
- return PTR_ERR(lis3->pdev);
-
- platform_set_drvdata(lis3->pdev, lis3);
- return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
-}
-
-int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
-{
- sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
- platform_device_unregister(lis3->pdev);
- if (lis3->pm_dev) {
- /* Barrier after the sysfs remove */
- pm_runtime_barrier(lis3->pm_dev);
-
- /* SYSFS may have left chip running. Turn off if necessary */
- if (!pm_runtime_suspended(lis3->pm_dev))
- lis3lv02d_poweroff(lis3);
-
- pm_runtime_disable(lis3->pm_dev);
- pm_runtime_set_suspended(lis3->pm_dev);
- }
- kfree(lis3->reg_cache);
- return 0;
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
-
-static void lis3lv02d_8b_configure(struct lis3lv02d *lis3,
- struct lis3lv02d_platform_data *p)
-{
- int err;
- int ctrl2 = p->hipass_ctrl;
-
- if (p->click_flags) {
- lis3->write(lis3, CLICK_CFG, p->click_flags);
- lis3->write(lis3, CLICK_TIMELIMIT, p->click_time_limit);
- lis3->write(lis3, CLICK_LATENCY, p->click_latency);
- lis3->write(lis3, CLICK_WINDOW, p->click_window);
- lis3->write(lis3, CLICK_THSZ, p->click_thresh_z & 0xf);
- lis3->write(lis3, CLICK_THSY_X,
- (p->click_thresh_x & 0xf) |
- (p->click_thresh_y << 4));
-
- if (lis3->idev) {
- struct input_dev *input_dev = lis3->idev->input;
- input_set_capability(input_dev, EV_KEY, BTN_X);
- input_set_capability(input_dev, EV_KEY, BTN_Y);
- input_set_capability(input_dev, EV_KEY, BTN_Z);
- }
- }
-
- if (p->wakeup_flags) {
- lis3->write(lis3, FF_WU_CFG_1, p->wakeup_flags);
- lis3->write(lis3, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
- /* pdata value + 1 to keep this backward compatible*/
- lis3->write(lis3, FF_WU_DURATION_1, p->duration1 + 1);
- ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
- }
-
- if (p->wakeup_flags2) {
- lis3->write(lis3, FF_WU_CFG_2, p->wakeup_flags2);
- lis3->write(lis3, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f);
- /* pdata value + 1 to keep this backward compatible*/
- lis3->write(lis3, FF_WU_DURATION_2, p->duration2 + 1);
- ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
- }
- /* Configure hipass filters */
- lis3->write(lis3, CTRL_REG2, ctrl2);
-
- if (p->irq2) {
- err = request_threaded_irq(p->irq2,
- NULL,
- lis302dl_interrupt_thread2_8b,
- IRQF_TRIGGER_RISING | IRQF_ONESHOT |
- (p->irq_flags2 & IRQF_TRIGGER_MASK),
- DRIVER_NAME, lis3);
- if (err < 0)
- pr_err("No second IRQ. Limited functionality\n");
- }
-}
-
-/*
- * Initialise the accelerometer and the various subsystems.
- * Should be rather independent of the bus system.
- */
-int lis3lv02d_init_device(struct lis3lv02d *lis3)
-{
- int err;
- irq_handler_t thread_fn;
- int irq_flags = 0;
-
- lis3->whoami = lis3lv02d_read_8(lis3, WHO_AM_I);
-
- switch (lis3->whoami) {
- case WAI_12B:
- pr_info("12 bits sensor found\n");
- lis3->read_data = lis3lv02d_read_12;
- lis3->mdps_max_val = 2048;
- lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_12B;
- lis3->odrs = lis3_12_rates;
- lis3->odr_mask = CTRL1_DF0 | CTRL1_DF1;
- lis3->scale = LIS3_SENSITIVITY_12B;
- lis3->regs = lis3_wai12_regs;
- lis3->regs_size = ARRAY_SIZE(lis3_wai12_regs);
- break;
- case WAI_8B:
- pr_info("8 bits sensor found\n");
- lis3->read_data = lis3lv02d_read_8;
- lis3->mdps_max_val = 128;
- lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
- lis3->odrs = lis3_8_rates;
- lis3->odr_mask = CTRL1_DR;
- lis3->scale = LIS3_SENSITIVITY_8B;
- lis3->regs = lis3_wai8_regs;
- lis3->regs_size = ARRAY_SIZE(lis3_wai8_regs);
- break;
- case WAI_3DC:
- pr_info("8 bits 3DC sensor found\n");
- lis3->read_data = lis3lv02d_read_8;
- lis3->mdps_max_val = 128;
- lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
- lis3->odrs = lis3_3dc_rates;
- lis3->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3;
- lis3->scale = LIS3_SENSITIVITY_8B;
- break;
- default:
- pr_err("unknown sensor type 0x%X\n", lis3->whoami);
- return -EINVAL;
- }
-
- lis3->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
- sizeof(lis3_wai12_regs)), GFP_KERNEL);
-
- if (lis3->reg_cache == NULL) {
- printk(KERN_ERR DRIVER_NAME "out of memory\n");
- return -ENOMEM;
- }
-
- mutex_init(&lis3->mutex);
- atomic_set(&lis3->wake_thread, 0);
-
- lis3lv02d_add_fs(lis3);
- err = lis3lv02d_poweron(lis3);
- if (err) {
- lis3lv02d_remove_fs(lis3);
- return err;
- }
-
- if (lis3->pm_dev) {
- pm_runtime_set_active(lis3->pm_dev);
- pm_runtime_enable(lis3->pm_dev);
- }
-
- if (lis3lv02d_joystick_enable(lis3))
- pr_err("joystick initialization failed\n");
-
- /* passing in platform specific data is purely optional and only
- * used by the SPI transport layer at the moment */
- if (lis3->pdata) {
- struct lis3lv02d_platform_data *p = lis3->pdata;
-
- if (lis3->whoami == WAI_8B)
- lis3lv02d_8b_configure(lis3, p);
-
- irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK;
-
- lis3->irq_cfg = p->irq_cfg;
- if (p->irq_cfg)
- lis3->write(lis3, CTRL_REG3, p->irq_cfg);
-
- if (p->default_rate)
- lis3lv02d_set_odr(lis3, p->default_rate);
- }
-
- /* bail if we did not get an IRQ from the bus layer */
- if (!lis3->irq) {
- pr_debug("No IRQ. Disabling /dev/freefall\n");
- goto out;
- }
-
- /*
- * The sensor can generate interrupts for free-fall and direction
- * detection (distinguishable with FF_WU_SRC and DD_SRC) but to keep
- * the things simple and _fast_ we activate it only for free-fall, so
- * no need to read register (very slow with ACPI). For the same reason,
- * we forbid shared interrupts.
- *
- * IRQF_TRIGGER_RISING seems pointless on HP laptops because the
- * io-apic is not configurable (and generates a warning) but I keep it
- * in case of support for other hardware.
- */
- if (lis3->pdata && lis3->whoami == WAI_8B)
- thread_fn = lis302dl_interrupt_thread1_8b;
- else
- thread_fn = NULL;
-
- err = request_threaded_irq(lis3->irq, lis302dl_interrupt,
- thread_fn,
- IRQF_TRIGGER_RISING | IRQF_ONESHOT |
- irq_flags,
- DRIVER_NAME, lis3);
-
- if (err < 0) {
- pr_err("Cannot get IRQ\n");
- goto out;
- }
-
- lis3->miscdev.minor = MISC_DYNAMIC_MINOR;
- lis3->miscdev.name = "freefall";
- lis3->miscdev.fops = &lis3lv02d_misc_fops;
-
- if (misc_register(&lis3->miscdev))
- pr_err("misc_register failed\n");
-out:
- return 0;
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
-
-MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
-MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d.h b/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d.h
deleted file mode 100644
index 2b1482ad..00000000
--- a/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * lis3lv02d.h - ST LIS3LV02DL accelerometer driver
- *
- * Copyright (C) 2007-2008 Yan Burman
- * Copyright (C) 2008-2009 Eric Piel
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/platform_device.h>
-#include <linux/input-polldev.h>
-#include <linux/regulator/consumer.h>
-#include <linux/miscdevice.h>
-
-/*
- * This driver tries to support the "digital" accelerometer chips from
- * STMicroelectronics such as LIS3LV02DL, LIS302DL, LIS3L02DQ, LIS331DL,
- * LIS35DE, or LIS202DL. They are very similar in terms of programming, with
- * almost the same registers. In addition to differing on physical properties,
- * they differ on the number of axes (2/3), precision (8/12 bits), and special
- * features (freefall detection, click...). Unfortunately, not all the
- * differences can be probed via a register.
- * They can be connected either via I²C or SPI.
- */
-
-#include <linux/lis3lv02d.h>
-
-enum lis3_reg {
- WHO_AM_I = 0x0F,
- OFFSET_X = 0x16,
- OFFSET_Y = 0x17,
- OFFSET_Z = 0x18,
- GAIN_X = 0x19,
- GAIN_Y = 0x1A,
- GAIN_Z = 0x1B,
- CTRL_REG1 = 0x20,
- CTRL_REG2 = 0x21,
- CTRL_REG3 = 0x22,
- CTRL_REG4 = 0x23,
- HP_FILTER_RESET = 0x23,
- STATUS_REG = 0x27,
- OUTX_L = 0x28,
- OUTX_H = 0x29,
- OUTX = 0x29,
- OUTY_L = 0x2A,
- OUTY_H = 0x2B,
- OUTY = 0x2B,
- OUTZ_L = 0x2C,
- OUTZ_H = 0x2D,
- OUTZ = 0x2D,
-};
-
-enum lis302d_reg {
- FF_WU_CFG_1 = 0x30,
- FF_WU_SRC_1 = 0x31,
- FF_WU_THS_1 = 0x32,
- FF_WU_DURATION_1 = 0x33,
- FF_WU_CFG_2 = 0x34,
- FF_WU_SRC_2 = 0x35,
- FF_WU_THS_2 = 0x36,
- FF_WU_DURATION_2 = 0x37,
- CLICK_CFG = 0x38,
- CLICK_SRC = 0x39,
- CLICK_THSY_X = 0x3B,
- CLICK_THSZ = 0x3C,
- CLICK_TIMELIMIT = 0x3D,
- CLICK_LATENCY = 0x3E,
- CLICK_WINDOW = 0x3F,
-};
-
-enum lis3lv02d_reg {
- FF_WU_CFG = 0x30,
- FF_WU_SRC = 0x31,
- FF_WU_ACK = 0x32,
- FF_WU_THS_L = 0x34,
- FF_WU_THS_H = 0x35,
- FF_WU_DURATION = 0x36,
- DD_CFG = 0x38,
- DD_SRC = 0x39,
- DD_ACK = 0x3A,
- DD_THSI_L = 0x3C,
- DD_THSI_H = 0x3D,
- DD_THSE_L = 0x3E,
- DD_THSE_H = 0x3F,
-};
-
-enum lis3_who_am_i {
- WAI_3DC = 0x33, /* 8 bits: LIS3DC, HP3DC */
- WAI_12B = 0x3A, /* 12 bits: LIS3LV02D[LQ]... */
- WAI_8B = 0x3B, /* 8 bits: LIS[23]02D[LQ]... */
- WAI_6B = 0x52, /* 6 bits: LIS331DLF - not supported */
-};
-
-enum lis3lv02d_ctrl1_12b {
- CTRL1_Xen = 0x01,
- CTRL1_Yen = 0x02,
- CTRL1_Zen = 0x04,
- CTRL1_ST = 0x08,
- CTRL1_DF0 = 0x10,
- CTRL1_DF1 = 0x20,
- CTRL1_PD0 = 0x40,
- CTRL1_PD1 = 0x80,
-};
-
-/* Delta to ctrl1_12b version */
-enum lis3lv02d_ctrl1_8b {
- CTRL1_STM = 0x08,
- CTRL1_STP = 0x10,
- CTRL1_FS = 0x20,
- CTRL1_PD = 0x40,
- CTRL1_DR = 0x80,
-};
-
-enum lis3lv02d_ctrl1_3dc {
- CTRL1_ODR0 = 0x10,
- CTRL1_ODR1 = 0x20,
- CTRL1_ODR2 = 0x40,
- CTRL1_ODR3 = 0x80,
-};
-
-enum lis3lv02d_ctrl2 {
- CTRL2_DAS = 0x01,
- CTRL2_SIM = 0x02,
- CTRL2_DRDY = 0x04,
- CTRL2_IEN = 0x08,
- CTRL2_BOOT = 0x10,
- CTRL2_BLE = 0x20,
- CTRL2_BDU = 0x40, /* Block Data Update */
- CTRL2_FS = 0x80, /* Full Scale selection */
-};
-
-enum lis3lv02d_ctrl4_3dc {
- CTRL4_SIM = 0x01,
- CTRL4_ST0 = 0x02,
- CTRL4_ST1 = 0x04,
- CTRL4_FS0 = 0x10,
- CTRL4_FS1 = 0x20,
-};
-
-enum lis302d_ctrl2 {
- HP_FF_WU2 = 0x08,
- HP_FF_WU1 = 0x04,
- CTRL2_BOOT_8B = 0x40,
-};
-
-enum lis3lv02d_ctrl3 {
- CTRL3_CFS0 = 0x01,
- CTRL3_CFS1 = 0x02,
- CTRL3_FDS = 0x10,
- CTRL3_HPFF = 0x20,
- CTRL3_HPDD = 0x40,
- CTRL3_ECK = 0x80,
-};
-
-enum lis3lv02d_status_reg {
- STATUS_XDA = 0x01,
- STATUS_YDA = 0x02,
- STATUS_ZDA = 0x04,
- STATUS_XYZDA = 0x08,
- STATUS_XOR = 0x10,
- STATUS_YOR = 0x20,
- STATUS_ZOR = 0x40,
- STATUS_XYZOR = 0x80,
-};
-
-enum lis3lv02d_ff_wu_cfg {
- FF_WU_CFG_XLIE = 0x01,
- FF_WU_CFG_XHIE = 0x02,
- FF_WU_CFG_YLIE = 0x04,
- FF_WU_CFG_YHIE = 0x08,
- FF_WU_CFG_ZLIE = 0x10,
- FF_WU_CFG_ZHIE = 0x20,
- FF_WU_CFG_LIR = 0x40,
- FF_WU_CFG_AOI = 0x80,
-};
-
-enum lis3lv02d_ff_wu_src {
- FF_WU_SRC_XL = 0x01,
- FF_WU_SRC_XH = 0x02,
- FF_WU_SRC_YL = 0x04,
- FF_WU_SRC_YH = 0x08,
- FF_WU_SRC_ZL = 0x10,
- FF_WU_SRC_ZH = 0x20,
- FF_WU_SRC_IA = 0x40,
-};
-
-enum lis3lv02d_dd_cfg {
- DD_CFG_XLIE = 0x01,
- DD_CFG_XHIE = 0x02,
- DD_CFG_YLIE = 0x04,
- DD_CFG_YHIE = 0x08,
- DD_CFG_ZLIE = 0x10,
- DD_CFG_ZHIE = 0x20,
- DD_CFG_LIR = 0x40,
- DD_CFG_IEND = 0x80,
-};
-
-enum lis3lv02d_dd_src {
- DD_SRC_XL = 0x01,
- DD_SRC_XH = 0x02,
- DD_SRC_YL = 0x04,
- DD_SRC_YH = 0x08,
- DD_SRC_ZL = 0x10,
- DD_SRC_ZH = 0x20,
- DD_SRC_IA = 0x40,
-};
-
-enum lis3lv02d_click_src_8b {
- CLICK_SINGLE_X = 0x01,
- CLICK_DOUBLE_X = 0x02,
- CLICK_SINGLE_Y = 0x04,
- CLICK_DOUBLE_Y = 0x08,
- CLICK_SINGLE_Z = 0x10,
- CLICK_DOUBLE_Z = 0x20,
- CLICK_IA = 0x40,
-};
-
-enum lis3lv02d_reg_state {
- LIS3_REG_OFF = 0x00,
- LIS3_REG_ON = 0x01,
-};
-
-union axis_conversion {
- struct {
- int x, y, z;
- };
- int as_array[3];
-
-};
-
-struct lis3lv02d {
- void *bus_priv; /* used by the bus layer only */
- struct device *pm_dev; /* for pm_runtime purposes */
- int (*init) (struct lis3lv02d *lis3);
- int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
- int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
- int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
- int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
-
- int *odrs; /* Supported output data rates */
- u8 *regs; /* Regs to store / restore */
- int regs_size;
- u8 *reg_cache;
- bool regs_stored;
- u8 odr_mask; /* ODR bit mask */
- u8 whoami; /* indicates measurement precision */
- s16 (*read_data) (struct lis3lv02d *lis3, int reg);
- int mdps_max_val;
- int pwron_delay;
- int scale; /*
- * relationship between 1 LBS and mG
- * (1/1000th of earth gravity)
- */
-
- struct input_polled_dev *idev; /* input device */
- struct platform_device *pdev; /* platform device */
- struct regulator_bulk_data regulators[2];
- atomic_t count; /* interrupt count after last read */
- union axis_conversion ac; /* hw -> logical axis */
- int mapped_btns[3];
-
- u32 irq; /* IRQ number */
- struct fasync_struct *async_queue; /* queue for the misc device */
- wait_queue_head_t misc_wait; /* Wait queue for the misc device */
- unsigned long misc_opened; /* bit0: whether the device is open */
- struct miscdevice miscdev;
-
- int data_ready_count[2];
- atomic_t wake_thread;
- unsigned char irq_cfg;
-
- struct lis3lv02d_platform_data *pdata; /* for passing board config */
- struct mutex mutex; /* Serialize poll and selftest */
-};
-
-int lis3lv02d_init_device(struct lis3lv02d *lis3);
-int lis3lv02d_joystick_enable(struct lis3lv02d *lis3);
-void lis3lv02d_joystick_disable(struct lis3lv02d *lis3);
-void lis3lv02d_poweroff(struct lis3lv02d *lis3);
-int lis3lv02d_poweron(struct lis3lv02d *lis3);
-int lis3lv02d_remove_fs(struct lis3lv02d *lis3);
-
-extern struct lis3lv02d lis3_dev;
diff --git a/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
deleted file mode 100644
index e8c0019d..00000000
--- a/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d_i2c.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * drivers/hwmon/lis3lv02d_i2c.c
- *
- * Implements I2C interface for lis3lv02d (STMicroelectronics) accelerometer.
- * Driver is based on corresponding SPI driver written by Daniel Mack
- * (lis3lv02d_spi.c (C) 2009 Daniel Mack <daniel@caiaq.de> ).
- *
- * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/pm_runtime.h>
-#include <linux/delay.h>
-#include "lis3lv02d.h"
-
-#define DRV_NAME "lis3lv02d_i2c"
-
-static const char reg_vdd[] = "Vdd";
-static const char reg_vdd_io[] = "Vdd_IO";
-
-static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
-{
- int ret;
- if (state == LIS3_REG_OFF) {
- ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
- lis3->regulators);
- } else {
- ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
- lis3->regulators);
- /* Chip needs time to wakeup. Not mentioned in datasheet */
- usleep_range(10000, 20000);
- }
- return ret;
-}
-
-static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
-{
- struct i2c_client *c = lis3->bus_priv;
- return i2c_smbus_write_byte_data(c, reg, value);
-}
-
-static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
-{
- struct i2c_client *c = lis3->bus_priv;
- *v = i2c_smbus_read_byte_data(c, reg);
- return 0;
-}
-
-static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
- u8 *v)
-{
- struct i2c_client *c = lis3->bus_priv;
- reg |= (1 << 7); /* 7th bit enables address auto incrementation */
- return i2c_smbus_read_i2c_block_data(c, reg, len, v);
-}
-
-static int lis3_i2c_init(struct lis3lv02d *lis3)
-{
- u8 reg;
- int ret;
-
- lis3_reg_ctrl(lis3, LIS3_REG_ON);
-
- lis3->read(lis3, WHO_AM_I, &reg);
- if (reg != lis3->whoami)
- printk(KERN_ERR "lis3: power on failure\n");
-
- /* power up the device */
- ret = lis3->read(lis3, CTRL_REG1, &reg);
- if (ret < 0)
- return ret;
-
- reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
- return lis3->write(lis3, CTRL_REG1, reg);
-}
-
-/* Default axis mapping but it can be overwritten by platform data */
-static union axis_conversion lis3lv02d_axis_map =
- { .as_array = { LIS3_DEV_X, LIS3_DEV_Y, LIS3_DEV_Z } };
-
-static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int ret = 0;
- struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
-
- if (pdata) {
- if ((pdata->driver_features & LIS3_USE_BLOCK_READ) &&
- (i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_I2C_BLOCK)))
- lis3_dev.blkread = lis3_i2c_blockread;
-
- if (pdata->axis_x)
- lis3lv02d_axis_map.x = pdata->axis_x;
-
- if (pdata->axis_y)
- lis3lv02d_axis_map.y = pdata->axis_y;
-
- if (pdata->axis_z)
- lis3lv02d_axis_map.z = pdata->axis_z;
-
- if (pdata->setup_resources)
- ret = pdata->setup_resources();
-
- if (ret)
- goto fail;
- }
-
- lis3_dev.regulators[0].supply = reg_vdd;
- lis3_dev.regulators[1].supply = reg_vdd_io;
- ret = regulator_bulk_get(&client->dev,
- ARRAY_SIZE(lis3_dev.regulators),
- lis3_dev.regulators);
- if (ret < 0)
- goto fail;
-
- lis3_dev.pdata = pdata;
- lis3_dev.bus_priv = client;
- lis3_dev.init = lis3_i2c_init;
- lis3_dev.read = lis3_i2c_read;
- lis3_dev.write = lis3_i2c_write;
- lis3_dev.irq = client->irq;
- lis3_dev.ac = lis3lv02d_axis_map;
- lis3_dev.pm_dev = &client->dev;
-
- i2c_set_clientdata(client, &lis3_dev);
-
- /* Provide power over the init call */
- lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
-
- ret = lis3lv02d_init_device(&lis3_dev);
-
- lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
-
- if (ret)
- goto fail2;
- return 0;
-
-fail2:
- regulator_bulk_free(ARRAY_SIZE(lis3_dev.regulators),
- lis3_dev.regulators);
-fail:
- if (pdata && pdata->release_resources)
- pdata->release_resources();
- return ret;
-}
-
-static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
-{
- struct lis3lv02d *lis3 = i2c_get_clientdata(client);
- struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
-
- if (pdata && pdata->release_resources)
- pdata->release_resources();
-
- lis3lv02d_joystick_disable(lis3);
- lis3lv02d_remove_fs(&lis3_dev);
-
- regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
- lis3_dev.regulators);
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int lis3lv02d_i2c_suspend(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct lis3lv02d *lis3 = i2c_get_clientdata(client);
-
- if (!lis3->pdata || !lis3->pdata->wakeup_flags)
- lis3lv02d_poweroff(lis3);
- return 0;
-}
-
-static int lis3lv02d_i2c_resume(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct lis3lv02d *lis3 = i2c_get_clientdata(client);
-
- /*
- * pm_runtime documentation says that devices should always
- * be powered on at resume. Pm_runtime turns them off after system
- * wide resume is complete.
- */
- if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
- pm_runtime_suspended(dev))
- lis3lv02d_poweron(lis3);
-
- return 0;
-}
-#endif /* CONFIG_PM_SLEEP */
-
-#ifdef CONFIG_PM_RUNTIME
-static int lis3_i2c_runtime_suspend(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct lis3lv02d *lis3 = i2c_get_clientdata(client);
-
- lis3lv02d_poweroff(lis3);
- return 0;
-}
-
-static int lis3_i2c_runtime_resume(struct device *dev)
-{
- struct i2c_client *client = container_of(dev, struct i2c_client, dev);
- struct lis3lv02d *lis3 = i2c_get_clientdata(client);
-
- lis3lv02d_poweron(lis3);
- return 0;
-}
-#endif /* CONFIG_PM_RUNTIME */
-
-static const struct i2c_device_id lis3lv02d_id[] = {
- {"lis3lv02d", 0 },
- {}
-};
-
-MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
-
-static const struct dev_pm_ops lis3_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
- lis3lv02d_i2c_resume)
- SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
- lis3_i2c_runtime_resume,
- NULL)
-};
-
-static struct i2c_driver lis3lv02d_i2c_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- .pm = &lis3_pm_ops,
- },
- .probe = lis3lv02d_i2c_probe,
- .remove = __devexit_p(lis3lv02d_i2c_remove),
- .id_table = lis3lv02d_id,
-};
-
-module_i2c_driver(lis3lv02d_i2c_driver);
-
-MODULE_AUTHOR("Nokia Corporation");
-MODULE_DESCRIPTION("lis3lv02d I2C interface");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d_spi.c
deleted file mode 100644
index 80880e98..00000000
--- a/ANDROID_3.4.5/drivers/misc/lis3lv02d/lis3lv02d_spi.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * lis3lv02d_spi - SPI glue layer for lis3lv02d
- *
- * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * publishhed by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/spi/spi.h>
-#include <linux/pm.h>
-
-#include "lis3lv02d.h"
-
-#define DRV_NAME "lis3lv02d_spi"
-#define LIS3_SPI_READ 0x80
-
-static int lis3_spi_read(struct lis3lv02d *lis3, int reg, u8 *v)
-{
- struct spi_device *spi = lis3->bus_priv;
- int ret = spi_w8r8(spi, reg | LIS3_SPI_READ);
- if (ret < 0)
- return -EINVAL;
-
- *v = (u8) ret;
- return 0;
-}
-
-static int lis3_spi_write(struct lis3lv02d *lis3, int reg, u8 val)
-{
- u8 tmp[2] = { reg, val };
- struct spi_device *spi = lis3->bus_priv;
- return spi_write(spi, tmp, sizeof(tmp));
-}
-
-static int lis3_spi_init(struct lis3lv02d *lis3)
-{
- u8 reg;
- int ret;
-
- /* power up the device */
- ret = lis3->read(lis3, CTRL_REG1, &reg);
- if (ret < 0)
- return ret;
-
- reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
- return lis3->write(lis3, CTRL_REG1, reg);
-}
-
-static union axis_conversion lis3lv02d_axis_normal =
- { .as_array = { 1, 2, 3 } };
-
-static int __devinit lis302dl_spi_probe(struct spi_device *spi)
-{
- int ret;
-
- spi->bits_per_word = 8;
- spi->mode = SPI_MODE_0;
- ret = spi_setup(spi);
- if (ret < 0)
- return ret;
-
- lis3_dev.bus_priv = spi;
- lis3_dev.init = lis3_spi_init;
- lis3_dev.read = lis3_spi_read;
- lis3_dev.write = lis3_spi_write;
- lis3_dev.irq = spi->irq;
- lis3_dev.ac = lis3lv02d_axis_normal;
- lis3_dev.pdata = spi->dev.platform_data;
- spi_set_drvdata(spi, &lis3_dev);
-
- return lis3lv02d_init_device(&lis3_dev);
-}
-
-static int __devexit lis302dl_spi_remove(struct spi_device *spi)
-{
- struct lis3lv02d *lis3 = spi_get_drvdata(spi);
- lis3lv02d_joystick_disable(lis3);
- lis3lv02d_poweroff(lis3);
-
- return lis3lv02d_remove_fs(&lis3_dev);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int lis3lv02d_spi_suspend(struct device *dev)
-{
- struct spi_device *spi = to_spi_device(dev);
- struct lis3lv02d *lis3 = spi_get_drvdata(spi);
-
- if (!lis3->pdata || !lis3->pdata->wakeup_flags)
- lis3lv02d_poweroff(&lis3_dev);
-
- return 0;
-}
-
-static int lis3lv02d_spi_resume(struct device *dev)
-{
- struct spi_device *spi = to_spi_device(dev);
- struct lis3lv02d *lis3 = spi_get_drvdata(spi);
-
- if (!lis3->pdata || !lis3->pdata->wakeup_flags)
- lis3lv02d_poweron(lis3);
-
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(lis3lv02d_spi_pm, lis3lv02d_spi_suspend,
- lis3lv02d_spi_resume);
-
-static struct spi_driver lis302dl_spi_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- .pm = &lis3lv02d_spi_pm,
- },
- .probe = lis302dl_spi_probe,
- .remove = __devexit_p(lis302dl_spi_remove),
-};
-
-module_spi_driver(lis302dl_spi_driver);
-
-MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("lis3lv02d SPI glue layer");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("spi:" DRV_NAME);
diff --git a/ANDROID_3.4.5/drivers/misc/lkdtm.c b/ANDROID_3.4.5/drivers/misc/lkdtm.c
deleted file mode 100644
index 28adefe7..00000000
--- a/ANDROID_3.4.5/drivers/misc/lkdtm.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
- * Kprobe module for testing crash dumps
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2006
- *
- * Author: Ankita Garg <ankita@in.ibm.com>
- *
- * This module induces system failures at predefined crashpoints to
- * evaluate the reliability of crash dumps obtained using different dumping
- * solutions.
- *
- * It is adapted from the Linux Kernel Dump Test Tool by
- * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net>
- *
- * Debugfs support added by Simon Kagstrom <simon.kagstrom@netinsight.net>
- *
- * See Documentation/fault-injection/provoke-crashes.txt for instructions
- */
-
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/module.h>
-#include <linux/buffer_head.h>
-#include <linux/kprobes.h>
-#include <linux/list.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/hrtimer.h>
-#include <linux/slab.h>
-#include <scsi/scsi_cmnd.h>
-#include <linux/debugfs.h>
-
-#ifdef CONFIG_IDE
-#include <linux/ide.h>
-#endif
-
-#define DEFAULT_COUNT 10
-#define REC_NUM_DEFAULT 10
-
-enum cname {
- CN_INVALID,
- CN_INT_HARDWARE_ENTRY,
- CN_INT_HW_IRQ_EN,
- CN_INT_TASKLET_ENTRY,
- CN_FS_DEVRW,
- CN_MEM_SWAPOUT,
- CN_TIMERADD,
- CN_SCSI_DISPATCH_CMD,
- CN_IDE_CORE_CP,
- CN_DIRECT,
-};
-
-enum ctype {
- CT_NONE,
- CT_PANIC,
- CT_BUG,
- CT_EXCEPTION,
- CT_LOOP,
- CT_OVERFLOW,
- CT_CORRUPT_STACK,
- CT_UNALIGNED_LOAD_STORE_WRITE,
- CT_OVERWRITE_ALLOCATION,
- CT_WRITE_AFTER_FREE,
- CT_SOFTLOCKUP,
- CT_HARDLOCKUP,
- CT_HUNG_TASK,
-};
-
-static char* cp_name[] = {
- "INT_HARDWARE_ENTRY",
- "INT_HW_IRQ_EN",
- "INT_TASKLET_ENTRY",
- "FS_DEVRW",
- "MEM_SWAPOUT",
- "TIMERADD",
- "SCSI_DISPATCH_CMD",
- "IDE_CORE_CP",
- "DIRECT",
-};
-
-static char* cp_type[] = {
- "PANIC",
- "BUG",
- "EXCEPTION",
- "LOOP",
- "OVERFLOW",
- "CORRUPT_STACK",
- "UNALIGNED_LOAD_STORE_WRITE",
- "OVERWRITE_ALLOCATION",
- "WRITE_AFTER_FREE",
- "SOFTLOCKUP",
- "HARDLOCKUP",
- "HUNG_TASK",
-};
-
-static struct jprobe lkdtm;
-
-static int lkdtm_parse_commandline(void);
-static void lkdtm_handler(void);
-
-static char* cpoint_name;
-static char* cpoint_type;
-static int cpoint_count = DEFAULT_COUNT;
-static int recur_count = REC_NUM_DEFAULT;
-
-static enum cname cpoint = CN_INVALID;
-static enum ctype cptype = CT_NONE;
-static int count = DEFAULT_COUNT;
-static DEFINE_SPINLOCK(count_lock);
-
-module_param(recur_count, int, 0644);
-MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\
- "default is 10");
-module_param(cpoint_name, charp, 0444);
-MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed");
-module_param(cpoint_type, charp, 0444);
-MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\
- "hitting the crash point");
-module_param(cpoint_count, int, 0644);
-MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\
- "crash point is to be hit to trigger action");
-
-static unsigned int jp_do_irq(unsigned int irq)
-{
- lkdtm_handler();
- jprobe_return();
- return 0;
-}
-
-static irqreturn_t jp_handle_irq_event(unsigned int irq,
- struct irqaction *action)
-{
- lkdtm_handler();
- jprobe_return();
- return 0;
-}
-
-static void jp_tasklet_action(struct softirq_action *a)
-{
- lkdtm_handler();
- jprobe_return();
-}
-
-static void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
-{
- lkdtm_handler();
- jprobe_return();
-}
-
-struct scan_control;
-
-static unsigned long jp_shrink_inactive_list(unsigned long max_scan,
- struct zone *zone,
- struct scan_control *sc)
-{
- lkdtm_handler();
- jprobe_return();
- return 0;
-}
-
-static int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim,
- const enum hrtimer_mode mode)
-{
- lkdtm_handler();
- jprobe_return();
- return 0;
-}
-
-static int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd)
-{
- lkdtm_handler();
- jprobe_return();
- return 0;
-}
-
-#ifdef CONFIG_IDE
-int jp_generic_ide_ioctl(ide_drive_t *drive, struct file *file,
- struct block_device *bdev, unsigned int cmd,
- unsigned long arg)
-{
- lkdtm_handler();
- jprobe_return();
- return 0;
-}
-#endif
-
-/* Return the crashpoint number or NONE if the name is invalid */
-static enum ctype parse_cp_type(const char *what, size_t count)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cp_type); i++) {
- if (!strcmp(what, cp_type[i]))
- return i + 1;
- }
-
- return CT_NONE;
-}
-
-static const char *cp_type_to_str(enum ctype type)
-{
- if (type == CT_NONE || type < 0 || type > ARRAY_SIZE(cp_type))
- return "None";
-
- return cp_type[type - 1];
-}
-
-static const char *cp_name_to_str(enum cname name)
-{
- if (name == CN_INVALID || name < 0 || name > ARRAY_SIZE(cp_name))
- return "INVALID";
-
- return cp_name[name - 1];
-}
-
-
-static int lkdtm_parse_commandline(void)
-{
- int i;
- unsigned long flags;
-
- if (cpoint_count < 1 || recur_count < 1)
- return -EINVAL;
-
- spin_lock_irqsave(&count_lock, flags);
- count = cpoint_count;
- spin_unlock_irqrestore(&count_lock, flags);
-
- /* No special parameters */
- if (!cpoint_type && !cpoint_name)
- return 0;
-
- /* Neither or both of these need to be set */
- if (!cpoint_type || !cpoint_name)
- return -EINVAL;
-
- cptype = parse_cp_type(cpoint_type, strlen(cpoint_type));
- if (cptype == CT_NONE)
- return -EINVAL;
-
- for (i = 0; i < ARRAY_SIZE(cp_name); i++) {
- if (!strcmp(cpoint_name, cp_name[i])) {
- cpoint = i + 1;
- return 0;
- }
- }
-
- /* Could not find a valid crash point */
- return -EINVAL;
-}
-
-static int recursive_loop(int a)
-{
- char buf[1024];
-
- memset(buf,0xFF,1024);
- recur_count--;
- if (!recur_count)
- return 0;
- else
- return recursive_loop(a);
-}
-
-static void lkdtm_do_action(enum ctype which)
-{
- switch (which) {
- case CT_PANIC:
- panic("dumptest");
- break;
- case CT_BUG:
- BUG();
- break;
- case CT_EXCEPTION:
- *((int *) 0) = 0;
- break;
- case CT_LOOP:
- for (;;)
- ;
- break;
- case CT_OVERFLOW:
- (void) recursive_loop(0);
- break;
- case CT_CORRUPT_STACK: {
- volatile u32 data[8];
- volatile u32 *p = data;
-
- p[12] = 0x12345678;
- break;
- }
- case CT_UNALIGNED_LOAD_STORE_WRITE: {
- static u8 data[5] __attribute__((aligned(4))) = {1, 2,
- 3, 4, 5};
- u32 *p;
- u32 val = 0x12345678;
-
- p = (u32 *)(data + 1);
- if (*p == 0)
- val = 0x87654321;
- *p = val;
- break;
- }
- case CT_OVERWRITE_ALLOCATION: {
- size_t len = 1020;
- u32 *data = kmalloc(len, GFP_KERNEL);
-
- data[1024 / sizeof(u32)] = 0x12345678;
- kfree(data);
- break;
- }
- case CT_WRITE_AFTER_FREE: {
- size_t len = 1024;
- u32 *data = kmalloc(len, GFP_KERNEL);
-
- kfree(data);
- schedule();
- memset(data, 0x78, len);
- break;
- }
- case CT_SOFTLOCKUP:
- preempt_disable();
- for (;;)
- cpu_relax();
- break;
- case CT_HARDLOCKUP:
- local_irq_disable();
- for (;;)
- cpu_relax();
- break;
- case CT_HUNG_TASK:
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule();
- break;
- case CT_NONE:
- default:
- break;
- }
-
-}
-
-static void lkdtm_handler(void)
-{
- unsigned long flags;
- bool do_it = false;
-
- spin_lock_irqsave(&count_lock, flags);
- count--;
- printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n",
- cp_name_to_str(cpoint), cp_type_to_str(cptype), count);
-
- if (count == 0) {
- do_it = true;
- count = cpoint_count;
- }
- spin_unlock_irqrestore(&count_lock, flags);
-
- if (do_it)
- lkdtm_do_action(cptype);
-}
-
-static int lkdtm_register_cpoint(enum cname which)
-{
- int ret;
-
- cpoint = CN_INVALID;
- if (lkdtm.entry != NULL)
- unregister_jprobe(&lkdtm);
-
- switch (which) {
- case CN_DIRECT:
- lkdtm_do_action(cptype);
- return 0;
- case CN_INT_HARDWARE_ENTRY:
- lkdtm.kp.symbol_name = "do_IRQ";
- lkdtm.entry = (kprobe_opcode_t*) jp_do_irq;
- break;
- case CN_INT_HW_IRQ_EN:
- lkdtm.kp.symbol_name = "handle_IRQ_event";
- lkdtm.entry = (kprobe_opcode_t*) jp_handle_irq_event;
- break;
- case CN_INT_TASKLET_ENTRY:
- lkdtm.kp.symbol_name = "tasklet_action";
- lkdtm.entry = (kprobe_opcode_t*) jp_tasklet_action;
- break;
- case CN_FS_DEVRW:
- lkdtm.kp.symbol_name = "ll_rw_block";
- lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block;
- break;
- case CN_MEM_SWAPOUT:
- lkdtm.kp.symbol_name = "shrink_inactive_list";
- lkdtm.entry = (kprobe_opcode_t*) jp_shrink_inactive_list;
- break;
- case CN_TIMERADD:
- lkdtm.kp.symbol_name = "hrtimer_start";
- lkdtm.entry = (kprobe_opcode_t*) jp_hrtimer_start;
- break;
- case CN_SCSI_DISPATCH_CMD:
- lkdtm.kp.symbol_name = "scsi_dispatch_cmd";
- lkdtm.entry = (kprobe_opcode_t*) jp_scsi_dispatch_cmd;
- break;
- case CN_IDE_CORE_CP:
-#ifdef CONFIG_IDE
- lkdtm.kp.symbol_name = "generic_ide_ioctl";
- lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl;
-#else
- printk(KERN_INFO "lkdtm: Crash point not available\n");
- return -EINVAL;
-#endif
- break;
- default:
- printk(KERN_INFO "lkdtm: Invalid Crash Point\n");
- return -EINVAL;
- }
-
- cpoint = which;
- if ((ret = register_jprobe(&lkdtm)) < 0) {
- printk(KERN_INFO "lkdtm: Couldn't register jprobe\n");
- cpoint = CN_INVALID;
- }
-
- return ret;
-}
-
-static ssize_t do_register_entry(enum cname which, struct file *f,
- const char __user *user_buf, size_t count, loff_t *off)
-{
- char *buf;
- int err;
-
- if (count >= PAGE_SIZE)
- return -EINVAL;
-
- buf = (char *)__get_free_page(GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- if (copy_from_user(buf, user_buf, count)) {
- free_page((unsigned long) buf);
- return -EFAULT;
- }
- /* NULL-terminate and remove enter */
- buf[count] = '\0';
- strim(buf);
-
- cptype = parse_cp_type(buf, count);
- free_page((unsigned long) buf);
-
- if (cptype == CT_NONE)
- return -EINVAL;
-
- err = lkdtm_register_cpoint(which);
- if (err < 0)
- return err;
-
- *off += count;
-
- return count;
-}
-
-/* Generic read callback that just prints out the available crash types */
-static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
- size_t count, loff_t *off)
-{
- char *buf;
- int i, n, out;
-
- buf = (char *)__get_free_page(GFP_KERNEL);
-
- n = snprintf(buf, PAGE_SIZE, "Available crash types:\n");
- for (i = 0; i < ARRAY_SIZE(cp_type); i++)
- n += snprintf(buf + n, PAGE_SIZE - n, "%s\n", cp_type[i]);
- buf[n] = '\0';
-
- out = simple_read_from_buffer(user_buf, count, off,
- buf, n);
- free_page((unsigned long) buf);
-
- return out;
-}
-
-static int lkdtm_debugfs_open(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-
-static ssize_t int_hardware_entry(struct file *f, const char __user *buf,
- size_t count, loff_t *off)
-{
- return do_register_entry(CN_INT_HARDWARE_ENTRY, f, buf, count, off);
-}
-
-static ssize_t int_hw_irq_en(struct file *f, const char __user *buf,
- size_t count, loff_t *off)
-{
- return do_register_entry(CN_INT_HW_IRQ_EN, f, buf, count, off);
-}
-
-static ssize_t int_tasklet_entry(struct file *f, const char __user *buf,
- size_t count, loff_t *off)
-{
- return do_register_entry(CN_INT_TASKLET_ENTRY, f, buf, count, off);
-}
-
-static ssize_t fs_devrw_entry(struct file *f, const char __user *buf,
- size_t count, loff_t *off)
-{
- return do_register_entry(CN_FS_DEVRW, f, buf, count, off);
-}
-
-static ssize_t mem_swapout_entry(struct file *f, const char __user *buf,
- size_t count, loff_t *off)
-{
- return do_register_entry(CN_MEM_SWAPOUT, f, buf, count, off);
-}
-
-static ssize_t timeradd_entry(struct file *f, const char __user *buf,
- size_t count, loff_t *off)
-{
- return do_register_entry(CN_TIMERADD, f, buf, count, off);
-}
-
-static ssize_t scsi_dispatch_cmd_entry(struct file *f,
- const char __user *buf, size_t count, loff_t *off)
-{
- return do_register_entry(CN_SCSI_DISPATCH_CMD, f, buf, count, off);
-}
-
-static ssize_t ide_core_cp_entry(struct file *f, const char __user *buf,
- size_t count, loff_t *off)
-{
- return do_register_entry(CN_IDE_CORE_CP, f, buf, count, off);
-}
-
-/* Special entry to just crash directly. Available without KPROBEs */
-static ssize_t direct_entry(struct file *f, const char __user *user_buf,
- size_t count, loff_t *off)
-{
- enum ctype type;
- char *buf;
-
- if (count >= PAGE_SIZE)
- return -EINVAL;
- if (count < 1)
- return -EINVAL;
-
- buf = (char *)__get_free_page(GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- if (copy_from_user(buf, user_buf, count)) {
- free_page((unsigned long) buf);
- return -EFAULT;
- }
- /* NULL-terminate and remove enter */
- buf[count] = '\0';
- strim(buf);
-
- type = parse_cp_type(buf, count);
- free_page((unsigned long) buf);
- if (type == CT_NONE)
- return -EINVAL;
-
- printk(KERN_INFO "lkdtm: Performing direct entry %s\n",
- cp_type_to_str(type));
- lkdtm_do_action(type);
- *off += count;
-
- return count;
-}
-
-struct crash_entry {
- const char *name;
- const struct file_operations fops;
-};
-
-static const struct crash_entry crash_entries[] = {
- {"DIRECT", {.read = lkdtm_debugfs_read,
- .llseek = generic_file_llseek,
- .open = lkdtm_debugfs_open,
- .write = direct_entry} },
- {"INT_HARDWARE_ENTRY", {.read = lkdtm_debugfs_read,
- .llseek = generic_file_llseek,
- .open = lkdtm_debugfs_open,
- .write = int_hardware_entry} },
- {"INT_HW_IRQ_EN", {.read = lkdtm_debugfs_read,
- .llseek = generic_file_llseek,
- .open = lkdtm_debugfs_open,
- .write = int_hw_irq_en} },
- {"INT_TASKLET_ENTRY", {.read = lkdtm_debugfs_read,
- .llseek = generic_file_llseek,
- .open = lkdtm_debugfs_open,
- .write = int_tasklet_entry} },
- {"FS_DEVRW", {.read = lkdtm_debugfs_read,
- .llseek = generic_file_llseek,
- .open = lkdtm_debugfs_open,
- .write = fs_devrw_entry} },
- {"MEM_SWAPOUT", {.read = lkdtm_debugfs_read,
- .llseek = generic_file_llseek,
- .open = lkdtm_debugfs_open,
- .write = mem_swapout_entry} },
- {"TIMERADD", {.read = lkdtm_debugfs_read,
- .llseek = generic_file_llseek,
- .open = lkdtm_debugfs_open,
- .write = timeradd_entry} },
- {"SCSI_DISPATCH_CMD", {.read = lkdtm_debugfs_read,
- .llseek = generic_file_llseek,
- .open = lkdtm_debugfs_open,
- .write = scsi_dispatch_cmd_entry} },
- {"IDE_CORE_CP", {.read = lkdtm_debugfs_read,
- .llseek = generic_file_llseek,
- .open = lkdtm_debugfs_open,
- .write = ide_core_cp_entry} },
-};
-
-static struct dentry *lkdtm_debugfs_root;
-
-static int __init lkdtm_module_init(void)
-{
- int ret = -EINVAL;
- int n_debugfs_entries = 1; /* Assume only the direct entry */
- int i;
-
- /* Register debugfs interface */
- lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL);
- if (!lkdtm_debugfs_root) {
- printk(KERN_ERR "lkdtm: creating root dir failed\n");
- return -ENODEV;
- }
-
-#ifdef CONFIG_KPROBES
- n_debugfs_entries = ARRAY_SIZE(crash_entries);
-#endif
-
- for (i = 0; i < n_debugfs_entries; i++) {
- const struct crash_entry *cur = &crash_entries[i];
- struct dentry *de;
-
- de = debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root,
- NULL, &cur->fops);
- if (de == NULL) {
- printk(KERN_ERR "lkdtm: could not create %s\n",
- cur->name);
- goto out_err;
- }
- }
-
- if (lkdtm_parse_commandline() == -EINVAL) {
- printk(KERN_INFO "lkdtm: Invalid command\n");
- goto out_err;
- }
-
- if (cpoint != CN_INVALID && cptype != CT_NONE) {
- ret = lkdtm_register_cpoint(cpoint);
- if (ret < 0) {
- printk(KERN_INFO "lkdtm: Invalid crash point %d\n",
- cpoint);
- goto out_err;
- }
- printk(KERN_INFO "lkdtm: Crash point %s of type %s registered\n",
- cpoint_name, cpoint_type);
- } else {
- printk(KERN_INFO "lkdtm: No crash points registered, enable through debugfs\n");
- }
-
- return 0;
-
-out_err:
- debugfs_remove_recursive(lkdtm_debugfs_root);
- return ret;
-}
-
-static void __exit lkdtm_module_exit(void)
-{
- debugfs_remove_recursive(lkdtm_debugfs_root);
-
- unregister_jprobe(&lkdtm);
- printk(KERN_INFO "lkdtm: Crash point unregistered\n");
-}
-
-module_init(lkdtm_module_init);
-module_exit(lkdtm_module_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/max8997-muic.c b/ANDROID_3.4.5/drivers/misc/max8997-muic.c
deleted file mode 100644
index 19591eaa..00000000
--- a/ANDROID_3.4.5/drivers/misc/max8997-muic.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * max8997-muic.c - MAX8997 muic driver for the Maxim 8997
- *
- * Copyright (C) 2011 Samsung Electrnoics
- * Donggeun Kim <dg77.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/kobject.h>
-#include <linux/mfd/max8997.h>
-#include <linux/mfd/max8997-private.h>
-
-/* MAX8997-MUIC STATUS1 register */
-#define STATUS1_ADC_SHIFT 0
-#define STATUS1_ADCLOW_SHIFT 5
-#define STATUS1_ADCERR_SHIFT 6
-#define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT)
-#define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT)
-#define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT)
-
-/* MAX8997-MUIC STATUS2 register */
-#define STATUS2_CHGTYP_SHIFT 0
-#define STATUS2_CHGDETRUN_SHIFT 3
-#define STATUS2_DCDTMR_SHIFT 4
-#define STATUS2_DBCHG_SHIFT 5
-#define STATUS2_VBVOLT_SHIFT 6
-#define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT)
-#define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT)
-#define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT)
-#define STATUS2_DBCHG_MASK (0x1 << STATUS2_DBCHG_SHIFT)
-#define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT)
-
-/* MAX8997-MUIC STATUS3 register */
-#define STATUS3_OVP_SHIFT 2
-#define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT)
-
-/* MAX8997-MUIC CONTROL1 register */
-#define COMN1SW_SHIFT 0
-#define COMP2SW_SHIFT 3
-#define COMN1SW_MASK (0x7 << COMN1SW_SHIFT)
-#define COMP2SW_MASK (0x7 << COMP2SW_SHIFT)
-#define SW_MASK (COMP2SW_MASK | COMN1SW_MASK)
-
-#define MAX8997_SW_USB ((1 << COMP2SW_SHIFT) | (1 << COMN1SW_SHIFT))
-#define MAX8997_SW_AUDIO ((2 << COMP2SW_SHIFT) | (2 << COMN1SW_SHIFT))
-#define MAX8997_SW_UART ((3 << COMP2SW_SHIFT) | (3 << COMN1SW_SHIFT))
-#define MAX8997_SW_OPEN ((0 << COMP2SW_SHIFT) | (0 << COMN1SW_SHIFT))
-
-#define MAX8997_ADC_GROUND 0x00
-#define MAX8997_ADC_MHL 0x01
-#define MAX8997_ADC_JIG_USB_1 0x18
-#define MAX8997_ADC_JIG_USB_2 0x19
-#define MAX8997_ADC_DESKDOCK 0x1a
-#define MAX8997_ADC_JIG_UART 0x1c
-#define MAX8997_ADC_CARDOCK 0x1d
-#define MAX8997_ADC_OPEN 0x1f
-
-struct max8997_muic_irq {
- unsigned int irq;
- const char *name;
-};
-
-static struct max8997_muic_irq muic_irqs[] = {
- { MAX8997_MUICIRQ_ADCError, "muic-ADC_error" },
- { MAX8997_MUICIRQ_ADCLow, "muic-ADC_low" },
- { MAX8997_MUICIRQ_ADC, "muic-ADC" },
- { MAX8997_MUICIRQ_VBVolt, "muic-VB_voltage" },
- { MAX8997_MUICIRQ_DBChg, "muic-DB_charger" },
- { MAX8997_MUICIRQ_DCDTmr, "muic-DCD_timer" },
- { MAX8997_MUICIRQ_ChgDetRun, "muic-CDR_status" },
- { MAX8997_MUICIRQ_ChgTyp, "muic-charger_type" },
- { MAX8997_MUICIRQ_OVP, "muic-over_voltage" },
-};
-
-struct max8997_muic_info {
- struct device *dev;
- struct max8997_dev *iodev;
- struct i2c_client *muic;
- struct max8997_muic_platform_data *muic_pdata;
-
- int irq;
- struct work_struct irq_work;
-
- enum max8997_muic_charger_type pre_charger_type;
- int pre_adc;
-
- struct mutex mutex;
-};
-
-static int max8997_muic_handle_usb(struct max8997_muic_info *info,
- enum max8997_muic_usb_type usb_type, bool attached)
-{
- struct max8997_muic_platform_data *mdata = info->muic_pdata;
- int ret = 0;
-
- if (usb_type == MAX8997_USB_HOST) {
- /* switch to USB */
- ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
- attached ? MAX8997_SW_USB : MAX8997_SW_OPEN,
- SW_MASK);
- if (ret) {
- dev_err(info->dev, "failed to update muic register\n");
- goto out;
- }
- }
-
- if (mdata->usb_callback)
- mdata->usb_callback(usb_type, attached);
-out:
- return ret;
-}
-
-static void max8997_muic_handle_mhl(struct max8997_muic_info *info,
- bool attached)
-{
- struct max8997_muic_platform_data *mdata = info->muic_pdata;
-
- if (mdata->mhl_callback)
- mdata->mhl_callback(attached);
-}
-
-static int max8997_muic_handle_dock(struct max8997_muic_info *info,
- int adc, bool attached)
-{
- struct max8997_muic_platform_data *mdata = info->muic_pdata;
- int ret = 0;
-
- /* switch to AUDIO */
- ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
- attached ? MAX8997_SW_AUDIO : MAX8997_SW_OPEN,
- SW_MASK);
- if (ret) {
- dev_err(info->dev, "failed to update muic register\n");
- goto out;
- }
-
- switch (adc) {
- case MAX8997_ADC_DESKDOCK:
- if (mdata->deskdock_callback)
- mdata->deskdock_callback(attached);
- break;
- case MAX8997_ADC_CARDOCK:
- if (mdata->cardock_callback)
- mdata->cardock_callback(attached);
- break;
- default:
- break;
- }
-out:
- return ret;
-}
-
-static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info,
- bool attached)
-{
- struct max8997_muic_platform_data *mdata = info->muic_pdata;
- int ret = 0;
-
- /* switch to UART */
- ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
- attached ? MAX8997_SW_UART : MAX8997_SW_OPEN,
- SW_MASK);
- if (ret) {
- dev_err(info->dev, "failed to update muic register\n");
- goto out;
- }
-
- if (mdata->uart_callback)
- mdata->uart_callback(attached);
-out:
- return ret;
-}
-
-static int max8997_muic_handle_adc_detach(struct max8997_muic_info *info)
-{
- int ret = 0;
-
- switch (info->pre_adc) {
- case MAX8997_ADC_GROUND:
- ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, false);
- break;
- case MAX8997_ADC_MHL:
- max8997_muic_handle_mhl(info, false);
- break;
- case MAX8997_ADC_JIG_USB_1:
- case MAX8997_ADC_JIG_USB_2:
- ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, false);
- break;
- case MAX8997_ADC_DESKDOCK:
- case MAX8997_ADC_CARDOCK:
- ret = max8997_muic_handle_dock(info, info->pre_adc, false);
- break;
- case MAX8997_ADC_JIG_UART:
- ret = max8997_muic_handle_jig_uart(info, false);
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc)
-{
- int ret = 0;
-
- switch (adc) {
- case MAX8997_ADC_GROUND:
- ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, true);
- break;
- case MAX8997_ADC_MHL:
- max8997_muic_handle_mhl(info, true);
- break;
- case MAX8997_ADC_JIG_USB_1:
- case MAX8997_ADC_JIG_USB_2:
- ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, true);
- break;
- case MAX8997_ADC_DESKDOCK:
- case MAX8997_ADC_CARDOCK:
- ret = max8997_muic_handle_dock(info, adc, true);
- break;
- case MAX8997_ADC_JIG_UART:
- ret = max8997_muic_handle_jig_uart(info, true);
- break;
- case MAX8997_ADC_OPEN:
- ret = max8997_muic_handle_adc_detach(info);
- break;
- default:
- break;
- }
-
- info->pre_adc = adc;
-
- return ret;
-}
-
-static int max8997_muic_handle_charger_type(struct max8997_muic_info *info,
- enum max8997_muic_charger_type charger_type)
-{
- struct max8997_muic_platform_data *mdata = info->muic_pdata;
- u8 adc;
- int ret;
-
- ret = max8997_read_reg(info->muic, MAX8997_MUIC_REG_STATUS1, &adc);
- if (ret) {
- dev_err(info->dev, "failed to read muic register\n");
- goto out;
- }
-
- switch (charger_type) {
- case MAX8997_CHARGER_TYPE_NONE:
- if (mdata->charger_callback)
- mdata->charger_callback(false, charger_type);
- if (info->pre_charger_type == MAX8997_CHARGER_TYPE_USB) {
- max8997_muic_handle_usb(info,
- MAX8997_USB_DEVICE, false);
- }
- break;
- case MAX8997_CHARGER_TYPE_USB:
- if ((adc & STATUS1_ADC_MASK) == MAX8997_ADC_OPEN) {
- max8997_muic_handle_usb(info,
- MAX8997_USB_DEVICE, true);
- }
- if (mdata->charger_callback)
- mdata->charger_callback(true, charger_type);
- break;
- case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
- case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
- case MAX8997_CHARGER_TYPE_500MA:
- case MAX8997_CHARGER_TYPE_1A:
- if (mdata->charger_callback)
- mdata->charger_callback(true, charger_type);
- break;
- default:
- break;
- }
-
- info->pre_charger_type = charger_type;
-out:
- return ret;
-}
-
-static void max8997_muic_irq_work(struct work_struct *work)
-{
- struct max8997_muic_info *info = container_of(work,
- struct max8997_muic_info, irq_work);
- struct max8997_platform_data *pdata =
- dev_get_platdata(info->iodev->dev);
- u8 status[3];
- u8 adc, chg_type;
-
- int irq_type = info->irq - pdata->irq_base;
- int ret;
-
- mutex_lock(&info->mutex);
-
- ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1,
- 3, status);
- if (ret) {
- dev_err(info->dev, "failed to read muic register\n");
- mutex_unlock(&info->mutex);
- return;
- }
-
- dev_dbg(info->dev, "%s: STATUS1:0x%x, 2:0x%x\n", __func__,
- status[0], status[1]);
-
- switch (irq_type) {
- case MAX8997_MUICIRQ_ADC:
- adc = status[0] & STATUS1_ADC_MASK;
- adc >>= STATUS1_ADC_SHIFT;
-
- max8997_muic_handle_adc(info, adc);
- break;
- case MAX8997_MUICIRQ_ChgTyp:
- chg_type = status[1] & STATUS2_CHGTYP_MASK;
- chg_type >>= STATUS2_CHGTYP_SHIFT;
-
- max8997_muic_handle_charger_type(info, chg_type);
- break;
- default:
- dev_info(info->dev, "misc interrupt: %s occurred\n",
- muic_irqs[irq_type].name);
- break;
- }
-
- mutex_unlock(&info->mutex);
-
- return;
-}
-
-static irqreturn_t max8997_muic_irq_handler(int irq, void *data)
-{
- struct max8997_muic_info *info = data;
-
- dev_dbg(info->dev, "irq:%d\n", irq);
- info->irq = irq;
-
- schedule_work(&info->irq_work);
-
- return IRQ_HANDLED;
-}
-
-static void max8997_muic_detect_dev(struct max8997_muic_info *info)
-{
- int ret;
- u8 status[2], adc, chg_type;
-
- ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1,
- 2, status);
- if (ret) {
- dev_err(info->dev, "failed to read muic register\n");
- return;
- }
-
- dev_info(info->dev, "STATUS1:0x%x, STATUS2:0x%x\n",
- status[0], status[1]);
-
- adc = status[0] & STATUS1_ADC_MASK;
- adc >>= STATUS1_ADC_SHIFT;
-
- chg_type = status[1] & STATUS2_CHGTYP_MASK;
- chg_type >>= STATUS2_CHGTYP_SHIFT;
-
- max8997_muic_handle_adc(info, adc);
- max8997_muic_handle_charger_type(info, chg_type);
-}
-
-static void max8997_initialize_device(struct max8997_muic_info *info)
-{
- struct max8997_muic_platform_data *mdata = info->muic_pdata;
- int i;
-
- for (i = 0; i < mdata->num_init_data; i++) {
- max8997_write_reg(info->muic, mdata->init_data[i].addr,
- mdata->init_data[i].data);
- }
-}
-
-static int __devinit max8997_muic_probe(struct platform_device *pdev)
-{
- struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
- struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
- struct max8997_muic_info *info;
- int ret, i;
-
- info = kzalloc(sizeof(struct max8997_muic_info), GFP_KERNEL);
- if (!info) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
- ret = -ENOMEM;
- goto err_kfree;
- }
-
- if (!pdata->muic_pdata) {
- dev_err(&pdev->dev, "failed to get platform_data\n");
- ret = -EINVAL;
- goto err_pdata;
- }
- info->muic_pdata = pdata->muic_pdata;
-
- info->dev = &pdev->dev;
- info->iodev = iodev;
- info->muic = iodev->muic;
-
- platform_set_drvdata(pdev, info);
- mutex_init(&info->mutex);
-
- INIT_WORK(&info->irq_work, max8997_muic_irq_work);
-
- for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
- struct max8997_muic_irq *muic_irq = &muic_irqs[i];
-
- ret = request_threaded_irq(pdata->irq_base + muic_irq->irq,
- NULL, max8997_muic_irq_handler,
- 0, muic_irq->name,
- info);
- if (ret) {
- dev_err(&pdev->dev,
- "failed: irq request (IRQ: %d,"
- " error :%d)\n",
- muic_irq->irq, ret);
-
- for (i = i - 1; i >= 0; i--)
- free_irq(muic_irq->irq, info);
-
- goto err_irq;
- }
- }
-
- /* Initialize registers according to platform data */
- max8997_initialize_device(info);
-
- /* Initial device detection */
- max8997_muic_detect_dev(info);
-
- return ret;
-
-err_irq:
-err_pdata:
- kfree(info);
-err_kfree:
- return ret;
-}
-
-static int __devexit max8997_muic_remove(struct platform_device *pdev)
-{
- struct max8997_muic_info *info = platform_get_drvdata(pdev);
- struct max8997_platform_data *pdata =
- dev_get_platdata(info->iodev->dev);
- int i;
-
- for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
- free_irq(pdata->irq_base + muic_irqs[i].irq, info);
- cancel_work_sync(&info->irq_work);
-
- kfree(info);
-
- return 0;
-}
-
-static struct platform_driver max8997_muic_driver = {
- .driver = {
- .name = "max8997-muic",
- .owner = THIS_MODULE,
- },
- .probe = max8997_muic_probe,
- .remove = __devexit_p(max8997_muic_remove),
-};
-
-module_platform_driver(max8997_muic_driver);
-
-MODULE_DESCRIPTION("Maxim MAX8997 MUIC driver");
-MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/Kconfig b/ANDROID_3.4.5/drivers/misc/mediatek/Kconfig
deleted file mode 100755
index d882c767..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-menuconfig MTK_WIRELESS_SOLUTION
- bool "MTK wireless chip configuration"
- help
- "enable/disable and config MTK wireless solution"
-
-if MTK_WIRELESS_SOLUTION
-source "drivers/misc/mediatek/combo_mt66xx/Kconfig"
-source "drivers/misc/mediatek/mt6622/Kconfig"
-endif
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/Makefile b/ANDROID_3.4.5/drivers/misc/mediatek/Makefile
deleted file mode 100755
index d308cb1c..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-y += combo_mt66xx/
-#obj-$(CONFIG_MTK_MT6622) += mt6622/
-
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/Kconfig b/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/Kconfig
deleted file mode 100755
index 148f0505..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/Kconfig
+++ /dev/null
@@ -1,35 +0,0 @@
-menuconfig MTK_COMBO_MT66XX
- bool "MediaTek combo_mt66xx Config"
- help
- Config MTK combo chip mt6628&mt6620
-
-if MTK_COMBO_MT66XX
-
-config MTK_COMBO_WMT
- tristate "MediaTek Combo Chip wireless managment tool"
- default y
- help
- MTK wireless managment tool for WIFI/BT/GPS/FM
-
-config MTK_COMBO_BT
- tristate "MediaTek Combo Chip BT driver"
- default y
- #depends on MTK_COMBO_WMT
- help
- MTK BT /dev/stpbt driver for Bluedroid (mtk_stp_bt.ko)
-
-config MTK_COMBO_FM
- tristate "MediaTek Combo Chip FM driver"
- default y
- #depends on MTK_COMBO_WMT
- help
- MTK FM /dev/fm driver
-
-config MTK_COMBO_GPS
- tristate "MediaTek GPS Support"
- default y
- #depends on MTK_COMBO_WMT
- help
- MTK GPS /dev/gps driver (mtk_gps.ko)
-
-endif
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/Makefile b/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/Makefile
deleted file mode 100755
index 3ec2afb7..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright Statement:
-#
-# This software/firmware and related documentation ("MediaTek Software") are
-# protected under relevant copyright laws. The information contained herein
-# is confidential and proprietary to MediaTek Inc. and/or its licensors.
-# Without the prior written permission of MediaTek inc. and/or its licensors,
-# any reproduction, modification, use or disclosure of MediaTek Software,
-# and information contained herein, in whole or in part, shall be strictly prohibited.
-#
-# MediaTek Inc. (C) 2010. All rights reserved.
-#
-# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
-# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
-# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
-# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
-# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
-# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
-# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
-# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
-# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
-# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
-# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
-# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
-# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
-# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
-# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
-# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
-#
-# The following software/firmware and/or related documentation ("MediaTek Software")
-# have been modified by MediaTek Inc. All revisions are subject to any receiver's
-# applicable license agreements with MediaTek Inc.
-
-obj-y += wmt/
-obj-y += fm/
-obj-y += bt/
-obj-y += gps/
-
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/bt/Makefile b/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/bt/Makefile
deleted file mode 100755
index 41612ef7..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/bt/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright Statement:
-#
-# This software/firmware and related documentation ("MediaTek Software") are
-# protected under relevant copyright laws. The information contained herein
-# is confidential and proprietary to MediaTek Inc. and/or its licensors.
-# Without the prior written permission of MediaTek inc. and/or its licensors,
-# any reproduction, modification, use or disclosure of MediaTek Software,
-# and information contained herein, in whole or in part, shall be strictly prohibited.
-#
-# MediaTek Inc. (C) 2010. All rights reserved.
-#
-# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
-# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
-# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
-# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
-# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
-# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
-# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
-# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
-# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
-# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
-# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
-# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
-# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
-# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
-# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
-# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
-#
-# The following software/firmware and/or related documentation ("MediaTek Software")
-# have been modified by MediaTek Inc. All revisions are subject to any receiver's
-# applicable license agreements with MediaTek Inc.
-
-
-#
-# Makefile for the Linux Bluetooth HCI device drivers.
-#
-
-obj-y += uhid/
-
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/bt/uhid/Makefile b/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/bt/uhid/Makefile
deleted file mode 100755
index f2e00c9d..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/bt/uhid/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright Statement:
-#
-# This software/firmware and related documentation ("MediaTek Software") are
-# protected under relevant copyright laws. The information contained herein
-# is confidential and proprietary to MediaTek Inc. and/or its licensors.
-# Without the prior written permission of MediaTek inc. and/or its licensors,
-# any reproduction, modification, use or disclosure of MediaTek Software,
-# and information contained herein, in whole or in part, shall be strictly prohibited.
-
-# MediaTek Inc. (C) 2010. All rights reserved.
-#
-# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
-# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
-# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
-# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
-# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
-# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
-# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
-# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
-# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
-# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
-# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
-# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
-# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
-# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
-# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
-# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
-#
-# The following software/firmware and/or related documentation ("MediaTek Software")
-# have been modified by MediaTek Inc. All revisions are subject to any receiver's
-# applicable license agreements with MediaTek Inc.
-
-
-#
-# Makefile for the Bluetooth UHID driver.
-#
-#
-# 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.
-
-obj-y += bt_uhid.o
-
-# EOF
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/fm/Makefile b/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/fm/Makefile
deleted file mode 100755
index 11c3ca61..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/fm/Makefile
+++ /dev/null
@@ -1,72 +0,0 @@
-# Makefile generated by Mediatek
-CONFIG_MTK_COMBO_FM:=m
-#mt6628 fm
-ccflags-y += -I$(src)/inc \
- -I$(src)/mt6628/inc \
- -I$(src)/../wmt/include \
- -I$(src)/../wmt/linux/include \
- -I$(src)/cust/mt6628 \
- -I$(src)/private/inc \
- -DMT6628_FM
-
-obj-$(CONFIG_MTK_COMBO_FM) += mtk_fm_drv.o
- mtk_fm_drv-objs += core/fm_module.o \
- core/fm_main.o \
- core/fm_config.o \
- core/fm_rds_parser.o \
- core/fm_patch.o \
- core/fm_utils.o \
- core/fm_link.o \
- core/fm_eint.o \
- mt6628/pub/mt6628_fm_lib.o \
- mt6628/pub/mt6628_fm_rds.o \
- mt6628/pub/mt6628_fm_cmd.o \
- mt6628/pub/mt6628_fm_config.o
-#mt6620 fm start
- ccflags-y += -I$(src)/inc \
- -I$(src)/mt6620/inc \
- -I$(src)/../wmt/include \
- -I$(src)/../wmt/linux/include \
- -I$(src)/cust/mt6620 \
- -I$(src)/private/inc \
- -DMT6620_FM
-
- obj-$(CONFIG_MTK_COMBO_FM) += mtk_fm_drv.o
- mtk_fm_drv-objs += core/fm_module.o \
- core/fm_main.o \
- core/fm_config.o \
- core/fm_rds_parser.o \
- core/fm_patch.o \
- core/fm_utils.o \
- core/fm_link.o \
- core/fm_eint.o \
- mt6620/pub/mt6620_fm_lib.o \
- mt6620/pub/mt6620_fm_rds.o \
- mt6620/pub/mt6620_fm_cmd.o \
- mt6620/pub/mt6620_fm_config.o
-
-# MT6626 FM driver
-ifeq ($(CONFIG_MTK_COMBO_CHIP_MT6626), y)
-FM_CHIP = mt6626
-FM_CHIP_PATH = $(FM_CHIP)/pub/$(FM_CHIP)
-ccflags-y := -I$(src)/inc \
- -I$(src)/$(FM_CHIP)/inc \
- -I$(src)/cust/$(FM_CHIP) \
- -I$(src)/private/inc \
- -DMT6626_FM
-
-obj-$(CONFIG_MTK_COMBO_FM) += mtk_fm_drv.o
-mtk_fm_drv-objs := core/fm_module.o \
- core/fm_main.o \
- core/fm_config.o \
- core/fm_patch.o \
- core/fm_rds_parser.o \
- core/fm_utils.o \
- core/fm_link.o \
- $(FM_CHIP_PATH)_fm_lib.o \
- $(FM_CHIP_PATH)_fm_rds.o \
- $(FM_CHIP_PATH)_fm_link.o \
- $(FM_CHIP_PATH)_fm_eint.o
-endif
-
-
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/fm/private/Makefile b/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/fm/private/Makefile
deleted file mode 100755
index 1a8e7960..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/fm/private/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-# Makefile generated by Mediatek
-
-# fm support
-ifeq ($(MTK_FM_SUPPORT), yes)
-
-ifeq ($(CUSTOM_KERNEL_FM), mt6628)
-PRIV_CHIP = mt6628
-PRIV_SRC_PATH = private/src/$(PRIV_CHIP)
-PRIV_CONFIG = $(CONFIG_MTK_FM)
-
-ccflags-y := \
- -I$(src)/inc \
- -I$(src)/$(PRIV_SRC_PATH) \
- -I$(src)/../inc \
- -I$(src)/../cust/$(PRIV_CHIP) \
- -I$(src)/../../combo/common_mt6628/include \
- -I$(src)/../../combo/common_mt6628/linux/include
-
-
-obj-$(PRIV_CONFIG) += mtk_fm_priv.o
-mtk_fm_priv-objs := \
- src/$(PRIV_CHIP)/$(PRIV_CHIP)_fm_private.o
-endif
-
-ifeq ($(CUSTOM_KERNEL_FM), mt6620)
-PRIV_CHIP = mt6620
-PRIV_SRC_PATH = private/src/$(PRIV_CHIP)
-PRIV_CONFIG = $(CONFIG_MTK_FM)
-
-ccflags-y := \
- -I$(src)/inc \
- -I$(src)/$(PRIV_SRC_PATH) \
- -I$(src)/../inc \
- -I$(src)/../cust/$(PRIV_CHIP) \
- -I$(src)/../../combo/common/include \
- -I$(src)/../../combo/common/linux/include
-
-
-obj-$(PRIV_CONFIG) += mtk_fm_priv.o
-mtk_fm_priv-objs := \
- src/$(PRIV_CHIP)/$(PRIV_CHIP)_fm_private.o
-endif
-
-endif
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/gps/Makefile b/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/gps/Makefile
deleted file mode 100755
index 19d0d43a..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/gps/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright Statement:
-#
-# This software/firmware and related documentation ("MediaTek Software") are
-# protected under relevant copyright laws. The information contained herein
-# is confidential and proprietary to MediaTek Inc. and/or its licensors.
-# Without the prior written permission of MediaTek inc. and/or its licensors,
-# any reproduction, modification, use or disclosure of MediaTek Software,
-# and information contained herein, in whole or in part, shall be strictly prohibited.
-
-# MediaTek Inc. (C) 2010. All rights reserved.
-#
-# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
-# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
-# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
-# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
-# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
-# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
-# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
-# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
-# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
-# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
-# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
-# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
-# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
-# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
-# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
-# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
-#
-# The following software/firmware and/or related documentation ("MediaTek Software")
-# have been modified by MediaTek Inc. All revisions are subject to any receiver's
-# applicable license agreements with MediaTek Inc.
-
-
-# drivers/barcelona/gps/Makefile
-#
-# Makefile for the Barcelona GPS driver.
-#
-# Copyright (C) 2004,2005 TomTom BV <http://www.tomtom.com/>
-# Author: Dimitry Andric <dimitry.andric@tomtom.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.
-
-obj-y += gps.o
-
-
-# EOF
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/wmt/Makefile b/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/wmt/Makefile
deleted file mode 100755
index 64e0b362..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/combo_mt66xx/wmt/Makefile
+++ /dev/null
@@ -1,78 +0,0 @@
-MTK_WCN_CMB_SDIO_EINT := y
-CONFIG_MTK_COMBO_WMT:=m
-CONFIG_MTK_COMBO_BT:=m
-CONFIG_MTK_COMBO_GPS:=m
-
-ccflags-y += -I$(src)/linux/include -I$(src)/core/include -I$(src)/include -I$(src)/
-ccflags-y += -DWMT_PLAT_APEX=1
-ccflags-y += -DWMT_PLAT_ALPS=0
-ccflags-y += -DWMT_UART_RX_MODE_WORK=1 # 1. work thread 0. tasklet
-ccflags-y += -DREMOVE_MK_NODE=1
-ifeq ($(strip $(MTK_WCN_CMB_SDIO_EINT)), y)
-ccflags-y += -DMTK_CMB_SDIO_EINT
-endif
-
-#stub to build-in
-obj-y += platform/vendor/mtk_wcn_cmb_stub.o
-
-#Common SDIO driver for WIFI and STP(mtk_hif_sdio.ko)
-obj-$(CONFIG_MTK_COMBO_WMT) += mtk_hif_sdio.o
-mtk_hif_sdio-objs := linux/hif_sdio.o \
- linux/hif_sdio_chrdev.o \
- linux/osal.o
-
-ifeq ($(MTK_WCN_CMB_SDIO_EINT), y)
-mtk_hif_sdio-objs += linux/hif_sdio_eint.o
-endif
-
-# WMT/STP DRIVER(mtk_stp_wmt.ko)
-obj-$(CONFIG_MTK_COMBO_WMT) += mtk_stp_wmt.o
-mtk_stp_wmt-objs := core/wmt_core.o \
- core/wmt_ctrl.o \
- core/wmt_func.o \
- core/wmt_ic_6620.o \
- core/wmt_lib.o \
- core/wmt_conf.o \
- core/wmt_dbg.o \
- core/wmt_exp.o \
- core/wmt_ic_6628.o \
- linux/wmt_dev.o \
- linux/wmt_tm.o \
- platform/vendor/wmt_plat.o \
- platform/vendor/wmt_plat_stub.o \
- platform/vendor/mtk_wcn_cmb_hw.o \
- core/stp_exp.o \
- core/stp_core.o \
- core/psm_core.o \
- core/btm_core.o \
- linux/stp_dbg.o
-ifeq ($(CONFIG_MTK_COMBO_WMT), m)
-mtk_stp_wmt-objs += linux/osal.o
-endif
-
-#WMT/STP use UART interface(mtk_stp_uart.ko)
-obj-$(CONFIG_MTK_COMBO_WMT) += mtk_stp_uart.o
-mtk_stp_uart-objs := linux/stp_uart.o
-
-#WMT/STP use SDIO interface(mtk_stp_sdio.ko)
-obj-$(CONFIG_MTK_COMBO_WMT) += mtk_stp_sdio.o
-mtk_stp_sdio-objs := linux/stp_sdio.o \
-
-ifeq ($(CONFIG_MTK_COMBO_WMT), m)
-mtk_stp_sdio-objs += linux/osal.o
-endif
-
-#BT character device driver
-obj-$(CONFIG_MTK_COMBO_BT) += mtk_stp_bt.o
-mtk_stp_bt-objs := linux/stp_chrdev_bt.o
-
-#GPS character device driver
-obj-$(CONFIG_MTK_COMBO_GPS) += mtk_stp_gps.o
-mtk_stp_gps-objs := linux/stp_chrdev_gps.o
-
-#WIFI character device driver
-obj-$(CONFIG_MTK_COMBO_WIFI) += mtk_wmt_wifi.o
-mtk_wmt_wifi-objs := linux/wmt_chrdev_wifi.o
-
-#FM don't need such character device
-
diff --git a/ANDROID_3.4.5/drivers/misc/mediatek/dummy.c b/ANDROID_3.4.5/drivers/misc/mediatek/dummy.c
deleted file mode 100755
index e69de29b..00000000
--- a/ANDROID_3.4.5/drivers/misc/mediatek/dummy.c
+++ /dev/null
diff --git a/ANDROID_3.4.5/drivers/misc/pch_phub.c b/ANDROID_3.4.5/drivers/misc/pch_phub.c
deleted file mode 100644
index 10fc4785..00000000
--- a/ANDROID_3.4.5/drivers/misc/pch_phub.c
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/if_ether.h>
-#include <linux/ctype.h>
-#include <linux/dmi.h>
-
-#define PHUB_STATUS 0x00 /* Status Register offset */
-#define PHUB_CONTROL 0x04 /* Control Register offset */
-#define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */
-#define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */
-#define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */
-#define PCH_PHUB_MAC_START_ADDR_EG20T 0x14 /* MAC data area start address
- offset */
-#define PCH_PHUB_MAC_START_ADDR_ML7223 0x20C /* MAC data area start address
- offset */
-#define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset
- (Intel EG20T PCH)*/
-#define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address
- offset(LAPIS Semicon ML7213)
- */
-#define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address
- offset(LAPIS Semicon ML7223)
- */
-
-/* MAX number of INT_REDUCE_CONTROL registers */
-#define MAX_NUM_INT_REDUCE_CONTROL_REG 128
-#define PCI_DEVICE_ID_PCH1_PHUB 0x8801
-#define PCH_MINOR_NOS 1
-#define CLKCFG_CAN_50MHZ 0x12000000
-#define CLKCFG_CANCLK_MASK 0xFF000000
-#define CLKCFG_UART_MASK 0xFFFFFF
-
-/* CM-iTC */
-#define CLKCFG_UART_48MHZ (1 << 16)
-#define CLKCFG_BAUDDIV (2 << 20)
-#define CLKCFG_PLL2VCO (8 << 9)
-#define CLKCFG_UARTCLKSEL (1 << 18)
-
-/* Macros for ML7213 */
-#define PCI_VENDOR_ID_ROHM 0x10db
-#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A
-
-/* Macros for ML7213 */
-#define PCI_VENDOR_ID_ROHM 0x10db
-#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A
-
-/* Macros for ML7223 */
-#define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */
-#define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */
-
-/* Macros for ML7831 */
-#define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801
-
-/* SROM ACCESS Macro */
-#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
-
-/* Registers address offset */
-#define PCH_PHUB_ID_REG 0x0000
-#define PCH_PHUB_QUEUE_PRI_VAL_REG 0x0004
-#define PCH_PHUB_RC_QUEUE_MAXSIZE_REG 0x0008
-#define PCH_PHUB_BRI_QUEUE_MAXSIZE_REG 0x000C
-#define PCH_PHUB_COMP_RESP_TIMEOUT_REG 0x0010
-#define PCH_PHUB_BUS_SLAVE_CONTROL_REG 0x0014
-#define PCH_PHUB_DEADLOCK_AVOID_TYPE_REG 0x0018
-#define PCH_PHUB_INTPIN_REG_WPERMIT_REG0 0x0020
-#define PCH_PHUB_INTPIN_REG_WPERMIT_REG1 0x0024
-#define PCH_PHUB_INTPIN_REG_WPERMIT_REG2 0x0028
-#define PCH_PHUB_INTPIN_REG_WPERMIT_REG3 0x002C
-#define PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE 0x0040
-#define CLKCFG_REG_OFFSET 0x500
-#define FUNCSEL_REG_OFFSET 0x508
-
-#define PCH_PHUB_OROM_SIZE 15360
-
-/**
- * struct pch_phub_reg - PHUB register structure
- * @phub_id_reg: PHUB_ID register val
- * @q_pri_val_reg: QUEUE_PRI_VAL register val
- * @rc_q_maxsize_reg: RC_QUEUE_MAXSIZE register val
- * @bri_q_maxsize_reg: BRI_QUEUE_MAXSIZE register val
- * @comp_resp_timeout_reg: COMP_RESP_TIMEOUT register val
- * @bus_slave_control_reg: BUS_SLAVE_CONTROL_REG register val
- * @deadlock_avoid_type_reg: DEADLOCK_AVOID_TYPE register val
- * @intpin_reg_wpermit_reg0: INTPIN_REG_WPERMIT register 0 val
- * @intpin_reg_wpermit_reg1: INTPIN_REG_WPERMIT register 1 val
- * @intpin_reg_wpermit_reg2: INTPIN_REG_WPERMIT register 2 val
- * @intpin_reg_wpermit_reg3: INTPIN_REG_WPERMIT register 3 val
- * @int_reduce_control_reg: INT_REDUCE_CONTROL registers val
- * @clkcfg_reg: CLK CFG register val
- * @funcsel_reg: Function select register value
- * @pch_phub_base_address: Register base address
- * @pch_phub_extrom_base_address: external rom base address
- * @pch_mac_start_address: MAC address area start address
- * @pch_opt_rom_start_address: Option ROM start address
- * @ioh_type: Save IOH type
- * @pdev: pointer to pci device struct
- */
-struct pch_phub_reg {
- u32 phub_id_reg;
- u32 q_pri_val_reg;
- u32 rc_q_maxsize_reg;
- u32 bri_q_maxsize_reg;
- u32 comp_resp_timeout_reg;
- u32 bus_slave_control_reg;
- u32 deadlock_avoid_type_reg;
- u32 intpin_reg_wpermit_reg0;
- u32 intpin_reg_wpermit_reg1;
- u32 intpin_reg_wpermit_reg2;
- u32 intpin_reg_wpermit_reg3;
- u32 int_reduce_control_reg[MAX_NUM_INT_REDUCE_CONTROL_REG];
- u32 clkcfg_reg;
- u32 funcsel_reg;
- void __iomem *pch_phub_base_address;
- void __iomem *pch_phub_extrom_base_address;
- u32 pch_mac_start_address;
- u32 pch_opt_rom_start_address;
- int ioh_type;
- struct pci_dev *pdev;
-};
-
-/* SROM SPEC for MAC address assignment offset */
-static const int pch_phub_mac_offset[ETH_ALEN] = {0x3, 0x2, 0x1, 0x0, 0xb, 0xa};
-
-static DEFINE_MUTEX(pch_phub_mutex);
-
-/**
- * pch_phub_read_modify_write_reg() - Reading modifying and writing register
- * @reg_addr_offset: Register offset address value.
- * @data: Writing value.
- * @mask: Mask value.
- */
-static void pch_phub_read_modify_write_reg(struct pch_phub_reg *chip,
- unsigned int reg_addr_offset,
- unsigned int data, unsigned int mask)
-{
- void __iomem *reg_addr = chip->pch_phub_base_address + reg_addr_offset;
- iowrite32(((ioread32(reg_addr) & ~mask)) | data, reg_addr);
-}
-
-/* pch_phub_save_reg_conf - saves register configuration */
-static void pch_phub_save_reg_conf(struct pci_dev *pdev)
-{
- unsigned int i;
- struct pch_phub_reg *chip = pci_get_drvdata(pdev);
-
- void __iomem *p = chip->pch_phub_base_address;
-
- chip->phub_id_reg = ioread32(p + PCH_PHUB_ID_REG);
- chip->q_pri_val_reg = ioread32(p + PCH_PHUB_QUEUE_PRI_VAL_REG);
- chip->rc_q_maxsize_reg = ioread32(p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
- chip->bri_q_maxsize_reg = ioread32(p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
- chip->comp_resp_timeout_reg =
- ioread32(p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
- chip->bus_slave_control_reg =
- ioread32(p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
- chip->deadlock_avoid_type_reg =
- ioread32(p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
- chip->intpin_reg_wpermit_reg0 =
- ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
- chip->intpin_reg_wpermit_reg1 =
- ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
- chip->intpin_reg_wpermit_reg2 =
- ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
- chip->intpin_reg_wpermit_reg3 =
- ioread32(p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
- dev_dbg(&pdev->dev, "%s : "
- "chip->phub_id_reg=%x, "
- "chip->q_pri_val_reg=%x, "
- "chip->rc_q_maxsize_reg=%x, "
- "chip->bri_q_maxsize_reg=%x, "
- "chip->comp_resp_timeout_reg=%x, "
- "chip->bus_slave_control_reg=%x, "
- "chip->deadlock_avoid_type_reg=%x, "
- "chip->intpin_reg_wpermit_reg0=%x, "
- "chip->intpin_reg_wpermit_reg1=%x, "
- "chip->intpin_reg_wpermit_reg2=%x, "
- "chip->intpin_reg_wpermit_reg3=%x\n", __func__,
- chip->phub_id_reg,
- chip->q_pri_val_reg,
- chip->rc_q_maxsize_reg,
- chip->bri_q_maxsize_reg,
- chip->comp_resp_timeout_reg,
- chip->bus_slave_control_reg,
- chip->deadlock_avoid_type_reg,
- chip->intpin_reg_wpermit_reg0,
- chip->intpin_reg_wpermit_reg1,
- chip->intpin_reg_wpermit_reg2,
- chip->intpin_reg_wpermit_reg3);
- for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
- chip->int_reduce_control_reg[i] =
- ioread32(p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
- dev_dbg(&pdev->dev, "%s : "
- "chip->int_reduce_control_reg[%d]=%x\n",
- __func__, i, chip->int_reduce_control_reg[i]);
- }
- chip->clkcfg_reg = ioread32(p + CLKCFG_REG_OFFSET);
- if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
- chip->funcsel_reg = ioread32(p + FUNCSEL_REG_OFFSET);
-}
-
-/* pch_phub_restore_reg_conf - restore register configuration */
-static void pch_phub_restore_reg_conf(struct pci_dev *pdev)
-{
- unsigned int i;
- struct pch_phub_reg *chip = pci_get_drvdata(pdev);
- void __iomem *p;
- p = chip->pch_phub_base_address;
-
- iowrite32(chip->phub_id_reg, p + PCH_PHUB_ID_REG);
- iowrite32(chip->q_pri_val_reg, p + PCH_PHUB_QUEUE_PRI_VAL_REG);
- iowrite32(chip->rc_q_maxsize_reg, p + PCH_PHUB_RC_QUEUE_MAXSIZE_REG);
- iowrite32(chip->bri_q_maxsize_reg, p + PCH_PHUB_BRI_QUEUE_MAXSIZE_REG);
- iowrite32(chip->comp_resp_timeout_reg,
- p + PCH_PHUB_COMP_RESP_TIMEOUT_REG);
- iowrite32(chip->bus_slave_control_reg,
- p + PCH_PHUB_BUS_SLAVE_CONTROL_REG);
- iowrite32(chip->deadlock_avoid_type_reg,
- p + PCH_PHUB_DEADLOCK_AVOID_TYPE_REG);
- iowrite32(chip->intpin_reg_wpermit_reg0,
- p + PCH_PHUB_INTPIN_REG_WPERMIT_REG0);
- iowrite32(chip->intpin_reg_wpermit_reg1,
- p + PCH_PHUB_INTPIN_REG_WPERMIT_REG1);
- iowrite32(chip->intpin_reg_wpermit_reg2,
- p + PCH_PHUB_INTPIN_REG_WPERMIT_REG2);
- iowrite32(chip->intpin_reg_wpermit_reg3,
- p + PCH_PHUB_INTPIN_REG_WPERMIT_REG3);
- dev_dbg(&pdev->dev, "%s : "
- "chip->phub_id_reg=%x, "
- "chip->q_pri_val_reg=%x, "
- "chip->rc_q_maxsize_reg=%x, "
- "chip->bri_q_maxsize_reg=%x, "
- "chip->comp_resp_timeout_reg=%x, "
- "chip->bus_slave_control_reg=%x, "
- "chip->deadlock_avoid_type_reg=%x, "
- "chip->intpin_reg_wpermit_reg0=%x, "
- "chip->intpin_reg_wpermit_reg1=%x, "
- "chip->intpin_reg_wpermit_reg2=%x, "
- "chip->intpin_reg_wpermit_reg3=%x\n", __func__,
- chip->phub_id_reg,
- chip->q_pri_val_reg,
- chip->rc_q_maxsize_reg,
- chip->bri_q_maxsize_reg,
- chip->comp_resp_timeout_reg,
- chip->bus_slave_control_reg,
- chip->deadlock_avoid_type_reg,
- chip->intpin_reg_wpermit_reg0,
- chip->intpin_reg_wpermit_reg1,
- chip->intpin_reg_wpermit_reg2,
- chip->intpin_reg_wpermit_reg3);
- for (i = 0; i < MAX_NUM_INT_REDUCE_CONTROL_REG; i++) {
- iowrite32(chip->int_reduce_control_reg[i],
- p + PCH_PHUB_INT_REDUCE_CONTROL_REG_BASE + 4 * i);
- dev_dbg(&pdev->dev, "%s : "
- "chip->int_reduce_control_reg[%d]=%x\n",
- __func__, i, chip->int_reduce_control_reg[i]);
- }
-
- iowrite32(chip->clkcfg_reg, p + CLKCFG_REG_OFFSET);
- if ((chip->ioh_type == 2) || (chip->ioh_type == 4))
- iowrite32(chip->funcsel_reg, p + FUNCSEL_REG_OFFSET);
-}
-
-/**
- * pch_phub_read_serial_rom() - Reading Serial ROM
- * @offset_address: Serial ROM offset address to read.
- * @data: Read buffer for specified Serial ROM value.
- */
-static void pch_phub_read_serial_rom(struct pch_phub_reg *chip,
- unsigned int offset_address, u8 *data)
-{
- void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
- offset_address;
-
- *data = ioread8(mem_addr);
-}
-
-/**
- * pch_phub_write_serial_rom() - Writing Serial ROM
- * @offset_address: Serial ROM offset address.
- * @data: Serial ROM value to write.
- */
-static int pch_phub_write_serial_rom(struct pch_phub_reg *chip,
- unsigned int offset_address, u8 data)
-{
- void __iomem *mem_addr = chip->pch_phub_extrom_base_address +
- (offset_address & PCH_WORD_ADDR_MASK);
- int i;
- unsigned int word_data;
- unsigned int pos;
- unsigned int mask;
- pos = (offset_address % 4) * 8;
- mask = ~(0xFF << pos);
-
- iowrite32(PCH_PHUB_ROM_WRITE_ENABLE,
- chip->pch_phub_extrom_base_address + PHUB_CONTROL);
-
- word_data = ioread32(mem_addr);
- iowrite32((word_data & mask) | (u32)data << pos, mem_addr);
-
- i = 0;
- while (ioread8(chip->pch_phub_extrom_base_address +
- PHUB_STATUS) != 0x00) {
- msleep(1);
- if (i == PHUB_TIMEOUT)
- return -ETIMEDOUT;
- i++;
- }
-
- iowrite32(PCH_PHUB_ROM_WRITE_DISABLE,
- chip->pch_phub_extrom_base_address + PHUB_CONTROL);
-
- return 0;
-}
-
-/**
- * pch_phub_read_serial_rom_val() - Read Serial ROM value
- * @offset_address: Serial ROM address offset value.
- * @data: Serial ROM value to read.
- */
-static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip,
- unsigned int offset_address, u8 *data)
-{
- unsigned int mem_addr;
-
- mem_addr = chip->pch_mac_start_address +
- pch_phub_mac_offset[offset_address];
-
- pch_phub_read_serial_rom(chip, mem_addr, data);
-}
-
-/**
- * pch_phub_write_serial_rom_val() - writing Serial ROM value
- * @offset_address: Serial ROM address offset value.
- * @data: Serial ROM value.
- */
-static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip,
- unsigned int offset_address, u8 data)
-{
- int retval;
- unsigned int mem_addr;
-
- mem_addr = chip->pch_mac_start_address +
- pch_phub_mac_offset[offset_address];
-
- retval = pch_phub_write_serial_rom(chip, mem_addr, data);
-
- return retval;
-}
-
-/* pch_phub_gbe_serial_rom_conf - makes Serial ROM header format configuration
- * for Gigabit Ethernet MAC address
- */
-static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip)
-{
- int retval;
-
- retval = pch_phub_write_serial_rom(chip, 0x0b, 0xbc);
- retval |= pch_phub_write_serial_rom(chip, 0x0a, 0x10);
- retval |= pch_phub_write_serial_rom(chip, 0x09, 0x01);
- retval |= pch_phub_write_serial_rom(chip, 0x08, 0x02);
-
- retval |= pch_phub_write_serial_rom(chip, 0x0f, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x0e, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x0d, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x0c, 0x80);
-
- retval |= pch_phub_write_serial_rom(chip, 0x13, 0xbc);
- retval |= pch_phub_write_serial_rom(chip, 0x12, 0x10);
- retval |= pch_phub_write_serial_rom(chip, 0x11, 0x01);
- retval |= pch_phub_write_serial_rom(chip, 0x10, 0x18);
-
- retval |= pch_phub_write_serial_rom(chip, 0x1b, 0xbc);
- retval |= pch_phub_write_serial_rom(chip, 0x1a, 0x10);
- retval |= pch_phub_write_serial_rom(chip, 0x19, 0x01);
- retval |= pch_phub_write_serial_rom(chip, 0x18, 0x19);
-
- retval |= pch_phub_write_serial_rom(chip, 0x23, 0xbc);
- retval |= pch_phub_write_serial_rom(chip, 0x22, 0x10);
- retval |= pch_phub_write_serial_rom(chip, 0x21, 0x01);
- retval |= pch_phub_write_serial_rom(chip, 0x20, 0x3a);
-
- retval |= pch_phub_write_serial_rom(chip, 0x27, 0x01);
- retval |= pch_phub_write_serial_rom(chip, 0x26, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x25, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x24, 0x00);
-
- return retval;
-}
-
-/* pch_phub_gbe_serial_rom_conf_mp - makes SerialROM header format configuration
- * for Gigabit Ethernet MAC address
- */
-static int pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg *chip)
-{
- int retval;
- u32 offset_addr;
-
- offset_addr = 0x200;
- retval = pch_phub_write_serial_rom(chip, 0x03 + offset_addr, 0xbc);
- retval |= pch_phub_write_serial_rom(chip, 0x02 + offset_addr, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x01 + offset_addr, 0x40);
- retval |= pch_phub_write_serial_rom(chip, 0x00 + offset_addr, 0x02);
-
- retval |= pch_phub_write_serial_rom(chip, 0x07 + offset_addr, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x06 + offset_addr, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x05 + offset_addr, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x04 + offset_addr, 0x80);
-
- retval |= pch_phub_write_serial_rom(chip, 0x0b + offset_addr, 0xbc);
- retval |= pch_phub_write_serial_rom(chip, 0x0a + offset_addr, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x09 + offset_addr, 0x40);
- retval |= pch_phub_write_serial_rom(chip, 0x08 + offset_addr, 0x18);
-
- retval |= pch_phub_write_serial_rom(chip, 0x13 + offset_addr, 0xbc);
- retval |= pch_phub_write_serial_rom(chip, 0x12 + offset_addr, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x11 + offset_addr, 0x40);
- retval |= pch_phub_write_serial_rom(chip, 0x10 + offset_addr, 0x19);
-
- retval |= pch_phub_write_serial_rom(chip, 0x1b + offset_addr, 0xbc);
- retval |= pch_phub_write_serial_rom(chip, 0x1a + offset_addr, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x19 + offset_addr, 0x40);
- retval |= pch_phub_write_serial_rom(chip, 0x18 + offset_addr, 0x3a);
-
- retval |= pch_phub_write_serial_rom(chip, 0x1f + offset_addr, 0x01);
- retval |= pch_phub_write_serial_rom(chip, 0x1e + offset_addr, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x1d + offset_addr, 0x00);
- retval |= pch_phub_write_serial_rom(chip, 0x1c + offset_addr, 0x00);
-
- return retval;
-}
-
-/**
- * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
- * @offset_address: Gigabit Ethernet MAC address offset value.
- * @data: Buffer of the Gigabit Ethernet MAC address value.
- */
-static void pch_phub_read_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
-{
- int i;
- for (i = 0; i < ETH_ALEN; i++)
- pch_phub_read_serial_rom_val(chip, i, &data[i]);
-}
-
-/**
- * pch_phub_write_gbe_mac_addr() - Write MAC address
- * @offset_address: Gigabit Ethernet MAC address offset value.
- * @data: Gigabit Ethernet MAC address value.
- */
-static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
-{
- int retval;
- int i;
-
- if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/
- retval = pch_phub_gbe_serial_rom_conf(chip);
- else /* ML7223 */
- retval = pch_phub_gbe_serial_rom_conf_mp(chip);
- if (retval)
- return retval;
-
- for (i = 0; i < ETH_ALEN; i++) {
- retval = pch_phub_write_serial_rom_val(chip, i, data[i]);
- if (retval)
- return retval;
- }
-
- return retval;
-}
-
-static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr, char *buf,
- loff_t off, size_t count)
-{
- unsigned int rom_signature;
- unsigned char rom_length;
- unsigned int tmp;
- unsigned int addr_offset;
- unsigned int orom_size;
- int ret;
- int err;
- ssize_t rom_size;
-
- struct pch_phub_reg *chip =
- dev_get_drvdata(container_of(kobj, struct device, kobj));
-
- ret = mutex_lock_interruptible(&pch_phub_mutex);
- if (ret) {
- err = -ERESTARTSYS;
- goto return_err_nomutex;
- }
-
- /* Get Rom signature */
- chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
- if (!chip->pch_phub_extrom_base_address)
- goto exrom_map_err;
-
- pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
- (unsigned char *)&rom_signature);
- rom_signature &= 0xff;
- pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1,
- (unsigned char *)&tmp);
- rom_signature |= (tmp & 0xff) << 8;
- if (rom_signature == 0xAA55) {
- pch_phub_read_serial_rom(chip,
- chip->pch_opt_rom_start_address + 2,
- &rom_length);
- orom_size = rom_length * 512;
- if (orom_size < off) {
- addr_offset = 0;
- goto return_ok;
- }
- if (orom_size < count) {
- addr_offset = 0;
- goto return_ok;
- }
-
- for (addr_offset = 0; addr_offset < count; addr_offset++) {
- pch_phub_read_serial_rom(chip,
- chip->pch_opt_rom_start_address + addr_offset + off,
- &buf[addr_offset]);
- }
- } else {
- err = -ENODATA;
- goto return_err;
- }
-return_ok:
- pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
- mutex_unlock(&pch_phub_mutex);
- return addr_offset;
-
-return_err:
- pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
-exrom_map_err:
- mutex_unlock(&pch_phub_mutex);
-return_err_nomutex:
- return err;
-}
-
-static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- int err;
- unsigned int addr_offset;
- int ret;
- ssize_t rom_size;
- struct pch_phub_reg *chip =
- dev_get_drvdata(container_of(kobj, struct device, kobj));
-
- ret = mutex_lock_interruptible(&pch_phub_mutex);
- if (ret)
- return -ERESTARTSYS;
-
- if (off > PCH_PHUB_OROM_SIZE) {
- addr_offset = 0;
- goto return_ok;
- }
- if (count > PCH_PHUB_OROM_SIZE) {
- addr_offset = 0;
- goto return_ok;
- }
-
- chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
- if (!chip->pch_phub_extrom_base_address) {
- err = -ENOMEM;
- goto exrom_map_err;
- }
-
- for (addr_offset = 0; addr_offset < count; addr_offset++) {
- if (PCH_PHUB_OROM_SIZE < off + addr_offset)
- goto return_ok;
-
- ret = pch_phub_write_serial_rom(chip,
- chip->pch_opt_rom_start_address + addr_offset + off,
- buf[addr_offset]);
- if (ret) {
- err = ret;
- goto return_err;
- }
- }
-
-return_ok:
- pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
- mutex_unlock(&pch_phub_mutex);
- return addr_offset;
-
-return_err:
- pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
-
-exrom_map_err:
- mutex_unlock(&pch_phub_mutex);
- return err;
-}
-
-static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- u8 mac[8];
- struct pch_phub_reg *chip = dev_get_drvdata(dev);
- ssize_t rom_size;
-
- chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
- if (!chip->pch_phub_extrom_base_address)
- return -ENOMEM;
-
- pch_phub_read_gbe_mac_addr(chip, mac);
- pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
-
- return sprintf(buf, "%pM\n", mac);
-}
-
-static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- u8 mac[6];
- ssize_t rom_size;
- struct pch_phub_reg *chip = dev_get_drvdata(dev);
-
- if (count != 18)
- return -EINVAL;
-
- sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
- (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
- (u32 *)&mac[4], (u32 *)&mac[5]);
-
- chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
- if (!chip->pch_phub_extrom_base_address)
- return -ENOMEM;
-
- pch_phub_write_gbe_mac_addr(chip, mac);
- pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
-
- return count;
-}
-
-static DEVICE_ATTR(pch_mac, S_IRUGO | S_IWUSR, show_pch_mac, store_pch_mac);
-
-static struct bin_attribute pch_bin_attr = {
- .attr = {
- .name = "pch_firmware",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = PCH_PHUB_OROM_SIZE + 1,
- .read = pch_phub_bin_read,
- .write = pch_phub_bin_write,
-};
-
-static int __devinit pch_phub_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- int retval;
-
- int ret;
- struct pch_phub_reg *chip;
-
- chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
- if (chip == NULL)
- return -ENOMEM;
-
- ret = pci_enable_device(pdev);
- if (ret) {
- dev_err(&pdev->dev,
- "%s : pci_enable_device FAILED(ret=%d)", __func__, ret);
- goto err_pci_enable_dev;
- }
- dev_dbg(&pdev->dev, "%s : pci_enable_device returns %d\n", __func__,
- ret);
-
- ret = pci_request_regions(pdev, KBUILD_MODNAME);
- if (ret) {
- dev_err(&pdev->dev,
- "%s : pci_request_regions FAILED(ret=%d)", __func__, ret);
- goto err_req_regions;
- }
- dev_dbg(&pdev->dev, "%s : "
- "pci_request_regions returns %d\n", __func__, ret);
-
- chip->pch_phub_base_address = pci_iomap(pdev, 1, 0);
-
-
- if (chip->pch_phub_base_address == 0) {
- dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
- ret = -ENOMEM;
- goto err_pci_iomap;
- }
- dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
- "in pch_phub_base_address variable is %p\n", __func__,
- chip->pch_phub_base_address);
-
- chip->pdev = pdev; /* Save pci device struct */
-
- if (id->driver_data == 1) { /* EG20T PCH */
- const char *board_name;
-
- retval = sysfs_create_file(&pdev->dev.kobj,
- &dev_attr_pch_mac.attr);
- if (retval)
- goto err_sysfs_create;
-
- retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
- if (retval)
- goto exit_bin_attr;
-
- pch_phub_read_modify_write_reg(chip,
- (unsigned int)CLKCFG_REG_OFFSET,
- CLKCFG_CAN_50MHZ,
- CLKCFG_CANCLK_MASK);
-
- /* quirk for CM-iTC board */
- board_name = dmi_get_system_info(DMI_BOARD_NAME);
- if (board_name && strstr(board_name, "CM-iTC"))
- pch_phub_read_modify_write_reg(chip,
- (unsigned int)CLKCFG_REG_OFFSET,
- CLKCFG_UART_48MHZ | CLKCFG_BAUDDIV |
- CLKCFG_PLL2VCO | CLKCFG_UARTCLKSEL,
- CLKCFG_UART_MASK);
-
- /* set the prefech value */
- iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
- /* set the interrupt delay value */
- iowrite32(0x25, chip->pch_phub_base_address + 0x44);
- chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
- chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
- } else if (id->driver_data == 2) { /* ML7213 IOH */
- retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
- if (retval)
- goto err_sysfs_create;
- /* set the prefech value
- * Device2(USB OHCI #1/ USB EHCI #1/ USB Device):a
- * Device4(SDIO #0,1,2):f
- * Device6(SATA 2):f
- * Device8(USB OHCI #0/ USB EHCI #0):a
- */
- iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14);
- chip->pch_opt_rom_start_address =\
- PCH_PHUB_ROM_START_ADDR_ML7213;
- } else if (id->driver_data == 3) { /* ML7223 IOH Bus-m*/
- /* set the prefech value
- * Device8(GbE)
- */
- iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14);
- /* set the interrupt delay value */
- iowrite32(0x25, chip->pch_phub_base_address + 0x140);
- chip->pch_opt_rom_start_address =\
- PCH_PHUB_ROM_START_ADDR_ML7223;
- chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
- } else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/
- retval = sysfs_create_file(&pdev->dev.kobj,
- &dev_attr_pch_mac.attr);
- if (retval)
- goto err_sysfs_create;
- retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
- if (retval)
- goto exit_bin_attr;
- /* set the prefech value
- * Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a
- * Device4(SDIO #0,1):f
- * Device6(SATA 2):f
- */
- iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14);
- chip->pch_opt_rom_start_address =\
- PCH_PHUB_ROM_START_ADDR_ML7223;
- chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
- } else if (id->driver_data == 5) { /* ML7831 */
- retval = sysfs_create_file(&pdev->dev.kobj,
- &dev_attr_pch_mac.attr);
- if (retval)
- goto err_sysfs_create;
-
- retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
- if (retval)
- goto exit_bin_attr;
-
- /* set the prefech value */
- iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
- /* set the interrupt delay value */
- iowrite32(0x25, chip->pch_phub_base_address + 0x44);
- chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
- chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
- }
-
- chip->ioh_type = id->driver_data;
- pci_set_drvdata(pdev, chip);
-
- return 0;
-exit_bin_attr:
- sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
-
-err_sysfs_create:
- pci_iounmap(pdev, chip->pch_phub_base_address);
-err_pci_iomap:
- pci_release_regions(pdev);
-err_req_regions:
- pci_disable_device(pdev);
-err_pci_enable_dev:
- kfree(chip);
- dev_err(&pdev->dev, "%s returns %d\n", __func__, ret);
- return ret;
-}
-
-static void __devexit pch_phub_remove(struct pci_dev *pdev)
-{
- struct pch_phub_reg *chip = pci_get_drvdata(pdev);
-
- sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
- sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
- pci_iounmap(pdev, chip->pch_phub_base_address);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- kfree(chip);
-}
-
-#ifdef CONFIG_PM
-
-static int pch_phub_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- int ret;
-
- pch_phub_save_reg_conf(pdev);
- ret = pci_save_state(pdev);
- if (ret) {
- dev_err(&pdev->dev,
- " %s -pci_save_state returns %d\n", __func__, ret);
- return ret;
- }
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- return 0;
-}
-
-static int pch_phub_resume(struct pci_dev *pdev)
-{
- int ret;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- ret = pci_enable_device(pdev);
- if (ret) {
- dev_err(&pdev->dev,
- "%s-pci_enable_device failed(ret=%d) ", __func__, ret);
- return ret;
- }
-
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pch_phub_restore_reg_conf(pdev);
-
- return 0;
-}
-#else
-#define pch_phub_suspend NULL
-#define pch_phub_resume NULL
-#endif /* CONFIG_PM */
-
-static struct pci_device_id pch_phub_pcidev_id[] = {
- { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, },
- { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5, },
- { }
-};
-MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
-
-static struct pci_driver pch_phub_driver = {
- .name = "pch_phub",
- .id_table = pch_phub_pcidev_id,
- .probe = pch_phub_probe,
- .remove = __devexit_p(pch_phub_remove),
- .suspend = pch_phub_suspend,
- .resume = pch_phub_resume
-};
-
-static int __init pch_phub_pci_init(void)
-{
- return pci_register_driver(&pch_phub_driver);
-}
-
-static void __exit pch_phub_pci_exit(void)
-{
- pci_unregister_driver(&pch_phub_driver);
-}
-
-module_init(pch_phub_pci_init);
-module_exit(pch_phub_pci_exit);
-
-MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/phantom.c b/ANDROID_3.4.5/drivers/misc/phantom.c
deleted file mode 100644
index 21b28fc6..00000000
--- a/ANDROID_3.4.5/drivers/misc/phantom.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Copyright (C) 2005-2007 Jiri Slaby <jirislaby@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * You need a userspace library to cooperate with this driver. It (and other
- * info) may be obtained here:
- * http://www.fi.muni.cz/~xslaby/phantom.html
- * or alternatively, you might use OpenHaptics provided by Sensable.
- */
-
-#include <linux/compat.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/pci.h>
-#include <linux/fs.h>
-#include <linux/poll.h>
-#include <linux/interrupt.h>
-#include <linux/cdev.h>
-#include <linux/slab.h>
-#include <linux/phantom.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-
-#include <linux/atomic.h>
-#include <asm/io.h>
-
-#define PHANTOM_VERSION "n0.9.8"
-
-#define PHANTOM_MAX_MINORS 8
-
-#define PHN_IRQCTL 0x4c /* irq control in caddr space */
-
-#define PHB_RUNNING 1
-#define PHB_NOT_OH 2
-
-static DEFINE_MUTEX(phantom_mutex);
-static struct class *phantom_class;
-static int phantom_major;
-
-struct phantom_device {
- unsigned int opened;
- void __iomem *caddr;
- u32 __iomem *iaddr;
- u32 __iomem *oaddr;
- unsigned long status;
- atomic_t counter;
-
- wait_queue_head_t wait;
- struct cdev cdev;
-
- struct mutex open_lock;
- spinlock_t regs_lock;
-
- /* used in NOT_OH mode */
- struct phm_regs oregs;
- u32 ctl_reg;
-};
-
-static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
-
-static int phantom_status(struct phantom_device *dev, unsigned long newstat)
-{
- pr_debug("phantom_status %lx %lx\n", dev->status, newstat);
-
- if (!(dev->status & PHB_RUNNING) && (newstat & PHB_RUNNING)) {
- atomic_set(&dev->counter, 0);
- iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL);
- iowrite32(0x43, dev->caddr + PHN_IRQCTL);
- ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
- } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING)) {
- iowrite32(0, dev->caddr + PHN_IRQCTL);
- ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
- }
-
- dev->status = newstat;
-
- return 0;
-}
-
-/*
- * File ops
- */
-
-static long phantom_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct phantom_device *dev = file->private_data;
- struct phm_regs rs;
- struct phm_reg r;
- void __user *argp = (void __user *)arg;
- unsigned long flags;
- unsigned int i;
-
- switch (cmd) {
- case PHN_SETREG:
- case PHN_SET_REG:
- if (copy_from_user(&r, argp, sizeof(r)))
- return -EFAULT;
-
- if (r.reg > 7)
- return -EINVAL;
-
- spin_lock_irqsave(&dev->regs_lock, flags);
- if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
- phantom_status(dev, dev->status | PHB_RUNNING)){
- spin_unlock_irqrestore(&dev->regs_lock, flags);
- return -ENODEV;
- }
-
- pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
-
- /* preserve amp bit (don't allow to change it when in NOT_OH) */
- if (r.reg == PHN_CONTROL && (dev->status & PHB_NOT_OH)) {
- r.value &= ~PHN_CTL_AMP;
- r.value |= dev->ctl_reg & PHN_CTL_AMP;
- dev->ctl_reg = r.value;
- }
-
- iowrite32(r.value, dev->iaddr + r.reg);
- ioread32(dev->iaddr); /* PCI posting */
-
- if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
- phantom_status(dev, dev->status & ~PHB_RUNNING);
- spin_unlock_irqrestore(&dev->regs_lock, flags);
- break;
- case PHN_SETREGS:
- case PHN_SET_REGS:
- if (copy_from_user(&rs, argp, sizeof(rs)))
- return -EFAULT;
-
- pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
- spin_lock_irqsave(&dev->regs_lock, flags);
- if (dev->status & PHB_NOT_OH)
- memcpy(&dev->oregs, &rs, sizeof(rs));
- else {
- u32 m = min(rs.count, 8U);
- for (i = 0; i < m; i++)
- if (rs.mask & BIT(i))
- iowrite32(rs.values[i], dev->oaddr + i);
- ioread32(dev->iaddr); /* PCI posting */
- }
- spin_unlock_irqrestore(&dev->regs_lock, flags);
- break;
- case PHN_GETREG:
- case PHN_GET_REG:
- if (copy_from_user(&r, argp, sizeof(r)))
- return -EFAULT;
-
- if (r.reg > 7)
- return -EINVAL;
-
- r.value = ioread32(dev->iaddr + r.reg);
-
- if (copy_to_user(argp, &r, sizeof(r)))
- return -EFAULT;
- break;
- case PHN_GETREGS:
- case PHN_GET_REGS: {
- u32 m;
-
- if (copy_from_user(&rs, argp, sizeof(rs)))
- return -EFAULT;
-
- m = min(rs.count, 8U);
-
- pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
- spin_lock_irqsave(&dev->regs_lock, flags);
- for (i = 0; i < m; i++)
- if (rs.mask & BIT(i))
- rs.values[i] = ioread32(dev->iaddr + i);
- atomic_set(&dev->counter, 0);
- spin_unlock_irqrestore(&dev->regs_lock, flags);
-
- if (copy_to_user(argp, &rs, sizeof(rs)))
- return -EFAULT;
- break;
- } case PHN_NOT_OH:
- spin_lock_irqsave(&dev->regs_lock, flags);
- if (dev->status & PHB_RUNNING) {
- printk(KERN_ERR "phantom: you need to set NOT_OH "
- "before you start the device!\n");
- spin_unlock_irqrestore(&dev->regs_lock, flags);
- return -EINVAL;
- }
- dev->status |= PHB_NOT_OH;
- spin_unlock_irqrestore(&dev->regs_lock, flags);
- break;
- default:
- return -ENOTTY;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_COMPAT
-static long phantom_compat_ioctl(struct file *filp, unsigned int cmd,
- unsigned long arg)
-{
- if (_IOC_NR(cmd) <= 3 && _IOC_SIZE(cmd) == sizeof(compat_uptr_t)) {
- cmd &= ~(_IOC_SIZEMASK << _IOC_SIZESHIFT);
- cmd |= sizeof(void *) << _IOC_SIZESHIFT;
- }
- return phantom_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
-}
-#else
-#define phantom_compat_ioctl NULL
-#endif
-
-static int phantom_open(struct inode *inode, struct file *file)
-{
- struct phantom_device *dev = container_of(inode->i_cdev,
- struct phantom_device, cdev);
-
- mutex_lock(&phantom_mutex);
- nonseekable_open(inode, file);
-
- if (mutex_lock_interruptible(&dev->open_lock)) {
- mutex_unlock(&phantom_mutex);
- return -ERESTARTSYS;
- }
-
- if (dev->opened) {
- mutex_unlock(&dev->open_lock);
- mutex_unlock(&phantom_mutex);
- return -EINVAL;
- }
-
- WARN_ON(dev->status & PHB_NOT_OH);
-
- file->private_data = dev;
-
- atomic_set(&dev->counter, 0);
- dev->opened++;
- mutex_unlock(&dev->open_lock);
- mutex_unlock(&phantom_mutex);
- return 0;
-}
-
-static int phantom_release(struct inode *inode, struct file *file)
-{
- struct phantom_device *dev = file->private_data;
-
- mutex_lock(&dev->open_lock);
-
- dev->opened = 0;
- phantom_status(dev, dev->status & ~PHB_RUNNING);
- dev->status &= ~PHB_NOT_OH;
-
- mutex_unlock(&dev->open_lock);
-
- return 0;
-}
-
-static unsigned int phantom_poll(struct file *file, poll_table *wait)
-{
- struct phantom_device *dev = file->private_data;
- unsigned int mask = 0;
-
- pr_debug("phantom_poll: %d\n", atomic_read(&dev->counter));
- poll_wait(file, &dev->wait, wait);
-
- if (!(dev->status & PHB_RUNNING))
- mask = POLLERR;
- else if (atomic_read(&dev->counter))
- mask = POLLIN | POLLRDNORM;
-
- pr_debug("phantom_poll end: %x/%d\n", mask, atomic_read(&dev->counter));
-
- return mask;
-}
-
-static const struct file_operations phantom_file_ops = {
- .open = phantom_open,
- .release = phantom_release,
- .unlocked_ioctl = phantom_ioctl,
- .compat_ioctl = phantom_compat_ioctl,
- .poll = phantom_poll,
- .llseek = no_llseek,
-};
-
-static irqreturn_t phantom_isr(int irq, void *data)
-{
- struct phantom_device *dev = data;
- unsigned int i;
- u32 ctl;
-
- spin_lock(&dev->regs_lock);
- ctl = ioread32(dev->iaddr + PHN_CONTROL);
- if (!(ctl & PHN_CTL_IRQ)) {
- spin_unlock(&dev->regs_lock);
- return IRQ_NONE;
- }
-
- iowrite32(0, dev->iaddr);
- iowrite32(0xc0, dev->iaddr);
-
- if (dev->status & PHB_NOT_OH) {
- struct phm_regs *r = &dev->oregs;
- u32 m = min(r->count, 8U);
-
- for (i = 0; i < m; i++)
- if (r->mask & BIT(i))
- iowrite32(r->values[i], dev->oaddr + i);
-
- dev->ctl_reg ^= PHN_CTL_AMP;
- iowrite32(dev->ctl_reg, dev->iaddr + PHN_CONTROL);
- }
- spin_unlock(&dev->regs_lock);
-
- ioread32(dev->iaddr); /* PCI posting */
-
- atomic_inc(&dev->counter);
- wake_up_interruptible(&dev->wait);
-
- return IRQ_HANDLED;
-}
-
-/*
- * Init and deinit driver
- */
-
-static unsigned int __devinit phantom_get_free(void)
-{
- unsigned int i;
-
- for (i = 0; i < PHANTOM_MAX_MINORS; i++)
- if (phantom_devices[i] == 0)
- break;
-
- return i;
-}
-
-static int __devinit phantom_probe(struct pci_dev *pdev,
- const struct pci_device_id *pci_id)
-{
- struct phantom_device *pht;
- unsigned int minor;
- int retval;
-
- retval = pci_enable_device(pdev);
- if (retval) {
- dev_err(&pdev->dev, "pci_enable_device failed!\n");
- goto err;
- }
-
- minor = phantom_get_free();
- if (minor == PHANTOM_MAX_MINORS) {
- dev_err(&pdev->dev, "too many devices found!\n");
- retval = -EIO;
- goto err_dis;
- }
-
- phantom_devices[minor] = 1;
-
- retval = pci_request_regions(pdev, "phantom");
- if (retval) {
- dev_err(&pdev->dev, "pci_request_regions failed!\n");
- goto err_null;
- }
-
- retval = -ENOMEM;
- pht = kzalloc(sizeof(*pht), GFP_KERNEL);
- if (pht == NULL) {
- dev_err(&pdev->dev, "unable to allocate device\n");
- goto err_reg;
- }
-
- pht->caddr = pci_iomap(pdev, 0, 0);
- if (pht->caddr == NULL) {
- dev_err(&pdev->dev, "can't remap conf space\n");
- goto err_fr;
- }
- pht->iaddr = pci_iomap(pdev, 2, 0);
- if (pht->iaddr == NULL) {
- dev_err(&pdev->dev, "can't remap input space\n");
- goto err_unmc;
- }
- pht->oaddr = pci_iomap(pdev, 3, 0);
- if (pht->oaddr == NULL) {
- dev_err(&pdev->dev, "can't remap output space\n");
- goto err_unmi;
- }
-
- mutex_init(&pht->open_lock);
- spin_lock_init(&pht->regs_lock);
- init_waitqueue_head(&pht->wait);
- cdev_init(&pht->cdev, &phantom_file_ops);
- pht->cdev.owner = THIS_MODULE;
-
- iowrite32(0, pht->caddr + PHN_IRQCTL);
- ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
- retval = request_irq(pdev->irq, phantom_isr,
- IRQF_SHARED | IRQF_DISABLED, "phantom", pht);
- if (retval) {
- dev_err(&pdev->dev, "can't establish ISR\n");
- goto err_unmo;
- }
-
- retval = cdev_add(&pht->cdev, MKDEV(phantom_major, minor), 1);
- if (retval) {
- dev_err(&pdev->dev, "chardev registration failed\n");
- goto err_irq;
- }
-
- if (IS_ERR(device_create(phantom_class, &pdev->dev,
- MKDEV(phantom_major, minor), NULL,
- "phantom%u", minor)))
- dev_err(&pdev->dev, "can't create device\n");
-
- pci_set_drvdata(pdev, pht);
-
- return 0;
-err_irq:
- free_irq(pdev->irq, pht);
-err_unmo:
- pci_iounmap(pdev, pht->oaddr);
-err_unmi:
- pci_iounmap(pdev, pht->iaddr);
-err_unmc:
- pci_iounmap(pdev, pht->caddr);
-err_fr:
- kfree(pht);
-err_reg:
- pci_release_regions(pdev);
-err_null:
- phantom_devices[minor] = 0;
-err_dis:
- pci_disable_device(pdev);
-err:
- return retval;
-}
-
-static void __devexit phantom_remove(struct pci_dev *pdev)
-{
- struct phantom_device *pht = pci_get_drvdata(pdev);
- unsigned int minor = MINOR(pht->cdev.dev);
-
- device_destroy(phantom_class, MKDEV(phantom_major, minor));
-
- cdev_del(&pht->cdev);
-
- iowrite32(0, pht->caddr + PHN_IRQCTL);
- ioread32(pht->caddr + PHN_IRQCTL); /* PCI posting */
- free_irq(pdev->irq, pht);
-
- pci_iounmap(pdev, pht->oaddr);
- pci_iounmap(pdev, pht->iaddr);
- pci_iounmap(pdev, pht->caddr);
-
- kfree(pht);
-
- pci_release_regions(pdev);
-
- phantom_devices[minor] = 0;
-
- pci_disable_device(pdev);
-}
-
-#ifdef CONFIG_PM
-static int phantom_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct phantom_device *dev = pci_get_drvdata(pdev);
-
- iowrite32(0, dev->caddr + PHN_IRQCTL);
- ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
-
- synchronize_irq(pdev->irq);
-
- return 0;
-}
-
-static int phantom_resume(struct pci_dev *pdev)
-{
- struct phantom_device *dev = pci_get_drvdata(pdev);
-
- iowrite32(0, dev->caddr + PHN_IRQCTL);
-
- return 0;
-}
-#else
-#define phantom_suspend NULL
-#define phantom_resume NULL
-#endif
-
-static struct pci_device_id phantom_pci_tbl[] __devinitdata = {
- { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9050,
- .subvendor = PCI_VENDOR_ID_PLX, .subdevice = PCI_DEVICE_ID_PLX_9050,
- .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 },
- { 0, }
-};
-MODULE_DEVICE_TABLE(pci, phantom_pci_tbl);
-
-static struct pci_driver phantom_pci_driver = {
- .name = "phantom",
- .id_table = phantom_pci_tbl,
- .probe = phantom_probe,
- .remove = __devexit_p(phantom_remove),
- .suspend = phantom_suspend,
- .resume = phantom_resume
-};
-
-static CLASS_ATTR_STRING(version, 0444, PHANTOM_VERSION);
-
-static int __init phantom_init(void)
-{
- int retval;
- dev_t dev;
-
- phantom_class = class_create(THIS_MODULE, "phantom");
- if (IS_ERR(phantom_class)) {
- retval = PTR_ERR(phantom_class);
- printk(KERN_ERR "phantom: can't register phantom class\n");
- goto err;
- }
- retval = class_create_file(phantom_class, &class_attr_version.attr);
- if (retval) {
- printk(KERN_ERR "phantom: can't create sysfs version file\n");
- goto err_class;
- }
-
- retval = alloc_chrdev_region(&dev, 0, PHANTOM_MAX_MINORS, "phantom");
- if (retval) {
- printk(KERN_ERR "phantom: can't register character device\n");
- goto err_attr;
- }
- phantom_major = MAJOR(dev);
-
- retval = pci_register_driver(&phantom_pci_driver);
- if (retval) {
- printk(KERN_ERR "phantom: can't register pci driver\n");
- goto err_unchr;
- }
-
- printk(KERN_INFO "Phantom Linux Driver, version " PHANTOM_VERSION ", "
- "init OK\n");
-
- return 0;
-err_unchr:
- unregister_chrdev_region(dev, PHANTOM_MAX_MINORS);
-err_attr:
- class_remove_file(phantom_class, &class_attr_version.attr);
-err_class:
- class_destroy(phantom_class);
-err:
- return retval;
-}
-
-static void __exit phantom_exit(void)
-{
- pci_unregister_driver(&phantom_pci_driver);
-
- unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS);
-
- class_remove_file(phantom_class, &class_attr_version.attr);
- class_destroy(phantom_class);
-
- pr_debug("phantom: module successfully removed\n");
-}
-
-module_init(phantom_init);
-module_exit(phantom_exit);
-
-MODULE_AUTHOR("Jiri Slaby <jirislaby@gmail.com>");
-MODULE_DESCRIPTION("Sensable Phantom driver (PCI devices)");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(PHANTOM_VERSION);
diff --git a/ANDROID_3.4.5/drivers/misc/pn547.c b/ANDROID_3.4.5/drivers/misc/pn547.c
deleted file mode 100755
index ff819341..00000000
--- a/ANDROID_3.4.5/drivers/misc/pn547.c
+++ /dev/null
@@ -1,1180 +0,0 @@
-/*
- * Copyright (C) 2010 Trusted Logic S.A.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <linux/jiffies.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/miscdevice.h>
-#include <linux/spinlock.h>
-#include <linux/nfc/pn544.h>
-
-#include <mach/wmt_iomux.h>
-
-#include <mach/hardware.h>
-//#include <plat/gpio-core.h>
-//#include <plat/gpio-cfg.h>
-//#include <plat/gpio-cfg-helpers.h>
-
-
-#undef pr_err
-#define pr_err printk
-//#define pr_debug printk
-//#define pr_warning printk
-
-#define DRIVER_DESC "NFC driver for PN544"
-
-#define CLIENT_ADDR 0x28 //0x2b mod 2014-7-10
-#define WMT_PN544_I2C_CHANNEL 0
-
-struct i2c_client *pn544_client;
-static int g_chip_nr = 7;
-
-#define MAX_BUFFER_SIZE 512
-
-extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
-
-struct pn544_dev {
- wait_queue_head_t read_wq;
- struct mutex read_mutex;
- struct i2c_client *client;
- struct miscdevice pn544_device;
-
-
- int ven_gpio;
- int ven_active;
- int ven_on_off;
-
- int firm_gpio;
- int firm_active;
-
- int irq_gpio;
- int irq_active;
-
-
- bool irq_enabled;
- spinlock_t irq_enabled_lock;
-};
-
-//**********************add 2014-7-16
-static int irq_gpio = 0;
-
-void wmt_clr_int(void)
-{
- int num = irq_gpio;
-
- int reg_shift = 20;
- if (num > /*11*/42)
- {
- return;
- }
-
- if (num < 20)
- {
- REG32_VAL(__GPIO_BASE+0x0360) = 1<<num;
- }
- else
- {
- switch (num)
- {
- case WMT_PIN_GP5_VDOUT11:
- REG32_VAL(__GPIO_BASE+0x0360) = 1<<reg_shift;
- break;
- case WMT_PIN_GP5_VDOUT12:
- REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+1);
- break;
- case WMT_PIN_GP6_VDOUT18:
- REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+2);
- break;
- case WMT_PIN_GP6_VDOUT19:
- REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+3);
- break;
- case WMT_PIN_GP6_VDOUT20:
- REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+4);
- break;
- case WMT_PIN_GP6_VDOUT21:
- REG32_VAL(__GPIO_BASE+0x0360) = 1<<(reg_shift+5);
- break;
-
- }
- }
- //gpio 0-19 vdout11 12 18:21
- //REG32_VAL(__GPIO_BASE+0x0360) = 1<<num; //interrupt status register ,1:active 0:inactive
- // write 1:to clear
-}
-
-void wmt_set_irqinput(void)
-{
- int num = irq_gpio;
-
- if (num > /*19*/42)
- return;
- if (num < 20)
- {
- REG32_VAL(__GPIO_BASE+0x0040) |= (1<<num); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0080) &= ~(1<<num); //set input
- }
-
- //GPIO GP5 Enable Register for VDOUT[15:8]
- //GPIO GP6 Enable Register for VDOUT[23:16]
-
- switch (num) //gpio 0-19 vdout11 12 18:21 -->gpio 31 32 38:41
- {
- case WMT_PIN_GP5_VDOUT11:
- REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP5_VDOUT12:
- REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP6_VDOUT18:
- REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP6_VDOUT19:
- REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP6_VDOUT20:
- REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP6_VDOUT21:
- REG32_VAL(__GPIO_BASE+0x0044) |= (1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
-
- }
-}
-
-static void wmt_disable_irqinput(void)
-{
- int num = irq_gpio;
-
- if (num > /*19*/42)
- return;
- if (num < 20)
- {
- REG32_VAL(__GPIO_BASE+0x0040) &= ~(1<<num); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0080) &= ~(1<<num); //set input
- }
-
- //GPIO GP5 Enable Register for VDOUT[15:8]
- //GPIO GP6 Enable Register for VDOUT[23:16]
-
- switch (num) //gpio 0-19 vdout11 12 18:21 -->gpio 31 32 38:41
- {
- case WMT_PIN_GP5_VDOUT11:
- REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //disable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP5_VDOUT12:
- REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP6_VDOUT18:
- REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP6_VDOUT19:
- REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP6_VDOUT20:
- REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
- case WMT_PIN_GP6_VDOUT21:
- REG32_VAL(__GPIO_BASE+0x0044) &= ~(1<<(num-20)); //enable gpio
- REG32_VAL(__GPIO_BASE+0x0084) &= ~(1<<(num-20)); //set input
- break;
-
- }
-}
-
-static void wmt_pullup(void)
-{
- int num = irq_gpio;
-
- if(num >/*11*//*19*/42)
- return;
- if (num < 20)
- {
- REG32_VAL(__GPIO_BASE+0x04c0) |= (1<<num); //pull up!
- REG32_VAL(__GPIO_BASE+0x0480) |= (1<<num); //enable pull up/down
- }
- switch (num)
- { //vdout11 12 18:21-->gpio 31 32 38:41
- case WMT_PIN_GP5_VDOUT11:
- REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up!
- REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down
- break;
- case WMT_PIN_GP5_VDOUT12:
- REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up!
- REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down
- break;
- case WMT_PIN_GP6_VDOUT18:
- REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up!
- REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down
- break;
- case WMT_PIN_GP6_VDOUT19:
- REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up!
- REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down
- break;
- case WMT_PIN_GP6_VDOUT20:
- REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up!
- REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down
- break;
- case WMT_PIN_GP6_VDOUT21:
- REG32_VAL(__GPIO_BASE+0x04c4) |= (1<<(num-20)); //pull up!
- REG32_VAL(__GPIO_BASE+0x0484) |= (1<<(num-20)); //enable pull up/down
- break;
-
- }
-}
-
-int wmt_set_gpirq(int type)
-{
- int shift;
- int offset;
- unsigned long reg;
- int num = irq_gpio;
-
- if(num >/*11*//*19*/42)
- return -1;
- //if (num > 9)
- //GPIO_PIN_SHARING_SEL_4BYTE_VAL &= ~BIT4; // gpio10,11 as gpio
-#if 0
- REG32_VAL(__GPIO_BASE+0x0040) &= ~(1<<num); // gpio disable
- REG32_VAL(__GPIO_BASE+0x0080) &= ~(1<<num); //set input
-#endif
- wmt_disable_irqinput();//replace 2014-8-22
-#if 0
- REG32_VAL(__GPIO_BASE+0x04c0) |= (1<<num); //pull up!
- REG32_VAL(__GPIO_BASE+0x0480) |= (1<<num); //enable pull up/down
-#endif
- wmt_pullup();//replace 2014-8-22
-
- //set gpio irq triger type
- if(num < 4){//[0,3]
- shift = num;
- offset = 0x0300;
- }else if(num >= 4 && num < 8){//[4,7]
- shift = num-4;
- offset = 0x0304;
- }else if (num >= 8 && num <12){// [8,11]
- shift = num-8;
- offset = 0x0308;
- }
- else if (num>=12 && num < 16)
- {
- shift = num -12;
- offset = 0x030c;
- }
- else if (num>=16 && num <20)
- {
- shift = num -16;
- offset = 0x0310;
- }
- else ////vdout11 12 18:21-->gpio 31 32 38:41
- { // 0x0314----0x0319
- switch (num)
- {
- case WMT_PIN_GP5_VDOUT11:
- shift = 0;
- offset = 0x0314;
- break;
- case WMT_PIN_GP5_VDOUT12:
- shift = 1;
- offset = 0x0314;
- break;
-
- case WMT_PIN_GP6_VDOUT18:
- shift = 2;
- offset = 0x0314;
- break;
-
- case WMT_PIN_GP6_VDOUT19:
- shift = 3;
- offset = 0x0314;
- break;
- case WMT_PIN_GP6_VDOUT20:
- shift = 0;
- offset = 0x0318;
- break;
-
- case WMT_PIN_GP6_VDOUT21:
-
- shift = 1;
- offset = 0x0318;
- break;
- }
- #if 0
- else if (num>=20 && num<24) //videoOut11 12 18 19
- {
- shift = num -20;
- offset = 0x0314;
- }
- else if (num>=24 && num<28) //videoOut20 21
- {
- shift = num -24;
- offset = 0x0318;
- }
- #endif
- }
-
- reg = REG32_VAL(__GPIO_BASE + offset);
-
- switch(type){
- case IRQ_TYPE_LEVEL_LOW:
- reg &= ~(1<<(shift*8+2));
- reg &= ~(1<<(shift*8+1));
- reg &= ~(1<<(shift*8));
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- reg &= ~(1<<(shift*8+2));
- reg &= ~(1<<(shift*8+1));
- reg |= (1<<(shift*8));
- break;
- case IRQ_TYPE_EDGE_FALLING:
- reg &= ~(1<<(shift*8+2));
- reg |= (1<<(shift*8+1));
- reg &= ~(1<<(shift*8));
- break;
- case IRQ_TYPE_EDGE_RISING:
- reg &= ~(1<<(shift*8+2));
- reg |= (1<<(shift*8+1));
- reg |= (1<<(shift*8));
- break;
- default://both edge
- reg |= (1<<(shift*8+2));
- reg &= ~(1<<(shift*8+1));
- reg &= ~(1<<(shift*8));
- break;
-
- }
- //reg |= 1<<(shift*8+7);//enable interrupt
- reg &= ~(1<<(shift*8+7)); //disable int
-
- REG32_VAL(__GPIO_BASE + offset) = reg;
- wmt_clr_int(); //replace 2014-8-22
- //REG32_VAL(__GPIO_BASE+0x0360) = 1<<num; //clear interrupt status// 1 bit per int
- msleep(5);
- return 0;
-}
-
-int wmt_enable_gpirq(void)
-{
- int num = irq_gpio;
-
- if(num > /*11*/ /*19*/42)
- return -1;
-
- if(num<4)
- REG32_VAL(__GPIO_BASE+0x0300) |= 1<<(num*8+7); //enable interrupt
- else if(num >= 4 && num < 8)
- REG32_VAL(__GPIO_BASE+0x0304) |= 1<<((num-4)*8+7); //enable interrupt
- else if (num >= 8 && num < 12)
- REG32_VAL(__GPIO_BASE+0x0308) |= 1<<((num-8)*8+7); //enable interrupt
- else if (num >= 12 && num < 16)
- REG32_VAL(__GPIO_BASE+0x030c) |= 1<<((num-12)*8+7); //enable interrupt
- else if (num >= 16 && num < 20)
- REG32_VAL(__GPIO_BASE+0x0310) |= 1<<((num-16)*8+7); //enable interrupt
- else ////vdout11 12 18:21-->gpio 31 32 38:41
- { // 0x0314----0x0319
- switch (num)
- {
- case WMT_PIN_GP5_VDOUT11:
- REG32_VAL(__GPIO_BASE+0x0314) |= 1<<(0*8+7); //enable interrupt
-
- break;
- case WMT_PIN_GP5_VDOUT12:
- REG32_VAL(__GPIO_BASE+0x0314) |= 1<<(1*8+7); //enable interrupt
- break;
-
- case WMT_PIN_GP6_VDOUT18:
- REG32_VAL(__GPIO_BASE+0x0314) |= 1<<(2*8+7); //enable interrupt
- break;
-
- case WMT_PIN_GP6_VDOUT19:
- REG32_VAL(__GPIO_BASE+0x0314) |= 1<<(3*8+7); //enable interrupt
- break;
- case WMT_PIN_GP6_VDOUT20:
- REG32_VAL(__GPIO_BASE+0x0318) |= 1<<(0*8+7); //enable interrupt
-
- break;
-
- case WMT_PIN_GP6_VDOUT21:
-
- REG32_VAL(__GPIO_BASE+0x0318) |= 1<<(1*8+7); //enable interrupt
- break;
- }
-
- }
-
- return 0;
-}
-
-int wmt_disable_gpirq(void)
-{
- int num = irq_gpio;
-
- if(num > /*11*//*19*/42)
- return -1;
-
- if(num<4)
- REG32_VAL(__GPIO_BASE+0x0300) &= ~(1<<(num*8+7)); //disable interrupt
- else if(num >= 4 && num < 8)
- REG32_VAL(__GPIO_BASE+0x0304) &= ~(1<<((num-4)*8+7)); //enable interrupt
- else if (num >= 8 && num <12)
- REG32_VAL(__GPIO_BASE+0x0308) &= ~(1<<((num-8)*8+7)); //enable interrupt
- else if (num >= 12 && num <16)
- REG32_VAL(__GPIO_BASE+0x030c) &= ~(1<<((num-8)*8+7)); //enable interrupt
- else if (num >= 16 && num <20)
- REG32_VAL(__GPIO_BASE+0x0310) &= ~(1<<((num-8)*8+7)); //enable interrupt
- else ////vdout11 12 18:21-->gpio 31 32 38:41
- { // 0x0314----0x0319
- switch (num)
- {
- case WMT_PIN_GP5_VDOUT11:
- REG32_VAL(__GPIO_BASE+0x0314) &= ~(1<<(0*8+7)); //enable interrupt
-
- break;
- case WMT_PIN_GP5_VDOUT12:
- REG32_VAL(__GPIO_BASE+0x0314) &= ~(1<<(1*8+7)); //enable interrupt
- break;
-
- case WMT_PIN_GP6_VDOUT18:
- REG32_VAL(__GPIO_BASE+0x0314) &= ~(1<<(2*8+7)); //enable interrupt
- break;
-
- case WMT_PIN_GP6_VDOUT19:
- REG32_VAL(__GPIO_BASE+0x0314) &= ~(1<<(3*8+7)); //enable interrupt
- break;
- case WMT_PIN_GP6_VDOUT20:
- REG32_VAL(__GPIO_BASE+0x0318) &= ~(1<<(0*8+7)); //enable interrupt
-
- break;
-
- case WMT_PIN_GP6_VDOUT21:
-
- REG32_VAL(__GPIO_BASE+0x0318) &= ~(1<<(1*8+7)); //enable interrupt
- break;
- }
-
- }
-
- return 0;
-}
-
-static int pn544_wmt_is_int(int num)
-{
- if (num > 42)
- {
- return 0;
- }
- if (num < 20)
- {
- return REG32_VAL(__GPIO_BASE+0x0360) & (1<<num) ? 1 : 0;
- }
- else
- {
- switch (num)
- {
- case WMT_PIN_GP5_VDOUT11:
- return REG32_VAL(__GPIO_BASE+0x0360) & (1<<20) ? 1 : 0;
- break;
- case WMT_PIN_GP5_VDOUT12:
- return REG32_VAL(__GPIO_BASE+0x0360) & (1<<21) ? 1 : 0;
- break;
- case WMT_PIN_GP6_VDOUT18:
- return REG32_VAL(__GPIO_BASE+0x0360) & (1<<22) ? 1 : 0;
- break;
- case WMT_PIN_GP6_VDOUT19:
- return REG32_VAL(__GPIO_BASE+0x0360) & (1<<23) ? 1 : 0;
- break;
- case WMT_PIN_GP6_VDOUT20:
- return REG32_VAL(__GPIO_BASE+0x0360) & (1<<24) ? 1 : 0;
- break;
- case WMT_PIN_GP6_VDOUT21:
- return REG32_VAL(__GPIO_BASE+0x0360) & (1<<25) ? 1 : 0;
- break;
-
- }
-
- }
- //return (REG32_VAL(__GPIO_BASE+0x0360) & (1<<num)) ? 1: 0;
-}
-//*************add end
-
-
-static void pn544_disable_irq(struct pn544_dev *pn544_dev)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&pn544_dev->irq_enabled_lock, flags);
- if (pn544_dev->irq_enabled) {
- wmt_disable_gpirq();
- //disable_irq_nosync(pn544_dev->client->irq);
- pn544_dev->irq_enabled = false;
- }
- spin_unlock_irqrestore(&pn544_dev->irq_enabled_lock, flags);
-}
-
-static irqreturn_t pn544_dev_irq_handler(int irq, void *dev_id)
-{
- struct pn544_dev *pn544_dev = dev_id;
- //printk("<<<<<<<%s!\n", __func__);
-#if 0
- if (!gpio_get_value(pn544_dev->irq_gpio)) {
-
- return IRQ_NONE;
- //return IRQ_HANDLED;//???
- }
-#endif
- if (pn544_wmt_is_int(pn544_dev->irq_gpio))
- {
- wmt_clr_int();
- pn544_disable_irq(pn544_dev);
-
- //printk("<<<<<<<%s! wakeup reader!\n", __func__);
- /* Wake up waiting readers */
- wake_up(&pn544_dev->read_wq);
- return IRQ_HANDLED;
- }
- else
- {
- return IRQ_NONE;
- }
-}
-
-static ssize_t pn544_dev_read(struct file *filp, char __user *buf,
- size_t count, loff_t *offset)
-{
- struct pn544_dev *pn544_dev = filp->private_data;
- char tmp[MAX_BUFFER_SIZE];
- int ret,i;
-
- if (count > MAX_BUFFER_SIZE)
- count = MAX_BUFFER_SIZE;
-
- printk("%s : reading %zu bytes.\n", __func__, count);
-
- mutex_lock(&pn544_dev->read_mutex);
-
- printk("%s irq gpio %d val %d\n", __func__, pn544_dev->irq_gpio, gpio_get_value(pn544_dev->irq_gpio));
- if (/*!gpio_get_value(pn544_dev->irq_gpio)*/gpio_get_value(pn544_dev->irq_gpio)!=pn544_dev->irq_active) {
- printk("%s &&& waitting for interrupt!\n", __func__);
- if (filp->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- goto fail;
- }
-
- while (1) {
- pn544_dev->irq_enabled = true;
- wmt_enable_gpirq();
- //enable_irq(pn544_dev->client->irq);
-
- printk("%s &&& enter waitting for interrupt!\n", __func__);
-
- ret = wait_event_interruptible(
- pn544_dev->read_wq,
- !pn544_dev->irq_enabled/*false??*/);
-
- /*ret = wait_event_interruptible(pn544_dev->read_wq,
- gpio_get_value(pn544_dev->irq_gpio));
- */
-
- pn544_disable_irq(pn544_dev);
-
- if (ret)
- goto fail;
- if (gpio_get_value(pn544_dev->irq_gpio)==pn544_dev->irq_active)
- break;
-
- pr_warning("%s: spurious interrupt detected\n", __func__);
- }
- }
-
- /* Read data */
- ret = i2c_master_recv(pn544_dev->client, tmp, count);
- mutex_unlock(&pn544_dev->read_mutex);
- /* pn544 seems to be slow in handling I2C read requests
- * so add 1ms delay after recv operation */
- udelay(1000);
-
- if (ret < 0) {
- pr_err("%s: i2c_master_recv returned %d\n", __func__, ret);
- return ret;
- }
- if (ret > count) {
- pr_err("%s: received too many bytes from i2c (%d)\n",
- __func__, ret);
- return -EIO;
- }
- if (copy_to_user(buf, tmp, ret)) {
- pr_warning("%s : failed to copy to user space\n", __func__);
- return -EFAULT;
- }
-
- printk("IFD->PC:");
- for(i = 0; i < ret; i++){
- printk(" %02X", tmp[i]);
- }
- printk("\n");
-
- return ret;
-
-fail:
- printk("%s fail end! ret :%x\n", __func__, ret);
- mutex_unlock(&pn544_dev->read_mutex);
- return ret;
-}
-
-static ssize_t pn544_dev_write(struct file *filp, const char __user *buf,
- size_t count, loff_t *offset)
-{
- struct pn544_dev *pn544_dev;
- char tmp[MAX_BUFFER_SIZE];
- int ret,i;
-
- pn544_dev = filp->private_data;
-
- if (count > MAX_BUFFER_SIZE)
- count = MAX_BUFFER_SIZE;
-
- if (copy_from_user(tmp, buf, count)) {
- pr_err("%s : failed to copy from user space\n", __func__);
- return -EFAULT;
- }
-
- printk("%s : writing %zu bytes.\n", __func__, count);
- /* Write data */
- ret = i2c_master_send(pn544_dev->client, tmp, count);
- if (ret != count) {
- pr_err("%s : i2c_master_send returned %d\n", __func__, ret);
- ret = -EIO;
- }
- printk("PC->IFD:");
- for(i = 0; i < count; i++){
- printk(" %02X", tmp[i]);
- }
- /* pn544 seems to be slow in handling I2C write requests
- * so add 1ms delay after I2C send oparation */
- udelay(1000);
-
- return ret;
-}
-
-static int pn544_dev_open(struct inode *inode, struct file *filp)
-{
- struct pn544_dev *pn544_dev = container_of(filp->private_data,
- struct pn544_dev,
- pn544_device);
-
- filp->private_data = pn544_dev;
-
- pr_debug("%s : %d,%d\n", __func__, imajor(inode), iminor(inode));
-
- return 0;
-}
-
-static /*int*/long pn544_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- struct pn544_dev *pn544_dev = filp->private_data;
-
- switch (cmd) {
- case PN544_SET_PWR:
- if (arg == 2) {
- /* power on with firmware download (requires hw reset)
- */
- printk("%s power on with firmware\n", __func__);
- gpio_set_value(pn544_dev->ven_gpio, /*1*/pn544_dev->ven_active);
- msleep(20);
- if (pn544_dev->firm_gpio >= 0)
- gpio_set_value(pn544_dev->firm_gpio, /*1*/pn544_dev->firm_active);
- msleep(20);
- gpio_set_value(pn544_dev->ven_gpio, /*0*/!pn544_dev->ven_active);
- msleep(100);
- gpio_set_value(pn544_dev->ven_gpio, /*1*/pn544_dev->ven_active);
- msleep(20);
- pn544_dev->ven_on_off = 1;
- } else if (arg == 1) {
- /* power on */
- printk("%s power on\n", __func__);
- if (pn544_dev->firm_gpio >= 0)
- gpio_set_value(pn544_dev->firm_gpio, /*0*/!pn544_dev->firm_active);
- gpio_set_value(pn544_dev->ven_gpio, /*1*/pn544_dev->ven_active);
- msleep(100);
- pn544_dev->ven_on_off = 1;
- } else if (arg == 0) {
- /* power off */
- printk("%s power off ven %d \n", __func__, !pn544_dev->ven_active);
- if (pn544_dev->firm_gpio >= 0)
- gpio_set_value(pn544_dev->firm_gpio, /*0*/!pn544_dev->firm_active);
- gpio_set_value(pn544_dev->ven_gpio, /*0*/!pn544_dev->ven_active);
-
- pn544_dev->ven_on_off = 0;
- //gpio_set_value(pn544_dev->ven_gpio, 0);
- msleep(100);
- } else {
- printk("%s bad arg %u\n", __func__, arg);
- return -EINVAL;
- }
- break;
- default:
- printk("%s bad ioctl %u\n", __func__, cmd);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static const struct file_operations pn544_dev_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = pn544_dev_read,
- .write = pn544_dev_write,
- .open = pn544_dev_open,
- .unlocked_ioctl = pn544_dev_ioctl,
-};
-
-
-static int pn544_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int ret;
- struct pn544_nfc_platform_data *platform_data;
- struct pn544_dev *pn544_dev;
-
- platform_data = client->dev.platform_data;
-
- if (platform_data == NULL) {
- pr_err("%s : nfc probe fail\n", __func__);
- return -ENODEV;
- }
-
- printk("nfc probe step01 is ok\n");
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- pr_err("%s : need I2C_FUNC_I2C\n", __func__);
- return -ENODEV;
- }
-
- printk("nfc probe step02 is ok\n");
-
- ret = gpio_request(platform_data->irq_gpio, "nfc_int");
- if (ret)
- return -ENODEV;
-
-
-
- ret = gpio_request(platform_data->ven_gpio, "nfc_ven");
- if (ret)
- goto err_ven;
-
-
- if (platform_data->firm_gpio >= 0)
- {
-
- ret = gpio_request(platform_data->firm_gpio, "nfc_firm");
- if (ret)
- goto err_firm;
-
- }
-
- pn544_dev = kzalloc(sizeof(*pn544_dev), GFP_KERNEL);
- if (pn544_dev == NULL) {
- dev_err(&client->dev,
- "failed to allocate memory for module data\n");
- ret = -ENOMEM;
- goto err_exit;
- }
-
- printk("nfc probe step04 is ok\n");
-
- //pn544_dev->irq_enable = platform_data->irq_enable;
- pn544_dev->irq_gpio = platform_data->irq_gpio;
- pn544_dev->irq_active = platform_data->irq_active;
-
- //pn544_dev->ven_enable = platform_data->ven_enable;
- pn544_dev->ven_gpio = platform_data->ven_gpio;
- pn544_dev->ven_active = platform_data->ven_active;
- pn544_dev->ven_on_off = 0;
- //pn544_dev->firm_enable = platform_data->firm_enable;
- pn544_dev->firm_gpio = platform_data->firm_gpio;
- pn544_dev->firm_active = platform_data->firm_active;
-
- pn544_dev->client = client;
-
- irq_gpio = pn544_dev->irq_gpio;
- /* init mutex and queues */
- init_waitqueue_head(&pn544_dev->read_wq);
- mutex_init(&pn544_dev->read_mutex);
- spin_lock_init(&pn544_dev->irq_enabled_lock);
-
- pn544_dev->pn544_device.minor = MISC_DYNAMIC_MINOR;
- switch (g_chip_nr)
- {
- case 7:
- pn544_dev->pn544_device.name = "pn547"; //"pn544" modify 2014-7-21
- break;
- case 4:
- pn544_dev->pn544_device.name = "pn544"; //"pn544" modify 2014-8-22
- break;
- }
- pn544_dev->pn544_device.fops = &pn544_dev_fops;
-
- ret = misc_register(&pn544_dev->pn544_device);
- if (ret) {
- pr_err("%s : misc_register failed\n", __FILE__);
- goto err_misc_register;
- }
- printk("nfc probe step05 is ok\n");
-
- /* request irq. the irq is set whenever the chip has data available
- * for reading. it is cleared when all data has been read.
- */
-
-
- gpio_direction_output(platform_data->ven_gpio,/*0*/ !platform_data->ven_active);
-
- if (platform_data->firm_gpio >= 0)
- gpio_direction_output(platform_data->firm_gpio,/*0*/!platform_data->firm_active);
- //s3c_gpio_setpull(platform_data->ven_gpio, S3C_GPIO_PULL_UP);
- //s3c_gpio_setpull(platform_data->firm_gpio, S3C_GPIO_PULL_DOWN);
-
- //eint16 setting
-
- gpio_direction_input(platform_data->irq_gpio);
- //wmt_gpio_setpull(platform_data->irq_gpio, WMT_GPIO_PULL_UP);
- if (platform_data->irq_active)
- {
- printk("%s irq pull down!\n", __func__);
- wmt_gpio_setpull(platform_data->irq_gpio, WMT_GPIO_PULL_DOWN); //modify 2014-7-16
- }
- else
- {
- printk("%s irq pull up!\n", __func__);
- wmt_gpio_setpull(platform_data->irq_gpio, WMT_GPIO_PULL_UP);
- }
- //s3c_gpio_setpull(platform_data->irq_gpio, S3C_GPIO_PULL_UP);
-
-
- pr_info("%s : requesting IRQ %d\n", __func__, client->irq);
- pn544_dev->irq_enabled = true;
-
- ret = request_irq(client->irq, pn544_dev_irq_handler,
- /*platform_data->irq_active?IRQF_TRIGGER_HIGH:IRQF_TRIGGER_LOW*/IRQF_SHARED, \
- client->name, pn544_dev);//IRQF_TRIGGER_RISING IRQF_TRIGGER_HIGH
- if (ret) {
- printk(/*&client->dev, */"request_irq failed\n");
- goto err_request_irq_failed;
- }
- printk("nfc probe step06 is ok\n");
- //add 2014-7-16 for gpio irq config
- wmt_set_irqinput();
- wmt_set_gpirq(platform_data->irq_active?IRQF_TRIGGER_HIGH:IRQF_TRIGGER_LOW); //IRQF_TRIGGER_HIGH
- //wmt_enable_gpirq();
- //add end
-
- pn544_disable_irq(pn544_dev);
- i2c_set_clientdata(client, pn544_dev);
-
- //add debug 2014-7-10
-#if 0
- printk("%s power on\n", __func__);
- gpio_set_value(pn544_dev->firm_gpio, 0);
- gpio_set_value(pn544_dev->ven_gpio, 1);
- msleep(10);
-
- int maddr = 1;
- char mbuf[2] = {0};
- for (maddr=1; maddr<0x7f; maddr++)
- {
- mbuf[0] = maddr;
- /* Write data */
- //pn544_dev->client->addr = maddr;
- ret = i2c_master_send(pn544_dev->client, mbuf, 1);
- if (ret != 1) {
- pr_err("%s : reg 0x%x i2c_master_send returned %d\n", __func__, maddr, ret);
- //ret = -EIO;
- }
- else
- {
- pr_err("%s ok!!!: reg 0x%x i2c_master_send returned %d\n", __func__, maddr, ret);
- //break;
- }
-
- struct i2c_msg msg[2] = {
- {.addr = client->addr,
- .flags = 0|I2C_M_NOSTART,
- .len = 1,
- .buf = &mbuf[0],
- },
- { .addr = client->addr,
- .flags = I2C_M_RD,
- .len = 1,
- .buf = &mbuf[1],
- },
- };
-
- ret = i2c_transfer(client->adapter, msg, 2);
-
- //ret = i2c_master_recv(pn544_dev->client, mbuf, 1);
- if (ret != 2) {
- pr_err("%s : addr 0x%x i2c_master_recv %d returned %d\n", __func__, maddr, mbuf[1], ret);
- //ret = -EIO;
- }
- else
- {
- pr_err("%s ok!!!: addr 0x%x i2c_master_recv %d returned %d\n", __func__, maddr, mbuf[1], ret);
- //break;
- }
-
- }
-#endif
- //add end
-
- printk("nfc probe step07 is ok\n");
-
- return 0;
-
-err_request_irq_failed:
- misc_deregister(&pn544_dev->pn544_device);
-err_misc_register:
- mutex_destroy(&pn544_dev->read_mutex);
- kfree(pn544_dev);
-err_exit:
- if (platform_data->firm_gpio >= 0)
- gpio_free(platform_data->firm_gpio);
-err_firm:
-
- gpio_free(platform_data->ven_gpio);
-err_ven:
-
- gpio_free(platform_data->irq_gpio);
- return ret;
-}
-
-static int pn544_remove(struct i2c_client *client)
-{
- struct pn544_dev *pn544_dev;
-
- pn544_dev = i2c_get_clientdata(client);
- free_irq(client->irq, pn544_dev);
- misc_deregister(&pn544_dev->pn544_device);
- mutex_destroy(&pn544_dev->read_mutex);
- gpio_free(pn544_dev->irq_gpio);
- gpio_free(pn544_dev->ven_gpio);
- gpio_free(pn544_dev->firm_gpio);
- kfree(pn544_dev);
-
- return 0;
-}
-
-static const struct i2c_device_id pn544_id[] = {
- { "pn544", 0 },
- { }
-};
-
-static int pn544_suspend(struct i2c_client *client, pm_message_t mesg)
-{
- struct pn544_dev *pn544_dev;
-
- pn544_dev = i2c_get_clientdata(client);
- printk("\n%s on_off %d\n", __func__, pn544_dev->ven_on_off);
- return 0;
-}
-
-static int pn544_resume(struct i2c_client *client)
-{
- struct pn544_dev *pn544_dev;
-
- pn544_dev = i2c_get_clientdata(client);
-
- printk("%s on_off %d\n", __func__, pn544_dev->ven_on_off);
-
- gpio_direction_input(pn544_dev->irq_gpio);
- //wmt_gpio_setpull(platform_data->irq_gpio, WMT_GPIO_PULL_UP);
- if (pn544_dev->irq_active)
- wmt_gpio_setpull(pn544_dev->irq_gpio, WMT_GPIO_PULL_DOWN); //modify 2014-7-16
- else
- wmt_gpio_setpull(pn544_dev->irq_gpio, WMT_GPIO_PULL_UP);
-
- //add 2014-7-16 for gpio irq config
- wmt_set_irqinput();
- wmt_set_gpirq(pn544_dev->irq_active?IRQF_TRIGGER_HIGH:IRQF_TRIGGER_LOW); //IRQF_TRIGGER_HIGH
- //wmt_enable_gpirq();
- //add end
-
- pn544_disable_irq(pn544_dev);
-
- printk("%s active %d, !active %d\n", __func__, pn544_dev->ven_active, !pn544_dev->ven_active);
- if (pn544_dev->ven_on_off)
- gpio_set_value(pn544_dev->ven_gpio, pn544_dev->ven_active);
- else
- gpio_set_value(pn544_dev->ven_gpio, !pn544_dev->ven_active);
-
- //gpio_set_value(pn544_dev->ven_gpio, 0);
-
- return 0;
-}
-static struct i2c_driver pn544_driver = {
- .id_table = pn544_id,
- .probe = pn544_probe,
- .remove = pn544_remove,
- .suspend = pn544_suspend,
- .resume = pn544_resume,
- .driver = {
- .owner = THIS_MODULE,
- .name = "pn544",
- },
-};
-
-/*
- * module load/unload record keeping
- */
-
-static struct pn544_nfc_platform_data pn544_pdata = {
- //.irq_enable = 1,
- .irq_gpio = WMT_PIN_GP0_GPIO0,
- .irq_active = 1,
- //.ven_enable = 1,
- .ven_gpio= WMT_PIN_GP18_UART0RTS, // WMT_PIN_GP18_UART0RTS WMT_PIN_GP0_GPIO1
- .ven_active = 1,
- //.firm_enable = 1,
- .firm_gpio=WMT_PIN_GP0_GPIO1, //WMT_PIN_GP0_GPIO2,
- .firm_active = 1,
-};
-static int g_i2c_adapter = 0;
-static int g_i2c_addr = 0x28;
-static int get_board_info(void)
-{
- int ret;
- char buf[100] = {0};
- int len = sizeof(buf);
-
- char *pbuf = "wmt.nfc.pn54x"; // wmt.nfc.pn547
- printk("%s\n", __func__);
- //wmt.nfc.pn54x 4:43:0:39:1:1:1:132:1 2b-->43 wmt.nfc.pn54x 4:43:0:39:1:1:0:132:1
- ret = wmt_getsyspara(pbuf, buf, &len);
- if (!ret)
- {
- printk("%s %s:%s\n", __func__, pbuf, buf);//irq ven firm
-
- ret = sscanf(buf, "%d:%d:%d:%d:%d:%d:%d:%d:%d", \
- &g_chip_nr, &g_i2c_addr, &g_i2c_adapter, \
- &pn544_pdata.irq_gpio, &pn544_pdata.irq_active, \
- &pn544_pdata.ven_gpio, &pn544_pdata.ven_active, \
- &pn544_pdata.firm_gpio, &pn544_pdata.firm_active);
-
- printk("chip nr %d,i2c addr %d adapter %d, irq gpio %d active %d, ven %d %d, firm %d %d\n", \
- g_chip_nr, g_i2c_addr, g_i2c_adapter, \
- pn544_pdata.irq_gpio, pn544_pdata.irq_active, \
- pn544_pdata.ven_gpio, pn544_pdata.ven_active, \
- pn544_pdata.firm_gpio, pn544_pdata.firm_active);
-
- return 0;
- }
- else
- {
- printk("%s not get %s, use default\n", __func__, pbuf);
- return -1;
- }
-
- return 0;
-}
-
-static int __init pn544_dev_init(void)
-{
- //pr_info("Loading pn544 driver\n");
-
- int r;
- struct i2c_adapter *adapter;
-
-
-
- struct i2c_board_info wmt_pn544_bi = {
- .type = PN544_DRIVER_NAME,
- .flags = 0x00,
- .addr = CLIENT_ADDR,
- .platform_data = &pn544_pdata, //custom 2014-7-25
- .archdata = NULL,
- .irq = IRQ_GPIO,
- };
- //wmt_pn544_bi.addr = g_i2c_addr;
-
- pr_debug(DRIVER_DESC ": %s\n", __func__);
- r = get_board_info();
- if (r < 0)
- {
- printk("%s no env!!\n", __func__);
- return r;
- }
- wmt_pn544_bi.addr = g_i2c_addr;
- adapter = i2c_get_adapter(/*WMT_PN544_I2C_CHANNEL*/g_i2c_adapter);
- if (adapter == NULL) {
- printk("can not get i2c adapter, client address error");
- return -ENODEV;
- }
-
- pn544_client = i2c_new_device(adapter, &wmt_pn544_bi);
- if ( pn544_client == NULL) {
- printk("allocate i2c client failed");
- return -ENOMEM;
- }
-
- i2c_put_adapter(adapter);
-
- r = i2c_add_driver(&pn544_driver);
- if (r) {
- pr_err(PN544_DRIVER_NAME ": driver registration failed\n");
- return r;
- }
-
- return 0;
- //return i2c_add_driver(&pn544_driver);
-}
-module_init(pn544_dev_init);
-
-static void __exit pn544_dev_exit(void)
-{
- pr_info("Unloading pn544 driver\n");
- i2c_del_driver(&pn544_driver);
-
- i2c_unregister_device(pn544_client);
-}
-module_exit(pn544_dev_exit);
-
-MODULE_AUTHOR("Sylvain Fonteneau");
-MODULE_DESCRIPTION("NFC PN544 driver");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/pti.c b/ANDROID_3.4.5/drivers/misc/pti.c
deleted file mode 100644
index 383133b2..00000000
--- a/ANDROID_3.4.5/drivers/misc/pti.c
+++ /dev/null
@@ -1,996 +0,0 @@
-/*
- * pti.c - PTI driver for cJTAG data extration
- *
- * Copyright (C) Intel 2010
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * The PTI (Parallel Trace Interface) driver directs trace data routed from
- * various parts in the system out through the Intel Penwell PTI port and
- * out of the mobile device for analysis with a debugging tool
- * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
- * compact JTAG, standard.
- */
-
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/console.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/pci.h>
-#include <linux/mutex.h>
-#include <linux/miscdevice.h>
-#include <linux/pti.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#define DRIVERNAME "pti"
-#define PCINAME "pciPTI"
-#define TTYNAME "ttyPTI"
-#define CHARNAME "pti"
-#define PTITTY_MINOR_START 0
-#define PTITTY_MINOR_NUM 2
-#define MAX_APP_IDS 16 /* 128 channel ids / u8 bit size */
-#define MAX_OS_IDS 16 /* 128 channel ids / u8 bit size */
-#define MAX_MODEM_IDS 16 /* 128 channel ids / u8 bit size */
-#define MODEM_BASE_ID 71 /* modem master ID address */
-#define CONTROL_ID 72 /* control master ID address */
-#define CONSOLE_ID 73 /* console master ID address */
-#define OS_BASE_ID 74 /* base OS master ID address */
-#define APP_BASE_ID 80 /* base App master ID address */
-#define CONTROL_FRAME_LEN 32 /* PTI control frame maximum size */
-#define USER_COPY_SIZE 8192 /* 8Kb buffer for user space copy */
-#define APERTURE_14 0x3800000 /* offset to first OS write addr */
-#define APERTURE_LEN 0x400000 /* address length */
-
-struct pti_tty {
- struct pti_masterchannel *mc;
-};
-
-struct pti_dev {
- struct tty_port port;
- unsigned long pti_addr;
- unsigned long aperture_base;
- void __iomem *pti_ioaddr;
- u8 ia_app[MAX_APP_IDS];
- u8 ia_os[MAX_OS_IDS];
- u8 ia_modem[MAX_MODEM_IDS];
-};
-
-/*
- * This protects access to ia_app, ia_os, and ia_modem,
- * which keeps track of channels allocated in
- * an aperture write id.
- */
-static DEFINE_MUTEX(alloclock);
-
-static struct pci_device_id pci_ids[] __devinitconst = {
- {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)},
- {0}
-};
-
-static struct tty_driver *pti_tty_driver;
-static struct pti_dev *drv_data;
-
-static unsigned int pti_console_channel;
-static unsigned int pti_control_channel;
-
-/**
- * pti_write_to_aperture()- The private write function to PTI HW.
- *
- * @mc: The 'aperture'. It's part of a write address that holds
- * a master and channel ID.
- * @buf: Data being written to the HW that will ultimately be seen
- * in a debugging tool (Fido, Lauterbach).
- * @len: Size of buffer.
- *
- * Since each aperture is specified by a unique
- * master/channel ID, no two processes will be writing
- * to the same aperture at the same time so no lock is required. The
- * PTI-Output agent will send these out in the order that they arrived, and
- * thus, it will intermix these messages. The debug tool can then later
- * regroup the appropriate message segments together reconstituting each
- * message.
- */
-static void pti_write_to_aperture(struct pti_masterchannel *mc,
- u8 *buf,
- int len)
-{
- int dwordcnt;
- int final;
- int i;
- u32 ptiword;
- u32 __iomem *aperture;
- u8 *p = buf;
-
- /*
- * calculate the aperture offset from the base using the master and
- * channel id's.
- */
- aperture = drv_data->pti_ioaddr + (mc->master << 15)
- + (mc->channel << 8);
-
- dwordcnt = len >> 2;
- final = len - (dwordcnt << 2); /* final = trailing bytes */
- if (final == 0 && dwordcnt != 0) { /* always need a final dword */
- final += 4;
- dwordcnt--;
- }
-
- for (i = 0; i < dwordcnt; i++) {
- ptiword = be32_to_cpu(*(u32 *)p);
- p += 4;
- iowrite32(ptiword, aperture);
- }
-
- aperture += PTI_LASTDWORD_DTS; /* adding DTS signals that is EOM */
-
- ptiword = 0;
- for (i = 0; i < final; i++)
- ptiword |= *p++ << (24-(8*i));
-
- iowrite32(ptiword, aperture);
- return;
-}
-
-/**
- * pti_control_frame_built_and_sent()- control frame build and send function.
- *
- * @mc: The master / channel structure on which the function
- * built a control frame.
- * @thread_name: The thread name associated with the master / channel or
- * 'NULL' if using the 'current' global variable.
- *
- * To be able to post process the PTI contents on host side, a control frame
- * is added before sending any PTI content. So the host side knows on
- * each PTI frame the name of the thread using a dedicated master / channel.
- * The thread name is retrieved from 'current' global variable if 'thread_name'
- * is 'NULL', else it is retrieved from 'thread_name' parameter.
- * This function builds this frame and sends it to a master ID CONTROL_ID.
- * The overhead is only 32 bytes since the driver only writes to HW
- * in 32 byte chunks.
- */
-static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc,
- const char *thread_name)
-{
- /*
- * Since we access the comm member in current's task_struct, we only
- * need to be as large as what 'comm' in that structure is.
- */
- char comm[TASK_COMM_LEN];
- struct pti_masterchannel mccontrol = {.master = CONTROL_ID,
- .channel = 0};
- const char *thread_name_p;
- const char *control_format = "%3d %3d %s";
- u8 control_frame[CONTROL_FRAME_LEN];
-
- if (!thread_name) {
- if (!in_interrupt())
- get_task_comm(comm, current);
- else
- strncpy(comm, "Interrupt", TASK_COMM_LEN);
-
- /* Absolutely ensure our buffer is zero terminated. */
- comm[TASK_COMM_LEN-1] = 0;
- thread_name_p = comm;
- } else {
- thread_name_p = thread_name;
- }
-
- mccontrol.channel = pti_control_channel;
- pti_control_channel = (pti_control_channel + 1) & 0x7f;
-
- snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master,
- mc->channel, thread_name_p);
- pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame));
-}
-
-/**
- * pti_write_full_frame_to_aperture()- high level function to
- * write to PTI.
- *
- * @mc: The 'aperture'. It's part of a write address that holds
- * a master and channel ID.
- * @buf: Data being written to the HW that will ultimately be seen
- * in a debugging tool (Fido, Lauterbach).
- * @len: Size of buffer.
- *
- * All threads sending data (either console, user space application, ...)
- * are calling the high level function to write to PTI meaning that it is
- * possible to add a control frame before sending the content.
- */
-static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc,
- const unsigned char *buf,
- int len)
-{
- pti_control_frame_built_and_sent(mc, NULL);
- pti_write_to_aperture(mc, (u8 *)buf, len);
-}
-
-/**
- * get_id()- Allocate a master and channel ID.
- *
- * @id_array: an array of bits representing what channel
- * id's are allocated for writing.
- * @max_ids: The max amount of available write IDs to use.
- * @base_id: The starting SW channel ID, based on the Intel
- * PTI arch.
- * @thread_name: The thread name associated with the master / channel or
- * 'NULL' if using the 'current' global variable.
- *
- * Returns:
- * pti_masterchannel struct with master, channel ID address
- * 0 for error
- *
- * Each bit in the arrays ia_app and ia_os correspond to a master and
- * channel id. The bit is one if the id is taken and 0 if free. For
- * every master there are 128 channel id's.
- */
-static struct pti_masterchannel *get_id(u8 *id_array,
- int max_ids,
- int base_id,
- const char *thread_name)
-{
- struct pti_masterchannel *mc;
- int i, j, mask;
-
- mc = kmalloc(sizeof(struct pti_masterchannel), GFP_KERNEL);
- if (mc == NULL)
- return NULL;
-
- /* look for a byte with a free bit */
- for (i = 0; i < max_ids; i++)
- if (id_array[i] != 0xff)
- break;
- if (i == max_ids) {
- kfree(mc);
- return NULL;
- }
- /* find the bit in the 128 possible channel opportunities */
- mask = 0x80;
- for (j = 0; j < 8; j++) {
- if ((id_array[i] & mask) == 0)
- break;
- mask >>= 1;
- }
-
- /* grab it */
- id_array[i] |= mask;
- mc->master = base_id;
- mc->channel = ((i & 0xf)<<3) + j;
- /* write new master Id / channel Id allocation to channel control */
- pti_control_frame_built_and_sent(mc, thread_name);
- return mc;
-}
-
-/*
- * The following three functions:
- * pti_request_mastercahannel(), mipi_release_masterchannel()
- * and pti_writedata() are an API for other kernel drivers to
- * access PTI.
- */
-
-/**
- * pti_request_masterchannel()- Kernel API function used to allocate
- * a master, channel ID address
- * to write to PTI HW.
- *
- * @type: 0- request Application master, channel aperture ID
- * write address.
- * 1- request OS master, channel aperture ID write
- * address.
- * 2- request Modem master, channel aperture ID
- * write address.
- * Other values, error.
- * @thread_name: The thread name associated with the master / channel or
- * 'NULL' if using the 'current' global variable.
- *
- * Returns:
- * pti_masterchannel struct
- * 0 for error
- */
-struct pti_masterchannel *pti_request_masterchannel(u8 type,
- const char *thread_name)
-{
- struct pti_masterchannel *mc;
-
- mutex_lock(&alloclock);
-
- switch (type) {
-
- case 0:
- mc = get_id(drv_data->ia_app, MAX_APP_IDS,
- APP_BASE_ID, thread_name);
- break;
-
- case 1:
- mc = get_id(drv_data->ia_os, MAX_OS_IDS,
- OS_BASE_ID, thread_name);
- break;
-
- case 2:
- mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS,
- MODEM_BASE_ID, thread_name);
- break;
- default:
- mc = NULL;
- }
-
- mutex_unlock(&alloclock);
- return mc;
-}
-EXPORT_SYMBOL_GPL(pti_request_masterchannel);
-
-/**
- * pti_release_masterchannel()- Kernel API function used to release
- * a master, channel ID address
- * used to write to PTI HW.
- *
- * @mc: master, channel apeture ID address to be released. This
- * will de-allocate the structure via kfree().
- */
-void pti_release_masterchannel(struct pti_masterchannel *mc)
-{
- u8 master, channel, i;
-
- mutex_lock(&alloclock);
-
- if (mc) {
- master = mc->master;
- channel = mc->channel;
-
- if (master == APP_BASE_ID) {
- i = channel >> 3;
- drv_data->ia_app[i] &= ~(0x80>>(channel & 0x7));
- } else if (master == OS_BASE_ID) {
- i = channel >> 3;
- drv_data->ia_os[i] &= ~(0x80>>(channel & 0x7));
- } else {
- i = channel >> 3;
- drv_data->ia_modem[i] &= ~(0x80>>(channel & 0x7));
- }
-
- kfree(mc);
- }
-
- mutex_unlock(&alloclock);
-}
-EXPORT_SYMBOL_GPL(pti_release_masterchannel);
-
-/**
- * pti_writedata()- Kernel API function used to write trace
- * debugging data to PTI HW.
- *
- * @mc: Master, channel aperture ID address to write to.
- * Null value will return with no write occurring.
- * @buf: Trace debuging data to write to the PTI HW.
- * Null value will return with no write occurring.
- * @count: Size of buf. Value of 0 or a negative number will
- * return with no write occuring.
- */
-void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count)
-{
- /*
- * since this function is exported, this is treated like an
- * API function, thus, all parameters should
- * be checked for validity.
- */
- if ((mc != NULL) && (buf != NULL) && (count > 0))
- pti_write_to_aperture(mc, buf, count);
- return;
-}
-EXPORT_SYMBOL_GPL(pti_writedata);
-
-/**
- * pti_pci_remove()- Driver exit method to remove PTI from
- * PCI bus.
- * @pdev: variable containing pci info of PTI.
- */
-static void __devexit pti_pci_remove(struct pci_dev *pdev)
-{
- struct pti_dev *drv_data;
-
- drv_data = pci_get_drvdata(pdev);
- if (drv_data != NULL) {
- pci_iounmap(pdev, drv_data->pti_ioaddr);
- pci_set_drvdata(pdev, NULL);
- kfree(drv_data);
- pci_release_region(pdev, 1);
- pci_disable_device(pdev);
- }
-}
-
-/*
- * for the tty_driver_*() basic function descriptions, see tty_driver.h.
- * Specific header comments made for PTI-related specifics.
- */
-
-/**
- * pti_tty_driver_open()- Open an Application master, channel aperture
- * ID to the PTI device via tty device.
- *
- * @tty: tty interface.
- * @filp: filp interface pased to tty_port_open() call.
- *
- * Returns:
- * int, 0 for success
- * otherwise, fail value
- *
- * The main purpose of using the tty device interface is for
- * each tty port to have a unique PTI write aperture. In an
- * example use case, ttyPTI0 gets syslogd and an APP aperture
- * ID and ttyPTI1 is where the n_tracesink ldisc hooks to route
- * modem messages into PTI. Modem trace data does not have to
- * go to ttyPTI1, but ttyPTI0 and ttyPTI1 do need to be distinct
- * master IDs. These messages go through the PTI HW and out of
- * the handheld platform and to the Fido/Lauterbach device.
- */
-static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp)
-{
- /*
- * we actually want to allocate a new channel per open, per
- * system arch. HW gives more than plenty channels for a single
- * system task to have its own channel to write trace data. This
- * also removes a locking requirement for the actual write
- * procedure.
- */
- return tty_port_open(&drv_data->port, tty, filp);
-}
-
-/**
- * pti_tty_driver_close()- close tty device and release Application
- * master, channel aperture ID to the PTI device via tty device.
- *
- * @tty: tty interface.
- * @filp: filp interface pased to tty_port_close() call.
- *
- * The main purpose of using the tty device interface is to route
- * syslog daemon messages to the PTI HW and out of the handheld platform
- * and to the Fido/Lauterbach device.
- */
-static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp)
-{
- tty_port_close(&drv_data->port, tty, filp);
-}
-
-/**
- * pti_tty_install()- Used to set up specific master-channels
- * to tty ports for organizational purposes when
- * tracing viewed from debuging tools.
- *
- * @driver: tty driver information.
- * @tty: tty struct containing pti information.
- *
- * Returns:
- * 0 for success
- * otherwise, error
- */
-static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
-{
- int idx = tty->index;
- struct pti_tty *pti_tty_data;
- int ret = tty_standard_install(driver, tty);
-
- if (ret == 0) {
- pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL);
- if (pti_tty_data == NULL)
- return -ENOMEM;
-
- if (idx == PTITTY_MINOR_START)
- pti_tty_data->mc = pti_request_masterchannel(0, NULL);
- else
- pti_tty_data->mc = pti_request_masterchannel(2, NULL);
-
- if (pti_tty_data->mc == NULL) {
- kfree(pti_tty_data);
- return -ENXIO;
- }
- tty->driver_data = pti_tty_data;
- }
-
- return ret;
-}
-
-/**
- * pti_tty_cleanup()- Used to de-allocate master-channel resources
- * tied to tty's of this driver.
- *
- * @tty: tty struct containing pti information.
- */
-static void pti_tty_cleanup(struct tty_struct *tty)
-{
- struct pti_tty *pti_tty_data = tty->driver_data;
- if (pti_tty_data == NULL)
- return;
- pti_release_masterchannel(pti_tty_data->mc);
- kfree(pti_tty_data);
- tty->driver_data = NULL;
-}
-
-/**
- * pti_tty_driver_write()- Write trace debugging data through the char
- * interface to the PTI HW. Part of the misc device implementation.
- *
- * @filp: Contains private data which is used to obtain
- * master, channel write ID.
- * @data: trace data to be written.
- * @len: # of byte to write.
- *
- * Returns:
- * int, # of bytes written
- * otherwise, error
- */
-static int pti_tty_driver_write(struct tty_struct *tty,
- const unsigned char *buf, int len)
-{
- struct pti_tty *pti_tty_data = tty->driver_data;
- if ((pti_tty_data != NULL) && (pti_tty_data->mc != NULL)) {
- pti_write_to_aperture(pti_tty_data->mc, (u8 *)buf, len);
- return len;
- }
- /*
- * we can't write to the pti hardware if the private driver_data
- * and the mc address is not there.
- */
- else
- return -EFAULT;
-}
-
-/**
- * pti_tty_write_room()- Always returns 2048.
- *
- * @tty: contains tty info of the pti driver.
- */
-static int pti_tty_write_room(struct tty_struct *tty)
-{
- return 2048;
-}
-
-/**
- * pti_char_open()- Open an Application master, channel aperture
- * ID to the PTI device. Part of the misc device implementation.
- *
- * @inode: not used.
- * @filp: Output- will have a masterchannel struct set containing
- * the allocated application PTI aperture write address.
- *
- * Returns:
- * int, 0 for success
- * otherwise, a fail value
- */
-static int pti_char_open(struct inode *inode, struct file *filp)
-{
- struct pti_masterchannel *mc;
-
- /*
- * We really do want to fail immediately if
- * pti_request_masterchannel() fails,
- * before assigning the value to filp->private_data.
- * Slightly easier to debug if this driver needs debugging.
- */
- mc = pti_request_masterchannel(0, NULL);
- if (mc == NULL)
- return -ENOMEM;
- filp->private_data = mc;
- return 0;
-}
-
-/**
- * pti_char_release()- Close a char channel to the PTI device. Part
- * of the misc device implementation.
- *
- * @inode: Not used in this implementaiton.
- * @filp: Contains private_data that contains the master, channel
- * ID to be released by the PTI device.
- *
- * Returns:
- * always 0
- */
-static int pti_char_release(struct inode *inode, struct file *filp)
-{
- pti_release_masterchannel(filp->private_data);
- filp->private_data = NULL;
- return 0;
-}
-
-/**
- * pti_char_write()- Write trace debugging data through the char
- * interface to the PTI HW. Part of the misc device implementation.
- *
- * @filp: Contains private data which is used to obtain
- * master, channel write ID.
- * @data: trace data to be written.
- * @len: # of byte to write.
- * @ppose: Not used in this function implementation.
- *
- * Returns:
- * int, # of bytes written
- * otherwise, error value
- *
- * Notes: From side discussions with Alan Cox and experimenting
- * with PTI debug HW like Nokia's Fido box and Lauterbach
- * devices, 8192 byte write buffer used by USER_COPY_SIZE was
- * deemed an appropriate size for this type of usage with
- * debugging HW.
- */
-static ssize_t pti_char_write(struct file *filp, const char __user *data,
- size_t len, loff_t *ppose)
-{
- struct pti_masterchannel *mc;
- void *kbuf;
- const char __user *tmp;
- size_t size = USER_COPY_SIZE;
- size_t n = 0;
-
- tmp = data;
- mc = filp->private_data;
-
- kbuf = kmalloc(size, GFP_KERNEL);
- if (kbuf == NULL) {
- pr_err("%s(%d): buf allocation failed\n",
- __func__, __LINE__);
- return -ENOMEM;
- }
-
- do {
- if (len - n > USER_COPY_SIZE)
- size = USER_COPY_SIZE;
- else
- size = len - n;
-
- if (copy_from_user(kbuf, tmp, size)) {
- kfree(kbuf);
- return n ? n : -EFAULT;
- }
-
- pti_write_to_aperture(mc, kbuf, size);
- n += size;
- tmp += size;
-
- } while (len > n);
-
- kfree(kbuf);
- return len;
-}
-
-static const struct tty_operations pti_tty_driver_ops = {
- .open = pti_tty_driver_open,
- .close = pti_tty_driver_close,
- .write = pti_tty_driver_write,
- .write_room = pti_tty_write_room,
- .install = pti_tty_install,
- .cleanup = pti_tty_cleanup
-};
-
-static const struct file_operations pti_char_driver_ops = {
- .owner = THIS_MODULE,
- .write = pti_char_write,
- .open = pti_char_open,
- .release = pti_char_release,
-};
-
-static struct miscdevice pti_char_driver = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = CHARNAME,
- .fops = &pti_char_driver_ops
-};
-
-/**
- * pti_console_write()- Write to the console that has been acquired.
- *
- * @c: Not used in this implementaiton.
- * @buf: Data to be written.
- * @len: Length of buf.
- */
-static void pti_console_write(struct console *c, const char *buf, unsigned len)
-{
- static struct pti_masterchannel mc = {.master = CONSOLE_ID,
- .channel = 0};
-
- mc.channel = pti_console_channel;
- pti_console_channel = (pti_console_channel + 1) & 0x7f;
-
- pti_write_full_frame_to_aperture(&mc, buf, len);
-}
-
-/**
- * pti_console_device()- Return the driver tty structure and set the
- * associated index implementation.
- *
- * @c: Console device of the driver.
- * @index: index associated with c.
- *
- * Returns:
- * always value of pti_tty_driver structure when this function
- * is called.
- */
-static struct tty_driver *pti_console_device(struct console *c, int *index)
-{
- *index = c->index;
- return pti_tty_driver;
-}
-
-/**
- * pti_console_setup()- Initialize console variables used by the driver.
- *
- * @c: Not used.
- * @opts: Not used.
- *
- * Returns:
- * always 0.
- */
-static int pti_console_setup(struct console *c, char *opts)
-{
- pti_console_channel = 0;
- pti_control_channel = 0;
- return 0;
-}
-
-/*
- * pti_console struct, used to capture OS printk()'s and shift
- * out to the PTI device for debugging. This cannot be
- * enabled upon boot because of the possibility of eating
- * any serial console printk's (race condition discovered).
- * The console should be enabled upon when the tty port is
- * used for the first time. Since the primary purpose for
- * the tty port is to hook up syslog to it, the tty port
- * will be open for a really long time.
- */
-static struct console pti_console = {
- .name = TTYNAME,
- .write = pti_console_write,
- .device = pti_console_device,
- .setup = pti_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = 0,
-};
-
-/**
- * pti_port_activate()- Used to start/initialize any items upon
- * first opening of tty_port().
- *
- * @port- The tty port number of the PTI device.
- * @tty- The tty struct associated with this device.
- *
- * Returns:
- * always returns 0
- *
- * Notes: The primary purpose of the PTI tty port 0 is to hook
- * the syslog daemon to it; thus this port will be open for a
- * very long time.
- */
-static int pti_port_activate(struct tty_port *port, struct tty_struct *tty)
-{
- if (port->tty->index == PTITTY_MINOR_START)
- console_start(&pti_console);
- return 0;
-}
-
-/**
- * pti_port_shutdown()- Used to stop/shutdown any items upon the
- * last tty port close.
- *
- * @port- The tty port number of the PTI device.
- *
- * Notes: The primary purpose of the PTI tty port 0 is to hook
- * the syslog daemon to it; thus this port will be open for a
- * very long time.
- */
-static void pti_port_shutdown(struct tty_port *port)
-{
- if (port->tty->index == PTITTY_MINOR_START)
- console_stop(&pti_console);
-}
-
-static const struct tty_port_operations tty_port_ops = {
- .activate = pti_port_activate,
- .shutdown = pti_port_shutdown,
-};
-
-/*
- * Note the _probe() call sets everything up and ties the char and tty
- * to successfully detecting the PTI device on the pci bus.
- */
-
-/**
- * pti_pci_probe()- Used to detect pti on the pci bus and set
- * things up in the driver.
- *
- * @pdev- pci_dev struct values for pti.
- * @ent- pci_device_id struct for pti driver.
- *
- * Returns:
- * 0 for success
- * otherwise, error
- */
-static int __devinit pti_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- int retval = -EINVAL;
- int pci_bar = 1;
-
- dev_dbg(&pdev->dev, "%s %s(%d): PTI PCI ID %04x:%04x\n", __FILE__,
- __func__, __LINE__, pdev->vendor, pdev->device);
-
- retval = misc_register(&pti_char_driver);
- if (retval) {
- pr_err("%s(%d): CHAR registration failed of pti driver\n",
- __func__, __LINE__);
- pr_err("%s(%d): Error value returned: %d\n",
- __func__, __LINE__, retval);
- return retval;
- }
-
- retval = pci_enable_device(pdev);
- if (retval != 0) {
- dev_err(&pdev->dev,
- "%s: pci_enable_device() returned error %d\n",
- __func__, retval);
- return retval;
- }
-
- drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
-
- if (drv_data == NULL) {
- retval = -ENOMEM;
- dev_err(&pdev->dev,
- "%s(%d): kmalloc() returned NULL memory.\n",
- __func__, __LINE__);
- return retval;
- }
- drv_data->pti_addr = pci_resource_start(pdev, pci_bar);
-
- retval = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev));
- if (retval != 0) {
- dev_err(&pdev->dev,
- "%s(%d): pci_request_region() returned error %d\n",
- __func__, __LINE__, retval);
- kfree(drv_data);
- return retval;
- }
- drv_data->aperture_base = drv_data->pti_addr+APERTURE_14;
- drv_data->pti_ioaddr =
- ioremap_nocache((u32)drv_data->aperture_base,
- APERTURE_LEN);
- if (!drv_data->pti_ioaddr) {
- pci_release_region(pdev, pci_bar);
- retval = -ENOMEM;
- kfree(drv_data);
- return retval;
- }
-
- pci_set_drvdata(pdev, drv_data);
-
- tty_port_init(&drv_data->port);
- drv_data->port.ops = &tty_port_ops;
-
- tty_register_device(pti_tty_driver, 0, &pdev->dev);
- tty_register_device(pti_tty_driver, 1, &pdev->dev);
-
- register_console(&pti_console);
-
- return retval;
-}
-
-static struct pci_driver pti_pci_driver = {
- .name = PCINAME,
- .id_table = pci_ids,
- .probe = pti_pci_probe,
- .remove = pti_pci_remove,
-};
-
-/**
- *
- * pti_init()- Overall entry/init call to the pti driver.
- * It starts the registration process with the kernel.
- *
- * Returns:
- * int __init, 0 for success
- * otherwise value is an error
- *
- */
-static int __init pti_init(void)
-{
- int retval = -EINVAL;
-
- /* First register module as tty device */
-
- pti_tty_driver = alloc_tty_driver(PTITTY_MINOR_NUM);
- if (pti_tty_driver == NULL) {
- pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n",
- __func__, __LINE__);
- return -ENOMEM;
- }
-
- pti_tty_driver->driver_name = DRIVERNAME;
- pti_tty_driver->name = TTYNAME;
- pti_tty_driver->major = 0;
- pti_tty_driver->minor_start = PTITTY_MINOR_START;
- pti_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
- pti_tty_driver->subtype = SYSTEM_TYPE_SYSCONS;
- pti_tty_driver->flags = TTY_DRIVER_REAL_RAW |
- TTY_DRIVER_DYNAMIC_DEV;
- pti_tty_driver->init_termios = tty_std_termios;
-
- tty_set_operations(pti_tty_driver, &pti_tty_driver_ops);
-
- retval = tty_register_driver(pti_tty_driver);
- if (retval) {
- pr_err("%s(%d): TTY registration failed of pti driver\n",
- __func__, __LINE__);
- pr_err("%s(%d): Error value returned: %d\n",
- __func__, __LINE__, retval);
-
- pti_tty_driver = NULL;
- return retval;
- }
-
- retval = pci_register_driver(&pti_pci_driver);
-
- if (retval) {
- pr_err("%s(%d): PCI registration failed of pti driver\n",
- __func__, __LINE__);
- pr_err("%s(%d): Error value returned: %d\n",
- __func__, __LINE__, retval);
-
- tty_unregister_driver(pti_tty_driver);
- pr_err("%s(%d): Unregistering TTY part of pti driver\n",
- __func__, __LINE__);
- pti_tty_driver = NULL;
- return retval;
- }
-
- return retval;
-}
-
-/**
- * pti_exit()- Unregisters this module as a tty and pci driver.
- */
-static void __exit pti_exit(void)
-{
- int retval;
-
- tty_unregister_device(pti_tty_driver, 0);
- tty_unregister_device(pti_tty_driver, 1);
-
- retval = tty_unregister_driver(pti_tty_driver);
- if (retval) {
- pr_err("%s(%d): TTY unregistration failed of pti driver\n",
- __func__, __LINE__);
- pr_err("%s(%d): Error value returned: %d\n",
- __func__, __LINE__, retval);
- }
-
- pci_unregister_driver(&pti_pci_driver);
-
- retval = misc_deregister(&pti_char_driver);
- if (retval) {
- pr_err("%s(%d): CHAR unregistration failed of pti driver\n",
- __func__, __LINE__);
- pr_err("%s(%d): Error value returned: %d\n",
- __func__, __LINE__, retval);
- }
-
- unregister_console(&pti_console);
- return;
-}
-
-module_init(pti_init);
-module_exit(pti_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ken Mills, Jay Freyensee");
-MODULE_DESCRIPTION("PTI Driver");
-
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/Kconfig b/ANDROID_3.4.5/drivers/misc/rsa/Kconfig
deleted file mode 100755
index 30039d81..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-menu "WMT RSA "
-config WMT_RSA
- tristate "RSA"
- help
- This enables the RSA decode/encode
-endmenu
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/Makefile b/ANDROID_3.4.5/drivers/misc/rsa/Makefile
deleted file mode 100755
index be017d93..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Makefile for rsa drivers.
-#
-
-#obj-$(CONFIG_WMT_RSA) += bignum.o rsa_verify.o
-
-obj-y += bignum.o rsa_verify.o
-
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/asn1.h b/ANDROID_3.4.5/drivers/misc/rsa/asn1.h
deleted file mode 100755
index 20ced912..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/asn1.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/**
- * \file asn1.h
- *
- * \brief Generic ASN.1 parsing
- *
- * Copyright (C) 2006-2011, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef POLARSSL_ASN1_H
-#define POLARSSL_ASN1_H
-
-//#include "config.h"
-
-//#if defined(POLARSSL_BIGNUM_C)
-#include "bignum.h"
-//#endif
-
-//#include <string.h>
-
-/**
- * \addtogroup asn1_module
- * \{
- */
-
-/**
- * \name ASN1 Error codes
- * These error codes are OR'ed to X509 error codes for
- * higher error granularity.
- * ASN1 is a standard to specify data structures.
- * \{
- */
-#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0014 /**< Out of data when parsing an ASN1 data structure. */
-#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0016 /**< ASN1 tag was of an unexpected value. */
-#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0018 /**< Error when trying to determine the length or invalid length. */
-#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x001A /**< Actual length differs from expected length. */
-#define POLARSSL_ERR_ASN1_INVALID_DATA -0x001C /**< Data is invalid. (not used) */
-#define POLARSSL_ERR_ASN1_MALLOC_FAILED -0x001E /**< Memory allocation failed */
-/* \} name */
-
-/**
- * \name DER constants
- * These constants comply with DER encoded the ANS1 type tags.
- * DER encoding uses hexadecimal representation.
- * An example DER sequence is:\n
- * - 0x02 -- tag indicating INTEGER
- * - 0x01 -- length in octets
- * - 0x05 -- value
- * Such sequences are typically read into \c ::x509_buf.
- * \{
- */
-#define ASN1_BOOLEAN 0x01
-#define ASN1_INTEGER 0x02
-#define ASN1_BIT_STRING 0x03
-#define ASN1_OCTET_STRING 0x04
-#define ASN1_NULL 0x05
-#define ASN1_OID 0x06
-#define ASN1_UTF8_STRING 0x0C
-#define ASN1_SEQUENCE 0x10
-#define ASN1_SET 0x11
-#define ASN1_PRINTABLE_STRING 0x13
-#define ASN1_T61_STRING 0x14
-#define ASN1_IA5_STRING 0x16
-#define ASN1_UTC_TIME 0x17
-#define ASN1_GENERALIZED_TIME 0x18
-#define ASN1_UNIVERSAL_STRING 0x1C
-#define ASN1_BMP_STRING 0x1E
-#define ASN1_PRIMITIVE 0x00
-#define ASN1_CONSTRUCTED 0x20
-#define ASN1_CONTEXT_SPECIFIC 0x80
-/* \} name */
-/* \} addtogroup asn1_module */
-
-/** Returns the size of the binary string, without the trailing \\0 */
-#define OID_SIZE(x) (sizeof(x) - 1)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \name Functions to parse ASN.1 data structures
- * \{
- */
-
-/**
- * Type-length-value structure that allows for ASN1 using DER.
- */
-typedef struct _asn1_buf
-{
- int tag; /**< ASN1 type, e.g. ASN1_UTF8_STRING. */
- size_t len; /**< ASN1 length, e.g. in octets. */
- unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
-}
-asn1_buf;
-
-/**
- * Container for ASN1 bit strings.
- */
-typedef struct _asn1_bitstring
-{
- size_t len; /**< ASN1 length, e.g. in octets. */
- unsigned char unused_bits; /**< Number of unused bits at the end of the string */
- unsigned char *p; /**< Raw ASN1 data for the bit string */
-}
-asn1_bitstring;
-
-/**
- * Container for a sequence of ASN.1 items
- */
-typedef struct _asn1_sequence
-{
- asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
- struct _asn1_sequence *next; /**< The next entry in the sequence. */
-}
-asn1_sequence;
-
-/**
- * Get the length of an ASN.1 element.
- * Updates the pointer to immediately behind the length.
- *
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len The variable that will receive the value
- *
- * \return 0 if successful, POLARSSL_ERR_ASN1_OUT_OF_DATA on reaching
- * end of data, POLARSSL_ERR_ASN1_INVALID_LENGTH if length is
- * unparseable.
- */
-int asn1_get_len( unsigned char **p,
- const unsigned char *end,
- size_t *len );
-
-/**
- * Get the tag and length of the tag. Check for the requested tag.
- * Updates the pointer to immediately behind the tag and length.
- *
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len The variable that will receive the length
- * \param tag The expected tag
- *
- * \return 0 if successful, POLARSSL_ERR_ASN1_UNEXPECTED_TAG if tag did
- * not match requested tag, or another specific ASN.1 error code.
- */
-int asn1_get_tag( unsigned char **p,
- const unsigned char *end,
- size_t *len, int tag );
-
-/**
- * Retrieve a boolean ASN.1 tag and its value.
- * Updates the pointer to immediately behind the full tag.
- *
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param val The variable that will receive the value
- *
- * \return 0 if successful or a specific ASN.1 error code.
- */
-int asn1_get_bool( unsigned char **p,
- const unsigned char *end,
- int *val );
-
-/**
- * Retrieve an integer ASN.1 tag and its value.
- * Updates the pointer to immediately behind the full tag.
- *
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param val The variable that will receive the value
- *
- * \return 0 if successful or a specific ASN.1 error code.
- */
-int asn1_get_int( unsigned char **p,
- const unsigned char *end,
- int *val );
-
-/**
- * Retrieve a bitstring ASN.1 tag and its value.
- * Updates the pointer to immediately behind the full tag.
- *
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param bs The variable that will receive the value
- *
- * \return 0 if successful or a specific ASN.1 error code.
- */
-int asn1_get_bitstring( unsigned char **p, const unsigned char *end,
- asn1_bitstring *bs);
-
-/**
- * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
- * Updated the pointer to immediately behind the full sequence tag.
- *
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param cur First variable in the chain to fill
- * \param tag Type of sequence
- *
- * \return 0 if successful or a specific ASN.1 error code.
- */
-int asn1_get_sequence_of( unsigned char **p,
- const unsigned char *end,
- asn1_sequence *cur,
- int tag);
-
-#if defined(POLARSSL_BIGNUM_C)
-/**
- * Retrieve a MPI value from an integer ASN.1 tag.
- * Updates the pointer to immediately behind the full tag.
- *
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param X The MPI that will receive the value
- *
- * \return 0 if successful or a specific ASN.1 or MPI error code.
- */
-int asn1_get_mpi( unsigned char **p,
- const unsigned char *end,
- mpi *X );
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* asn1.h */
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/base64.h b/ANDROID_3.4.5/drivers/misc/rsa/base64.h
deleted file mode 100755
index 355116d7..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/base64.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * \file base64.h
- *
- * \brief RFC 1521 base64 encoding/decoding
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef POLARSSL_BASE64_H
-#define POLARSSL_BASE64_H
-
-//#include <string.h>
-
-#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
-#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Encode a buffer into base64 format
- *
- * \param dst destination buffer
- * \param dlen size of the buffer
- * \param src source buffer
- * \param slen amount of data to be encoded
- *
- * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
- * *dlen is always updated to reflect the amount
- * of data that has (or would have) been written.
- *
- * \note Call this function with *dlen = 0 to obtain the
- * required buffer size in *dlen
- */
-int base64_encode( unsigned char *dst, size_t *dlen,
- const unsigned char *src, size_t slen );
-
-/**
- * \brief Decode a base64-formatted buffer
- *
- * \param dst destination buffer
- * \param dlen size of the buffer
- * \param src source buffer
- * \param slen amount of data to be decoded
- *
- * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
- * POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not
- * correct. *dlen is always updated to reflect the amount
- * of data that has (or would have) been written.
- *
- * \note Call this function with *dlen = 0 to obtain the
- * required buffer size in *dlen
- */
-int base64_decode( unsigned char *dst, size_t *dlen,
- const unsigned char *src, size_t slen );
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int base64_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* base64.h */
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/bignum.c b/ANDROID_3.4.5/drivers/misc/rsa/bignum.c
deleted file mode 100755
index 01809e11..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/bignum.c
+++ /dev/null
@@ -1,2132 +0,0 @@
-/*
- * Multi-precision integer library
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/*
- * This MPI implementation is based on:
- *
- * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
- * http://www.stillhq.com/extracted/gnupg-api/mpi/
- * http://math.libtomcrypt.com/files/tommath.pdf
- */
-
-//#include "polarssl/config.h"
-
-#if 1
-
-//#include "polarssl/bn_mul.h"
-#include "bignum.h"
-#include "dhm.h"
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-#include <linux/backing-dev.h>
-#include <linux/compat.h>
-#include <linux/mount.h>
-#include <linux/blkpg.h>
-
-#include <linux/vmalloc.h>
-#include <asm/uaccess.h>
-
-#include <linux/types.h>
-#include <linux/moduleparam.h>
-#include <linux/delay.h>
-#include <mach/hardware.h>
-
-#define ciL (sizeof(t_uint)) /* chars in limb */
-#define biL (ciL << 3) /* bits in limb */
-#define biH (ciL << 2) /* half limb size */
-
-/*
- * Convert between bits/chars and number of limbs
- */
-#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
-#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
-
-/*
- * Initialize one MPI
- */
-void mpi_init( mpi *X )
-{
- if( X == NULL )
- return;
-
- X->s = 1;
- X->n = 0;
- X->p = NULL;
-}
-
-/*
- * Unallocate one MPI
- */
-void mpi_free( mpi *X )
-{
- if( X == NULL )
- return;
-
- if( X->p != NULL )
- {
- memset( X->p, 0, X->n * ciL );
- vfree( X->p );
- }
-
- X->s = 1;
- X->n = 0;
- X->p = NULL;
-}
-
-/*
- * Enlarge to the specified number of limbs
- */
-int mpi_grow( mpi *X, size_t nblimbs )
-{
- t_uint *p;
-
- if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
- return( POLARSSL_ERR_MPI_MALLOC_FAILED );
-
- if( X->n < nblimbs )
- {
- if( ( p = (t_uint *) vmalloc( nblimbs * ciL ) ) == NULL )
- return( POLARSSL_ERR_MPI_MALLOC_FAILED );
-
- memset( p, 0, nblimbs * ciL );
-
- if( X->p != NULL )
- {
- memcpy( p, X->p, X->n * ciL );
- memset( X->p, 0, X->n * ciL );
- vfree( X->p );
- }
-
- X->n = nblimbs;
- X->p = p;
- }
-
- return( 0 );
-}
-
-/*
- * Copy the contents of Y into X
- */
-int mpi_copy( mpi *X, const mpi *Y )
-{
- int ret;
- size_t i;
-
- if( X == Y )
- return( 0 );
-
- for( i = Y->n - 1; i > 0; i-- )
- if( Y->p[i] != 0 )
- break;
- i++;
-
- X->s = Y->s;
-
- MPI_CHK( mpi_grow( X, i ) );
-
- memset( X->p, 0, X->n * ciL );
- memcpy( X->p, Y->p, i * ciL );
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Swap the contents of X and Y
- */
-void mpi_swap( mpi *X, mpi *Y )
-{
- mpi T;
-
- memcpy( &T, X, sizeof( mpi ) );
- memcpy( X, Y, sizeof( mpi ) );
- memcpy( Y, &T, sizeof( mpi ) );
-}
-
-/*
- * Set value from integer
- */
-int mpi_lset( mpi *X, t_sint z )
-{
- int ret;
-
- MPI_CHK( mpi_grow( X, 1 ) );
- memset( X->p, 0, X->n * ciL );
-
- X->p[0] = ( z < 0 ) ? -z : z;
- X->s = ( z < 0 ) ? -1 : 1;
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Get a specific bit
- */
-int mpi_get_bit( mpi *X, size_t pos )
-{
- if( X->n * biL <= pos )
- return( 0 );
-
- return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01;
-}
-
-/*
- * Set a bit to a specific value of 0 or 1
- */
-int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
-{
- int ret = 0;
- size_t off = pos / biL;
- size_t idx = pos % biL;
-
- if( val != 0 && val != 1 )
- return POLARSSL_ERR_MPI_BAD_INPUT_DATA;
-
- if( X->n * biL <= pos )
- {
- if( val == 0 )
- return ( 0 );
-
- MPI_CHK( mpi_grow( X, off + 1 ) );
- }
-
- X->p[off] = ( X->p[off] & ~( 0x01 << idx ) ) | ( val << idx );
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Return the number of least significant bits
- */
-size_t mpi_lsb( const mpi *X )
-{
- size_t i, j, count = 0;
-
- for( i = 0; i < X->n; i++ )
- for( j = 0; j < biL; j++, count++ )
- if( ( ( X->p[i] >> j ) & 1 ) != 0 )
- return( count );
-
- return( 0 );
-}
-
-/*
- * Return the number of most significant bits
- */
-size_t mpi_msb( const mpi *X )
-{
- size_t i, j;
-
- for( i = X->n - 1; i > 0; i-- )
- if( X->p[i] != 0 )
- break;
-
- for( j = biL; j > 0; j-- )
- if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
- break;
-
- return( ( i * biL ) + j );
-}
-
-/*
- * Return the total size in bytes
- */
-size_t mpi_size( const mpi *X )
-{
- return( ( mpi_msb( X ) + 7 ) >> 3 );
-}
-
-/*
- * Convert an ASCII character to digit value
- */
-static int mpi_get_digit( t_uint *d, int radix, char c )
-{
- *d = 255;
-
- if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
- if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
- if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
-
- if( *d >= (t_uint) radix )
- return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
-
- return( 0 );
-}
-
-/*
- * Import from an ASCII string
- */
-int mpi_read_string( mpi *X, int radix, const char *s )
-{
- int ret;
- size_t i, j, slen, n;
- t_uint d;
- mpi T;
-
- if( radix < 2 || radix > 16 )
- return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
-
- mpi_init( &T );
-
- slen = strlen( s );
-
- if( radix == 16 )
- {
- n = BITS_TO_LIMBS( slen << 2 );
-
- MPI_CHK( mpi_grow( X, n ) );
- MPI_CHK( mpi_lset( X, 0 ) );
-
- for( i = slen, j = 0; i > 0; i--, j++ )
- {
- if( i == 1 && s[i - 1] == '-' )
- {
- X->s = -1;
- break;
- }
-
- MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
- X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
- }
- }
- else
- {
- MPI_CHK( mpi_lset( X, 0 ) );
-
- for( i = 0; i < slen; i++ )
- {
- if( i == 0 && s[i] == '-' )
- {
- X->s = -1;
- continue;
- }
-
- MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
- MPI_CHK( mpi_mul_int( &T, X, radix ) );
-
- if( X->s == 1 )
- {
- MPI_CHK( mpi_add_int( X, &T, d ) );
- }
- else
- {
- MPI_CHK( mpi_sub_int( X, &T, d ) );
- }
- }
- }
-
-cleanup:
-
- mpi_free( &T );
-
- return( ret );
-}
-
-/*
- * Helper to write the digits high-order first
- */
-static int mpi_write_hlp( mpi *X, int radix, char **p )
-{
- int ret;
- t_uint r;
-
- if( radix < 2 || radix > 16 )
- return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
-
- MPI_CHK( mpi_mod_int( &r, X, radix ) );
- MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
-
- if( mpi_cmp_int( X, 0 ) != 0 )
- MPI_CHK( mpi_write_hlp( X, radix, p ) );
-
- if( r < 10 )
- *(*p)++ = (char)( r + 0x30 );
- else
- *(*p)++ = (char)( r + 0x37 );
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Export into an ASCII string
- */
-int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
-{
- int ret = 0;
- size_t n;
- char *p;
- mpi T;
-
- if( radix < 2 || radix > 16 )
- return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
-
- n = mpi_msb( X );
- if( radix >= 4 ) n >>= 1;
- if( radix >= 16 ) n >>= 1;
- n += 3;
-
- if( *slen < n )
- {
- *slen = n;
- return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
- }
-
- p = s;
- mpi_init( &T );
-
- if( X->s == -1 )
- *p++ = '-';
-
- if( radix == 16 )
- {
- int c;
- size_t i, j, k;
-
- for( i = X->n, k = 0; i > 0; i-- )
- {
- for( j = ciL; j > 0; j-- )
- {
- c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
-
- if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
- continue;
-
- p += sprintf( p, "%02X", c );
- k = 1;
- }
- }
- }
- else
- {
- MPI_CHK( mpi_copy( &T, X ) );
-
- if( T.s == -1 )
- T.s = 1;
-
- MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
- }
-
- *p++ = '\0';
- *slen = p - s;
-
-cleanup:
-
- mpi_free( &T );
-
- return( ret );
-}
-
-#if defined(POLARSSL_FS_IO)
-/*
- * Read X from an opened file
- */
-int mpi_read_file( mpi *X, int radix, FILE *fin )
-{
- t_uint d;
- size_t slen;
- char *p;
- /*
- * Buffer should have space for (short) label and decimal formatted MPI,
- * newline characters and '\0'
- */
- char s[ POLARSSL_MPI_READ_BUFFER_SIZE ];
-
- memset( s, 0, sizeof( s ) );
- if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
- return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
-
- slen = strlen( s );
- if( slen == sizeof( s ) - 2 )
- return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
-
- if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
- if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
-
- p = s + slen;
- while( --p >= s )
- if( mpi_get_digit( &d, radix, *p ) != 0 )
- break;
-
- return( mpi_read_string( X, radix, p + 1 ) );
-}
-
-/*
- * Write X into an opened file (or stdout if fout == NULL)
- */
-int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
-{
- int ret;
- size_t n, slen, plen;
- /*
- * Buffer should have space for minus sign, hexified MPI and '\0'
- */
- char s[ 2 * POLARSSL_MPI_MAX_SIZE + 2 ];
-
- n = sizeof( s );
- memset( s, 0, n );
- n -= 2;
-
- MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
-
- if( p == NULL ) p = "";
-
- plen = strlen( p );
- slen = strlen( s );
- s[slen++] = '\r';
- s[slen++] = '\n';
-
- if( fout != NULL )
- {
- if( fwrite( p, 1, plen, fout ) != plen ||
- fwrite( s, 1, slen, fout ) != slen )
- return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
- }
- else
- printf( "%s%s", p, s );
-
-cleanup:
-
- return( ret );
-}
-#endif /* POLARSSL_FS_IO */
-
-/*
- * Import X from unsigned binary data, big endian
- */
-int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
-{
- int ret;
- size_t i, j, n;
-
- for( n = 0; n < buflen; n++ )
- if( buf[n] != 0 )
- break;
-
- MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
- MPI_CHK( mpi_lset( X, 0 ) );
-
- for( i = buflen, j = 0; i > n; i--, j++ )
- X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Export X into unsigned binary data, big endian
- */
-int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
-{
- size_t i, j, n;
-
- n = mpi_size( X );
-
- if( buflen < n )
- return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
-
- memset( buf, 0, buflen );
-
- for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
- buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
-
- return( 0 );
-}
-
-/*
- * Left-shift: X <<= count
- */
-int mpi_shift_l( mpi *X, size_t count )
-{
- int ret;
- size_t i, v0, t1;
- t_uint r0 = 0, r1;
-
- v0 = count / (biL );
- t1 = count & (biL - 1);
-
- i = mpi_msb( X ) + count;
-
- if( X->n * biL < i )
- MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
-
- ret = 0;
-
- /*
- * shift by count / limb_size
- */
- if( v0 > 0 )
- {
- for( i = X->n; i > v0; i-- )
- X->p[i - 1] = X->p[i - v0 - 1];
-
- for( ; i > 0; i-- )
- X->p[i - 1] = 0;
- }
-
- /*
- * shift by count % limb_size
- */
- if( t1 > 0 )
- {
- for( i = v0; i < X->n; i++ )
- {
- r1 = X->p[i] >> (biL - t1);
- X->p[i] <<= t1;
- X->p[i] |= r0;
- r0 = r1;
- }
- }
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Right-shift: X >>= count
- */
-int mpi_shift_r( mpi *X, size_t count )
-{
- size_t i, v0, v1;
- t_uint r0 = 0, r1;
-
- v0 = count / biL;
- v1 = count & (biL - 1);
-
- /*
- * shift by count / limb_size
- */
- if( v0 > 0 )
- {
- for( i = 0; i < X->n - v0; i++ )
- X->p[i] = X->p[i + v0];
-
- for( ; i < X->n; i++ )
- X->p[i] = 0;
- }
-
- /*
- * shift by count % limb_size
- */
- if( v1 > 0 )
- {
- for( i = X->n; i > 0; i-- )
- {
- r1 = X->p[i - 1] << (biL - v1);
- X->p[i - 1] >>= v1;
- X->p[i - 1] |= r0;
- r0 = r1;
- }
- }
-
- return( 0 );
-}
-
-/*
- * Compare unsigned values
- */
-int mpi_cmp_abs( const mpi *X, const mpi *Y )
-{
- size_t i, j;
-
- for( i = X->n; i > 0; i-- )
- if( X->p[i - 1] != 0 )
- break;
-
- for( j = Y->n; j > 0; j-- )
- if( Y->p[j - 1] != 0 )
- break;
-
- if( i == 0 && j == 0 )
- return( 0 );
-
- if( i > j ) return( 1 );
- if( j > i ) return( -1 );
-
- for( ; i > 0; i-- )
- {
- if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
- if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
- }
-
- return( 0 );
-}
-
-/*
- * Compare signed values
- */
-int mpi_cmp_mpi( const mpi *X, const mpi *Y )
-{
- size_t i, j;
-
- for( i = X->n; i > 0; i-- )
- if( X->p[i - 1] != 0 )
- break;
-
- for( j = Y->n; j > 0; j-- )
- if( Y->p[j - 1] != 0 )
- break;
-
- if( i == 0 && j == 0 )
- return( 0 );
-
- if( i > j ) return( X->s );
- if( j > i ) return( -Y->s );
-
- if( X->s > 0 && Y->s < 0 ) return( 1 );
- if( Y->s > 0 && X->s < 0 ) return( -1 );
-
- for( ; i > 0; i-- )
- {
- if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
- if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
- }
-
- return( 0 );
-}
-
-/*
- * Compare signed values
- */
-int mpi_cmp_int( const mpi *X, t_sint z )
-{
- mpi Y;
- t_uint p[1];
-
- *p = ( z < 0 ) ? -z : z;
- Y.s = ( z < 0 ) ? -1 : 1;
- Y.n = 1;
- Y.p = p;
-
- return( mpi_cmp_mpi( X, &Y ) );
-}
-
-/*
- * Unsigned addition: X = |A| + |B| (HAC 14.7)
- */
-int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
-{
- int ret;
- size_t i, j;
- t_uint *o, *p, c;
-
- if( X == B )
- {
- const mpi *T = A; A = X; B = T;
- }
-
- if( X != A )
- MPI_CHK( mpi_copy( X, A ) );
-
- /*
- * X should always be positive as a result of unsigned additions.
- */
- X->s = 1;
-
- for( j = B->n; j > 0; j-- )
- if( B->p[j - 1] != 0 )
- break;
-
- MPI_CHK( mpi_grow( X, j ) );
-
- o = B->p; p = X->p; c = 0;
-
- for( i = 0; i < j; i++, o++, p++ )
- {
- *p += c; c = ( *p < c );
- *p += *o; c += ( *p < *o );
- }
-
- while( c != 0 )
- {
- if( i >= X->n )
- {
- MPI_CHK( mpi_grow( X, i + 1 ) );
- p = X->p + i;
- }
-
- *p += c; c = ( *p < c ); i++;
- }
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Helper for mpi substraction
- */
-static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
-{
- size_t i;
- t_uint c, z;
-
- for( i = c = 0; i < n; i++, s++, d++ )
- {
- z = ( *d < c ); *d -= c;
- c = ( *d < *s ) + z; *d -= *s;
- }
-
- while( c != 0 )
- {
- z = ( *d < c ); *d -= c;
- c = z; i++; d++;
- }
-}
-
-/*
- * Unsigned substraction: X = |A| - |B| (HAC 14.9)
- */
-int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
-{
- mpi TB;
- int ret;
- size_t n;
-
- if( mpi_cmp_abs( A, B ) < 0 )
- return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
-
- mpi_init( &TB );
-
- if( X == B )
- {
- MPI_CHK( mpi_copy( &TB, B ) );
- B = &TB;
- }
-
- if( X != A )
- MPI_CHK( mpi_copy( X, A ) );
-
- /*
- * X should always be positive as a result of unsigned substractions.
- */
- X->s = 1;
-
- ret = 0;
-
- for( n = B->n; n > 0; n-- )
- if( B->p[n - 1] != 0 )
- break;
-
- mpi_sub_hlp( n, B->p, X->p );
-
-cleanup:
-
- mpi_free( &TB );
-
- return( ret );
-}
-
-/*
- * Signed addition: X = A + B
- */
-int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
-{
- int ret, s = A->s;
-
- if( A->s * B->s < 0 )
- {
- if( mpi_cmp_abs( A, B ) >= 0 )
- {
- MPI_CHK( mpi_sub_abs( X, A, B ) );
- X->s = s;
- }
- else
- {
- MPI_CHK( mpi_sub_abs( X, B, A ) );
- X->s = -s;
- }
- }
- else
- {
- MPI_CHK( mpi_add_abs( X, A, B ) );
- X->s = s;
- }
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Signed substraction: X = A - B
- */
-int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
-{
- int ret, s = A->s;
-
- if( A->s * B->s > 0 )
- {
- if( mpi_cmp_abs( A, B ) >= 0 )
- {
- MPI_CHK( mpi_sub_abs( X, A, B ) );
- X->s = s;
- }
- else
- {
- MPI_CHK( mpi_sub_abs( X, B, A ) );
- X->s = -s;
- }
- }
- else
- {
- MPI_CHK( mpi_add_abs( X, A, B ) );
- X->s = s;
- }
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Signed addition: X = A + b
- */
-int mpi_add_int( mpi *X, const mpi *A, t_sint b )
-{
- mpi _B;
- t_uint p[1];
-
- p[0] = ( b < 0 ) ? -b : b;
- _B.s = ( b < 0 ) ? -1 : 1;
- _B.n = 1;
- _B.p = p;
-
- return( mpi_add_mpi( X, A, &_B ) );
-}
-
-/*
- * Signed substraction: X = A - b
- */
-int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
-{
- mpi _B;
- t_uint p[1];
-
- p[0] = ( b < 0 ) ? -b : b;
- _B.s = ( b < 0 ) ? -1 : 1;
- _B.n = 1;
- _B.p = p;
-
- return( mpi_sub_mpi( X, A, &_B ) );
-}
-
-/*
- * Helper for mpi multiplication
- */
-static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
-{
- t_uint c = 0, t = 0;
-
-#if defined(MULADDC_HUIT)
- for( ; i >= 8; i -= 8 )
- {
- MULADDC_INIT
- MULADDC_HUIT
- MULADDC_STOP
- }
-
- for( ; i > 0; i-- )
- {
- MULADDC_INIT
- MULADDC_CORE
- MULADDC_STOP
- }
-#else
- for( ; i >= 16; i -= 16 )
- {
- MULADDC_INIT
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
-
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_STOP
- }
-
- for( ; i >= 8; i -= 8 )
- {
- MULADDC_INIT
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
-
- MULADDC_CORE MULADDC_CORE
- MULADDC_CORE MULADDC_CORE
- MULADDC_STOP
- }
-
- for( ; i > 0; i-- )
- {
- MULADDC_INIT
- MULADDC_CORE
- MULADDC_STOP
- }
-#endif
-
- t++;
-
- do {
- *d += c; c = ( *d < c ); d++;
- }
- while( c != 0 );
-}
-//mpi TA, TB;
-/*
- * Baseline multiplication: X = A * B (HAC 14.12)
- */
-int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
-{
- int ret;
- size_t i, j;
- mpi TDA, TB;
-
- mpi_init( &TDA ); mpi_init( &TB );
-
- if( X == A ) { MPI_CHK( mpi_copy( &TDA, A ) ); A = &TDA; }
- if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
-
- for( i = A->n; i > 0; i-- )
- if( A->p[i - 1] != 0 )
- break;
-
- for( j = B->n; j > 0; j-- )
- if( B->p[j - 1] != 0 )
- break;
-
- MPI_CHK( mpi_grow( X, i + j ) );
- MPI_CHK( mpi_lset( X, 0 ) );
-
- for( i++; j > 0; j-- )
- mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
-
- X->s = A->s * B->s;
-
-cleanup:
-
- mpi_free( &TB ); mpi_free( &TDA );
-
- return( ret );
-}
-
-/*
- * Baseline multiplication: X = A * b
- */
-int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
-{
- mpi _B;
- t_uint p[1];
-
- _B.s = 1;
- _B.n = 1;
- _B.p = p;
- p[0] = b;
-
- return( mpi_mul_mpi( X, A, &_B ) );
-}
-
-/*
- * Division by mpi: A = Q * B + R (HAC 14.20)
- */
-int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
-{
- int ret;
- size_t i, n, t, k;
- mpi X, Y, Z, T1, T2;
-
- if( mpi_cmp_int( B, 0 ) == 0 )
- return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
-
- mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
- mpi_init( &T1 ); mpi_init( &T2 );
-
- if( mpi_cmp_abs( A, B ) < 0 )
- {
- if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
- if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
- return( 0 );
- }
-
- MPI_CHK( mpi_copy( &X, A ) );
- MPI_CHK( mpi_copy( &Y, B ) );
- X.s = Y.s = 1;
-
- MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
- MPI_CHK( mpi_lset( &Z, 0 ) );
- MPI_CHK( mpi_grow( &T1, 2 ) );
- MPI_CHK( mpi_grow( &T2, 3 ) );
-
- k = mpi_msb( &Y ) % biL;
- if( k < biL - 1 )
- {
- k = biL - 1 - k;
- MPI_CHK( mpi_shift_l( &X, k ) );
- MPI_CHK( mpi_shift_l( &Y, k ) );
- }
- else k = 0;
-
- n = X.n - 1;
- t = Y.n - 1;
- mpi_shift_l( &Y, biL * (n - t) );
-
- while( mpi_cmp_mpi( &X, &Y ) >= 0 )
- {
- Z.p[n - t]++;
- mpi_sub_mpi( &X, &X, &Y );
- }
- mpi_shift_r( &Y, biL * (n - t) );
-
- for( i = n; i > t ; i-- )
- {
- if( X.p[i] >= Y.p[t] )
- Z.p[i - t - 1] = ~0;
- else
- {
-#if defined(POLARSSL_HAVE_LONGLONG)
- t_udbl r;
-
- r = (t_udbl) X.p[i] << biL;
- r |= (t_udbl) X.p[i - 1];
- r /= Y.p[t];
- if( r > ((t_udbl) 1 << biL) - 1)
- r = ((t_udbl) 1 << biL) - 1;
-
- Z.p[i - t - 1] = (t_uint) r;
-#else
- /*
- * __udiv_qrnnd_c, from gmp/longlong.h
- */
- t_uint q0, q1, r0, r1;
- t_uint d0, d1, d, m;
-
- d = Y.p[t];
- d0 = ( d << biH ) >> biH;
- d1 = ( d >> biH );
-
- q1 = X.p[i] / d1;
- r1 = X.p[i] - d1 * q1;
- r1 <<= biH;
- r1 |= ( X.p[i - 1] >> biH );
-
- m = q1 * d0;
- if( r1 < m )
- {
- q1--, r1 += d;
- while( r1 >= d && r1 < m )
- q1--, r1 += d;
- }
- r1 -= m;
-
- q0 = r1 / d1;
- r0 = r1 - d1 * q0;
- r0 <<= biH;
- r0 |= ( X.p[i - 1] << biH ) >> biH;
-
- m = q0 * d0;
- if( r0 < m )
- {
- q0--, r0 += d;
- while( r0 >= d && r0 < m )
- q0--, r0 += d;
- }
- r0 -= m;
-
- Z.p[i - t - 1] = ( q1 << biH ) | q0;
-#endif
- }
-
- Z.p[i - t - 1]++;
- do
- {
- Z.p[i - t - 1]--;
-
- MPI_CHK( mpi_lset( &T1, 0 ) );
- T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
- T1.p[1] = Y.p[t];
- MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
-
- MPI_CHK( mpi_lset( &T2, 0 ) );
- T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
- T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
- T2.p[2] = X.p[i];
- }
- while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
-
- MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
- MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
- MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
-
- if( mpi_cmp_int( &X, 0 ) < 0 )
- {
- MPI_CHK( mpi_copy( &T1, &Y ) );
- MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
- MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
- Z.p[i - t - 1]--;
- }
- }
-
- if( Q != NULL )
- {
- mpi_copy( Q, &Z );
- Q->s = A->s * B->s;
- }
-
- if( R != NULL )
- {
- mpi_shift_r( &X, k );
- mpi_copy( R, &X );
-
- R->s = A->s;
- if( mpi_cmp_int( R, 0 ) == 0 )
- R->s = 1;
- }
-
-cleanup:
-
- mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
- mpi_free( &T1 ); mpi_free( &T2 );
-
- return( ret );
-}
-
-/*
- * Division by int: A = Q * b + R
- *
- * Returns 0 if successful
- * 1 if memory allocation failed
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
- */
-int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
-{
- mpi _B;
- t_uint p[1];
-
- p[0] = ( b < 0 ) ? -b : b;
- _B.s = ( b < 0 ) ? -1 : 1;
- _B.n = 1;
- _B.p = p;
-
- return( mpi_div_mpi( Q, R, A, &_B ) );
-}
-
-/*
- * Modulo: R = A mod B
- */
-int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
-{
- int ret;
-
- if( mpi_cmp_int( B, 0 ) < 0 )
- return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
-
- MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
-
- while( mpi_cmp_int( R, 0 ) < 0 )
- MPI_CHK( mpi_add_mpi( R, R, B ) );
-
- while( mpi_cmp_mpi( R, B ) >= 0 )
- MPI_CHK( mpi_sub_mpi( R, R, B ) );
-
-cleanup:
-
- return( ret );
-}
-
-/*
- * Modulo: r = A mod b
- */
-int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
-{
- size_t i;
- t_uint x, y, z;
-
- if( b == 0 )
- return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
-
- if( b < 0 )
- return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
-
- /*
- * handle trivial cases
- */
- if( b == 1 )
- {
- *r = 0;
- return( 0 );
- }
-
- if( b == 2 )
- {
- *r = A->p[0] & 1;
- return( 0 );
- }
-
- /*
- * general case
- */
- for( i = A->n, y = 0; i > 0; i-- )
- {
- x = A->p[i - 1];
- y = ( y << biH ) | ( x >> biH );
- z = y / b;
- y -= z * b;
-
- x <<= biH;
- y = ( y << biH ) | ( x >> biH );
- z = y / b;
- y -= z * b;
- }
-
- /*
- * If A is negative, then the current y represents a negative value.
- * Flipping it to the positive side.
- */
- if( A->s < 0 && y != 0 )
- y = b - y;
-
- *r = y;
-
- return( 0 );
-}
-
-/*
- * Fast Montgomery initialization (thanks to Tom St Denis)
- */
-static void mpi_montg_init( t_uint *mm, const mpi *N )
-{
- t_uint x, m0 = N->p[0];
-
- x = m0;
- x += ( ( m0 + 2 ) & 4 ) << 1;
- x *= ( 2 - ( m0 * x ) );
-
- if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
- if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
- if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
-
- *mm = ~x + 1;
-}
-
-/*
- * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
- */
-static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
-{
- size_t i, n, m;
- t_uint u0, u1, *d;
-
- memset( T->p, 0, T->n * ciL );
-
- d = T->p;
- n = N->n;
- m = ( B->n < n ) ? B->n : n;
-
- for( i = 0; i < n; i++ )
- {
- /*
- * T = (T + u0*B + u1*N) / 2^biL
- */
- u0 = A->p[i];
- u1 = ( d[0] + u0 * B->p[0] ) * mm;
-
- mpi_mul_hlp( m, B->p, d, u0 );
- mpi_mul_hlp( n, N->p, d, u1 );
-
- *d++ = u0; d[n + 1] = 0;
- }
-
- memcpy( A->p, d, (n + 1) * ciL );
-
- if( mpi_cmp_abs( A, N ) >= 0 )
- mpi_sub_hlp( n, N->p, A->p );
- else
- /* prevent timing attacks */
- mpi_sub_hlp( n, A->p, T->p );
-}
-
-/*
- * Montgomery reduction: A = A * R^-1 mod N
- */
-static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
-{
- t_uint z = 1;
- mpi U;
-
- U.n = U.s = z;
- U.p = &z;
-
- mpi_montmul( A, &U, N, mm, T );
-}
-
-/*
- * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
- */
-int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
-{
- int ret;
- size_t wbits, wsize, one = 1;
- size_t i, j, nblimbs;
- size_t bufsize, nbits;
- t_uint ei, mm, state;
- mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ];
-
- if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
- return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
-
- /*
- * Init temps and window size
- */
- mpi_montg_init( &mm, N );
- mpi_init( &RR ); mpi_init( &T );
- memset( W, 0, sizeof( W ) );
-
- i = mpi_msb( E );
-
- wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
- ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
-
- if( wsize > POLARSSL_MPI_WINDOW_SIZE )
- wsize = POLARSSL_MPI_WINDOW_SIZE;
-
- j = N->n + 1;
- MPI_CHK( mpi_grow( X, j ) );
- MPI_CHK( mpi_grow( &W[1], j ) );
- MPI_CHK( mpi_grow( &T, j * 2 ) );
-
- /*
- * If 1st call, pre-compute R^2 mod N
- */
- if( _RR == NULL || _RR->p == NULL )
- {
- MPI_CHK( mpi_lset( &RR, 1 ) );
- MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
- MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
-
- if( _RR != NULL )
- memcpy( _RR, &RR, sizeof( mpi ) );
- }
- else
- memcpy( &RR, _RR, sizeof( mpi ) );
-
- /*
- * W[1] = A * R^2 * R^-1 mod N = A * R mod N
- */
- if( mpi_cmp_mpi( A, N ) >= 0 )
- mpi_mod_mpi( &W[1], A, N );
- else mpi_copy( &W[1], A );
-
- mpi_montmul( &W[1], &RR, N, mm, &T );
-
- /*
- * X = R^2 * R^-1 mod N = R mod N
- */
- MPI_CHK( mpi_copy( X, &RR ) );
- mpi_montred( X, N, mm, &T );
-
- if( wsize > 1 )
- {
- /*
- * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
- */
- j = one << (wsize - 1);
-
- MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
- MPI_CHK( mpi_copy( &W[j], &W[1] ) );
-
- for( i = 0; i < wsize - 1; i++ )
- mpi_montmul( &W[j], &W[j], N, mm, &T );
-
- /*
- * W[i] = W[i - 1] * W[1]
- */
- for( i = j + 1; i < (one << wsize); i++ )
- {
- MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
- MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
-
- mpi_montmul( &W[i], &W[1], N, mm, &T );
- }
- }
-
- nblimbs = E->n;
- bufsize = 0;
- nbits = 0;
- wbits = 0;
- state = 0;
-
- while( 1 )
- {
- if( bufsize == 0 )
- {
- if( nblimbs-- == 0 )
- break;
-
- bufsize = sizeof( t_uint ) << 3;
- }
-
- bufsize--;
-
- ei = (E->p[nblimbs] >> bufsize) & 1;
-
- /*
- * skip leading 0s
- */
- if( ei == 0 && state == 0 )
- continue;
-
- if( ei == 0 && state == 1 )
- {
- /*
- * out of window, square X
- */
- mpi_montmul( X, X, N, mm, &T );
- continue;
- }
-
- /*
- * add ei to current window
- */
- state = 2;
-
- nbits++;
- wbits |= (ei << (wsize - nbits));
-
- if( nbits == wsize )
- {
- /*
- * X = X^wsize R^-1 mod N
- */
- for( i = 0; i < wsize; i++ )
- mpi_montmul( X, X, N, mm, &T );
-
- /*
- * X = X * W[wbits] R^-1 mod N
- */
- mpi_montmul( X, &W[wbits], N, mm, &T );
-
- state--;
- nbits = 0;
- wbits = 0;
- }
- }
-
- /*
- * process the remaining bits
- */
- for( i = 0; i < nbits; i++ )
- {
- mpi_montmul( X, X, N, mm, &T );
-
- wbits <<= 1;
-
- if( (wbits & (one << wsize)) != 0 )
- mpi_montmul( X, &W[1], N, mm, &T );
- }
-
- /*
- * X = A^E * R * R^-1 mod N = A^E mod N
- */
- mpi_montred( X, N, mm, &T );
-
-cleanup:
-
- for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
- mpi_free( &W[i] );
-
- mpi_free( &W[1] ); mpi_free( &T );
-
- if( _RR == NULL )
- mpi_free( &RR );
-
- return( ret );
-}
-
-/*
- * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
- */
-int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
-{
- int ret;
- size_t lz, lzt;
- mpi TG, TDA, TB;
-
- mpi_init( &TG ); mpi_init( &TDA ); mpi_init( &TB );
-
- MPI_CHK( mpi_copy( &TDA, A ) );
- MPI_CHK( mpi_copy( &TB, B ) );
-
- lz = mpi_lsb( &TDA );
- lzt = mpi_lsb( &TB );
-
- if ( lzt < lz )
- lz = lzt;
-
- MPI_CHK( mpi_shift_r( &TDA, lz ) );
- MPI_CHK( mpi_shift_r( &TB, lz ) );
-
- TDA.s = TB.s = 1;
-
- while( mpi_cmp_int( &TDA, 0 ) != 0 )
- {
- MPI_CHK( mpi_shift_r( &TDA, mpi_lsb( &TDA ) ) );
- MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
-
- if( mpi_cmp_mpi( &TDA, &TB ) >= 0 )
- {
- MPI_CHK( mpi_sub_abs( &TDA, &TDA, &TB ) );
- MPI_CHK( mpi_shift_r( &TDA, 1 ) );
- }
- else
- {
- MPI_CHK( mpi_sub_abs( &TB, &TB, &TDA ) );
- MPI_CHK( mpi_shift_r( &TB, 1 ) );
- }
- }
-
- MPI_CHK( mpi_shift_l( &TB, lz ) );
- MPI_CHK( mpi_copy( G, &TB ) );
-
-cleanup:
-
- mpi_free( &TG ); mpi_free( &TDA ); mpi_free( &TB );
-
- return ret;
-}
-
-int mpi_fill_random( mpi *X, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
-{
- int ret;
-
- MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
- MPI_CHK( mpi_lset( X, 0 ) );
-
- MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, size ) );
-
-cleanup:
- return( ret );
-}
-
-#if defined(POLARSSL_GENPRIME)
-
-/*
- * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
- */
-int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
-{
- int ret;
- mpi G, TDA, TU, U1, U2, TB, TV, V1, V2;
-
- if( mpi_cmp_int( N, 0 ) <= 0 )
- return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
-
- mpi_init( &TDA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
- mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
- mpi_init( &V1 ); mpi_init( &V2 );
-
- MPI_CHK( mpi_gcd( &G, A, N ) );
-
- if( mpi_cmp_int( &G, 1 ) != 0 )
- {
- ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
- goto cleanup;
- }
-
- MPI_CHK( mpi_mod_mpi( &TDA, A, N ) );
- MPI_CHK( mpi_copy( &TU, &TDA ) );
- MPI_CHK( mpi_copy( &TB, N ) );
- MPI_CHK( mpi_copy( &TV, N ) );
-
- MPI_CHK( mpi_lset( &U1, 1 ) );
- MPI_CHK( mpi_lset( &U2, 0 ) );
- MPI_CHK( mpi_lset( &V1, 0 ) );
- MPI_CHK( mpi_lset( &V2, 1 ) );
-
- do
- {
- while( ( TU.p[0] & 1 ) == 0 )
- {
- MPI_CHK( mpi_shift_r( &TU, 1 ) );
-
- if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
- {
- MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
- MPI_CHK( mpi_sub_mpi( &U2, &U2, &TDA ) );
- }
-
- MPI_CHK( mpi_shift_r( &U1, 1 ) );
- MPI_CHK( mpi_shift_r( &U2, 1 ) );
- }
-
- while( ( TV.p[0] & 1 ) == 0 )
- {
- MPI_CHK( mpi_shift_r( &TV, 1 ) );
-
- if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
- {
- MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
- MPI_CHK( mpi_sub_mpi( &V2, &V2, &TDA ) );
- }
-
- MPI_CHK( mpi_shift_r( &V1, 1 ) );
- MPI_CHK( mpi_shift_r( &V2, 1 ) );
- }
-
- if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
- {
- MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
- MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
- MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
- }
- else
- {
- MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
- MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
- MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
- }
- }
- while( mpi_cmp_int( &TU, 0 ) != 0 );
-
- while( mpi_cmp_int( &V1, 0 ) < 0 )
- MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
-
- while( mpi_cmp_mpi( &V1, N ) >= 0 )
- MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
-
- MPI_CHK( mpi_copy( X, &V1 ) );
-
-cleanup:
-
- mpi_free( &TDA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
- mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
- mpi_free( &V1 ); mpi_free( &V2 );
-
- return( ret );
-}
-
-static const int small_prime[] =
-{
- 3, 5, 7, 11, 13, 17, 19, 23,
- 29, 31, 37, 41, 43, 47, 53, 59,
- 61, 67, 71, 73, 79, 83, 89, 97,
- 101, 103, 107, 109, 113, 127, 131, 137,
- 139, 149, 151, 157, 163, 167, 173, 179,
- 181, 191, 193, 197, 199, 211, 223, 227,
- 229, 233, 239, 241, 251, 257, 263, 269,
- 271, 277, 281, 283, 293, 307, 311, 313,
- 317, 331, 337, 347, 349, 353, 359, 367,
- 373, 379, 383, 389, 397, 401, 409, 419,
- 421, 431, 433, 439, 443, 449, 457, 461,
- 463, 467, 479, 487, 491, 499, 503, 509,
- 521, 523, 541, 547, 557, 563, 569, 571,
- 577, 587, 593, 599, 601, 607, 613, 617,
- 619, 631, 641, 643, 647, 653, 659, 661,
- 673, 677, 683, 691, 701, 709, 719, 727,
- 733, 739, 743, 751, 757, 761, 769, 773,
- 787, 797, 809, 811, 821, 823, 827, 829,
- 839, 853, 857, 859, 863, 877, 881, 883,
- 887, 907, 911, 919, 929, 937, 941, 947,
- 953, 967, 971, 977, 983, 991, 997, -103
-};
-
-/*
- * Miller-Rabin primality test (HAC 4.24)
- */
-int mpi_is_prime( mpi *X,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
-{
- int ret, xs;
- size_t i, j, n, s;
- mpi W, R, T, A, RR;
-
- if( mpi_cmp_int( X, 0 ) == 0 ||
- mpi_cmp_int( X, 1 ) == 0 )
- return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
-
- if( mpi_cmp_int( X, 2 ) == 0 )
- return( 0 );
-
- mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
- mpi_init( &RR );
-
- xs = X->s; X->s = 1;
-
- /*
- * test trivial factors first
- */
- if( ( X->p[0] & 1 ) == 0 )
- return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
-
- for( i = 0; small_prime[i] > 0; i++ )
- {
- t_uint r;
-
- if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
- return( 0 );
-
- MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
-
- if( r == 0 )
- return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
- }
-
- /*
- * W = |X| - 1
- * R = W >> lsb( W )
- */
- MPI_CHK( mpi_sub_int( &W, X, 1 ) );
- s = mpi_lsb( &W );
- MPI_CHK( mpi_copy( &R, &W ) );
- MPI_CHK( mpi_shift_r( &R, s ) );
-
- i = mpi_msb( X );
- /*
- * HAC, table 4.4
- */
- n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
- ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
- ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
-
- for( i = 0; i < n; i++ )
- {
- /*
- * pick a random A, 1 < A < |X| - 1
- */
- MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
-
- if( mpi_cmp_mpi( &A, &W ) >= 0 )
- {
- j = mpi_msb( &A ) - mpi_msb( &W );
- MPI_CHK( mpi_shift_r( &A, j + 1 ) );
- }
- A.p[0] |= 3;
-
- /*
- * A = A^R mod |X|
- */
- MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
-
- if( mpi_cmp_mpi( &A, &W ) == 0 ||
- mpi_cmp_int( &A, 1 ) == 0 )
- continue;
-
- j = 1;
- while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
- {
- /*
- * A = A * A mod |X|
- */
- MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
- MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
-
- if( mpi_cmp_int( &A, 1 ) == 0 )
- break;
-
- j++;
- }
-
- /*
- * not prime if A != |X| - 1 or A == 1
- */
- if( mpi_cmp_mpi( &A, &W ) != 0 ||
- mpi_cmp_int( &A, 1 ) == 0 )
- {
- ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
- break;
- }
- }
-
-cleanup:
-
- X->s = xs;
-
- mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
- mpi_free( &RR );
-
- return( ret );
-}
-
-/*
- * Prime number generation
- */
-int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng )
-{
- int ret;
- size_t k, n;
- mpi Y;
-
- if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
- return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
-
- mpi_init( &Y );
-
- n = BITS_TO_LIMBS( nbits );
-
- MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
-
- k = mpi_msb( X );
- if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
- if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
-
- X->p[0] |= 3;
-
- if( dh_flag == 0 )
- {
- while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
- {
- if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
- goto cleanup;
-
- MPI_CHK( mpi_add_int( X, X, 2 ) );
- }
- }
- else
- {
- MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
- MPI_CHK( mpi_shift_r( &Y, 1 ) );
-
- while( 1 )
- {
- if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
- {
- if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
- break;
-
- if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
- goto cleanup;
- }
-
- if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
- goto cleanup;
-
- MPI_CHK( mpi_add_int( &Y, X, 1 ) );
- MPI_CHK( mpi_add_int( X, X, 2 ) );
- MPI_CHK( mpi_shift_r( &Y, 1 ) );
- }
- }
-
-cleanup:
-
- mpi_free( &Y );
-
- return( ret );
-}
-
-#endif
-
-#if defined(POLARSSL_SELF_TEST)
-
-#define GCD_PAIR_COUNT 3
-
-static const int gcd_pairs[GCD_PAIR_COUNT][3] =
-{
- { 693, 609, 21 },
- { 1764, 868, 28 },
- { 768454923, 542167814, 1 }
-};
-
-/*
- * Checkup routine
- */
-int mpi_self_test( int verbose )
-{
- int ret, i;
- mpi A, E, N, X, Y, U, V;
-
- mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
- mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
-
- MPI_CHK( mpi_read_string( &A, 16,
- "EFE021C2645FD1DC586E69184AF4A31E" \
- "D5F53E93B5F123FA41680867BA110131" \
- "944FE7952E2517337780CB0DB80E61AA" \
- "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
-
- MPI_CHK( mpi_read_string( &E, 16,
- "B2E7EFD37075B9F03FF989C7C5051C20" \
- "34D2A323810251127E7BF8625A4F49A5" \
- "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
- "5B5C25763222FEFCCFC38B832366C29E" ) );
-
- MPI_CHK( mpi_read_string( &N, 16,
- "0066A198186C18C10B2F5ED9B522752A" \
- "9830B69916E535C8F047518A889A43A5" \
- "94B6BED27A168D31D4A52F88925AA8F5" ) );
-
- MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
-
- MPI_CHK( mpi_read_string( &U, 16,
- "602AB7ECA597A3D6B56FF9829A5E8B85" \
- "9E857EA95A03512E2BAE7391688D264A" \
- "A5663B0341DB9CCFD2C4C5F421FEC814" \
- "8001B72E848A38CAE1C65F78E56ABDEF" \
- "E12D3C039B8A02D6BE593F0BBBDA56F1" \
- "ECF677152EF804370C1A305CAF3B5BF1" \
- "30879B56C61DE584A0F53A2447A51E" ) );
-
- if( verbose != 0 )
- printf( " MPI test #1 (mul_mpi): " );
-
- if( mpi_cmp_mpi( &X, &U ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n" );
-
- MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
-
- MPI_CHK( mpi_read_string( &U, 16,
- "256567336059E52CAE22925474705F39A94" ) );
-
- MPI_CHK( mpi_read_string( &V, 16,
- "6613F26162223DF488E9CD48CC132C7A" \
- "0AC93C701B001B092E4E5B9F73BCD27B" \
- "9EE50D0657C77F374E903CDFA4C642" ) );
-
- if( verbose != 0 )
- printf( " MPI test #2 (div_mpi): " );
-
- if( mpi_cmp_mpi( &X, &U ) != 0 ||
- mpi_cmp_mpi( &Y, &V ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n" );
-
- MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
-
- MPI_CHK( mpi_read_string( &U, 16,
- "36E139AEA55215609D2816998ED020BB" \
- "BD96C37890F65171D948E9BC7CBAA4D9" \
- "325D24D6A3C12710F10A09FA08AB87" ) );
-
- if( verbose != 0 )
- printf( " MPI test #3 (exp_mod): " );
-
- if( mpi_cmp_mpi( &X, &U ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n" );
-
-#if defined(POLARSSL_GENPRIME)
- MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
-
- MPI_CHK( mpi_read_string( &U, 16,
- "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
- "C3DBA76456363A10869622EAC2DD84EC" \
- "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
-
- if( verbose != 0 )
- printf( " MPI test #4 (inv_mod): " );
-
- if( mpi_cmp_mpi( &X, &U ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( 1 );
- }
-
- if( verbose != 0 )
- printf( "passed\n" );
-#endif
-
- if( verbose != 0 )
- printf( " MPI test #5 (simple gcd): " );
-
- for ( i = 0; i < GCD_PAIR_COUNT; i++)
- {
- MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
- MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
-
- MPI_CHK( mpi_gcd( &A, &X, &Y ) );
-
- if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed at %d\n", i );
-
- return( 1 );
- }
- }
-
- if( verbose != 0 )
- printf( "passed\n" );
-
-cleanup:
-
- if( ret != 0 && verbose != 0 )
- printf( "Unexpected error, return code = %08X\n", ret );
-
- mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
- mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
-
- if( verbose != 0 )
- printf( "\n" );
-
- return( ret );
-}
-
-#endif
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/bignum.h b/ANDROID_3.4.5/drivers/misc/rsa/bignum.h
deleted file mode 100755
index 3b4d19c4..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/bignum.h
+++ /dev/null
@@ -1,763 +0,0 @@
-/**
- * \file bignum.h
- *
- * \brief Multi-precision integer library
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef POLARSSL_BIGNUM_H
-#define POLARSSL_BIGNUM_H
-
-//#include <common.h>
-//#include <command.h>
-#include <asm/io.h>
-
-//#include <stdio.h>
-//#include <string.h>
-
-//#include "config.h"
-
-#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */
-#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */
-#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */
-#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */
-#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */
-#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */
-#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */
-#define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */
-
-#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
-
-/*
- * Maximum size MPIs are allowed to grow to in number of limbs.
- */
-#define POLARSSL_MPI_MAX_LIMBS 10000
-
-/*
- * Maximum window size used for modular exponentiation. Default: 6
- * Minimum value: 1. Maximum value: 6.
- *
- * Result is an array of ( 2 << POLARSSL_MPI_WINDOW_SIZE ) MPIs used
- * for the sliding window calculation. (So 64 by default)
- *
- * Reduction in size, reduces speed.
- */
-#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
-
-/*
- * Maximum size of MPIs allowed in bits and bytes for user-MPIs.
- * ( Default: 512 bytes => 4096 bits )
- *
- * Note: Calculations can results temporarily in larger MPIs. So the number
- * of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher.
- */
-#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */
-#define POLARSSL_MPI_MAX_BITS ( 8 * POLARSSL_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */
-
-/*
- * When reading from files with mpi_read_file() the buffer should have space
- * for a (short) label, the MPI (in the provided radix), the newline
- * characters and the '\0'.
- *
- * By default we assume at least a 10 char label, a minimum radix of 10
- * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars).
- */
-#define POLARSSL_MPI_READ_BUFFER_SIZE 1250
-
-/*
- * Define the base integer type, architecture-wise
- */
-#if defined(POLARSSL_HAVE_INT8)
-typedef signed char t_sint;
-typedef unsigned char t_uint;
-typedef unsigned short t_udbl;
-#else
-#if defined(POLARSSL_HAVE_INT16)
-typedef signed short t_sint;
-typedef unsigned short t_uint;
-typedef unsigned long t_udbl;
-#else
- typedef signed long t_sint;
- typedef unsigned long t_uint;
- #if defined(_MSC_VER) && defined(_M_IX86)
- typedef unsigned __int64 t_udbl;
- #else
- #if defined(__GNUC__) && ( \
- defined(__amd64__) || defined(__x86_64__) || \
- defined(__ppc64__) || defined(__powerpc64__) || \
- defined(__ia64__) || defined(__alpha__) || \
- (defined(__sparc__) && defined(__arch64__)) || \
- defined(__s390x__) )
- typedef unsigned int t_udbl __attribute__((mode(TI)));
- #define POLARSSL_HAVE_LONGLONG
- #else
- #if defined(POLARSSL_HAVE_LONGLONG)
- typedef unsigned long long t_udbl;
- #endif
- #endif
- #endif
-#endif
-#endif
-
-/**
- * \brief MPI structure
- */
-typedef struct
-{
- int s; /*!< integer sign */
- size_t n; /*!< total # of limbs */
- t_uint *p; /*!< pointer to limbs */
-}
-mpi;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Initialize one MPI
- *
- * \param X One MPI to initialize.
- */
-void mpi_init( mpi *X );
-
-/**
- * \brief Unallocate one MPI
- *
- * \param X One MPI to unallocate.
- */
-void mpi_free( mpi *X );
-
-/**
- * \brief Enlarge to the specified number of limbs
- *
- * \param X MPI to grow
- * \param nblimbs The target number of limbs
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_grow( mpi *X, size_t nblimbs );
-
-/**
- * \brief Copy the contents of Y into X
- *
- * \param X Destination MPI
- * \param Y Source MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_copy( mpi *X, const mpi *Y );
-
-/**
- * \brief Swap the contents of X and Y
- *
- * \param X First MPI value
- * \param Y Second MPI value
- */
-void mpi_swap( mpi *X, mpi *Y );
-
-/**
- * \brief Set value from integer
- *
- * \param X MPI to set
- * \param z Value to use
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_lset( mpi *X, t_sint z );
-
-/*
- * \brief Get a specific bit from X
- *
- * \param X MPI to use
- * \param pos Zero-based index of the bit in X
- *
- * \return Either a 0 or a 1
- */
-int mpi_get_bit( mpi *X, size_t pos );
-
-/*
- * \brief Set a bit of X to a specific value of 0 or 1
- *
- * \note Will grow X if necessary to set a bit to 1 in a not yet
- * existing limb. Will not grow if bit should be set to 0
- *
- * \param X MPI to use
- * \param pos Zero-based index of the bit in X
- * \param val The value to set the bit to (0 or 1)
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1
- */
-int mpi_set_bit( mpi *X, size_t pos, unsigned char val );
-
-/**
- * \brief Return the number of least significant bits
- *
- * \param X MPI to use
- */
-size_t mpi_lsb( const mpi *X );
-
-/**
- * \brief Return the number of most significant bits
- *
- * \param X MPI to use
- */
-size_t mpi_msb( const mpi *X );
-
-/**
- * \brief Return the total size in bytes
- *
- * \param X MPI to use
- */
-size_t mpi_size( const mpi *X );
-
-/**
- * \brief Import from an ASCII string
- *
- * \param X Destination MPI
- * \param radix Input numeric base
- * \param s Null-terminated string buffer
- *
- * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
- */
-int mpi_read_string( mpi *X, int radix, const char *s );
-
-/**
- * \brief Export into an ASCII string
- *
- * \param X Source MPI
- * \param radix Output numeric base
- * \param s String buffer
- * \param slen String buffer size
- *
- * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code.
- * *slen is always updated to reflect the amount
- * of data that has (or would have) been written.
- *
- * \note Call this function with *slen = 0 to obtain the
- * minimum required buffer size in *slen.
- */
-int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen );
-
-/**
- * \brief Read X from an opened file
- *
- * \param X Destination MPI
- * \param radix Input numeric base
- * \param fin Input file handle
- *
- * \return 0 if successful, POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if
- * the file read buffer is too small or a
- * POLARSSL_ERR_MPI_XXX error code
- */
-//int mpi_read_file( mpi *X, int radix, FILE *fin );
-
-/**
- * \brief Write X into an opened file, or stdout if fout is NULL
- *
- * \param p Prefix, can be NULL
- * \param X Source MPI
- * \param radix Output numeric base
- * \param fout Output file handle (can be NULL)
- *
- * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
- *
- * \note Set fout == NULL to print X on the console.
- */
-//int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout );
-
-/**
- * \brief Import X from unsigned binary data, big endian
- *
- * \param X Destination MPI
- * \param buf Input buffer
- * \param buflen Input buffer size
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen );
-
-/**
- * \brief Export X into unsigned binary data, big endian
- *
- * \param X Source MPI
- * \param buf Output buffer
- * \param buflen Output buffer size
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
- */
-int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen );
-
-/**
- * \brief Left-shift: X <<= count
- *
- * \param X MPI to shift
- * \param count Amount to shift
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_shift_l( mpi *X, size_t count );
-
-/**
- * \brief Right-shift: X >>= count
- *
- * \param X MPI to shift
- * \param count Amount to shift
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_shift_r( mpi *X, size_t count );
-
-/**
- * \brief Compare unsigned values
- *
- * \param X Left-hand MPI
- * \param Y Right-hand MPI
- *
- * \return 1 if |X| is greater than |Y|,
- * -1 if |X| is lesser than |Y| or
- * 0 if |X| is equal to |Y|
- */
-int mpi_cmp_abs( const mpi *X, const mpi *Y );
-
-/**
- * \brief Compare signed values
- *
- * \param X Left-hand MPI
- * \param Y Right-hand MPI
- *
- * \return 1 if X is greater than Y,
- * -1 if X is lesser than Y or
- * 0 if X is equal to Y
- */
-int mpi_cmp_mpi( const mpi *X, const mpi *Y );
-
-/**
- * \brief Compare signed values
- *
- * \param X Left-hand MPI
- * \param z The integer value to compare to
- *
- * \return 1 if X is greater than z,
- * -1 if X is lesser than z or
- * 0 if X is equal to z
- */
-int mpi_cmp_int( const mpi *X, t_sint z );
-
-/**
- * \brief Unsigned addition: X = |A| + |B|
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_add_abs( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Unsigned substraction: X = |A| - |B|
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
- */
-int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Signed addition: X = A + B
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Signed substraction: X = A - B
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Signed addition: X = A + b
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param b The integer value to add
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_add_int( mpi *X, const mpi *A, t_sint b );
-
-/**
- * \brief Signed substraction: X = A - b
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param b The integer value to subtract
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_sub_int( mpi *X, const mpi *A, t_sint b );
-
-/**
- * \brief Baseline multiplication: X = A * B
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B );
-
-/**
- * \brief Baseline multiplication: X = A * b
- * Note: b is an unsigned integer type, thus
- * Negative values of b are ignored.
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param b The integer value to multiply with
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_mul_int( mpi *X, const mpi *A, t_sint b );
-
-/**
- * \brief Division by mpi: A = Q * B + R
- *
- * \param Q Destination MPI for the quotient
- * \param R Destination MPI for the rest value
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
- *
- * \note Either Q or R can be NULL.
- */
-int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B );
-
-/**
- * \brief Division by int: A = Q * b + R
- *
- * \param Q Destination MPI for the quotient
- * \param R Destination MPI for the rest value
- * \param A Left-hand MPI
- * \param b Integer to divide by
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
- *
- * \note Either Q or R can be NULL.
- */
-int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b );
-
-/**
- * \brief Modulo: R = A mod B
- *
- * \param R Destination MPI for the rest value
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0,
- * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0
- */
-int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B );
-
-/**
- * \brief Modulo: r = A mod b
- *
- * \param r Destination t_uint
- * \param A Left-hand MPI
- * \param b Integer to divide by
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
- * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0,
- * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0
- */
-int mpi_mod_int( t_uint *r, const mpi *A, t_sint b );
-
-/**
- * \brief Sliding-window exponentiation: X = A^E mod N
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param E Exponent MPI
- * \param N Modular MPI
- * \param _RR Speed-up MPI used for recalculations
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
- *
- * \note _RR is used to avoid re-computing R*R mod N across
- * multiple calls, which speeds up things a bit. It can
- * be set to NULL if the extra performance is unneeded.
- */
-int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR );
-
-/**
- * \brief Fill an MPI X with size bytes of random
- *
- * \param X Destination MPI
- * \param size Size in bytes
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_fill_random( mpi *X, size_t size,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng );
-
-/**
- * \brief Greatest common divisor: G = gcd(A, B)
- *
- * \param G Destination MPI
- * \param A Left-hand MPI
- * \param B Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
- */
-int mpi_gcd( mpi *G, const mpi *A, const mpi *B );
-
-/**
- * \brief Modular inverse: X = A^-1 mod N
- *
- * \param X Destination MPI
- * \param A Left-hand MPI
- * \param N Right-hand MPI
- *
- * \return 0 if successful,
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
- POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
- */
-int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N );
-
-/**
- * \brief Miller-Rabin primality test
- *
- * \param X MPI to check
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \return 0 if successful (probably prime),
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
- * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
- */
-int mpi_is_prime( mpi *X,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng );
-
-/**
- * \brief Prime number generation
- *
- * \param X Destination MPI
- * \param nbits Required size of X in bits ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS )
- * \param dh_flag If 1, then (X-1)/2 will be prime too
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \return 0 if successful (probably prime),
- * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
- * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
- */
-int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng );
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int mpi_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#define __ARM__ 1
-#ifdef __ARM__
-#define MULADDC_INIT \
- asm( "ldr r0, %0 " :: "m" (s)); \
- asm( "ldr r1, %0 " :: "m" (d)); \
- asm( "ldr r2, %0 " :: "m" (c)); \
- asm( "ldr r3, %0 " :: "m" (b));
-
-#define MULADDC_CORE \
- asm( "ldr r4, [r0], #4 " ); \
- asm( "mov r5, #0 " ); \
- asm( "ldr r6, [r1] " ); \
- asm( "umlal r2, r5, r3, r4 " ); \
- asm( "adds r7, r6, r2 " ); \
- asm( "adc r2, r5, #0 " ); \
- asm( "str r7, [r1], #4 " );
-
-#define MULADDC_STOP \
- asm( "str r2, %0 " : "=m" (c)); \
- asm( "str r1, %0 " : "=m" (d)); \
- asm( "str r0, %0 " : "=m" (s) :: \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
-
-#endif
-
-#ifdef __i386__
-#define MULADDC_INIT \
- asm( " \
- movl %%ebx, %0; \
- movl %5, %%esi; \
- movl %6, %%edi; \
- movl %7, %%ecx; \
- movl %8, %%ebx; \
- "
-
-#define MULADDC_CORE \
- " \
- lodsl; \
- mull %%ebx; \
- addl %%ecx, %%eax; \
- adcl $0, %%edx; \
- addl (%%edi), %%eax; \
- adcl $0, %%edx; \
- movl %%edx, %%ecx; \
- stosl; \
- "
-
-
-#define MULADDC_HUIT \
- " \
- movd %%ecx, %%mm1; \
- movd %%ebx, %%mm0; \
- movd (%%edi), %%mm3; \
- paddq %%mm3, %%mm1; \
- movd (%%esi), %%mm2; \
- pmuludq %%mm0, %%mm2; \
- movd 4(%%esi), %%mm4; \
- pmuludq %%mm0, %%mm4; \
- movd 8(%%esi), %%mm6; \
- pmuludq %%mm0, %%mm6; \
- movd 12(%%esi), %%mm7; \
- pmuludq %%mm0, %%mm7; \
- paddq %%mm2, %%mm1; \
- movd 4(%%edi), %%mm3; \
- paddq %%mm4, %%mm3; \
- movd 8(%%edi), %%mm5; \
- paddq %%mm6, %%mm5; \
- movd 12(%%edi), %%mm4; \
- paddq %%mm4, %%mm7; \
- movd %%mm1, (%%edi); \
- movd 16(%%esi), %%mm2; \
- pmuludq %%mm0, %%mm2; \
- psrlq $32, %%mm1; \
- movd 20(%%esi), %%mm4; \
- pmuludq %%mm0, %%mm4; \
- paddq %%mm3, %%mm1; \
- movd 24(%%esi), %%mm6; \
- pmuludq %%mm0, %%mm6; \
- movd %%mm1, 4(%%edi); \
- psrlq $32, %%mm1; \
- movd 28(%%esi), %%mm3; \
- pmuludq %%mm0, %%mm3; \
- paddq %%mm5, %%mm1; \
- movd 16(%%edi), %%mm5; \
- paddq %%mm5, %%mm2; \
- movd %%mm1, 8(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm7, %%mm1; \
- movd 20(%%edi), %%mm5; \
- paddq %%mm5, %%mm4; \
- movd %%mm1, 12(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm2, %%mm1; \
- movd 24(%%edi), %%mm5; \
- paddq %%mm5, %%mm6; \
- movd %%mm1, 16(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm4, %%mm1; \
- movd 28(%%edi), %%mm5; \
- paddq %%mm5, %%mm3; \
- movd %%mm1, 20(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm6, %%mm1; \
- movd %%mm1, 24(%%edi); \
- psrlq $32, %%mm1; \
- paddq %%mm3, %%mm1; \
- movd %%mm1, 28(%%edi); \
- addl $32, %%edi; \
- addl $32, %%esi; \
- psrlq $32, %%mm1; \
- movd %%mm1, %%ecx; \
- "
-
-#define MULADDC_STOP \
- " \
- emms; \
- movl %4, %%ebx; \
- movl %%ecx, %1; \
- movl %%edi, %2; \
- movl %%esi, %3; \
- " \
- : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \
- : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \
- : "eax", "ecx", "edx", "esi", "edi" \
- );
-
-#endif
-#endif /* bignum.h */
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/dhm.h b/ANDROID_3.4.5/drivers/misc/rsa/dhm.h
deleted file mode 100755
index 0c8dd55e..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/dhm.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * \file dhm.h
- *
- * \brief Diffie-Hellman-Merkle key exchange
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef POLARSSL_DHM_H
-#define POLARSSL_DHM_H
-
-#include "bignum.h"
-
-/*
- * DHM Error codes
- */
-#define POLARSSL_ERR_DHM_BAD_INPUT_DATA -0x3080 /**< Bad input parameters to function. */
-#define POLARSSL_ERR_DHM_READ_PARAMS_FAILED -0x3100 /**< Reading of the DHM parameters failed. */
-#define POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 /**< Making of the DHM parameters failed. */
-#define POLARSSL_ERR_DHM_READ_PUBLIC_FAILED -0x3200 /**< Reading of the public values failed. */
-#define POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 /**< Making of the public value failed. */
-#define POLARSSL_ERR_DHM_CALC_SECRET_FAILED -0x3300 /**< Calculation of the DHM secret failed. */
-
-/**
- * \brief DHM context structure
- */
-typedef struct
-{
- size_t len; /*!< size(P) in chars */
- mpi P; /*!< prime modulus */
- mpi G; /*!< generator */
- mpi X; /*!< secret value */
- mpi GX; /*!< self = G^X mod P */
- mpi GY; /*!< peer = G^Y mod P */
- mpi K; /*!< key = GY^X mod P */
- mpi RP; /*!< cached R^2 mod P */
-}
-dhm_context;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Parse the ServerKeyExchange parameters
- *
- * \param ctx DHM context
- * \param p &(start of input buffer)
- * \param end end of buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
- */
-int dhm_read_params( dhm_context *ctx,
- unsigned char **p,
- const unsigned char *end );
-
-/**
- * \brief Setup and write the ServerKeyExchange parameters
- *
- * \param ctx DHM context
- * \param x_size private value size in bytes
- * \param output destination buffer
- * \param olen number of chars written
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \note This function assumes that ctx->P and ctx->G
- * have already been properly set (for example
- * using mpi_read_string or mpi_read_binary).
- *
- * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
- */
-int dhm_make_params( dhm_context *ctx, int x_size,
- unsigned char *output, size_t *olen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng );
-
-/**
- * \brief Import the peer's public value G^Y
- *
- * \param ctx DHM context
- * \param input input buffer
- * \param ilen size of buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
- */
-int dhm_read_public( dhm_context *ctx,
- const unsigned char *input, size_t ilen );
-
-/**
- * \brief Create own private value X and export G^X
- *
- * \param ctx DHM context
- * \param x_size private value size in bytes
- * \param output destination buffer
- * \param olen must be equal to ctx->P.len
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- *
- * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
- */
-int dhm_make_public( dhm_context *ctx, int x_size,
- unsigned char *output, size_t olen,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng );
-
-/**
- * \brief Derive and export the shared secret (G^Y)^X mod P
- *
- * \param ctx DHM context
- * \param output destination buffer
- * \param olen number of chars written
- *
- * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code
- */
-int dhm_calc_secret( dhm_context *ctx,
- unsigned char *output, size_t *olen );
-
-/*
- * \brief Free the components of a DHM key
- */
-void dhm_free( dhm_context *ctx );
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int dhm_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/pem.h b/ANDROID_3.4.5/drivers/misc/rsa/pem.h
deleted file mode 100755
index fbae8c55..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/pem.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * \file pem.h
- *
- * \brief Privacy Enhanced Mail (PEM) decoding
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef POLARSSL_PEM_H
-#define POLARSSL_PEM_H
-
-//#include <string.h>
-
-/**
- * \name PEM Error codes
- * These error codes are returned in case of errors reading the
- * PEM data.
- * \{
- */
-#define POLARSSL_ERR_PEM_NO_HEADER_PRESENT -0x1080 /**< No PEM header found. */
-#define POLARSSL_ERR_PEM_INVALID_DATA -0x1100 /**< PEM string is not as expected. */
-#define POLARSSL_ERR_PEM_MALLOC_FAILED -0x1180 /**< Failed to allocate memory. */
-#define POLARSSL_ERR_PEM_INVALID_ENC_IV -0x1200 /**< RSA IV is not in hex-format. */
-#define POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG -0x1280 /**< Unsupported key encryption algorithm. */
-#define POLARSSL_ERR_PEM_PASSWORD_REQUIRED -0x1300 /**< Private key password can't be empty. */
-#define POLARSSL_ERR_PEM_PASSWORD_MISMATCH -0x1380 /**< Given private key password does not allow for correct decryption. */
-#define POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE -0x1400 /**< Unavailable feature, e.g. hashing/encryption combination. */
-/* \} name */
-
-/**
- * \brief PEM context structure
- */
-typedef struct
-{
- unsigned char *buf; /*!< buffer for decoded data */
- size_t buflen; /*!< length of the buffer */
- unsigned char *info; /*!< buffer for extra header information */
-}
-pem_context;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief PEM context setup
- *
- * \param ctx context to be initialized
- */
-void pem_init( pem_context *ctx );
-
-/**
- * \brief Read a buffer for PEM information and store the resulting
- * data into the specified context buffers.
- *
- * \param ctx context to use
- * \param header header string to seek and expect
- * \param footer footer string to seek and expect
- * \param data source data to look in
- * \param pwd password for decryption (can be NULL)
- * \param pwdlen length of password
- * \param use_len destination for total length used
- *
- * \return 0 on success, ior a specific PEM error code
- */
-int pem_read_buffer( pem_context *ctx,
- const unsigned char *data,
- const unsigned char *pwd,
- size_t pwdlen, size_t *use_len );
-
-/**
- * \brief PEM context memory freeing
- *
- * \param ctx context to be freed
- */
-void pem_free( pem_context *ctx );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* pem.h */
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/rsa.h b/ANDROID_3.4.5/drivers/misc/rsa/rsa.h
deleted file mode 100755
index 41691ae1..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/rsa.h
+++ /dev/null
@@ -1,373 +0,0 @@
-/**
- * \file rsa.h
- *
- * \brief The RSA public-key cryptosystem
- *
- * Copyright (C) 2006-2010, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef POLARSSL_RSA_H
-#define POLARSSL_RSA_H
-
-#include "bignum.h"
-#include <stddef.h>
-/*
- * RSA Error codes
- */
-#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x4080 /**< Bad input parameters to function. */
-#define POLARSSL_ERR_RSA_INVALID_PADDING -0x4100 /**< Input data contains invalid padding and is rejected. */
-#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x4180 /**< Something failed during generation of a key. */
-#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x4200 /**< Key failed to pass the libraries validity check. */
-#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */
-#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x4300 /**< The private key operation failed. */
-#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */
-#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */
-#define POLARSSL_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */
-
-/*
- * PKCS#1 constants
- */
-#define SIG_RSA_RAW 0
-#define SIG_RSA_MD2 2
-#define SIG_RSA_MD4 3
-#define SIG_RSA_MD5 4
-#define SIG_RSA_SHA1 5
-#define SIG_RSA_SHA224 14
-#define SIG_RSA_SHA256 11
-#define SIG_RSA_SHA384 12
-#define SIG_RSA_SHA512 13
-
-#define RSA_PUBLIC 0
-#define RSA_PRIVATE 1
-
-#define RSA_PKCS_V15 0
-#define RSA_PKCS_V21 1
-
-#define RSA_SIGN 1
-#define RSA_CRYPT 2
-
-#define ASN1_STR_CONSTRUCTED_SEQUENCE "\x30"
-#define ASN1_STR_NULL "\x05"
-#define ASN1_STR_OID "\x06"
-#define ASN1_STR_OCTET_STRING "\x04"
-
-#define OID_DIGEST_ALG_MDX "\x2A\x86\x48\x86\xF7\x0D\x02\x00"
-#define OID_HASH_ALG_SHA1 "\x2b\x0e\x03\x02\x1a"
-#define OID_HASH_ALG_SHA2X "\x60\x86\x48\x01\x65\x03\x04\x02\x00"
-
-#define OID_ISO_MEMBER_BODIES "\x2a"
-#define OID_ISO_IDENTIFIED_ORG "\x2b"
-
-/*
- * ISO Member bodies OID parts
- */
-#define OID_COUNTRY_US "\x86\x48"
-#define OID_RSA_DATA_SECURITY "\x86\xf7\x0d"
-
-/*
- * ISO Identified organization OID parts
- */
-#define OID_OIW_SECSIG_SHA1 "\x0e\x03\x02\x1a"
-
-/*
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm DigestAlgorithmIdentifier,
- * digest Digest }
- *
- * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
- *
- * Digest ::= OCTET STRING
- */
-#define ASN1_HASH_MDX \
-( \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x20" \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x0C" \
- ASN1_STR_OID "\x08" \
- OID_DIGEST_ALG_MDX \
- ASN1_STR_NULL "\x00" \
- ASN1_STR_OCTET_STRING "\x10" \
-)
-
-#define ASN1_HASH_SHA1 \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x21" \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x09" \
- ASN1_STR_OID "\x05" \
- OID_HASH_ALG_SHA1 \
- ASN1_STR_NULL "\x00" \
- ASN1_STR_OCTET_STRING "\x14"
-
-#define ASN1_HASH_SHA2X \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x11" \
- ASN1_STR_CONSTRUCTED_SEQUENCE "\x0d" \
- ASN1_STR_OID "\x09" \
- OID_HASH_ALG_SHA2X \
- ASN1_STR_NULL "\x00" \
- ASN1_STR_OCTET_STRING "\x00"
-
-
-/**
- * \brief RSA context structure
- */
-typedef struct
-{
- int ver; /*!< always 0 */
- size_t len; /*!< size(N) in chars */
-
- mpi N; /*!< public modulus */
- mpi E; /*!< public exponent */
-
- mpi D; /*!< private exponent */
- mpi P; /*!< 1st prime factor */
- mpi Q; /*!< 2nd prime factor */
- mpi DP; /*!< D % (P - 1) */
- mpi DQ; /*!< D % (Q - 1) */
- mpi QP; /*!< 1 / (Q % P) */
-
- mpi RN; /*!< cached R^2 mod N */
- mpi RP; /*!< cached R^2 mod P */
- mpi RQ; /*!< cached R^2 mod Q */
-
- int padding; /*!< RSA_PKCS_V15 for 1.5 padding and
- RSA_PKCS_v21 for OAEP/PSS */
- int hash_id; /*!< Hash identifier of md_type_t as
- specified in the md.h header file
- for the EME-OAEP and EMSA-PSS
- encoding */
-}
-rsa_context;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Initialize an RSA context
- *
- * \param ctx RSA context to be initialized
- * \param padding RSA_PKCS_V15 or RSA_PKCS_V21
- * \param hash_id RSA_PKCS_V21 hash identifier
- *
- * \note The hash_id parameter is actually ignored
- * when using RSA_PKCS_V15 padding.
- */
-void rsa_init( rsa_context *ctx,
- int padding,
- int hash_id);
-
-/**
- * \brief Generate an RSA keypair
- *
- * \param ctx RSA context that will hold the key
- * \param f_rng RNG function
- * \param p_rng RNG parameter
- * \param nbits size of the public key in bits
- * \param exponent public exponent (e.g., 65537)
- *
- * \note rsa_init() must be called beforehand to setup
- * the RSA context.
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- */
-int rsa_gen_key( rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- unsigned int nbits, int exponent );
-
-/**
- * \brief Check a public RSA key
- *
- * \param ctx RSA context to be checked
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- */
-int rsa_check_pubkey( const rsa_context *ctx );
-
-/**
- * \brief Check a private RSA key
- *
- * \param ctx RSA context to be checked
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- */
-int rsa_check_privkey( const rsa_context *ctx );
-
-/**
- * \brief Do an RSA public key operation
- *
- * \param ctx RSA context
- * \param input input buffer
- * \param output output buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note This function does NOT take care of message
- * padding. Also, be sure to set input[0] = 0 or assure that
- * input is smaller than N.
- *
- * \note The input and output buffers must be large
- * enough (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_public( rsa_context *ctx,
- const unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief Do an RSA private key operation
- *
- * \param ctx RSA context
- * \param input input buffer
- * \param output output buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The input and output buffers must be large
- * enough (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_private( rsa_context *ctx,
- const unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief Add the message padding, then do an RSA operation
- *
- * \param ctx RSA context
- * \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding)
- * \param p_rng RNG parameter
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param ilen contains the plaintext length
- * \param input buffer holding the data to be encrypted
- * \param output buffer that will hold the ciphertext
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The output buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used).
- */
-int rsa_pkcs1_encrypt( rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode, size_t ilen,
- const unsigned char *input,
- unsigned char *output );
-
-/**
- * \brief Do an RSA operation, then remove the message padding
- *
- * \param ctx RSA context
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param olen will contain the plaintext length
- * \param input buffer holding the encrypted data
- * \param output buffer that will hold the plaintext
- * \param output_max_len maximum length of the output buffer
- *
- * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The output buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
- * an error is thrown.
- */
-int rsa_pkcs1_decrypt( rsa_context *ctx,
- int mode, size_t *olen,
- const unsigned char *input,
- unsigned char *output,
- size_t output_max_len );
-
-/**
- * \brief Do a private RSA to sign a message digest
- *
- * \param ctx RSA context
- * \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding)
- * \param p_rng RNG parameter
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
- * \param hashlen message digest length (for SIG_RSA_RAW only)
- * \param hash buffer holding the message digest
- * \param sig buffer that will hold the ciphertext
- *
- * \return 0 if the signing operation was successful,
- * or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The "sig" buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used).
- *
- * \note In case of PKCS#1 v2.1 encoding keep in mind that
- * the hash_id in the RSA context is the one used for the
- * encoding. hash_id in the function call is the type of hash
- * that is encoded. According to RFC 3447 it is advised to
- * keep both hashes the same.
- */
-int rsa_pkcs1_sign( rsa_context *ctx,
- int (*f_rng)(void *, unsigned char *, size_t),
- void *p_rng,
- int mode,
- int hash_id,
- unsigned int hashlen,
- const unsigned char *hash,
- unsigned char *sig );
-
-/**
- * \brief Do a public RSA and check the message digest
- *
- * \param ctx points to an RSA public key
- * \param mode RSA_PUBLIC or RSA_PRIVATE
- * \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
- * \param hashlen message digest length (for SIG_RSA_RAW only)
- * \param hash buffer holding the message digest
- * \param sig buffer holding the ciphertext
- *
- * \return 0 if the verify operation was successful,
- * or an POLARSSL_ERR_RSA_XXX error code
- *
- * \note The "sig" buffer must be as large as the size
- * of ctx->N (eg. 128 bytes if RSA-1024 is used).
- *
- * \note In case of PKCS#1 v2.1 encoding keep in mind that
- * the hash_id in the RSA context is the one used for the
- * verification. hash_id in the function call is the type of hash
- * that is verified. According to RFC 3447 it is advised to
- * keep both hashes the same.
- */
-int rsa_pkcs1_verify( rsa_context *ctx,
- int mode,
- int hash_id,
- unsigned int hashlen,
- const unsigned char *hash,
- unsigned char *sig );
-
-/**
- * \brief Free the components of an RSA key
- *
- * \param ctx RSA Context to free
- */
-void rsa_free( rsa_context *ctx );
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int rsa_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* rsa.h */
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/rsa_verify.c b/ANDROID_3.4.5/drivers/misc/rsa/rsa_verify.c
deleted file mode 100755
index 7d864016..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/rsa_verify.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * The RSA public-key cryptosystem
- *
- * Copyright (C) 2006-2011, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/*
- * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
- *
- * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
- * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
- */
-
-#include "rsa.h"
-#include "base64.h"
-#include "pem.h"
-#include "asn1.h"
-#include "x509.h"
-//#include <stdlib.h>
-//#include <stdio.h>
-#include <linux/vmalloc.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <asm/io.h>
-#include <linux/mtd/partitions.h>
-#include <linux/platform_device.h>
-#include <mach/hardware.h>
-#include <linux/delay.h>
-
-
-
-static const unsigned char base64_dec_map[128] =
-{
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
- 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
- 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
- 127, 64, 127, 127, 127, 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, 127, 127, 127, 127, 127, 127, 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, 127, 127, 127, 127, 127
-};
-
-/*
- * Decode a base64-formatted buffer
- */
-int base64_decode( unsigned char *dst, size_t *dlen,
- const unsigned char *src, size_t slen )
-{
- size_t i, j, n;
- unsigned long x;
- unsigned char *p;
-
- for( i = j = n = 0; i < slen; i++ )
- {
- if( ( slen - i ) >= 2 &&
- src[i] == '\r' && src[i + 1] == '\n' )
- continue;
-
- if( src[i] == '\n' )
- continue;
-
- if( src[i] == '=' && ++j > 2 )
- return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-
- if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
- return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-
- if( base64_dec_map[src[i]] < 64 && j != 0 )
- return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
-
- n++;
- }
-
- if( n == 0 )
- return( 0 );
-
- n = ((n * 6) + 7) >> 3;
-
- if( *dlen < n )
- {
- *dlen = n;
- return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
- }
-
- for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
- {
- if( *src == '\r' || *src == '\n' )
- continue;
-
- j -= ( base64_dec_map[*src] == 64 );
- x = (x << 6) | ( base64_dec_map[*src] & 0x3F );
-
- if( ++n == 4 )
- {
- n = 0;
- if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
- if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
- if( j > 2 ) *p++ = (unsigned char)( x );
- }
- }
-
- *dlen = p - dst;
-
- return( 0 );
-}
-
-int pem_read_buffer( pem_context *ctx, const unsigned char *data, const unsigned char *pwd, size_t pwdlen, size_t *use_len )
-{
- int ret;
- size_t len;
- unsigned char *buf;
-
- ((void) pwd);
- ((void) pwdlen);
-
- if( ctx == NULL )
- return( POLARSSL_ERR_PEM_INVALID_DATA );
-
-
-
- len = 0;
- ret = base64_decode( NULL, &len, data, strlen((char *)data) );
-
- if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
- return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
-
- if( ( buf = (unsigned char *) vmalloc( len ) ) == NULL )
- return( POLARSSL_ERR_PEM_MALLOC_FAILED );
-
- if( ( ret = base64_decode( buf, &len, data, strlen((char *)data) ) ) != 0 )
- {
- vfree( buf );
- return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
- }
-
-
- ctx->buf = buf;
- ctx->buflen = len;
- //*use_len = s2 - data;
-
- return( 0 );
-}
-
-int asn1_get_len( unsigned char **p,
- const unsigned char *end,
- size_t *len )
-{
- if( ( end - *p ) < 1 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- if( ( **p & 0x80 ) == 0 )
- *len = *(*p)++;
- else
- {
- switch( **p & 0x7F )
- {
- case 1:
- if( ( end - *p ) < 2 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- *len = (*p)[1];
- (*p) += 2;
- break;
-
- case 2:
- if( ( end - *p ) < 3 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- *len = ( (*p)[1] << 8 ) | (*p)[2];
- (*p) += 3;
- break;
-
- case 3:
- if( ( end - *p ) < 4 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3];
- (*p) += 4;
- break;
-
- case 4:
- if( ( end - *p ) < 5 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | (*p)[4];
- (*p) += 5;
- break;
-
- default:
- return( POLARSSL_ERR_ASN1_INVALID_LENGTH );
- }
- }
-
- if( *len > (size_t) ( end - *p ) )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- return( 0 );
-}
-
-int asn1_get_tag( unsigned char **p,
- const unsigned char *end,
- size_t *len, int tag )
-{
- if( ( end - *p ) < 1 )
- return( POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- if( **p != tag )
- return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
-
- (*p)++;
-
- return( asn1_get_len( p, end, len ) );
-}
-
-int asn1_get_mpi( unsigned char **p,
- const unsigned char *end,
- mpi *X )
-{
- int ret;
- size_t len;
-
- if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
- return( ret );
-
- ret = mpi_read_binary( X, *p, len );
-
- *p += len;
-
- return( ret );
-}
-
-static int x509_get_alg( unsigned char **p,
- const unsigned char *end,
- x509_buf *alg )
-{
- int ret;
- size_t len;
-
- if( ( ret = asn1_get_tag( p, end, &len,
- ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
- return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
-
- end = *p + len;
- alg->tag = **p;
-
- if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
- return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
-
- alg->p = *p;
- *p += alg->len;
-
- if( *p == end )
- return( 0 );
-
- /*
- * assume the algorithm parameters must be NULL
- */
- if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
- return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
-
- if( *p != end )
- return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
- POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
-
- return( 0 );
-}
-
-static int x509_get_pubkey( unsigned char **p,
- const unsigned char *end,
- x509_buf *pk_alg_oid,
- mpi *N, mpi *E )
-{
- int ret, can_handle;
- size_t len;
- unsigned char *end2;
-
- if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
- return( ret );
-
- /*
- * only RSA public keys handled at this time
- */
- can_handle = 0;
-
- if( pk_alg_oid->len == 9 &&
- memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
- can_handle = 1;
-
- if( pk_alg_oid->len == 9 &&
- memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
- {
- if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
- can_handle = 1;
-
- if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
- can_handle = 1;
- }
-
- if( pk_alg_oid->len == 5 &&
- memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
- can_handle = 1;
-
- if( can_handle == 0 )
- return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
-
- if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
- return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
-
- if( ( end - *p ) < 1 )
- return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
- POLARSSL_ERR_ASN1_OUT_OF_DATA );
-
- end2 = *p + len;
-
- if( *(*p)++ != 0 )
- return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
-
- /*
- * RSAPublicKey ::= SEQUENCE {
- * modulus INTEGER, -- n
- * publicExponent INTEGER -- e
- * }
- */
- if( ( ret = asn1_get_tag( p, end2, &len,
- ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
- return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
-
- if( *p + len != end2 )
- return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
- POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
-
- if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
- ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
- return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
-
- if( *p != end )
- return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
- POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
-
- return( 0 );
-}
-
-
-void pem_free( pem_context *ctx )
-{
- if( ctx->buf )
- vfree( ctx->buf );
-
- if( ctx->info )
- vfree( ctx->info );
-
- memset(ctx, 0, sizeof(pem_context));
-}
-
-int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
-{
- int ret;
- size_t len;
- unsigned char *p, *end;
- x509_buf alg_oid;
- pem_context pem;
-
- memset( &pem, 0, sizeof( pem_context ) );
- ret = pem_read_buffer( &pem,
- key, NULL, 0, &len );
-
- if( ret == 0 )
- {
- /*
- * Was PEM encoded
- */
- keylen = pem.buflen;
-
- }
- else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
- {
- pem_free( &pem );
- return( ret );
- }
-
- p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
- end = p + keylen;
-
- /*
- * PublicKeyInfo ::= SEQUENCE {
- * algorithm AlgorithmIdentifier,
- * PublicKey BIT STRING
- * }
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * RSAPublicKey ::= SEQUENCE {
- * modulus INTEGER, -- n
- * publicExponent INTEGER -- e
- * }
- */
-
- if( ( ret = asn1_get_tag( &p, end, &len,
- ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
- {
- pem_free( &pem );
- rsa_free( rsa );
- return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
- }
-
- if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
- {
- pem_free( &pem );
- rsa_free( rsa );
- return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
- }
-
-#if 0
- if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
- {
-#if defined(POLARSSL_PEM_C)
- pem_free( &pem );
-#endif
- rsa_free( rsa );
- return( ret );
- }
-#endif
- rsa->len = mpi_size( &rsa->N );
-
-
-
- pem_free( &pem );
-
- return( 0 );
-}
-/*
- * Initialize an RSA context
- */
-void rsa_init( rsa_context *ctx, int padding, int hash_id)
-{
- memset( ctx, 0, sizeof(rsa_context));
-
- ctx->padding = padding;
- ctx->hash_id = hash_id;
-}
-
-
-/*
- * Do an RSA public key operation
- */
-
-int rsa_public( rsa_context *ctx, const unsigned char *input, unsigned char *output)
-{
- int ret;
- size_t olen;
- mpi T;
-
- mpi_init( &T );
-
- MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
-
- if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) {
- mpi_free( &T );
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- }
-
- olen = ctx->len;
- MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
- MPI_CHK( mpi_write_binary( &T, output, olen ) );
-
-cleanup:
-
- mpi_free( &T );
-
- if( ret != 0 )
- return( POLARSSL_ERR_RSA_PUBLIC_FAILED + ret );
-
- return( 0 );
-}
-
-
-
-/*
- * Free the components of an RSA key
- */
-void rsa_free( rsa_context *ctx )
-{
- mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN );
- mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP );
- mpi_free( &ctx->Q ); mpi_free( &ctx->P ); mpi_free( &ctx->D );
- mpi_free( &ctx->E ); mpi_free( &ctx->N );
-}
-
-int rsa_check(unsigned int pub_key_addr, unsigned int pub_key_size, unsigned int sig_addr, unsigned int sig_size, u8 *out_buf)
-{
-
- size_t len;
- rsa_context rsa;
- unsigned char key[1024];
- unsigned char signature[1024];
- unsigned char verified[1024];
- int i;
- unsigned char *tmp;
- int ret, siglen;
-
- rsa_init(&rsa, RSA_PKCS_V15, 0);
-
- memcpy((void *)key, (void *)pub_key_addr, pub_key_size);
- key[pub_key_size] = '\0';
- len = pub_key_size;
-
- x509parse_public_key(&rsa, key, len);
-
- tmp = (unsigned char *) rsa.N.p;
-
- memcpy(signature, (void *)sig_addr, sig_size);
- signature[sig_size]='\0';
-
- ret = rsa_public(&rsa, signature, verified);
-
- if (ret){
- printk("Signature verify failed!!!\n");
- return -2;
- }
-
-
- if ((verified[0] != 0) && (verified[1] != RSA_SIGN)) {
- printk("Signature verify failed!!!\n");
- return -1;
- }
-
- tmp = &verified[2];
- while (*tmp == 0xff) // skip padding
- tmp++;
- tmp++; // skip a terminator
-
- siglen = rsa.len -( tmp - verified);
-
- for (i = 0; i < siglen; i++) {
- out_buf[i] = tmp[i];
- }
-
- rsa_free(&rsa);
- return 0;
-}
-EXPORT_SYMBOL(rsa_check); \ No newline at end of file
diff --git a/ANDROID_3.4.5/drivers/misc/rsa/x509.h b/ANDROID_3.4.5/drivers/misc/rsa/x509.h
deleted file mode 100755
index cd0dc84a..00000000
--- a/ANDROID_3.4.5/drivers/misc/rsa/x509.h
+++ /dev/null
@@ -1,726 +0,0 @@
-/**
- * \file x509.h
- *
- * \brief X.509 certificate and private key decoding
- *
- * Copyright (C) 2006-2011, Brainspark B.V.
- *
- * This file is part of PolarSSL (http://www.polarssl.org)
- * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#ifndef POLARSSL_X509_H
-#define POLARSSL_X509_H
-
-#include "asn1.h"
-#include "rsa.h"
-#include "dhm.h"
-
-/**
- * \addtogroup x509_module
- * \{
- */
-
-/**
- * \name X509 Error codes
- * \{
- */
-#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x2080 /**< Unavailable feature, e.g. RSA hashing/encryption combination. */
-#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x2100 /**< The PEM-encoded certificate contains invalid elements, e.g. invalid character. */
-#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x2180 /**< The certificate format is invalid, e.g. different type expected. */
-#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x2200 /**< The certificate version element is invalid. */
-#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x2280 /**< The serial tag or value is invalid. */
-#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x2300 /**< The algorithm tag or value is invalid. */
-#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x2380 /**< The name tag or value is invalid. */
-#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x2400 /**< The date tag or value is invalid. */
-#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x2480 /**< The pubkey tag or value is invalid (only RSA is supported). */
-#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x2500 /**< The signature tag or value invalid. */
-#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x2580 /**< The extension tag or value is invalid. */
-#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x2600 /**< Certificate or CRL has an unsupported version number. */
-#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x2680 /**< Signature algorithm (oid) is unsupported. */
-#define POLARSSL_ERR_X509_UNKNOWN_PK_ALG -0x2700 /**< Key algorithm is unsupported (only RSA is supported). */
-#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x2780 /**< Certificate signature algorithms do not match. (see \c ::x509_cert sig_oid) */
-#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x2800 /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */
-#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x2880 /**< Unsupported RSA key version */
-#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x2900 /**< Invalid RSA key tag or value. */
-#define POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT -0x2980 /**< Format not recognized as DER or PEM. */
-#define POLARSSL_ERR_X509_INVALID_INPUT -0x2A00 /**< Input invalid. */
-#define POLARSSL_ERR_X509_MALLOC_FAILED -0x2A80 /**< Allocation of memory failed. */
-#define POLARSSL_ERR_X509_FILE_IO_ERROR -0x2B00 /**< Read/write of file failed. */
-/* \} name */
-
-
-/**
- * \name X509 Verify codes
- * \{
- */
-#define BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */
-#define BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */
-#define BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */
-#define BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */
-#define BADCRL_NOT_TRUSTED 0x10 /**< CRL is not correctly signed by the trusted CA. */
-#define BADCRL_EXPIRED 0x20 /**< CRL is expired. */
-#define BADCERT_MISSING 0x40 /**< Certificate was missing. */
-#define BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */
-/* \} name */
-/* \} addtogroup x509_module */
-
-/*
- * various object identifiers
- */
-#define X520_COMMON_NAME 3
-#define X520_COUNTRY 6
-#define X520_LOCALITY 7
-#define X520_STATE 8
-#define X520_ORGANIZATION 10
-#define X520_ORG_UNIT 11
-#define PKCS9_EMAIL 1
-
-#define X509_OUTPUT_DER 0x01
-#define X509_OUTPUT_PEM 0x02
-#define PEM_LINE_LENGTH 72
-#define X509_ISSUER 0x01
-#define X509_SUBJECT 0x02
-
-#define OID_X520 "\x55\x04"
-#define OID_CN OID_X520 "\x03"
-
-#define OID_PKCS1 "\x2A\x86\x48\x86\xF7\x0D\x01\x01"
-#define OID_PKCS1_RSA OID_PKCS1 "\x01"
-
-#define OID_RSA_SHA_OBS "\x2B\x0E\x03\x02\x1D"
-
-#define OID_PKCS9 "\x2A\x86\x48\x86\xF7\x0D\x01\x09"
-#define OID_PKCS9_EMAIL OID_PKCS9 "\x01"
-
-/** ISO arc for standard certificate and CRL extensions */
-#define OID_ID_CE "\x55\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */
-
-/**
- * Private Internet Extensions
- * { iso(1) identified-organization(3) dod(6) internet(1)
- * security(5) mechanisms(5) pkix(7) }
- */
-#define OID_PKIX "\x2B\x06\x01\x05\x05\x07"
-
-/*
- * OIDs for standard certificate extensions
- */
-#define OID_AUTHORITY_KEY_IDENTIFIER OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } */
-#define OID_SUBJECT_KEY_IDENTIFIER OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } */
-#define OID_KEY_USAGE OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } */
-#define OID_CERTIFICATE_POLICIES OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } */
-#define OID_POLICY_MAPPINGS OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } */
-#define OID_SUBJECT_ALT_NAME OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } */
-#define OID_ISSUER_ALT_NAME OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } */
-#define OID_SUBJECT_DIRECTORY_ATTRS OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } */
-#define OID_BASIC_CONSTRAINTS OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } */
-#define OID_NAME_CONSTRAINTS OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } */
-#define OID_POLICY_CONSTRAINTS OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } */
-#define OID_EXTENDED_KEY_USAGE OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */
-#define OID_CRL_DISTRIBUTION_POINTS OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } */
-#define OID_INIHIBIT_ANYPOLICY OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */
-#define OID_FRESHEST_CRL OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */
-
-/*
- * X.509 v3 Key Usage Extension flags
- */
-#define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */
-#define KU_NON_REPUDIATION (0x40) /* bit 1 */
-#define KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */
-#define KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */
-#define KU_KEY_AGREEMENT (0x08) /* bit 4 */
-#define KU_KEY_CERT_SIGN (0x04) /* bit 5 */
-#define KU_CRL_SIGN (0x02) /* bit 6 */
-
-/*
- * X.509 v3 Extended key usage OIDs
- */
-#define OID_ANY_EXTENDED_KEY_USAGE OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */
-
-#define OID_KP OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */
-#define OID_SERVER_AUTH OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */
-#define OID_CLIENT_AUTH OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */
-#define OID_CODE_SIGNING OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */
-#define OID_EMAIL_PROTECTION OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */
-#define OID_TIME_STAMPING OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
-#define OID_OCSP_SIGNING OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
-
-#define STRING_SERVER_AUTH "TLS Web Server Authentication"
-#define STRING_CLIENT_AUTH "TLS Web Client Authentication"
-#define STRING_CODE_SIGNING "Code Signing"
-#define STRING_EMAIL_PROTECTION "E-mail Protection"
-#define STRING_TIME_STAMPING "Time Stamping"
-#define STRING_OCSP_SIGNING "OCSP Signing"
-
-/*
- * OIDs for CRL extensions
- */
-#define OID_PRIVATE_KEY_USAGE_PERIOD OID_ID_CE "\x10"
-#define OID_CRL_NUMBER OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */
-
-/*
- * Netscape certificate extensions
- */
-#define OID_NETSCAPE "\x60\x86\x48\x01\x86\xF8\x42" /**< Netscape OID */
-#define OID_NS_CERT OID_NETSCAPE "\x01"
-#define OID_NS_CERT_TYPE OID_NS_CERT "\x01"
-#define OID_NS_BASE_URL OID_NS_CERT "\x02"
-#define OID_NS_REVOCATION_URL OID_NS_CERT "\x03"
-#define OID_NS_CA_REVOCATION_URL OID_NS_CERT "\x04"
-#define OID_NS_RENEWAL_URL OID_NS_CERT "\x07"
-#define OID_NS_CA_POLICY_URL OID_NS_CERT "\x08"
-#define OID_NS_SSL_SERVER_NAME OID_NS_CERT "\x0C"
-#define OID_NS_COMMENT OID_NS_CERT "\x0D"
-#define OID_NS_DATA_TYPE OID_NETSCAPE "\x02"
-#define OID_NS_CERT_SEQUENCE OID_NS_DATA_TYPE "\x05"
-
-/*
- * Netscape certificate types
- * (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html)
- */
-
-#define NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */
-#define NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */
-#define NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */
-#define NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */
-#define NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */
-#define NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */
-#define NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */
-#define NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */
-
-#define EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0)
-#define EXT_SUBJECT_KEY_IDENTIFIER (1 << 1)
-#define EXT_KEY_USAGE (1 << 2)
-#define EXT_CERTIFICATE_POLICIES (1 << 3)
-#define EXT_POLICY_MAPPINGS (1 << 4)
-#define EXT_SUBJECT_ALT_NAME (1 << 5)
-#define EXT_ISSUER_ALT_NAME (1 << 6)
-#define EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7)
-#define EXT_BASIC_CONSTRAINTS (1 << 8)
-#define EXT_NAME_CONSTRAINTS (1 << 9)
-#define EXT_POLICY_CONSTRAINTS (1 << 10)
-#define EXT_EXTENDED_KEY_USAGE (1 << 11)
-#define EXT_CRL_DISTRIBUTION_POINTS (1 << 12)
-#define EXT_INIHIBIT_ANYPOLICY (1 << 13)
-#define EXT_FRESHEST_CRL (1 << 14)
-
-#define EXT_NS_CERT_TYPE (1 << 16)
-
-/*
- * Storage format identifiers
- * Recognized formats: PEM and DER
- */
-#define X509_FORMAT_DER 1
-#define X509_FORMAT_PEM 2
-
-/**
- * \addtogroup x509_module
- * \{ */
-
-/**
- * \name Structures for parsing X.509 certificates and CRLs
- * \{
- */
-
-/**
- * Type-length-value structure that allows for ASN1 using DER.
- */
-typedef asn1_buf x509_buf;
-
-/**
- * Container for ASN1 bit strings.
- */
-typedef asn1_bitstring x509_bitstring;
-
-/**
- * Container for ASN1 named information objects.
- * It allows for Relative Distinguished Names (e.g. cn=polarssl,ou=code,etc.).
- */
-typedef struct _x509_name
-{
- x509_buf oid; /**< The object identifier. */
- x509_buf val; /**< The named value. */
- struct _x509_name *next; /**< The next named information object. */
-}
-x509_name;
-
-/**
- * Container for a sequence of ASN.1 items
- */
-typedef asn1_sequence x509_sequence;
-
-/** Container for date and time (precision in seconds). */
-typedef struct _x509_time
-{
- int year, mon, day; /**< Date. */
- int hour, min, sec; /**< Time. */
-}
-x509_time;
-
-/**
- * Container for an X.509 certificate. The certificate may be chained.
- */
-typedef struct _x509_cert
-{
- x509_buf raw; /**< The raw certificate data (DER). */
- x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
-
- int version; /**< The X.509 version. (0=v1, 1=v2, 2=v3) */
- x509_buf serial; /**< Unique id for certificate issued by a specific CA. */
- x509_buf sig_oid1; /**< Signature algorithm, e.g. sha1RSA */
-
- x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */
- x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */
-
- x509_name issuer; /**< The parsed issuer data (named information object). */
- x509_name subject; /**< The parsed subject data (named information object). */
-
- x509_time valid_from; /**< Start time of certificate validity. */
- x509_time valid_to; /**< End time of certificate validity. */
-
- x509_buf pk_oid; /**< Subject public key info. Includes the public key algorithm and the key itself. */
- rsa_context rsa; /**< Container for the RSA context. Only RSA is supported for public keys at this time. */
-
- x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
- x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
- x509_buf v3_ext; /**< Optional X.509 v3 extensions. Only Basic Contraints are supported at this time. */
-
- int ext_types; /**< Bit string containing detected and parsed extensions */
- int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
- int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. */
-
- unsigned char key_usage; /**< Optional key usage extension value: See the values below */
-
- x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */
-
- unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values below */
-
- x509_buf sig_oid2; /**< Signature algorithm. Must match sig_oid1. */
- x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */
- int sig_alg; /**< Internal representation of the signature algorithm, e.g. SIG_RSA_MD2 */
-
- struct _x509_cert *next; /**< Next certificate in the CA-chain. */
-}
-x509_cert;
-
-/**
- * Certificate revocation list entry.
- * Contains the CA-specific serial numbers and revocation dates.
- */
-typedef struct _x509_crl_entry
-{
- x509_buf raw;
-
- x509_buf serial;
-
- x509_time revocation_date;
-
- x509_buf entry_ext;
-
- struct _x509_crl_entry *next;
-}
-x509_crl_entry;
-
-/**
- * Certificate revocation list structure.
- * Every CRL may have multiple entries.
- */
-typedef struct _x509_crl
-{
- x509_buf raw; /**< The raw certificate data (DER). */
- x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
-
- int version;
- x509_buf sig_oid1;
-
- x509_buf issuer_raw; /**< The raw issuer data (DER). */
-
- x509_name issuer; /**< The parsed issuer data (named information object). */
-
- x509_time this_update;
- x509_time next_update;
-
- x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */
-
- x509_buf crl_ext;
-
- x509_buf sig_oid2;
- x509_buf sig;
- int sig_alg;
-
- struct _x509_crl *next;
-}
-x509_crl;
-/** \} name Structures for parsing X.509 certificates and CRLs */
-/** \} addtogroup x509_module */
-
-/**
- * \name Structures for writing X.509 certificates.
- * XvP: commented out as they are not used.
- * - <tt>typedef struct _x509_node x509_node;</tt>
- * - <tt>typedef struct _x509_raw x509_raw;</tt>
- */
-/*
-typedef struct _x509_node
-{
- unsigned char *data;
- unsigned char *p;
- unsigned char *end;
-
- size_t len;
-}
-x509_node;
-
-typedef struct _x509_raw
-{
- x509_node raw;
- x509_node tbs;
-
- x509_node version;
- x509_node serial;
- x509_node tbs_signalg;
- x509_node issuer;
- x509_node validity;
- x509_node subject;
- x509_node subpubkey;
-
- x509_node signalg;
- x509_node sign;
-}
-x509_raw;
-*/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \name Functions to read in DHM parameters, a certificate, CRL or private RSA key
- * \{
- */
-
-/** \ingroup x509_module */
-/**
- * \brief Parse one or more certificates and add them
- * to the chained list. Parses permissively. If some
- * certificates can be parsed, the result is the number
- * of failed certificates it encountered. If none complete
- * correctly, the first error is returned.
- *
- * \param chain points to the start of the chain
- * \param buf buffer holding the certificate data
- * \param buflen size of the buffer
- *
- * \return 0 if all certificates parsed successfully, a positive number
- * if partly successful or a specific X509 or PEM error code
- */
-int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen );
-
-/** \ingroup x509_module */
-/**
- * \brief Load one or more certificates and add them
- * to the chained list. Parses permissively. If some
- * certificates can be parsed, the result is the number
- * of failed certificates it encountered. If none complete
- * correctly, the first error is returned.
- *
- * \param chain points to the start of the chain
- * \param path filename to read the certificates from
- *
- * \return 0 if all certificates parsed successfully, a positive number
- * if partly successful or a specific X509 or PEM error code
- */
-int x509parse_crtfile( x509_cert *chain, const char *path );
-
-/** \ingroup x509_module */
-/**
- * \brief Parse one or more CRLs and add them
- * to the chained list
- *
- * \param chain points to the start of the chain
- * \param buf buffer holding the CRL data
- * \param buflen size of the buffer
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen );
-
-/** \ingroup x509_module */
-/**
- * \brief Load one or more CRLs and add them
- * to the chained list
- *
- * \param chain points to the start of the chain
- * \param path filename to read the CRLs from
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_crlfile( x509_crl *chain, const char *path );
-
-/** \ingroup x509_module */
-/**
- * \brief Parse a private RSA key
- *
- * \param rsa RSA context to be initialized
- * \param key input buffer
- * \param keylen size of the buffer
- * \param pwd password for decryption (optional)
- * \param pwdlen size of the password
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_key( rsa_context *rsa,
- const unsigned char *key, size_t keylen,
- const unsigned char *pwd, size_t pwdlen );
-
-/** \ingroup x509_module */
-/**
- * \brief Load and parse a private RSA key
- *
- * \param rsa RSA context to be initialized
- * \param path filename to read the private key from
- * \param password password to decrypt the file (can be NULL)
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_keyfile( rsa_context *rsa, const char *path,
- const char *password );
-
-/** \ingroup x509_module */
-/**
- * \brief Parse a public RSA key
- *
- * \param rsa RSA context to be initialized
- * \param key input buffer
- * \param keylen size of the buffer
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_public_key( rsa_context *rsa,
- const unsigned char *key, size_t keylen );
-
-/** \ingroup x509_module */
-/**
- * \brief Load and parse a public RSA key
- *
- * \param rsa RSA context to be initialized
- * \param path filename to read the private key from
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_public_keyfile( rsa_context *rsa, const char *path );
-
-/** \ingroup x509_module */
-/**
- * \brief Parse DHM parameters
- *
- * \param dhm DHM context to be initialized
- * \param dhmin input buffer
- * \param dhminlen size of the buffer
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen );
-
-/** \ingroup x509_module */
-/**
- * \brief Load and parse DHM parameters
- *
- * \param dhm DHM context to be initialized
- * \param path filename to read the DHM Parameters from
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_dhmfile( dhm_context *dhm, const char *path );
-
-/** \} name Functions to read in DHM parameters, a certificate, CRL or private RSA key */
-
-/**
- * \brief Store the certificate DN in printable form into buf;
- * no more than size characters will be written.
- *
- * \param buf Buffer to write to
- * \param size Maximum size of buffer
- * \param dn The X509 name to represent
- *
- * \return The amount of data written to the buffer, or -1 in
- * case of an error.
- */
-int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn );
-
-/**
- * \brief Store the certificate serial in printable form into buf;
- * no more than size characters will be written.
- *
- * \param buf Buffer to write to
- * \param size Maximum size of buffer
- * \param serial The X509 serial to represent
- *
- * \return The amount of data written to the buffer, or -1 in
- * case of an error.
- */
-int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial );
-
-/**
- * \brief Returns an informational string about the
- * certificate.
- *
- * \param buf Buffer to write to
- * \param size Maximum size of buffer
- * \param prefix A line prefix
- * \param crt The X509 certificate to represent
- *
- * \return The amount of data written to the buffer, or -1 in
- * case of an error.
- */
-int x509parse_cert_info( char *buf, size_t size, const char *prefix,
- const x509_cert *crt );
-
-/**
- * \brief Returns an informational string about the
- * CRL.
- *
- * \param buf Buffer to write to
- * \param size Maximum size of buffer
- * \param prefix A line prefix
- * \param crl The X509 CRL to represent
- *
- * \return The amount of data written to the buffer, or -1 in
- * case of an error.
- */
-int x509parse_crl_info( char *buf, size_t size, const char *prefix,
- const x509_crl *crl );
-
-/**
- * \brief Give an known OID, return its descriptive string.
- *
- * \param oid buffer containing the oid
- *
- * \return Return a string if the OID is known,
- * or NULL otherwise.
- */
-const char *x509_oid_get_description( x509_buf *oid );
-
-/*
- * \brief Give an OID, return a string version of its OID number.
- *
- * \param buf Buffer to write to
- * \param size Maximum size of buffer
- * \param oid Buffer containing the OID
- *
- * \return The amount of data written to the buffer, or -1 in
- * case of an error.
- */
-int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid );
-
-/**
- * \brief Check a given x509_time against the system time and check
- * if it is valid.
- *
- * \param time x509_time to check
- *
- * \return Return 0 if the x509_time is still valid,
- * or 1 otherwise.
- */
-int x509parse_time_expired( const x509_time *time );
-
-/**
- * \name Functions to verify a certificate
- * \{
- */
-/** \ingroup x509_module */
-/**
- * \brief Verify the certificate signature
- *
- * \param crt a certificate to be verified
- * \param trust_ca the trusted CA chain
- * \param ca_crl the CRL chain for trusted CA's
- * \param cn expected Common Name (can be set to
- * NULL if the CN must not be verified)
- * \param flags result of the verification
- * \param f_vrfy verification function
- * \param p_vrfy verification parameter
- *
- * \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED,
- * in which case *flags will have one or more of
- * the following values set:
- * BADCERT_EXPIRED --
- * BADCERT_REVOKED --
- * BADCERT_CN_MISMATCH --
- * BADCERT_NOT_TRUSTED
- *
- * \note TODO: add two arguments, depth and crl
- */
-int x509parse_verify( x509_cert *crt,
- x509_cert *trust_ca,
- x509_crl *ca_crl,
- const char *cn, int *flags,
- int (*f_vrfy)(void *, x509_cert *, int, int),
- void *p_vrfy );
-
-/**
- * \brief Verify the certificate signature
- *
- * \param crt a certificate to be verified
- * \param crl the CRL to verify against
- *
- * \return 1 if the certificate is revoked, 0 otherwise
- *
- */
-int x509parse_revoked( const x509_cert *crt, const x509_crl *crl );
-
-/** \} name Functions to verify a certificate */
-
-
-
-/**
- * \name Functions to clear a certificate, CRL or private RSA key
- * \{
- */
-/** \ingroup x509_module */
-/**
- * \brief Unallocate all certificate data
- *
- * \param crt Certificate chain to free
- */
-void x509_free( x509_cert *crt );
-
-/** \ingroup x509_module */
-/**
- * \brief Unallocate all CRL data
- *
- * \param crl CRL chain to free
- */
-void x509_crl_free( x509_crl *crl );
-
-/** \} name Functions to clear a certificate, CRL or private RSA key */
-
-
-/**
- * \brief Checkup routine
- *
- * \return 0 if successful, or 1 if the test failed
- */
-int x509_self_test( int verbose );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* x509.h */
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/Makefile b/ANDROID_3.4.5/drivers/misc/sgi-gru/Makefile
deleted file mode 100644
index 0003a1d5..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-ccflags-$(CONFIG_SGI_GRU_DEBUG) := -DDEBUG
-
-obj-$(CONFIG_SGI_GRU) := gru.o
-gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o gruhandles.o grukdump.o
-
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/gru.h b/ANDROID_3.4.5/drivers/misc/sgi-gru/gru.h
deleted file mode 100644
index 3ad76cd1..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/gru.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __GRU_H__
-#define __GRU_H__
-
-/*
- * GRU architectural definitions
- */
-#define GRU_CACHE_LINE_BYTES 64
-#define GRU_HANDLE_STRIDE 256
-#define GRU_CB_BASE 0
-#define GRU_DS_BASE 0x20000
-
-/*
- * Size used to map GRU GSeg
- */
-#if defined(CONFIG_IA64)
-#define GRU_GSEG_PAGESIZE (256 * 1024UL)
-#elif defined(CONFIG_X86_64)
-#define GRU_GSEG_PAGESIZE (256 * 1024UL) /* ZZZ 2MB ??? */
-#else
-#error "Unsupported architecture"
-#endif
-
-/*
- * Structure for obtaining GRU resource information
- */
-struct gru_chiplet_info {
- int node;
- int chiplet;
- int blade;
- int total_dsr_bytes;
- int total_cbr;
- int total_user_dsr_bytes;
- int total_user_cbr;
- int free_user_dsr_bytes;
- int free_user_cbr;
-};
-
-/*
- * Statictics kept for each context.
- */
-struct gru_gseg_statistics {
- unsigned long fmm_tlbmiss;
- unsigned long upm_tlbmiss;
- unsigned long tlbdropin;
- unsigned long context_stolen;
- unsigned long reserved[10];
-};
-
-/* Flags for GRU options on the gru_create_context() call */
-/* Select one of the follow 4 options to specify how TLB misses are handled */
-#define GRU_OPT_MISS_DEFAULT 0x0000 /* Use default mode */
-#define GRU_OPT_MISS_USER_POLL 0x0001 /* User will poll CB for faults */
-#define GRU_OPT_MISS_FMM_INTR 0x0002 /* Send interrupt to cpu to
- handle fault */
-#define GRU_OPT_MISS_FMM_POLL 0x0003 /* Use system polling thread */
-#define GRU_OPT_MISS_MASK 0x0003 /* Mask for TLB MISS option */
-
-
-
-#endif /* __GRU_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/gru_instructions.h b/ANDROID_3.4.5/drivers/misc/sgi-gru/gru_instructions.h
deleted file mode 100644
index 04d5170a..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/gru_instructions.h
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __GRU_INSTRUCTIONS_H__
-#define __GRU_INSTRUCTIONS_H__
-
-extern int gru_check_status_proc(void *cb);
-extern int gru_wait_proc(void *cb);
-extern void gru_wait_abort_proc(void *cb);
-
-
-
-/*
- * Architecture dependent functions
- */
-
-#if defined(CONFIG_IA64)
-#include <linux/compiler.h>
-#include <asm/intrinsics.h>
-#define __flush_cache(p) ia64_fc((unsigned long)p)
-/* Use volatile on IA64 to ensure ordering via st4.rel */
-#define gru_ordered_store_ulong(p, v) \
- do { \
- barrier(); \
- *((volatile unsigned long *)(p)) = v; /* force st.rel */ \
- } while (0)
-#elif defined(CONFIG_X86_64)
-#include <asm/cacheflush.h>
-#define __flush_cache(p) clflush(p)
-#define gru_ordered_store_ulong(p, v) \
- do { \
- barrier(); \
- *(unsigned long *)p = v; \
- } while (0)
-#else
-#error "Unsupported architecture"
-#endif
-
-/*
- * Control block status and exception codes
- */
-#define CBS_IDLE 0
-#define CBS_EXCEPTION 1
-#define CBS_ACTIVE 2
-#define CBS_CALL_OS 3
-
-/* CB substatus bitmasks */
-#define CBSS_MSG_QUEUE_MASK 7
-#define CBSS_IMPLICIT_ABORT_ACTIVE_MASK 8
-
-/* CB substatus message queue values (low 3 bits of substatus) */
-#define CBSS_NO_ERROR 0
-#define CBSS_LB_OVERFLOWED 1
-#define CBSS_QLIMIT_REACHED 2
-#define CBSS_PAGE_OVERFLOW 3
-#define CBSS_AMO_NACKED 4
-#define CBSS_PUT_NACKED 5
-
-/*
- * Structure used to fetch exception detail for CBs that terminate with
- * CBS_EXCEPTION
- */
-struct control_block_extended_exc_detail {
- unsigned long cb;
- int opc;
- int ecause;
- int exopc;
- long exceptdet0;
- int exceptdet1;
- int cbrstate;
- int cbrexecstatus;
-};
-
-/*
- * Instruction formats
- */
-
-/*
- * Generic instruction format.
- * This definition has precise bit field definitions.
- */
-struct gru_instruction_bits {
- /* DW 0 - low */
- unsigned int icmd: 1;
- unsigned char ima: 3; /* CB_DelRep, unmapped mode */
- unsigned char reserved0: 4;
- unsigned int xtype: 3;
- unsigned int iaa0: 2;
- unsigned int iaa1: 2;
- unsigned char reserved1: 1;
- unsigned char opc: 8; /* opcode */
- unsigned char exopc: 8; /* extended opcode */
- /* DW 0 - high */
- unsigned int idef2: 22; /* TRi0 */
- unsigned char reserved2: 2;
- unsigned char istatus: 2;
- unsigned char isubstatus:4;
- unsigned char reserved3: 1;
- unsigned char tlb_fault_color: 1;
- /* DW 1 */
- unsigned long idef4; /* 42 bits: TRi1, BufSize */
- /* DW 2-6 */
- unsigned long idef1; /* BAddr0 */
- unsigned long idef5; /* Nelem */
- unsigned long idef6; /* Stride, Operand1 */
- unsigned long idef3; /* BAddr1, Value, Operand2 */
- unsigned long reserved4;
- /* DW 7 */
- unsigned long avalue; /* AValue */
-};
-
-/*
- * Generic instruction with friendlier names. This format is used
- * for inline instructions.
- */
-struct gru_instruction {
- /* DW 0 */
- union {
- unsigned long op64; /* icmd,xtype,iaa0,ima,opc,tri0 */
- struct {
- unsigned int op32;
- unsigned int tri0;
- };
- };
- unsigned long tri1_bufsize; /* DW 1 */
- unsigned long baddr0; /* DW 2 */
- unsigned long nelem; /* DW 3 */
- unsigned long op1_stride; /* DW 4 */
- unsigned long op2_value_baddr1; /* DW 5 */
- unsigned long reserved0; /* DW 6 */
- unsigned long avalue; /* DW 7 */
-};
-
-/* Some shifts and masks for the low 64 bits of a GRU command */
-#define GRU_CB_ICMD_SHFT 0
-#define GRU_CB_ICMD_MASK 0x1
-#define GRU_CB_XTYPE_SHFT 8
-#define GRU_CB_XTYPE_MASK 0x7
-#define GRU_CB_IAA0_SHFT 11
-#define GRU_CB_IAA0_MASK 0x3
-#define GRU_CB_IAA1_SHFT 13
-#define GRU_CB_IAA1_MASK 0x3
-#define GRU_CB_IMA_SHFT 1
-#define GRU_CB_IMA_MASK 0x3
-#define GRU_CB_OPC_SHFT 16
-#define GRU_CB_OPC_MASK 0xff
-#define GRU_CB_EXOPC_SHFT 24
-#define GRU_CB_EXOPC_MASK 0xff
-#define GRU_IDEF2_SHFT 32
-#define GRU_IDEF2_MASK 0x3ffff
-#define GRU_ISTATUS_SHFT 56
-#define GRU_ISTATUS_MASK 0x3
-
-/* GRU instruction opcodes (opc field) */
-#define OP_NOP 0x00
-#define OP_BCOPY 0x01
-#define OP_VLOAD 0x02
-#define OP_IVLOAD 0x03
-#define OP_VSTORE 0x04
-#define OP_IVSTORE 0x05
-#define OP_VSET 0x06
-#define OP_IVSET 0x07
-#define OP_MESQ 0x08
-#define OP_GAMXR 0x09
-#define OP_GAMIR 0x0a
-#define OP_GAMIRR 0x0b
-#define OP_GAMER 0x0c
-#define OP_GAMERR 0x0d
-#define OP_BSTORE 0x0e
-#define OP_VFLUSH 0x0f
-
-
-/* Extended opcodes values (exopc field) */
-
-/* GAMIR - AMOs with implicit operands */
-#define EOP_IR_FETCH 0x01 /* Plain fetch of memory */
-#define EOP_IR_CLR 0x02 /* Fetch and clear */
-#define EOP_IR_INC 0x05 /* Fetch and increment */
-#define EOP_IR_DEC 0x07 /* Fetch and decrement */
-#define EOP_IR_QCHK1 0x0d /* Queue check, 64 byte msg */
-#define EOP_IR_QCHK2 0x0e /* Queue check, 128 byte msg */
-
-/* GAMIRR - Registered AMOs with implicit operands */
-#define EOP_IRR_FETCH 0x01 /* Registered fetch of memory */
-#define EOP_IRR_CLR 0x02 /* Registered fetch and clear */
-#define EOP_IRR_INC 0x05 /* Registered fetch and increment */
-#define EOP_IRR_DEC 0x07 /* Registered fetch and decrement */
-#define EOP_IRR_DECZ 0x0f /* Registered fetch and decrement, update on zero*/
-
-/* GAMER - AMOs with explicit operands */
-#define EOP_ER_SWAP 0x00 /* Exchange argument and memory */
-#define EOP_ER_OR 0x01 /* Logical OR with memory */
-#define EOP_ER_AND 0x02 /* Logical AND with memory */
-#define EOP_ER_XOR 0x03 /* Logical XOR with memory */
-#define EOP_ER_ADD 0x04 /* Add value to memory */
-#define EOP_ER_CSWAP 0x08 /* Compare with operand2, write operand1 if match*/
-#define EOP_ER_CADD 0x0c /* Queue check, operand1*64 byte msg */
-
-/* GAMERR - Registered AMOs with explicit operands */
-#define EOP_ERR_SWAP 0x00 /* Exchange argument and memory */
-#define EOP_ERR_OR 0x01 /* Logical OR with memory */
-#define EOP_ERR_AND 0x02 /* Logical AND with memory */
-#define EOP_ERR_XOR 0x03 /* Logical XOR with memory */
-#define EOP_ERR_ADD 0x04 /* Add value to memory */
-#define EOP_ERR_CSWAP 0x08 /* Compare with operand2, write operand1 if match*/
-#define EOP_ERR_EPOLL 0x09 /* Poll for equality */
-#define EOP_ERR_NPOLL 0x0a /* Poll for inequality */
-
-/* GAMXR - SGI Arithmetic unit */
-#define EOP_XR_CSWAP 0x0b /* Masked compare exchange */
-
-
-/* Transfer types (xtype field) */
-#define XTYPE_B 0x0 /* byte */
-#define XTYPE_S 0x1 /* short (2-byte) */
-#define XTYPE_W 0x2 /* word (4-byte) */
-#define XTYPE_DW 0x3 /* doubleword (8-byte) */
-#define XTYPE_CL 0x6 /* cacheline (64-byte) */
-
-
-/* Instruction access attributes (iaa0, iaa1 fields) */
-#define IAA_RAM 0x0 /* normal cached RAM access */
-#define IAA_NCRAM 0x2 /* noncoherent RAM access */
-#define IAA_MMIO 0x1 /* noncoherent memory-mapped I/O space */
-#define IAA_REGISTER 0x3 /* memory-mapped registers, etc. */
-
-
-/* Instruction mode attributes (ima field) */
-#define IMA_MAPPED 0x0 /* Virtual mode */
-#define IMA_CB_DELAY 0x1 /* hold read responses until status changes */
-#define IMA_UNMAPPED 0x2 /* bypass the TLBs (OS only) */
-#define IMA_INTERRUPT 0x4 /* Interrupt when instruction completes */
-
-/* CBE ecause bits */
-#define CBE_CAUSE_RI (1 << 0)
-#define CBE_CAUSE_INVALID_INSTRUCTION (1 << 1)
-#define CBE_CAUSE_UNMAPPED_MODE_FORBIDDEN (1 << 2)
-#define CBE_CAUSE_PE_CHECK_DATA_ERROR (1 << 3)
-#define CBE_CAUSE_IAA_GAA_MISMATCH (1 << 4)
-#define CBE_CAUSE_DATA_SEGMENT_LIMIT_EXCEPTION (1 << 5)
-#define CBE_CAUSE_OS_FATAL_TLB_FAULT (1 << 6)
-#define CBE_CAUSE_EXECUTION_HW_ERROR (1 << 7)
-#define CBE_CAUSE_TLBHW_ERROR (1 << 8)
-#define CBE_CAUSE_RA_REQUEST_TIMEOUT (1 << 9)
-#define CBE_CAUSE_HA_REQUEST_TIMEOUT (1 << 10)
-#define CBE_CAUSE_RA_RESPONSE_FATAL (1 << 11)
-#define CBE_CAUSE_RA_RESPONSE_NON_FATAL (1 << 12)
-#define CBE_CAUSE_HA_RESPONSE_FATAL (1 << 13)
-#define CBE_CAUSE_HA_RESPONSE_NON_FATAL (1 << 14)
-#define CBE_CAUSE_ADDRESS_SPACE_DECODE_ERROR (1 << 15)
-#define CBE_CAUSE_PROTOCOL_STATE_DATA_ERROR (1 << 16)
-#define CBE_CAUSE_RA_RESPONSE_DATA_ERROR (1 << 17)
-#define CBE_CAUSE_HA_RESPONSE_DATA_ERROR (1 << 18)
-#define CBE_CAUSE_FORCED_ERROR (1 << 19)
-
-/* CBE cbrexecstatus bits */
-#define CBR_EXS_ABORT_OCC_BIT 0
-#define CBR_EXS_INT_OCC_BIT 1
-#define CBR_EXS_PENDING_BIT 2
-#define CBR_EXS_QUEUED_BIT 3
-#define CBR_EXS_TLB_INVAL_BIT 4
-#define CBR_EXS_EXCEPTION_BIT 5
-#define CBR_EXS_CB_INT_PENDING_BIT 6
-
-#define CBR_EXS_ABORT_OCC (1 << CBR_EXS_ABORT_OCC_BIT)
-#define CBR_EXS_INT_OCC (1 << CBR_EXS_INT_OCC_BIT)
-#define CBR_EXS_PENDING (1 << CBR_EXS_PENDING_BIT)
-#define CBR_EXS_QUEUED (1 << CBR_EXS_QUEUED_BIT)
-#define CBR_EXS_TLB_INVAL (1 << CBR_EXS_TLB_INVAL_BIT)
-#define CBR_EXS_EXCEPTION (1 << CBR_EXS_EXCEPTION_BIT)
-#define CBR_EXS_CB_INT_PENDING (1 << CBR_EXS_CB_INT_PENDING_BIT)
-
-/*
- * Exceptions are retried for the following cases. If any OTHER bits are set
- * in ecause, the exception is not retryable.
- */
-#define EXCEPTION_RETRY_BITS (CBE_CAUSE_EXECUTION_HW_ERROR | \
- CBE_CAUSE_TLBHW_ERROR | \
- CBE_CAUSE_RA_REQUEST_TIMEOUT | \
- CBE_CAUSE_RA_RESPONSE_NON_FATAL | \
- CBE_CAUSE_HA_RESPONSE_NON_FATAL | \
- CBE_CAUSE_RA_RESPONSE_DATA_ERROR | \
- CBE_CAUSE_HA_RESPONSE_DATA_ERROR \
- )
-
-/* Message queue head structure */
-union gru_mesqhead {
- unsigned long val;
- struct {
- unsigned int head;
- unsigned int limit;
- };
-};
-
-
-/* Generate the low word of a GRU instruction */
-static inline unsigned long
-__opdword(unsigned char opcode, unsigned char exopc, unsigned char xtype,
- unsigned char iaa0, unsigned char iaa1,
- unsigned long idef2, unsigned char ima)
-{
- return (1 << GRU_CB_ICMD_SHFT) |
- ((unsigned long)CBS_ACTIVE << GRU_ISTATUS_SHFT) |
- (idef2<< GRU_IDEF2_SHFT) |
- (iaa0 << GRU_CB_IAA0_SHFT) |
- (iaa1 << GRU_CB_IAA1_SHFT) |
- (ima << GRU_CB_IMA_SHFT) |
- (xtype << GRU_CB_XTYPE_SHFT) |
- (opcode << GRU_CB_OPC_SHFT) |
- (exopc << GRU_CB_EXOPC_SHFT);
-}
-
-/*
- * Architecture specific intrinsics
- */
-static inline void gru_flush_cache(void *p)
-{
- __flush_cache(p);
-}
-
-/*
- * Store the lower 64 bits of the command including the "start" bit. Then
- * start the instruction executing.
- */
-static inline void gru_start_instruction(struct gru_instruction *ins, unsigned long op64)
-{
- gru_ordered_store_ulong(ins, op64);
- mb();
- gru_flush_cache(ins);
-}
-
-
-/* Convert "hints" to IMA */
-#define CB_IMA(h) ((h) | IMA_UNMAPPED)
-
-/* Convert data segment cache line index into TRI0 / TRI1 value */
-#define GRU_DINDEX(i) ((i) * GRU_CACHE_LINE_BYTES)
-
-/* Inline functions for GRU instructions.
- * Note:
- * - nelem and stride are in elements
- * - tri0/tri1 is in bytes for the beginning of the data segment.
- */
-static inline void gru_vload_phys(void *cb, unsigned long gpa,
- unsigned int tri0, int iaa, unsigned long hints)
-{
- struct gru_instruction *ins = (struct gru_instruction *)cb;
-
- ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
- ins->nelem = 1;
- ins->op1_stride = 1;
- gru_start_instruction(ins, __opdword(OP_VLOAD, 0, XTYPE_DW, iaa, 0,
- (unsigned long)tri0, CB_IMA(hints)));
-}
-
-static inline void gru_vstore_phys(void *cb, unsigned long gpa,
- unsigned int tri0, int iaa, unsigned long hints)
-{
- struct gru_instruction *ins = (struct gru_instruction *)cb;
-
- ins->baddr0 = (long)gpa | ((unsigned long)iaa << 62);
- ins->nelem = 1;
- ins->op1_stride = 1;
- gru_start_instruction(ins, __opdword(OP_VSTORE, 0, XTYPE_DW, iaa, 0,
- (unsigned long)tri0, CB_IMA(hints)));
-}
-
-static inline void gru_vload(void *cb, unsigned long mem_addr,
- unsigned int tri0, unsigned char xtype, unsigned long nelem,
- unsigned long stride, unsigned long hints)
-{
- struct gru_instruction *ins = (struct gru_instruction *)cb;
-
- ins->baddr0 = (long)mem_addr;
- ins->nelem = nelem;
- ins->op1_stride = stride;
- gru_start_instruction(ins, __opdword(OP_VLOAD, 0, xtype, IAA_RAM, 0,
- (unsigned long)tri0, CB_IMA(hints)));
-}
-
-static inline void gru_vstore(void *cb, unsigned long mem_addr,
- unsigned int tri0, unsigned char xtype, unsigned long nelem,
- unsigned long stride, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)mem_addr;
- ins->nelem = nelem;
- ins->op1_stride = stride;
- gru_start_instruction(ins, __opdword(OP_VSTORE, 0, xtype, IAA_RAM, 0,
- tri0, CB_IMA(hints)));
-}
-
-static inline void gru_ivload(void *cb, unsigned long mem_addr,
- unsigned int tri0, unsigned int tri1, unsigned char xtype,
- unsigned long nelem, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)mem_addr;
- ins->nelem = nelem;
- ins->tri1_bufsize = tri1;
- gru_start_instruction(ins, __opdword(OP_IVLOAD, 0, xtype, IAA_RAM, 0,
- tri0, CB_IMA(hints)));
-}
-
-static inline void gru_ivstore(void *cb, unsigned long mem_addr,
- unsigned int tri0, unsigned int tri1,
- unsigned char xtype, unsigned long nelem, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)mem_addr;
- ins->nelem = nelem;
- ins->tri1_bufsize = tri1;
- gru_start_instruction(ins, __opdword(OP_IVSTORE, 0, xtype, IAA_RAM, 0,
- tri0, CB_IMA(hints)));
-}
-
-static inline void gru_vset(void *cb, unsigned long mem_addr,
- unsigned long value, unsigned char xtype, unsigned long nelem,
- unsigned long stride, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)mem_addr;
- ins->op2_value_baddr1 = value;
- ins->nelem = nelem;
- ins->op1_stride = stride;
- gru_start_instruction(ins, __opdword(OP_VSET, 0, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
-}
-
-static inline void gru_ivset(void *cb, unsigned long mem_addr,
- unsigned int tri1, unsigned long value, unsigned char xtype,
- unsigned long nelem, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)mem_addr;
- ins->op2_value_baddr1 = value;
- ins->nelem = nelem;
- ins->tri1_bufsize = tri1;
- gru_start_instruction(ins, __opdword(OP_IVSET, 0, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
-}
-
-static inline void gru_vflush(void *cb, unsigned long mem_addr,
- unsigned long nelem, unsigned char xtype, unsigned long stride,
- unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)mem_addr;
- ins->op1_stride = stride;
- ins->nelem = nelem;
- gru_start_instruction(ins, __opdword(OP_VFLUSH, 0, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
-}
-
-static inline void gru_nop(void *cb, int hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- gru_start_instruction(ins, __opdword(OP_NOP, 0, 0, 0, 0, 0, CB_IMA(hints)));
-}
-
-
-static inline void gru_bcopy(void *cb, const unsigned long src,
- unsigned long dest,
- unsigned int tri0, unsigned int xtype, unsigned long nelem,
- unsigned int bufsize, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)src;
- ins->op2_value_baddr1 = (long)dest;
- ins->nelem = nelem;
- ins->tri1_bufsize = bufsize;
- gru_start_instruction(ins, __opdword(OP_BCOPY, 0, xtype, IAA_RAM,
- IAA_RAM, tri0, CB_IMA(hints)));
-}
-
-static inline void gru_bstore(void *cb, const unsigned long src,
- unsigned long dest, unsigned int tri0, unsigned int xtype,
- unsigned long nelem, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)src;
- ins->op2_value_baddr1 = (long)dest;
- ins->nelem = nelem;
- gru_start_instruction(ins, __opdword(OP_BSTORE, 0, xtype, 0, IAA_RAM,
- tri0, CB_IMA(hints)));
-}
-
-static inline void gru_gamir(void *cb, int exopc, unsigned long src,
- unsigned int xtype, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)src;
- gru_start_instruction(ins, __opdword(OP_GAMIR, exopc, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
-}
-
-static inline void gru_gamirr(void *cb, int exopc, unsigned long src,
- unsigned int xtype, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)src;
- gru_start_instruction(ins, __opdword(OP_GAMIRR, exopc, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
-}
-
-static inline void gru_gamer(void *cb, int exopc, unsigned long src,
- unsigned int xtype,
- unsigned long operand1, unsigned long operand2,
- unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)src;
- ins->op1_stride = operand1;
- ins->op2_value_baddr1 = operand2;
- gru_start_instruction(ins, __opdword(OP_GAMER, exopc, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
-}
-
-static inline void gru_gamerr(void *cb, int exopc, unsigned long src,
- unsigned int xtype, unsigned long operand1,
- unsigned long operand2, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)src;
- ins->op1_stride = operand1;
- ins->op2_value_baddr1 = operand2;
- gru_start_instruction(ins, __opdword(OP_GAMERR, exopc, xtype, IAA_RAM, 0,
- 0, CB_IMA(hints)));
-}
-
-static inline void gru_gamxr(void *cb, unsigned long src,
- unsigned int tri0, unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)src;
- ins->nelem = 4;
- gru_start_instruction(ins, __opdword(OP_GAMXR, EOP_XR_CSWAP, XTYPE_DW,
- IAA_RAM, 0, 0, CB_IMA(hints)));
-}
-
-static inline void gru_mesq(void *cb, unsigned long queue,
- unsigned long tri0, unsigned long nelem,
- unsigned long hints)
-{
- struct gru_instruction *ins = (void *)cb;
-
- ins->baddr0 = (long)queue;
- ins->nelem = nelem;
- gru_start_instruction(ins, __opdword(OP_MESQ, 0, XTYPE_CL, IAA_RAM, 0,
- tri0, CB_IMA(hints)));
-}
-
-static inline unsigned long gru_get_amo_value(void *cb)
-{
- struct gru_instruction *ins = (void *)cb;
-
- return ins->avalue;
-}
-
-static inline int gru_get_amo_value_head(void *cb)
-{
- struct gru_instruction *ins = (void *)cb;
-
- return ins->avalue & 0xffffffff;
-}
-
-static inline int gru_get_amo_value_limit(void *cb)
-{
- struct gru_instruction *ins = (void *)cb;
-
- return ins->avalue >> 32;
-}
-
-static inline union gru_mesqhead gru_mesq_head(int head, int limit)
-{
- union gru_mesqhead mqh;
-
- mqh.head = head;
- mqh.limit = limit;
- return mqh;
-}
-
-/*
- * Get struct control_block_extended_exc_detail for CB.
- */
-extern int gru_get_cb_exception_detail(void *cb,
- struct control_block_extended_exc_detail *excdet);
-
-#define GRU_EXC_STR_SIZE 256
-
-
-/*
- * Control block definition for checking status
- */
-struct gru_control_block_status {
- unsigned int icmd :1;
- unsigned int ima :3;
- unsigned int reserved0 :4;
- unsigned int unused1 :24;
- unsigned int unused2 :24;
- unsigned int istatus :2;
- unsigned int isubstatus :4;
- unsigned int unused3 :2;
-};
-
-/* Get CB status */
-static inline int gru_get_cb_status(void *cb)
-{
- struct gru_control_block_status *cbs = (void *)cb;
-
- return cbs->istatus;
-}
-
-/* Get CB message queue substatus */
-static inline int gru_get_cb_message_queue_substatus(void *cb)
-{
- struct gru_control_block_status *cbs = (void *)cb;
-
- return cbs->isubstatus & CBSS_MSG_QUEUE_MASK;
-}
-
-/* Get CB substatus */
-static inline int gru_get_cb_substatus(void *cb)
-{
- struct gru_control_block_status *cbs = (void *)cb;
-
- return cbs->isubstatus;
-}
-
-/*
- * User interface to check an instruction status. UPM and exceptions
- * are handled automatically. However, this function does NOT wait
- * for an active instruction to complete.
- *
- */
-static inline int gru_check_status(void *cb)
-{
- struct gru_control_block_status *cbs = (void *)cb;
- int ret;
-
- ret = cbs->istatus;
- if (ret != CBS_ACTIVE)
- ret = gru_check_status_proc(cb);
- return ret;
-}
-
-/*
- * User interface (via inline function) to wait for an instruction
- * to complete. Completion status (IDLE or EXCEPTION is returned
- * to the user. Exception due to hardware errors are automatically
- * retried before returning an exception.
- *
- */
-static inline int gru_wait(void *cb)
-{
- return gru_wait_proc(cb);
-}
-
-/*
- * Wait for CB to complete. Aborts program if error. (Note: error does NOT
- * mean TLB mis - only fatal errors such as memory parity error or user
- * bugs will cause termination.
- */
-static inline void gru_wait_abort(void *cb)
-{
- gru_wait_abort_proc(cb);
-}
-
-/*
- * Get a pointer to the start of a gseg
- * p - Any valid pointer within the gseg
- */
-static inline void *gru_get_gseg_pointer (void *p)
-{
- return (void *)((unsigned long)p & ~(GRU_GSEG_PAGESIZE - 1));
-}
-
-/*
- * Get a pointer to a control block
- * gseg - GSeg address returned from gru_get_thread_gru_segment()
- * index - index of desired CB
- */
-static inline void *gru_get_cb_pointer(void *gseg,
- int index)
-{
- return gseg + GRU_CB_BASE + index * GRU_HANDLE_STRIDE;
-}
-
-/*
- * Get a pointer to a cacheline in the data segment portion of a GSeg
- * gseg - GSeg address returned from gru_get_thread_gru_segment()
- * index - index of desired cache line
- */
-static inline void *gru_get_data_pointer(void *gseg, int index)
-{
- return gseg + GRU_DS_BASE + index * GRU_CACHE_LINE_BYTES;
-}
-
-/*
- * Convert a vaddr into the tri index within the GSEG
- * vaddr - virtual address of within gseg
- */
-static inline int gru_get_tri(void *vaddr)
-{
- return ((unsigned long)vaddr & (GRU_GSEG_PAGESIZE - 1)) - GRU_DS_BASE;
-}
-#endif /* __GRU_INSTRUCTIONS_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/grufault.c b/ANDROID_3.4.5/drivers/misc/sgi-gru/grufault.c
deleted file mode 100644
index c4acac74..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/grufault.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/*
- * SN Platform GRU Driver
- *
- * FAULT HANDLER FOR GRU DETECTED TLB MISSES
- *
- * This file contains code that handles TLB misses within the GRU.
- * These misses are reported either via interrupts or user polling of
- * the user CB.
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/hugetlb.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/security.h>
-#include <linux/prefetch.h>
-#include <asm/pgtable.h>
-#include "gru.h"
-#include "grutables.h"
-#include "grulib.h"
-#include "gru_instructions.h"
-#include <asm/uv/uv_hub.h>
-
-/* Return codes for vtop functions */
-#define VTOP_SUCCESS 0
-#define VTOP_INVALID -1
-#define VTOP_RETRY -2
-
-
-/*
- * Test if a physical address is a valid GRU GSEG address
- */
-static inline int is_gru_paddr(unsigned long paddr)
-{
- return paddr >= gru_start_paddr && paddr < gru_end_paddr;
-}
-
-/*
- * Find the vma of a GRU segment. Caller must hold mmap_sem.
- */
-struct vm_area_struct *gru_find_vma(unsigned long vaddr)
-{
- struct vm_area_struct *vma;
-
- vma = find_vma(current->mm, vaddr);
- if (vma && vma->vm_start <= vaddr && vma->vm_ops == &gru_vm_ops)
- return vma;
- return NULL;
-}
-
-/*
- * Find and lock the gts that contains the specified user vaddr.
- *
- * Returns:
- * - *gts with the mmap_sem locked for read and the GTS locked.
- * - NULL if vaddr invalid OR is not a valid GSEG vaddr.
- */
-
-static struct gru_thread_state *gru_find_lock_gts(unsigned long vaddr)
-{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- struct gru_thread_state *gts = NULL;
-
- down_read(&mm->mmap_sem);
- vma = gru_find_vma(vaddr);
- if (vma)
- gts = gru_find_thread_state(vma, TSID(vaddr, vma));
- if (gts)
- mutex_lock(&gts->ts_ctxlock);
- else
- up_read(&mm->mmap_sem);
- return gts;
-}
-
-static struct gru_thread_state *gru_alloc_locked_gts(unsigned long vaddr)
-{
- struct mm_struct *mm = current->mm;
- struct vm_area_struct *vma;
- struct gru_thread_state *gts = ERR_PTR(-EINVAL);
-
- down_write(&mm->mmap_sem);
- vma = gru_find_vma(vaddr);
- if (!vma)
- goto err;
-
- gts = gru_alloc_thread_state(vma, TSID(vaddr, vma));
- if (IS_ERR(gts))
- goto err;
- mutex_lock(&gts->ts_ctxlock);
- downgrade_write(&mm->mmap_sem);
- return gts;
-
-err:
- up_write(&mm->mmap_sem);
- return gts;
-}
-
-/*
- * Unlock a GTS that was previously locked with gru_find_lock_gts().
- */
-static void gru_unlock_gts(struct gru_thread_state *gts)
-{
- mutex_unlock(&gts->ts_ctxlock);
- up_read(&current->mm->mmap_sem);
-}
-
-/*
- * Set a CB.istatus to active using a user virtual address. This must be done
- * just prior to a TFH RESTART. The new cb.istatus is an in-cache status ONLY.
- * If the line is evicted, the status may be lost. The in-cache update
- * is necessary to prevent the user from seeing a stale cb.istatus that will
- * change as soon as the TFH restart is complete. Races may cause an
- * occasional failure to clear the cb.istatus, but that is ok.
- */
-static void gru_cb_set_istatus_active(struct gru_instruction_bits *cbk)
-{
- if (cbk) {
- cbk->istatus = CBS_ACTIVE;
- }
-}
-
-/*
- * Read & clear a TFM
- *
- * The GRU has an array of fault maps. A map is private to a cpu
- * Only one cpu will be accessing a cpu's fault map.
- *
- * This function scans the cpu-private fault map & clears all bits that
- * are set. The function returns a bitmap that indicates the bits that
- * were cleared. Note that sense the maps may be updated asynchronously by
- * the GRU, atomic operations must be used to clear bits.
- */
-static void get_clear_fault_map(struct gru_state *gru,
- struct gru_tlb_fault_map *imap,
- struct gru_tlb_fault_map *dmap)
-{
- unsigned long i, k;
- struct gru_tlb_fault_map *tfm;
-
- tfm = get_tfm_for_cpu(gru, gru_cpu_fault_map_id());
- prefetchw(tfm); /* Helps on hardware, required for emulator */
- for (i = 0; i < BITS_TO_LONGS(GRU_NUM_CBE); i++) {
- k = tfm->fault_bits[i];
- if (k)
- k = xchg(&tfm->fault_bits[i], 0UL);
- imap->fault_bits[i] = k;
- k = tfm->done_bits[i];
- if (k)
- k = xchg(&tfm->done_bits[i], 0UL);
- dmap->fault_bits[i] = k;
- }
-
- /*
- * Not functionally required but helps performance. (Required
- * on emulator)
- */
- gru_flush_cache(tfm);
-}
-
-/*
- * Atomic (interrupt context) & non-atomic (user context) functions to
- * convert a vaddr into a physical address. The size of the page
- * is returned in pageshift.
- * returns:
- * 0 - successful
- * < 0 - error code
- * 1 - (atomic only) try again in non-atomic context
- */
-static int non_atomic_pte_lookup(struct vm_area_struct *vma,
- unsigned long vaddr, int write,
- unsigned long *paddr, int *pageshift)
-{
- struct page *page;
-
-#ifdef CONFIG_HUGETLB_PAGE
- *pageshift = is_vm_hugetlb_page(vma) ? HPAGE_SHIFT : PAGE_SHIFT;
-#else
- *pageshift = PAGE_SHIFT;
-#endif
- if (get_user_pages
- (current, current->mm, vaddr, 1, write, 0, &page, NULL) <= 0)
- return -EFAULT;
- *paddr = page_to_phys(page);
- put_page(page);
- return 0;
-}
-
-/*
- * atomic_pte_lookup
- *
- * Convert a user virtual address to a physical address
- * Only supports Intel large pages (2MB only) on x86_64.
- * ZZZ - hugepage support is incomplete
- *
- * NOTE: mmap_sem is already held on entry to this function. This
- * guarantees existence of the page tables.
- */
-static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
- int write, unsigned long *paddr, int *pageshift)
-{
- pgd_t *pgdp;
- pmd_t *pmdp;
- pud_t *pudp;
- pte_t pte;
-
- pgdp = pgd_offset(vma->vm_mm, vaddr);
- if (unlikely(pgd_none(*pgdp)))
- goto err;
-
- pudp = pud_offset(pgdp, vaddr);
- if (unlikely(pud_none(*pudp)))
- goto err;
-
- pmdp = pmd_offset(pudp, vaddr);
- if (unlikely(pmd_none(*pmdp)))
- goto err;
-#ifdef CONFIG_X86_64
- if (unlikely(pmd_large(*pmdp)))
- pte = *(pte_t *) pmdp;
- else
-#endif
- pte = *pte_offset_kernel(pmdp, vaddr);
-
- if (unlikely(!pte_present(pte) ||
- (write && (!pte_write(pte) || !pte_dirty(pte)))))
- return 1;
-
- *paddr = pte_pfn(pte) << PAGE_SHIFT;
-#ifdef CONFIG_HUGETLB_PAGE
- *pageshift = is_vm_hugetlb_page(vma) ? HPAGE_SHIFT : PAGE_SHIFT;
-#else
- *pageshift = PAGE_SHIFT;
-#endif
- return 0;
-
-err:
- return 1;
-}
-
-static int gru_vtop(struct gru_thread_state *gts, unsigned long vaddr,
- int write, int atomic, unsigned long *gpa, int *pageshift)
-{
- struct mm_struct *mm = gts->ts_mm;
- struct vm_area_struct *vma;
- unsigned long paddr;
- int ret, ps;
-
- vma = find_vma(mm, vaddr);
- if (!vma)
- goto inval;
-
- /*
- * Atomic lookup is faster & usually works even if called in non-atomic
- * context.
- */
- rmb(); /* Must/check ms_range_active before loading PTEs */
- ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &ps);
- if (ret) {
- if (atomic)
- goto upm;
- if (non_atomic_pte_lookup(vma, vaddr, write, &paddr, &ps))
- goto inval;
- }
- if (is_gru_paddr(paddr))
- goto inval;
- paddr = paddr & ~((1UL << ps) - 1);
- *gpa = uv_soc_phys_ram_to_gpa(paddr);
- *pageshift = ps;
- return VTOP_SUCCESS;
-
-inval:
- return VTOP_INVALID;
-upm:
- return VTOP_RETRY;
-}
-
-
-/*
- * Flush a CBE from cache. The CBE is clean in the cache. Dirty the
- * CBE cacheline so that the line will be written back to home agent.
- * Otherwise the line may be silently dropped. This has no impact
- * except on performance.
- */
-static void gru_flush_cache_cbe(struct gru_control_block_extended *cbe)
-{
- if (unlikely(cbe)) {
- cbe->cbrexecstatus = 0; /* make CL dirty */
- gru_flush_cache(cbe);
- }
-}
-
-/*
- * Preload the TLB with entries that may be required. Currently, preloading
- * is implemented only for BCOPY. Preload <tlb_preload_count> pages OR to
- * the end of the bcopy tranfer, whichever is smaller.
- */
-static void gru_preload_tlb(struct gru_state *gru,
- struct gru_thread_state *gts, int atomic,
- unsigned long fault_vaddr, int asid, int write,
- unsigned char tlb_preload_count,
- struct gru_tlb_fault_handle *tfh,
- struct gru_control_block_extended *cbe)
-{
- unsigned long vaddr = 0, gpa;
- int ret, pageshift;
-
- if (cbe->opccpy != OP_BCOPY)
- return;
-
- if (fault_vaddr == cbe->cbe_baddr0)
- vaddr = fault_vaddr + GRU_CACHE_LINE_BYTES * cbe->cbe_src_cl - 1;
- else if (fault_vaddr == cbe->cbe_baddr1)
- vaddr = fault_vaddr + (1 << cbe->xtypecpy) * cbe->cbe_nelemcur - 1;
-
- fault_vaddr &= PAGE_MASK;
- vaddr &= PAGE_MASK;
- vaddr = min(vaddr, fault_vaddr + tlb_preload_count * PAGE_SIZE);
-
- while (vaddr > fault_vaddr) {
- ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift);
- if (ret || tfh_write_only(tfh, gpa, GAA_RAM, vaddr, asid, write,
- GRU_PAGESIZE(pageshift)))
- return;
- gru_dbg(grudev,
- "%s: gid %d, gts 0x%p, tfh 0x%p, vaddr 0x%lx, asid 0x%x, rw %d, ps %d, gpa 0x%lx\n",
- atomic ? "atomic" : "non-atomic", gru->gs_gid, gts, tfh,
- vaddr, asid, write, pageshift, gpa);
- vaddr -= PAGE_SIZE;
- STAT(tlb_preload_page);
- }
-}
-
-/*
- * Drop a TLB entry into the GRU. The fault is described by info in an TFH.
- * Input:
- * cb Address of user CBR. Null if not running in user context
- * Return:
- * 0 = dropin, exception, or switch to UPM successful
- * 1 = range invalidate active
- * < 0 = error code
- *
- */
-static int gru_try_dropin(struct gru_state *gru,
- struct gru_thread_state *gts,
- struct gru_tlb_fault_handle *tfh,
- struct gru_instruction_bits *cbk)
-{
- struct gru_control_block_extended *cbe = NULL;
- unsigned char tlb_preload_count = gts->ts_tlb_preload_count;
- int pageshift = 0, asid, write, ret, atomic = !cbk, indexway;
- unsigned long gpa = 0, vaddr = 0;
-
- /*
- * NOTE: The GRU contains magic hardware that eliminates races between
- * TLB invalidates and TLB dropins. If an invalidate occurs
- * in the window between reading the TFH and the subsequent TLB dropin,
- * the dropin is ignored. This eliminates the need for additional locks.
- */
-
- /*
- * Prefetch the CBE if doing TLB preloading
- */
- if (unlikely(tlb_preload_count)) {
- cbe = gru_tfh_to_cbe(tfh);
- prefetchw(cbe);
- }
-
- /*
- * Error if TFH state is IDLE or FMM mode & the user issuing a UPM call.
- * Might be a hardware race OR a stupid user. Ignore FMM because FMM
- * is a transient state.
- */
- if (tfh->status != TFHSTATUS_EXCEPTION) {
- gru_flush_cache(tfh);
- sync_core();
- if (tfh->status != TFHSTATUS_EXCEPTION)
- goto failnoexception;
- STAT(tfh_stale_on_fault);
- }
- if (tfh->state == TFHSTATE_IDLE)
- goto failidle;
- if (tfh->state == TFHSTATE_MISS_FMM && cbk)
- goto failfmm;
-
- write = (tfh->cause & TFHCAUSE_TLB_MOD) != 0;
- vaddr = tfh->missvaddr;
- asid = tfh->missasid;
- indexway = tfh->indexway;
- if (asid == 0)
- goto failnoasid;
-
- rmb(); /* TFH must be cache resident before reading ms_range_active */
-
- /*
- * TFH is cache resident - at least briefly. Fail the dropin
- * if a range invalidate is active.
- */
- if (atomic_read(&gts->ts_gms->ms_range_active))
- goto failactive;
-
- ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift);
- if (ret == VTOP_INVALID)
- goto failinval;
- if (ret == VTOP_RETRY)
- goto failupm;
-
- if (!(gts->ts_sizeavail & GRU_SIZEAVAIL(pageshift))) {
- gts->ts_sizeavail |= GRU_SIZEAVAIL(pageshift);
- if (atomic || !gru_update_cch(gts)) {
- gts->ts_force_cch_reload = 1;
- goto failupm;
- }
- }
-
- if (unlikely(cbe) && pageshift == PAGE_SHIFT) {
- gru_preload_tlb(gru, gts, atomic, vaddr, asid, write, tlb_preload_count, tfh, cbe);
- gru_flush_cache_cbe(cbe);
- }
-
- gru_cb_set_istatus_active(cbk);
- gts->ustats.tlbdropin++;
- tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write,
- GRU_PAGESIZE(pageshift));
- gru_dbg(grudev,
- "%s: gid %d, gts 0x%p, tfh 0x%p, vaddr 0x%lx, asid 0x%x, indexway 0x%x,"
- " rw %d, ps %d, gpa 0x%lx\n",
- atomic ? "atomic" : "non-atomic", gru->gs_gid, gts, tfh, vaddr, asid,
- indexway, write, pageshift, gpa);
- STAT(tlb_dropin);
- return 0;
-
-failnoasid:
- /* No asid (delayed unload). */
- STAT(tlb_dropin_fail_no_asid);
- gru_dbg(grudev, "FAILED no_asid tfh: 0x%p, vaddr 0x%lx\n", tfh, vaddr);
- if (!cbk)
- tfh_user_polling_mode(tfh);
- else
- gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
- return -EAGAIN;
-
-failupm:
- /* Atomic failure switch CBR to UPM */
- tfh_user_polling_mode(tfh);
- gru_flush_cache_cbe(cbe);
- STAT(tlb_dropin_fail_upm);
- gru_dbg(grudev, "FAILED upm tfh: 0x%p, vaddr 0x%lx\n", tfh, vaddr);
- return 1;
-
-failfmm:
- /* FMM state on UPM call */
- gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
- STAT(tlb_dropin_fail_fmm);
- gru_dbg(grudev, "FAILED fmm tfh: 0x%p, state %d\n", tfh, tfh->state);
- return 0;
-
-failnoexception:
- /* TFH status did not show exception pending */
- gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
- if (cbk)
- gru_flush_cache(cbk);
- STAT(tlb_dropin_fail_no_exception);
- gru_dbg(grudev, "FAILED non-exception tfh: 0x%p, status %d, state %d\n",
- tfh, tfh->status, tfh->state);
- return 0;
-
-failidle:
- /* TFH state was idle - no miss pending */
- gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
- if (cbk)
- gru_flush_cache(cbk);
- STAT(tlb_dropin_fail_idle);
- gru_dbg(grudev, "FAILED idle tfh: 0x%p, state %d\n", tfh, tfh->state);
- return 0;
-
-failinval:
- /* All errors (atomic & non-atomic) switch CBR to EXCEPTION state */
- tfh_exception(tfh);
- gru_flush_cache_cbe(cbe);
- STAT(tlb_dropin_fail_invalid);
- gru_dbg(grudev, "FAILED inval tfh: 0x%p, vaddr 0x%lx\n", tfh, vaddr);
- return -EFAULT;
-
-failactive:
- /* Range invalidate active. Switch to UPM iff atomic */
- if (!cbk)
- tfh_user_polling_mode(tfh);
- else
- gru_flush_cache(tfh);
- gru_flush_cache_cbe(cbe);
- STAT(tlb_dropin_fail_range_active);
- gru_dbg(grudev, "FAILED range active: tfh 0x%p, vaddr 0x%lx\n",
- tfh, vaddr);
- return 1;
-}
-
-/*
- * Process an external interrupt from the GRU. This interrupt is
- * caused by a TLB miss.
- * Note that this is the interrupt handler that is registered with linux
- * interrupt handlers.
- */
-static irqreturn_t gru_intr(int chiplet, int blade)
-{
- struct gru_state *gru;
- struct gru_tlb_fault_map imap, dmap;
- struct gru_thread_state *gts;
- struct gru_tlb_fault_handle *tfh = NULL;
- struct completion *cmp;
- int cbrnum, ctxnum;
-
- STAT(intr);
-
- gru = &gru_base[blade]->bs_grus[chiplet];
- if (!gru) {
- dev_err(grudev, "GRU: invalid interrupt: cpu %d, chiplet %d\n",
- raw_smp_processor_id(), chiplet);
- return IRQ_NONE;
- }
- get_clear_fault_map(gru, &imap, &dmap);
- gru_dbg(grudev,
- "cpu %d, chiplet %d, gid %d, imap %016lx %016lx, dmap %016lx %016lx\n",
- smp_processor_id(), chiplet, gru->gs_gid,
- imap.fault_bits[0], imap.fault_bits[1],
- dmap.fault_bits[0], dmap.fault_bits[1]);
-
- for_each_cbr_in_tfm(cbrnum, dmap.fault_bits) {
- STAT(intr_cbr);
- cmp = gru->gs_blade->bs_async_wq;
- if (cmp)
- complete(cmp);
- gru_dbg(grudev, "gid %d, cbr_done %d, done %d\n",
- gru->gs_gid, cbrnum, cmp ? cmp->done : -1);
- }
-
- for_each_cbr_in_tfm(cbrnum, imap.fault_bits) {
- STAT(intr_tfh);
- tfh = get_tfh_by_index(gru, cbrnum);
- prefetchw(tfh); /* Helps on hdw, required for emulator */
-
- /*
- * When hardware sets a bit in the faultmap, it implicitly
- * locks the GRU context so that it cannot be unloaded.
- * The gts cannot change until a TFH start/writestart command
- * is issued.
- */
- ctxnum = tfh->ctxnum;
- gts = gru->gs_gts[ctxnum];
-
- /* Spurious interrupts can cause this. Ignore. */
- if (!gts) {
- STAT(intr_spurious);
- continue;
- }
-
- /*
- * This is running in interrupt context. Trylock the mmap_sem.
- * If it fails, retry the fault in user context.
- */
- gts->ustats.fmm_tlbmiss++;
- if (!gts->ts_force_cch_reload &&
- down_read_trylock(&gts->ts_mm->mmap_sem)) {
- gru_try_dropin(gru, gts, tfh, NULL);
- up_read(&gts->ts_mm->mmap_sem);
- } else {
- tfh_user_polling_mode(tfh);
- STAT(intr_mm_lock_failed);
- }
- }
- return IRQ_HANDLED;
-}
-
-irqreturn_t gru0_intr(int irq, void *dev_id)
-{
- return gru_intr(0, uv_numa_blade_id());
-}
-
-irqreturn_t gru1_intr(int irq, void *dev_id)
-{
- return gru_intr(1, uv_numa_blade_id());
-}
-
-irqreturn_t gru_intr_mblade(int irq, void *dev_id)
-{
- int blade;
-
- for_each_possible_blade(blade) {
- if (uv_blade_nr_possible_cpus(blade))
- continue;
- gru_intr(0, blade);
- gru_intr(1, blade);
- }
- return IRQ_HANDLED;
-}
-
-
-static int gru_user_dropin(struct gru_thread_state *gts,
- struct gru_tlb_fault_handle *tfh,
- void *cb)
-{
- struct gru_mm_struct *gms = gts->ts_gms;
- int ret;
-
- gts->ustats.upm_tlbmiss++;
- while (1) {
- wait_event(gms->ms_wait_queue,
- atomic_read(&gms->ms_range_active) == 0);
- prefetchw(tfh); /* Helps on hdw, required for emulator */
- ret = gru_try_dropin(gts->ts_gru, gts, tfh, cb);
- if (ret <= 0)
- return ret;
- STAT(call_os_wait_queue);
- }
-}
-
-/*
- * This interface is called as a result of a user detecting a "call OS" bit
- * in a user CB. Normally means that a TLB fault has occurred.
- * cb - user virtual address of the CB
- */
-int gru_handle_user_call_os(unsigned long cb)
-{
- struct gru_tlb_fault_handle *tfh;
- struct gru_thread_state *gts;
- void *cbk;
- int ucbnum, cbrnum, ret = -EINVAL;
-
- STAT(call_os);
-
- /* sanity check the cb pointer */
- ucbnum = get_cb_number((void *)cb);
- if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB)
- return -EINVAL;
-
- gts = gru_find_lock_gts(cb);
- if (!gts)
- return -EINVAL;
- gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);
-
- if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
- goto exit;
-
- gru_check_context_placement(gts);
-
- /*
- * CCH may contain stale data if ts_force_cch_reload is set.
- */
- if (gts->ts_gru && gts->ts_force_cch_reload) {
- gts->ts_force_cch_reload = 0;
- gru_update_cch(gts);
- }
-
- ret = -EAGAIN;
- cbrnum = thread_cbr_number(gts, ucbnum);
- if (gts->ts_gru) {
- tfh = get_tfh_by_index(gts->ts_gru, cbrnum);
- cbk = get_gseg_base_address_cb(gts->ts_gru->gs_gru_base_vaddr,
- gts->ts_ctxnum, ucbnum);
- ret = gru_user_dropin(gts, tfh, cbk);
- }
-exit:
- gru_unlock_gts(gts);
- return ret;
-}
-
-/*
- * Fetch the exception detail information for a CB that terminated with
- * an exception.
- */
-int gru_get_exception_detail(unsigned long arg)
-{
- struct control_block_extended_exc_detail excdet;
- struct gru_control_block_extended *cbe;
- struct gru_thread_state *gts;
- int ucbnum, cbrnum, ret;
-
- STAT(user_exception);
- if (copy_from_user(&excdet, (void __user *)arg, sizeof(excdet)))
- return -EFAULT;
-
- gts = gru_find_lock_gts(excdet.cb);
- if (!gts)
- return -EINVAL;
-
- gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", excdet.cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);
- ucbnum = get_cb_number((void *)excdet.cb);
- if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
- ret = -EINVAL;
- } else if (gts->ts_gru) {
- cbrnum = thread_cbr_number(gts, ucbnum);
- cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
- gru_flush_cache(cbe); /* CBE not coherent */
- sync_core(); /* make sure we are have current data */
- excdet.opc = cbe->opccpy;
- excdet.exopc = cbe->exopccpy;
- excdet.ecause = cbe->ecause;
- excdet.exceptdet0 = cbe->idef1upd;
- excdet.exceptdet1 = cbe->idef3upd;
- excdet.cbrstate = cbe->cbrstate;
- excdet.cbrexecstatus = cbe->cbrexecstatus;
- gru_flush_cache_cbe(cbe);
- ret = 0;
- } else {
- ret = -EAGAIN;
- }
- gru_unlock_gts(gts);
-
- gru_dbg(grudev,
- "cb 0x%lx, op %d, exopc %d, cbrstate %d, cbrexecstatus 0x%x, ecause 0x%x, "
- "exdet0 0x%lx, exdet1 0x%x\n",
- excdet.cb, excdet.opc, excdet.exopc, excdet.cbrstate, excdet.cbrexecstatus,
- excdet.ecause, excdet.exceptdet0, excdet.exceptdet1);
- if (!ret && copy_to_user((void __user *)arg, &excdet, sizeof(excdet)))
- ret = -EFAULT;
- return ret;
-}
-
-/*
- * User request to unload a context. Content is saved for possible reload.
- */
-static int gru_unload_all_contexts(void)
-{
- struct gru_thread_state *gts;
- struct gru_state *gru;
- int gid, ctxnum;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- foreach_gid(gid) {
- gru = GID_TO_GRU(gid);
- spin_lock(&gru->gs_lock);
- for (ctxnum = 0; ctxnum < GRU_NUM_CCH; ctxnum++) {
- gts = gru->gs_gts[ctxnum];
- if (gts && mutex_trylock(&gts->ts_ctxlock)) {
- spin_unlock(&gru->gs_lock);
- gru_unload_context(gts, 1);
- mutex_unlock(&gts->ts_ctxlock);
- spin_lock(&gru->gs_lock);
- }
- }
- spin_unlock(&gru->gs_lock);
- }
- return 0;
-}
-
-int gru_user_unload_context(unsigned long arg)
-{
- struct gru_thread_state *gts;
- struct gru_unload_context_req req;
-
- STAT(user_unload_context);
- if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
- return -EFAULT;
-
- gru_dbg(grudev, "gseg 0x%lx\n", req.gseg);
-
- if (!req.gseg)
- return gru_unload_all_contexts();
-
- gts = gru_find_lock_gts(req.gseg);
- if (!gts)
- return -EINVAL;
-
- if (gts->ts_gru)
- gru_unload_context(gts, 1);
- gru_unlock_gts(gts);
-
- return 0;
-}
-
-/*
- * User request to flush a range of virtual addresses from the GRU TLB
- * (Mainly for testing).
- */
-int gru_user_flush_tlb(unsigned long arg)
-{
- struct gru_thread_state *gts;
- struct gru_flush_tlb_req req;
- struct gru_mm_struct *gms;
-
- STAT(user_flush_tlb);
- if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
- return -EFAULT;
-
- gru_dbg(grudev, "gseg 0x%lx, vaddr 0x%lx, len 0x%lx\n", req.gseg,
- req.vaddr, req.len);
-
- gts = gru_find_lock_gts(req.gseg);
- if (!gts)
- return -EINVAL;
-
- gms = gts->ts_gms;
- gru_unlock_gts(gts);
- gru_flush_tlb_range(gms, req.vaddr, req.len);
-
- return 0;
-}
-
-/*
- * Fetch GSEG statisticss
- */
-long gru_get_gseg_statistics(unsigned long arg)
-{
- struct gru_thread_state *gts;
- struct gru_get_gseg_statistics_req req;
-
- if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
- return -EFAULT;
-
- /*
- * The library creates arrays of contexts for threaded programs.
- * If no gts exists in the array, the context has never been used & all
- * statistics are implicitly 0.
- */
- gts = gru_find_lock_gts(req.gseg);
- if (gts) {
- memcpy(&req.stats, &gts->ustats, sizeof(gts->ustats));
- gru_unlock_gts(gts);
- } else {
- memset(&req.stats, 0, sizeof(gts->ustats));
- }
-
- if (copy_to_user((void __user *)arg, &req, sizeof(req)))
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * Register the current task as the user of the GSEG slice.
- * Needed for TLB fault interrupt targeting.
- */
-int gru_set_context_option(unsigned long arg)
-{
- struct gru_thread_state *gts;
- struct gru_set_context_option_req req;
- int ret = 0;
-
- STAT(set_context_option);
- if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
- return -EFAULT;
- gru_dbg(grudev, "op %d, gseg 0x%lx, value1 0x%lx\n", req.op, req.gseg, req.val1);
-
- gts = gru_find_lock_gts(req.gseg);
- if (!gts) {
- gts = gru_alloc_locked_gts(req.gseg);
- if (IS_ERR(gts))
- return PTR_ERR(gts);
- }
-
- switch (req.op) {
- case sco_blade_chiplet:
- /* Select blade/chiplet for GRU context */
- if (req.val1 < -1 || req.val1 >= GRU_MAX_BLADES || !gru_base[req.val1] ||
- req.val0 < -1 || req.val0 >= GRU_CHIPLETS_PER_HUB) {
- ret = -EINVAL;
- } else {
- gts->ts_user_blade_id = req.val1;
- gts->ts_user_chiplet_id = req.val0;
- gru_check_context_placement(gts);
- }
- break;
- case sco_gseg_owner:
- /* Register the current task as the GSEG owner */
- gts->ts_tgid_owner = current->tgid;
- break;
- case sco_cch_req_slice:
- /* Set the CCH slice option */
- gts->ts_cch_req_slice = req.val1 & 3;
- break;
- default:
- ret = -EINVAL;
- }
- gru_unlock_gts(gts);
-
- return ret;
-}
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/grufile.c b/ANDROID_3.4.5/drivers/misc/sgi-gru/grufile.c
deleted file mode 100644
index ecafa4ba..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/grufile.c
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * SN Platform GRU Driver
- *
- * FILE OPERATIONS & DRIVER INITIALIZATION
- *
- * This file supports the user system call for file open, close, mmap, etc.
- * This also incudes the driver initialization code.
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <linux/device.h>
-#include <linux/miscdevice.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/uaccess.h>
-#ifdef CONFIG_X86_64
-#include <asm/uv/uv_irq.h>
-#endif
-#include <asm/uv/uv.h>
-#include "gru.h"
-#include "grulib.h"
-#include "grutables.h"
-
-#include <asm/uv/uv_hub.h>
-#include <asm/uv/uv_mmrs.h>
-
-struct gru_blade_state *gru_base[GRU_MAX_BLADES] __read_mostly;
-unsigned long gru_start_paddr __read_mostly;
-void *gru_start_vaddr __read_mostly;
-unsigned long gru_end_paddr __read_mostly;
-unsigned int gru_max_gids __read_mostly;
-struct gru_stats_s gru_stats;
-
-/* Guaranteed user available resources on each node */
-static int max_user_cbrs, max_user_dsr_bytes;
-
-static struct miscdevice gru_miscdev;
-
-
-/*
- * gru_vma_close
- *
- * Called when unmapping a device mapping. Frees all gru resources
- * and tables belonging to the vma.
- */
-static void gru_vma_close(struct vm_area_struct *vma)
-{
- struct gru_vma_data *vdata;
- struct gru_thread_state *gts;
- struct list_head *entry, *next;
-
- if (!vma->vm_private_data)
- return;
-
- vdata = vma->vm_private_data;
- vma->vm_private_data = NULL;
- gru_dbg(grudev, "vma %p, file %p, vdata %p\n", vma, vma->vm_file,
- vdata);
- list_for_each_safe(entry, next, &vdata->vd_head) {
- gts =
- list_entry(entry, struct gru_thread_state, ts_next);
- list_del(&gts->ts_next);
- mutex_lock(&gts->ts_ctxlock);
- if (gts->ts_gru)
- gru_unload_context(gts, 0);
- mutex_unlock(&gts->ts_ctxlock);
- gts_drop(gts);
- }
- kfree(vdata);
- STAT(vdata_free);
-}
-
-/*
- * gru_file_mmap
- *
- * Called when mmapping the device. Initializes the vma with a fault handler
- * and private data structure necessary to allocate, track, and free the
- * underlying pages.
- */
-static int gru_file_mmap(struct file *file, struct vm_area_struct *vma)
-{
- if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) != (VM_SHARED | VM_WRITE))
- return -EPERM;
-
- if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) ||
- vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
- return -EINVAL;
-
- vma->vm_flags |=
- (VM_IO | VM_DONTCOPY | VM_LOCKED | VM_DONTEXPAND | VM_PFNMAP |
- VM_RESERVED);
- vma->vm_page_prot = PAGE_SHARED;
- vma->vm_ops = &gru_vm_ops;
-
- vma->vm_private_data = gru_alloc_vma_data(vma, 0);
- if (!vma->vm_private_data)
- return -ENOMEM;
-
- gru_dbg(grudev, "file %p, vaddr 0x%lx, vma %p, vdata %p\n",
- file, vma->vm_start, vma, vma->vm_private_data);
- return 0;
-}
-
-/*
- * Create a new GRU context
- */
-static int gru_create_new_context(unsigned long arg)
-{
- struct gru_create_context_req req;
- struct vm_area_struct *vma;
- struct gru_vma_data *vdata;
- int ret = -EINVAL;
-
- if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
- return -EFAULT;
-
- if (req.data_segment_bytes > max_user_dsr_bytes)
- return -EINVAL;
- if (req.control_blocks > max_user_cbrs || !req.maximum_thread_count)
- return -EINVAL;
-
- if (!(req.options & GRU_OPT_MISS_MASK))
- req.options |= GRU_OPT_MISS_FMM_INTR;
-
- down_write(&current->mm->mmap_sem);
- vma = gru_find_vma(req.gseg);
- if (vma) {
- vdata = vma->vm_private_data;
- vdata->vd_user_options = req.options;
- vdata->vd_dsr_au_count =
- GRU_DS_BYTES_TO_AU(req.data_segment_bytes);
- vdata->vd_cbr_au_count = GRU_CB_COUNT_TO_AU(req.control_blocks);
- vdata->vd_tlb_preload_count = req.tlb_preload_count;
- ret = 0;
- }
- up_write(&current->mm->mmap_sem);
-
- return ret;
-}
-
-/*
- * Get GRU configuration info (temp - for emulator testing)
- */
-static long gru_get_config_info(unsigned long arg)
-{
- struct gru_config_info info;
- int nodesperblade;
-
- if (num_online_nodes() > 1 &&
- (uv_node_to_blade_id(1) == uv_node_to_blade_id(0)))
- nodesperblade = 2;
- else
- nodesperblade = 1;
- info.cpus = num_online_cpus();
- info.nodes = num_online_nodes();
- info.blades = info.nodes / nodesperblade;
- info.chiplets = GRU_CHIPLETS_PER_BLADE * info.blades;
-
- if (copy_to_user((void __user *)arg, &info, sizeof(info)))
- return -EFAULT;
- return 0;
-}
-
-/*
- * gru_file_unlocked_ioctl
- *
- * Called to update file attributes via IOCTL calls.
- */
-static long gru_file_unlocked_ioctl(struct file *file, unsigned int req,
- unsigned long arg)
-{
- int err = -EBADRQC;
-
- gru_dbg(grudev, "file %p, req 0x%x, 0x%lx\n", file, req, arg);
-
- switch (req) {
- case GRU_CREATE_CONTEXT:
- err = gru_create_new_context(arg);
- break;
- case GRU_SET_CONTEXT_OPTION:
- err = gru_set_context_option(arg);
- break;
- case GRU_USER_GET_EXCEPTION_DETAIL:
- err = gru_get_exception_detail(arg);
- break;
- case GRU_USER_UNLOAD_CONTEXT:
- err = gru_user_unload_context(arg);
- break;
- case GRU_USER_FLUSH_TLB:
- err = gru_user_flush_tlb(arg);
- break;
- case GRU_USER_CALL_OS:
- err = gru_handle_user_call_os(arg);
- break;
- case GRU_GET_GSEG_STATISTICS:
- err = gru_get_gseg_statistics(arg);
- break;
- case GRU_KTEST:
- err = gru_ktest(arg);
- break;
- case GRU_GET_CONFIG_INFO:
- err = gru_get_config_info(arg);
- break;
- case GRU_DUMP_CHIPLET_STATE:
- err = gru_dump_chiplet_request(arg);
- break;
- }
- return err;
-}
-
-/*
- * Called at init time to build tables for all GRUs that are present in the
- * system.
- */
-static void gru_init_chiplet(struct gru_state *gru, unsigned long paddr,
- void *vaddr, int blade_id, int chiplet_id)
-{
- spin_lock_init(&gru->gs_lock);
- spin_lock_init(&gru->gs_asid_lock);
- gru->gs_gru_base_paddr = paddr;
- gru->gs_gru_base_vaddr = vaddr;
- gru->gs_gid = blade_id * GRU_CHIPLETS_PER_BLADE + chiplet_id;
- gru->gs_blade = gru_base[blade_id];
- gru->gs_blade_id = blade_id;
- gru->gs_chiplet_id = chiplet_id;
- gru->gs_cbr_map = (GRU_CBR_AU == 64) ? ~0 : (1UL << GRU_CBR_AU) - 1;
- gru->gs_dsr_map = (1UL << GRU_DSR_AU) - 1;
- gru->gs_asid_limit = MAX_ASID;
- gru_tgh_flush_init(gru);
- if (gru->gs_gid >= gru_max_gids)
- gru_max_gids = gru->gs_gid + 1;
- gru_dbg(grudev, "bid %d, gid %d, vaddr %p (0x%lx)\n",
- blade_id, gru->gs_gid, gru->gs_gru_base_vaddr,
- gru->gs_gru_base_paddr);
-}
-
-static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr)
-{
- int pnode, nid, bid, chip;
- int cbrs, dsrbytes, n;
- int order = get_order(sizeof(struct gru_blade_state));
- struct page *page;
- struct gru_state *gru;
- unsigned long paddr;
- void *vaddr;
-
- max_user_cbrs = GRU_NUM_CB;
- max_user_dsr_bytes = GRU_NUM_DSR_BYTES;
- for_each_possible_blade(bid) {
- pnode = uv_blade_to_pnode(bid);
- nid = uv_blade_to_memory_nid(bid);/* -1 if no memory on blade */
- page = alloc_pages_node(nid, GFP_KERNEL, order);
- if (!page)
- goto fail;
- gru_base[bid] = page_address(page);
- memset(gru_base[bid], 0, sizeof(struct gru_blade_state));
- gru_base[bid]->bs_lru_gru = &gru_base[bid]->bs_grus[0];
- spin_lock_init(&gru_base[bid]->bs_lock);
- init_rwsem(&gru_base[bid]->bs_kgts_sema);
-
- dsrbytes = 0;
- cbrs = 0;
- for (gru = gru_base[bid]->bs_grus, chip = 0;
- chip < GRU_CHIPLETS_PER_BLADE;
- chip++, gru++) {
- paddr = gru_chiplet_paddr(gru_base_paddr, pnode, chip);
- vaddr = gru_chiplet_vaddr(gru_base_vaddr, pnode, chip);
- gru_init_chiplet(gru, paddr, vaddr, bid, chip);
- n = hweight64(gru->gs_cbr_map) * GRU_CBR_AU_SIZE;
- cbrs = max(cbrs, n);
- n = hweight64(gru->gs_dsr_map) * GRU_DSR_AU_BYTES;
- dsrbytes = max(dsrbytes, n);
- }
- max_user_cbrs = min(max_user_cbrs, cbrs);
- max_user_dsr_bytes = min(max_user_dsr_bytes, dsrbytes);
- }
-
- return 0;
-
-fail:
- for (bid--; bid >= 0; bid--)
- free_pages((unsigned long)gru_base[bid], order);
- return -ENOMEM;
-}
-
-static void gru_free_tables(void)
-{
- int bid;
- int order = get_order(sizeof(struct gru_state) *
- GRU_CHIPLETS_PER_BLADE);
-
- for (bid = 0; bid < GRU_MAX_BLADES; bid++)
- free_pages((unsigned long)gru_base[bid], order);
-}
-
-static unsigned long gru_chiplet_cpu_to_mmr(int chiplet, int cpu, int *corep)
-{
- unsigned long mmr = 0;
- int core;
-
- /*
- * We target the cores of a blade and not the hyperthreads themselves.
- * There is a max of 8 cores per socket and 2 sockets per blade,
- * making for a max total of 16 cores (i.e., 16 CPUs without
- * hyperthreading and 32 CPUs with hyperthreading).
- */
- core = uv_cpu_core_number(cpu) + UV_MAX_INT_CORES * uv_cpu_socket_number(cpu);
- if (core >= GRU_NUM_TFM || uv_cpu_ht_number(cpu))
- return 0;
-
- if (chiplet == 0) {
- mmr = UVH_GR0_TLB_INT0_CONFIG +
- core * (UVH_GR0_TLB_INT1_CONFIG - UVH_GR0_TLB_INT0_CONFIG);
- } else if (chiplet == 1) {
- mmr = UVH_GR1_TLB_INT0_CONFIG +
- core * (UVH_GR1_TLB_INT1_CONFIG - UVH_GR1_TLB_INT0_CONFIG);
- } else {
- BUG();
- }
-
- *corep = core;
- return mmr;
-}
-
-#ifdef CONFIG_IA64
-
-static int gru_irq_count[GRU_CHIPLETS_PER_BLADE];
-
-static void gru_noop(struct irq_data *d)
-{
-}
-
-static struct irq_chip gru_chip[GRU_CHIPLETS_PER_BLADE] = {
- [0 ... GRU_CHIPLETS_PER_BLADE - 1] {
- .irq_mask = gru_noop,
- .irq_unmask = gru_noop,
- .irq_ack = gru_noop
- }
-};
-
-static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name,
- irq_handler_t irq_handler, int cpu, int blade)
-{
- unsigned long mmr;
- int irq = IRQ_GRU + chiplet;
- int ret, core;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr == 0)
- return 0;
-
- if (gru_irq_count[chiplet] == 0) {
- gru_chip[chiplet].name = irq_name;
- ret = irq_set_chip(irq, &gru_chip[chiplet]);
- if (ret) {
- printk(KERN_ERR "%s: set_irq_chip failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -ret);
- return ret;
- }
-
- ret = request_irq(irq, irq_handler, 0, irq_name, NULL);
- if (ret) {
- printk(KERN_ERR "%s: request_irq failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -ret);
- return ret;
- }
- }
- gru_irq_count[chiplet]++;
-
- return 0;
-}
-
-static void gru_chiplet_teardown_tlb_irq(int chiplet, int cpu, int blade)
-{
- unsigned long mmr;
- int core, irq = IRQ_GRU + chiplet;
-
- if (gru_irq_count[chiplet] == 0)
- return;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr == 0)
- return;
-
- if (--gru_irq_count[chiplet] == 0)
- free_irq(irq, NULL);
-}
-
-#elif defined CONFIG_X86_64
-
-static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name,
- irq_handler_t irq_handler, int cpu, int blade)
-{
- unsigned long mmr;
- int irq, core;
- int ret;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr == 0)
- return 0;
-
- irq = uv_setup_irq(irq_name, cpu, blade, mmr, UV_AFFINITY_CPU);
- if (irq < 0) {
- printk(KERN_ERR "%s: uv_setup_irq failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -irq);
- return irq;
- }
-
- ret = request_irq(irq, irq_handler, 0, irq_name, NULL);
- if (ret) {
- uv_teardown_irq(irq);
- printk(KERN_ERR "%s: request_irq failed, errno=%d\n",
- GRU_DRIVER_ID_STR, -ret);
- return ret;
- }
- gru_base[blade]->bs_grus[chiplet].gs_irq[core] = irq;
- return 0;
-}
-
-static void gru_chiplet_teardown_tlb_irq(int chiplet, int cpu, int blade)
-{
- int irq, core;
- unsigned long mmr;
-
- mmr = gru_chiplet_cpu_to_mmr(chiplet, cpu, &core);
- if (mmr) {
- irq = gru_base[blade]->bs_grus[chiplet].gs_irq[core];
- if (irq) {
- free_irq(irq, NULL);
- uv_teardown_irq(irq);
- }
- }
-}
-
-#endif
-
-static void gru_teardown_tlb_irqs(void)
-{
- int blade;
- int cpu;
-
- for_each_online_cpu(cpu) {
- blade = uv_cpu_to_blade_id(cpu);
- gru_chiplet_teardown_tlb_irq(0, cpu, blade);
- gru_chiplet_teardown_tlb_irq(1, cpu, blade);
- }
- for_each_possible_blade(blade) {
- if (uv_blade_nr_possible_cpus(blade))
- continue;
- gru_chiplet_teardown_tlb_irq(0, 0, blade);
- gru_chiplet_teardown_tlb_irq(1, 0, blade);
- }
-}
-
-static int gru_setup_tlb_irqs(void)
-{
- int blade;
- int cpu;
- int ret;
-
- for_each_online_cpu(cpu) {
- blade = uv_cpu_to_blade_id(cpu);
- ret = gru_chiplet_setup_tlb_irq(0, "GRU0_TLB", gru0_intr, cpu, blade);
- if (ret != 0)
- goto exit1;
-
- ret = gru_chiplet_setup_tlb_irq(1, "GRU1_TLB", gru1_intr, cpu, blade);
- if (ret != 0)
- goto exit1;
- }
- for_each_possible_blade(blade) {
- if (uv_blade_nr_possible_cpus(blade))
- continue;
- ret = gru_chiplet_setup_tlb_irq(0, "GRU0_TLB", gru_intr_mblade, 0, blade);
- if (ret != 0)
- goto exit1;
-
- ret = gru_chiplet_setup_tlb_irq(1, "GRU1_TLB", gru_intr_mblade, 0, blade);
- if (ret != 0)
- goto exit1;
- }
-
- return 0;
-
-exit1:
- gru_teardown_tlb_irqs();
- return ret;
-}
-
-/*
- * gru_init
- *
- * Called at boot or module load time to initialize the GRUs.
- */
-static int __init gru_init(void)
-{
- int ret;
-
- if (!is_uv_system())
- return 0;
-
-#if defined CONFIG_IA64
- gru_start_paddr = 0xd000000000UL; /* ZZZZZZZZZZZZZZZZZZZ fixme */
-#else
- gru_start_paddr = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR) &
- 0x7fffffffffffUL;
-#endif
- gru_start_vaddr = __va(gru_start_paddr);
- gru_end_paddr = gru_start_paddr + GRU_MAX_BLADES * GRU_SIZE;
- printk(KERN_INFO "GRU space: 0x%lx - 0x%lx\n",
- gru_start_paddr, gru_end_paddr);
- ret = misc_register(&gru_miscdev);
- if (ret) {
- printk(KERN_ERR "%s: misc_register failed\n",
- GRU_DRIVER_ID_STR);
- goto exit0;
- }
-
- ret = gru_proc_init();
- if (ret) {
- printk(KERN_ERR "%s: proc init failed\n", GRU_DRIVER_ID_STR);
- goto exit1;
- }
-
- ret = gru_init_tables(gru_start_paddr, gru_start_vaddr);
- if (ret) {
- printk(KERN_ERR "%s: init tables failed\n", GRU_DRIVER_ID_STR);
- goto exit2;
- }
-
- ret = gru_setup_tlb_irqs();
- if (ret != 0)
- goto exit3;
-
- gru_kservices_init();
-
- printk(KERN_INFO "%s: v%s\n", GRU_DRIVER_ID_STR,
- GRU_DRIVER_VERSION_STR);
- return 0;
-
-exit3:
- gru_free_tables();
-exit2:
- gru_proc_exit();
-exit1:
- misc_deregister(&gru_miscdev);
-exit0:
- return ret;
-
-}
-
-static void __exit gru_exit(void)
-{
- if (!is_uv_system())
- return;
-
- gru_teardown_tlb_irqs();
- gru_kservices_exit();
- gru_free_tables();
- misc_deregister(&gru_miscdev);
- gru_proc_exit();
-}
-
-static const struct file_operations gru_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = gru_file_unlocked_ioctl,
- .mmap = gru_file_mmap,
- .llseek = noop_llseek,
-};
-
-static struct miscdevice gru_miscdev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "gru",
- .fops = &gru_fops,
-};
-
-const struct vm_operations_struct gru_vm_ops = {
- .close = gru_vma_close,
- .fault = gru_fault,
-};
-
-#ifndef MODULE
-fs_initcall(gru_init);
-#else
-module_init(gru_init);
-#endif
-module_exit(gru_exit);
-
-module_param(gru_options, ulong, 0644);
-MODULE_PARM_DESC(gru_options, "Various debug options");
-
-MODULE_AUTHOR("Silicon Graphics, Inc.");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(GRU_DRIVER_ID_STR GRU_DRIVER_VERSION_STR);
-MODULE_VERSION(GRU_DRIVER_VERSION_STR);
-
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/gruhandles.c b/ANDROID_3.4.5/drivers/misc/sgi-gru/gruhandles.c
deleted file mode 100644
index 2f30badc..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/gruhandles.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * GRU KERNEL MCS INSTRUCTIONS
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include "gru.h"
-#include "grulib.h"
-#include "grutables.h"
-
-/* 10 sec */
-#ifdef CONFIG_IA64
-#include <asm/processor.h>
-#define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
-#define CLKS2NSEC(c) ((c) *1000000000 / local_cpu_data->itc_freq)
-#else
-#include <asm/tsc.h>
-#define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
-#define CLKS2NSEC(c) ((c) * 1000000 / tsc_khz)
-#endif
-
-/* Extract the status field from a kernel handle */
-#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)
-
-struct mcs_op_statistic mcs_op_statistics[mcsop_last];
-
-static void update_mcs_stats(enum mcs_op op, unsigned long clks)
-{
- unsigned long nsec;
-
- nsec = CLKS2NSEC(clks);
- atomic_long_inc(&mcs_op_statistics[op].count);
- atomic_long_add(nsec, &mcs_op_statistics[op].total);
- if (mcs_op_statistics[op].max < nsec)
- mcs_op_statistics[op].max = nsec;
-}
-
-static void start_instruction(void *h)
-{
- unsigned long *w0 = h;
-
- wmb(); /* setting CMD/STATUS bits must be last */
- *w0 = *w0 | 0x20001;
- gru_flush_cache(h);
-}
-
-static void report_instruction_timeout(void *h)
-{
- unsigned long goff = GSEGPOFF((unsigned long)h);
- char *id = "???";
-
- if (TYPE_IS(CCH, goff))
- id = "CCH";
- else if (TYPE_IS(TGH, goff))
- id = "TGH";
- else if (TYPE_IS(TFH, goff))
- id = "TFH";
-
- panic(KERN_ALERT "GRU %p (%s) is malfunctioning\n", h, id);
-}
-
-static int wait_instruction_complete(void *h, enum mcs_op opc)
-{
- int status;
- unsigned long start_time = get_cycles();
-
- while (1) {
- cpu_relax();
- status = GET_MSEG_HANDLE_STATUS(h);
- if (status != CCHSTATUS_ACTIVE)
- break;
- if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time)) {
- report_instruction_timeout(h);
- start_time = get_cycles();
- }
- }
- if (gru_options & OPT_STATS)
- update_mcs_stats(opc, get_cycles() - start_time);
- return status;
-}
-
-int cch_allocate(struct gru_context_configuration_handle *cch)
-{
- int ret;
-
- cch->opc = CCHOP_ALLOCATE;
- start_instruction(cch);
- ret = wait_instruction_complete(cch, cchop_allocate);
-
- /*
- * Stop speculation into the GSEG being mapped by the previous ALLOCATE.
- * The GSEG memory does not exist until the ALLOCATE completes.
- */
- sync_core();
- return ret;
-}
-
-int cch_start(struct gru_context_configuration_handle *cch)
-{
- cch->opc = CCHOP_START;
- start_instruction(cch);
- return wait_instruction_complete(cch, cchop_start);
-}
-
-int cch_interrupt(struct gru_context_configuration_handle *cch)
-{
- cch->opc = CCHOP_INTERRUPT;
- start_instruction(cch);
- return wait_instruction_complete(cch, cchop_interrupt);
-}
-
-int cch_deallocate(struct gru_context_configuration_handle *cch)
-{
- int ret;
-
- cch->opc = CCHOP_DEALLOCATE;
- start_instruction(cch);
- ret = wait_instruction_complete(cch, cchop_deallocate);
-
- /*
- * Stop speculation into the GSEG being unmapped by the previous
- * DEALLOCATE.
- */
- sync_core();
- return ret;
-}
-
-int cch_interrupt_sync(struct gru_context_configuration_handle
- *cch)
-{
- cch->opc = CCHOP_INTERRUPT_SYNC;
- start_instruction(cch);
- return wait_instruction_complete(cch, cchop_interrupt_sync);
-}
-
-int tgh_invalidate(struct gru_tlb_global_handle *tgh,
- unsigned long vaddr, unsigned long vaddrmask,
- int asid, int pagesize, int global, int n,
- unsigned short ctxbitmap)
-{
- tgh->vaddr = vaddr;
- tgh->asid = asid;
- tgh->pagesize = pagesize;
- tgh->n = n;
- tgh->global = global;
- tgh->vaddrmask = vaddrmask;
- tgh->ctxbitmap = ctxbitmap;
- tgh->opc = TGHOP_TLBINV;
- start_instruction(tgh);
- return wait_instruction_complete(tgh, tghop_invalidate);
-}
-
-int tfh_write_only(struct gru_tlb_fault_handle *tfh,
- unsigned long paddr, int gaa,
- unsigned long vaddr, int asid, int dirty,
- int pagesize)
-{
- tfh->fillasid = asid;
- tfh->fillvaddr = vaddr;
- tfh->pfn = paddr >> GRU_PADDR_SHIFT;
- tfh->gaa = gaa;
- tfh->dirty = dirty;
- tfh->pagesize = pagesize;
- tfh->opc = TFHOP_WRITE_ONLY;
- start_instruction(tfh);
- return wait_instruction_complete(tfh, tfhop_write_only);
-}
-
-void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
- unsigned long paddr, int gaa,
- unsigned long vaddr, int asid, int dirty,
- int pagesize)
-{
- tfh->fillasid = asid;
- tfh->fillvaddr = vaddr;
- tfh->pfn = paddr >> GRU_PADDR_SHIFT;
- tfh->gaa = gaa;
- tfh->dirty = dirty;
- tfh->pagesize = pagesize;
- tfh->opc = TFHOP_WRITE_RESTART;
- start_instruction(tfh);
-}
-
-void tfh_restart(struct gru_tlb_fault_handle *tfh)
-{
- tfh->opc = TFHOP_RESTART;
- start_instruction(tfh);
-}
-
-void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
-{
- tfh->opc = TFHOP_USER_POLLING_MODE;
- start_instruction(tfh);
-}
-
-void tfh_exception(struct gru_tlb_fault_handle *tfh)
-{
- tfh->opc = TFHOP_EXCEPTION;
- start_instruction(tfh);
-}
-
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/gruhandles.h b/ANDROID_3.4.5/drivers/misc/sgi-gru/gruhandles.h
deleted file mode 100644
index 3f998b92..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/gruhandles.h
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * SN Platform GRU Driver
- *
- * GRU HANDLE DEFINITION
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __GRUHANDLES_H__
-#define __GRUHANDLES_H__
-#include "gru_instructions.h"
-
-/*
- * Manifest constants for GRU Memory Map
- */
-#define GRU_GSEG0_BASE 0
-#define GRU_MCS_BASE (64 * 1024 * 1024)
-#define GRU_SIZE (128UL * 1024 * 1024)
-
-/* Handle & resource counts */
-#define GRU_NUM_CB 128
-#define GRU_NUM_DSR_BYTES (32 * 1024)
-#define GRU_NUM_TFM 16
-#define GRU_NUM_TGH 24
-#define GRU_NUM_CBE 128
-#define GRU_NUM_TFH 128
-#define GRU_NUM_CCH 16
-
-/* Maximum resource counts that can be reserved by user programs */
-#define GRU_NUM_USER_CBR GRU_NUM_CBE
-#define GRU_NUM_USER_DSR_BYTES GRU_NUM_DSR_BYTES
-
-/* Bytes per handle & handle stride. Code assumes all cb, tfh, cbe handles
- * are the same */
-#define GRU_HANDLE_BYTES 64
-#define GRU_HANDLE_STRIDE 256
-
-/* Base addresses of handles */
-#define GRU_TFM_BASE (GRU_MCS_BASE + 0x00000)
-#define GRU_TGH_BASE (GRU_MCS_BASE + 0x08000)
-#define GRU_CBE_BASE (GRU_MCS_BASE + 0x10000)
-#define GRU_TFH_BASE (GRU_MCS_BASE + 0x18000)
-#define GRU_CCH_BASE (GRU_MCS_BASE + 0x20000)
-
-/* User gseg constants */
-#define GRU_GSEG_STRIDE (4 * 1024 * 1024)
-#define GSEG_BASE(a) ((a) & ~(GRU_GSEG_PAGESIZE - 1))
-
-/* Data segment constants */
-#define GRU_DSR_AU_BYTES 1024
-#define GRU_DSR_CL (GRU_NUM_DSR_BYTES / GRU_CACHE_LINE_BYTES)
-#define GRU_DSR_AU_CL (GRU_DSR_AU_BYTES / GRU_CACHE_LINE_BYTES)
-#define GRU_DSR_AU (GRU_NUM_DSR_BYTES / GRU_DSR_AU_BYTES)
-
-/* Control block constants */
-#define GRU_CBR_AU_SIZE 2
-#define GRU_CBR_AU (GRU_NUM_CBE / GRU_CBR_AU_SIZE)
-
-/* Convert resource counts to the number of AU */
-#define GRU_DS_BYTES_TO_AU(n) DIV_ROUND_UP(n, GRU_DSR_AU_BYTES)
-#define GRU_CB_COUNT_TO_AU(n) DIV_ROUND_UP(n, GRU_CBR_AU_SIZE)
-
-/* UV limits */
-#define GRU_CHIPLETS_PER_HUB 2
-#define GRU_HUBS_PER_BLADE 1
-#define GRU_CHIPLETS_PER_BLADE (GRU_HUBS_PER_BLADE * GRU_CHIPLETS_PER_HUB)
-
-/* User GRU Gseg offsets */
-#define GRU_CB_BASE 0
-#define GRU_CB_LIMIT (GRU_CB_BASE + GRU_HANDLE_STRIDE * GRU_NUM_CBE)
-#define GRU_DS_BASE 0x20000
-#define GRU_DS_LIMIT (GRU_DS_BASE + GRU_NUM_DSR_BYTES)
-
-/* Convert a GRU physical address to the chiplet offset */
-#define GSEGPOFF(h) ((h) & (GRU_SIZE - 1))
-
-/* Convert an arbitrary handle address to the beginning of the GRU segment */
-#define GRUBASE(h) ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
-
-/* Test a valid handle address to determine the type */
-#define TYPE_IS(hn, h) ((h) >= GRU_##hn##_BASE && (h) < \
- GRU_##hn##_BASE + GRU_NUM_##hn * GRU_HANDLE_STRIDE && \
- (((h) & (GRU_HANDLE_STRIDE - 1)) == 0))
-
-
-/* General addressing macros. */
-static inline void *get_gseg_base_address(void *base, int ctxnum)
-{
- return (void *)(base + GRU_GSEG0_BASE + GRU_GSEG_STRIDE * ctxnum);
-}
-
-static inline void *get_gseg_base_address_cb(void *base, int ctxnum, int line)
-{
- return (void *)(get_gseg_base_address(base, ctxnum) +
- GRU_CB_BASE + GRU_HANDLE_STRIDE * line);
-}
-
-static inline void *get_gseg_base_address_ds(void *base, int ctxnum, int line)
-{
- return (void *)(get_gseg_base_address(base, ctxnum) + GRU_DS_BASE +
- GRU_CACHE_LINE_BYTES * line);
-}
-
-static inline struct gru_tlb_fault_map *get_tfm(void *base, int ctxnum)
-{
- return (struct gru_tlb_fault_map *)(base + GRU_TFM_BASE +
- ctxnum * GRU_HANDLE_STRIDE);
-}
-
-static inline struct gru_tlb_global_handle *get_tgh(void *base, int ctxnum)
-{
- return (struct gru_tlb_global_handle *)(base + GRU_TGH_BASE +
- ctxnum * GRU_HANDLE_STRIDE);
-}
-
-static inline struct gru_control_block_extended *get_cbe(void *base, int ctxnum)
-{
- return (struct gru_control_block_extended *)(base + GRU_CBE_BASE +
- ctxnum * GRU_HANDLE_STRIDE);
-}
-
-static inline struct gru_tlb_fault_handle *get_tfh(void *base, int ctxnum)
-{
- return (struct gru_tlb_fault_handle *)(base + GRU_TFH_BASE +
- ctxnum * GRU_HANDLE_STRIDE);
-}
-
-static inline struct gru_context_configuration_handle *get_cch(void *base,
- int ctxnum)
-{
- return (struct gru_context_configuration_handle *)(base +
- GRU_CCH_BASE + ctxnum * GRU_HANDLE_STRIDE);
-}
-
-static inline unsigned long get_cb_number(void *cb)
-{
- return (((unsigned long)cb - GRU_CB_BASE) % GRU_GSEG_PAGESIZE) /
- GRU_HANDLE_STRIDE;
-}
-
-/* byte offset to a specific GRU chiplet. (p=pnode, c=chiplet (0 or 1)*/
-static inline unsigned long gru_chiplet_paddr(unsigned long paddr, int pnode,
- int chiplet)
-{
- return paddr + GRU_SIZE * (2 * pnode + chiplet);
-}
-
-static inline void *gru_chiplet_vaddr(void *vaddr, int pnode, int chiplet)
-{
- return vaddr + GRU_SIZE * (2 * pnode + chiplet);
-}
-
-static inline struct gru_control_block_extended *gru_tfh_to_cbe(
- struct gru_tlb_fault_handle *tfh)
-{
- unsigned long cbe;
-
- cbe = (unsigned long)tfh - GRU_TFH_BASE + GRU_CBE_BASE;
- return (struct gru_control_block_extended*)cbe;
-}
-
-
-
-
-/*
- * Global TLB Fault Map
- * Bitmap of outstanding TLB misses needing interrupt/polling service.
- *
- */
-struct gru_tlb_fault_map {
- unsigned long fault_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
- unsigned long fill0[2];
- unsigned long done_bits[BITS_TO_LONGS(GRU_NUM_CBE)];
- unsigned long fill1[2];
-};
-
-/*
- * TGH - TLB Global Handle
- * Used for TLB flushing.
- *
- */
-struct gru_tlb_global_handle {
- unsigned int cmd:1; /* DW 0 */
- unsigned int delresp:1;
- unsigned int opc:1;
- unsigned int fill1:5;
-
- unsigned int fill2:8;
-
- unsigned int status:2;
- unsigned long fill3:2;
- unsigned int state:3;
- unsigned long fill4:1;
-
- unsigned int cause:3;
- unsigned long fill5:37;
-
- unsigned long vaddr:64; /* DW 1 */
-
- unsigned int asid:24; /* DW 2 */
- unsigned int fill6:8;
-
- unsigned int pagesize:5;
- unsigned int fill7:11;
-
- unsigned int global:1;
- unsigned int fill8:15;
-
- unsigned long vaddrmask:39; /* DW 3 */
- unsigned int fill9:9;
- unsigned int n:10;
- unsigned int fill10:6;
-
- unsigned int ctxbitmap:16; /* DW4 */
- unsigned long fill11[3];
-};
-
-enum gru_tgh_cmd {
- TGHCMD_START
-};
-
-enum gru_tgh_opc {
- TGHOP_TLBNOP,
- TGHOP_TLBINV
-};
-
-enum gru_tgh_status {
- TGHSTATUS_IDLE,
- TGHSTATUS_EXCEPTION,
- TGHSTATUS_ACTIVE
-};
-
-enum gru_tgh_state {
- TGHSTATE_IDLE,
- TGHSTATE_PE_INVAL,
- TGHSTATE_INTERRUPT_INVAL,
- TGHSTATE_WAITDONE,
- TGHSTATE_RESTART_CTX,
-};
-
-enum gru_tgh_cause {
- TGHCAUSE_RR_ECC,
- TGHCAUSE_TLB_ECC,
- TGHCAUSE_LRU_ECC,
- TGHCAUSE_PS_ECC,
- TGHCAUSE_MUL_ERR,
- TGHCAUSE_DATA_ERR,
- TGHCAUSE_SW_FORCE
-};
-
-
-/*
- * TFH - TLB Global Handle
- * Used for TLB dropins into the GRU TLB.
- *
- */
-struct gru_tlb_fault_handle {
- unsigned int cmd:1; /* DW 0 - low 32*/
- unsigned int delresp:1;
- unsigned int fill0:2;
- unsigned int opc:3;
- unsigned int fill1:9;
-
- unsigned int status:2;
- unsigned int fill2:2;
- unsigned int state:3;
- unsigned int fill3:1;
-
- unsigned int cause:6;
- unsigned int cb_int:1;
- unsigned int fill4:1;
-
- unsigned int indexway:12; /* DW 0 - high 32 */
- unsigned int fill5:4;
-
- unsigned int ctxnum:4;
- unsigned int fill6:12;
-
- unsigned long missvaddr:64; /* DW 1 */
-
- unsigned int missasid:24; /* DW 2 */
- unsigned int fill7:8;
- unsigned int fillasid:24;
- unsigned int dirty:1;
- unsigned int gaa:2;
- unsigned long fill8:5;
-
- unsigned long pfn:41; /* DW 3 */
- unsigned int fill9:7;
- unsigned int pagesize:5;
- unsigned int fill10:11;
-
- unsigned long fillvaddr:64; /* DW 4 */
-
- unsigned long fill11[3];
-};
-
-enum gru_tfh_opc {
- TFHOP_NOOP,
- TFHOP_RESTART,
- TFHOP_WRITE_ONLY,
- TFHOP_WRITE_RESTART,
- TFHOP_EXCEPTION,
- TFHOP_USER_POLLING_MODE = 7,
-};
-
-enum tfh_status {
- TFHSTATUS_IDLE,
- TFHSTATUS_EXCEPTION,
- TFHSTATUS_ACTIVE,
-};
-
-enum tfh_state {
- TFHSTATE_INACTIVE,
- TFHSTATE_IDLE,
- TFHSTATE_MISS_UPM,
- TFHSTATE_MISS_FMM,
- TFHSTATE_HW_ERR,
- TFHSTATE_WRITE_TLB,
- TFHSTATE_RESTART_CBR,
-};
-
-/* TFH cause bits */
-enum tfh_cause {
- TFHCAUSE_NONE,
- TFHCAUSE_TLB_MISS,
- TFHCAUSE_TLB_MOD,
- TFHCAUSE_HW_ERROR_RR,
- TFHCAUSE_HW_ERROR_MAIN_ARRAY,
- TFHCAUSE_HW_ERROR_VALID,
- TFHCAUSE_HW_ERROR_PAGESIZE,
- TFHCAUSE_INSTRUCTION_EXCEPTION,
- TFHCAUSE_UNCORRECTIBLE_ERROR,
-};
-
-/* GAA values */
-#define GAA_RAM 0x0
-#define GAA_NCRAM 0x2
-#define GAA_MMIO 0x1
-#define GAA_REGISTER 0x3
-
-/* GRU paddr shift for pfn. (NOTE: shift is NOT by actual pagesize) */
-#define GRU_PADDR_SHIFT 12
-
-/*
- * Context Configuration handle
- * Used to allocate resources to a GSEG context.
- *
- */
-struct gru_context_configuration_handle {
- unsigned int cmd:1; /* DW0 */
- unsigned int delresp:1;
- unsigned int opc:3;
- unsigned int unmap_enable:1;
- unsigned int req_slice_set_enable:1;
- unsigned int req_slice:2;
- unsigned int cb_int_enable:1;
- unsigned int tlb_int_enable:1;
- unsigned int tfm_fault_bit_enable:1;
- unsigned int tlb_int_select:4;
-
- unsigned int status:2;
- unsigned int state:2;
- unsigned int reserved2:4;
-
- unsigned int cause:4;
- unsigned int tfm_done_bit_enable:1;
- unsigned int unused:3;
-
- unsigned int dsr_allocation_map;
-
- unsigned long cbr_allocation_map; /* DW1 */
-
- unsigned int asid[8]; /* DW 2 - 5 */
- unsigned short sizeavail[8]; /* DW 6 - 7 */
-} __attribute__ ((packed));
-
-enum gru_cch_opc {
- CCHOP_START = 1,
- CCHOP_ALLOCATE,
- CCHOP_INTERRUPT,
- CCHOP_DEALLOCATE,
- CCHOP_INTERRUPT_SYNC,
-};
-
-enum gru_cch_status {
- CCHSTATUS_IDLE,
- CCHSTATUS_EXCEPTION,
- CCHSTATUS_ACTIVE,
-};
-
-enum gru_cch_state {
- CCHSTATE_INACTIVE,
- CCHSTATE_MAPPED,
- CCHSTATE_ACTIVE,
- CCHSTATE_INTERRUPTED,
-};
-
-/* CCH Exception cause */
-enum gru_cch_cause {
- CCHCAUSE_REGION_REGISTER_WRITE_ERROR = 1,
- CCHCAUSE_ILLEGAL_OPCODE = 2,
- CCHCAUSE_INVALID_START_REQUEST = 3,
- CCHCAUSE_INVALID_ALLOCATION_REQUEST = 4,
- CCHCAUSE_INVALID_DEALLOCATION_REQUEST = 5,
- CCHCAUSE_INVALID_INTERRUPT_REQUEST = 6,
- CCHCAUSE_CCH_BUSY = 7,
- CCHCAUSE_NO_CBRS_TO_ALLOCATE = 8,
- CCHCAUSE_BAD_TFM_CONFIG = 9,
- CCHCAUSE_CBR_RESOURCES_OVERSUBSCRIPED = 10,
- CCHCAUSE_DSR_RESOURCES_OVERSUBSCRIPED = 11,
- CCHCAUSE_CBR_DEALLOCATION_ERROR = 12,
-};
-/*
- * CBE - Control Block Extended
- * Maintains internal GRU state for active CBs.
- *
- */
-struct gru_control_block_extended {
- unsigned int reserved0:1; /* DW 0 - low */
- unsigned int imacpy:3;
- unsigned int reserved1:4;
- unsigned int xtypecpy:3;
- unsigned int iaa0cpy:2;
- unsigned int iaa1cpy:2;
- unsigned int reserved2:1;
- unsigned int opccpy:8;
- unsigned int exopccpy:8;
-
- unsigned int idef2cpy:22; /* DW 0 - high */
- unsigned int reserved3:10;
-
- unsigned int idef4cpy:22; /* DW 1 */
- unsigned int reserved4:10;
- unsigned int idef4upd:22;
- unsigned int reserved5:10;
-
- unsigned long idef1upd:64; /* DW 2 */
-
- unsigned long idef5cpy:64; /* DW 3 */
-
- unsigned long idef6cpy:64; /* DW 4 */
-
- unsigned long idef3upd:64; /* DW 5 */
-
- unsigned long idef5upd:64; /* DW 6 */
-
- unsigned int idef2upd:22; /* DW 7 */
- unsigned int reserved6:10;
-
- unsigned int ecause:20;
- unsigned int cbrstate:4;
- unsigned int cbrexecstatus:8;
-};
-
-/* CBE fields for active BCOPY instructions */
-#define cbe_baddr0 idef1upd
-#define cbe_baddr1 idef3upd
-#define cbe_src_cl idef6cpy
-#define cbe_nelemcur idef5upd
-
-enum gru_cbr_state {
- CBRSTATE_INACTIVE,
- CBRSTATE_IDLE,
- CBRSTATE_PE_CHECK,
- CBRSTATE_QUEUED,
- CBRSTATE_WAIT_RESPONSE,
- CBRSTATE_INTERRUPTED,
- CBRSTATE_INTERRUPTED_MISS_FMM,
- CBRSTATE_BUSY_INTERRUPT_MISS_FMM,
- CBRSTATE_INTERRUPTED_MISS_UPM,
- CBRSTATE_BUSY_INTERRUPTED_MISS_UPM,
- CBRSTATE_REQUEST_ISSUE,
- CBRSTATE_BUSY_INTERRUPT,
-};
-
-/* CBE cbrexecstatus bits - defined in gru_instructions.h*/
-/* CBE ecause bits - defined in gru_instructions.h */
-
-/*
- * Convert a processor pagesize into the strange encoded pagesize used by the
- * GRU. Processor pagesize is encoded as log of bytes per page. (or PAGE_SHIFT)
- * pagesize log pagesize grupagesize
- * 4k 12 0
- * 16k 14 1
- * 64k 16 2
- * 256k 18 3
- * 1m 20 4
- * 2m 21 5
- * 4m 22 6
- * 16m 24 7
- * 64m 26 8
- * ...
- */
-#define GRU_PAGESIZE(sh) ((((sh) > 20 ? (sh) + 2 : (sh)) >> 1) - 6)
-#define GRU_SIZEAVAIL(sh) (1UL << GRU_PAGESIZE(sh))
-
-/* minimum TLB purge count to ensure a full purge */
-#define GRUMAXINVAL 1024UL
-
-int cch_allocate(struct gru_context_configuration_handle *cch);
-int cch_start(struct gru_context_configuration_handle *cch);
-int cch_interrupt(struct gru_context_configuration_handle *cch);
-int cch_deallocate(struct gru_context_configuration_handle *cch);
-int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
-int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
- unsigned long vaddrmask, int asid, int pagesize, int global, int n,
- unsigned short ctxbitmap);
-int tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
- int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
-void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
- int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
-void tfh_restart(struct gru_tlb_fault_handle *tfh);
-void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh);
-void tfh_exception(struct gru_tlb_fault_handle *tfh);
-
-#endif /* __GRUHANDLES_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/grukdump.c b/ANDROID_3.4.5/drivers/misc/sgi-gru/grukdump.c
deleted file mode 100644
index 9b2062d1..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/grukdump.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * SN Platform GRU Driver
- *
- * Dump GRU State
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-#include <asm/uv/uv_hub.h>
-#include "gru.h"
-#include "grutables.h"
-#include "gruhandles.h"
-#include "grulib.h"
-
-#define CCH_LOCK_ATTEMPTS 10
-
-static int gru_user_copy_handle(void __user **dp, void *s)
-{
- if (copy_to_user(*dp, s, GRU_HANDLE_BYTES))
- return -1;
- *dp += GRU_HANDLE_BYTES;
- return 0;
-}
-
-static int gru_dump_context_data(void *grubase,
- struct gru_context_configuration_handle *cch,
- void __user *ubuf, int ctxnum, int dsrcnt,
- int flush_cbrs)
-{
- void *cb, *cbe, *tfh, *gseg;
- int i, scr;
-
- gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
- cb = gseg + GRU_CB_BASE;
- cbe = grubase + GRU_CBE_BASE;
- tfh = grubase + GRU_TFH_BASE;
-
- for_each_cbr_in_allocation_map(i, &cch->cbr_allocation_map, scr) {
- if (flush_cbrs)
- gru_flush_cache(cb);
- if (gru_user_copy_handle(&ubuf, cb))
- goto fail;
- if (gru_user_copy_handle(&ubuf, tfh + i * GRU_HANDLE_STRIDE))
- goto fail;
- if (gru_user_copy_handle(&ubuf, cbe + i * GRU_HANDLE_STRIDE))
- goto fail;
- cb += GRU_HANDLE_STRIDE;
- }
- if (dsrcnt)
- memcpy(ubuf, gseg + GRU_DS_BASE, dsrcnt * GRU_HANDLE_STRIDE);
- return 0;
-
-fail:
- return -EFAULT;
-}
-
-static int gru_dump_tfm(struct gru_state *gru,
- void __user *ubuf, void __user *ubufend)
-{
- struct gru_tlb_fault_map *tfm;
- int i, ret, bytes;
-
- bytes = GRU_NUM_TFM * GRU_CACHE_LINE_BYTES;
- if (bytes > ubufend - ubuf)
- ret = -EFBIG;
-
- for (i = 0; i < GRU_NUM_TFM; i++) {
- tfm = get_tfm(gru->gs_gru_base_vaddr, i);
- if (gru_user_copy_handle(&ubuf, tfm))
- goto fail;
- }
- return GRU_NUM_TFM * GRU_CACHE_LINE_BYTES;
-
-fail:
- return -EFAULT;
-}
-
-static int gru_dump_tgh(struct gru_state *gru,
- void __user *ubuf, void __user *ubufend)
-{
- struct gru_tlb_global_handle *tgh;
- int i, ret, bytes;
-
- bytes = GRU_NUM_TGH * GRU_CACHE_LINE_BYTES;
- if (bytes > ubufend - ubuf)
- ret = -EFBIG;
-
- for (i = 0; i < GRU_NUM_TGH; i++) {
- tgh = get_tgh(gru->gs_gru_base_vaddr, i);
- if (gru_user_copy_handle(&ubuf, tgh))
- goto fail;
- }
- return GRU_NUM_TGH * GRU_CACHE_LINE_BYTES;
-
-fail:
- return -EFAULT;
-}
-
-static int gru_dump_context(struct gru_state *gru, int ctxnum,
- void __user *ubuf, void __user *ubufend, char data_opt,
- char lock_cch, char flush_cbrs)
-{
- struct gru_dump_context_header hdr;
- struct gru_dump_context_header __user *uhdr = ubuf;
- struct gru_context_configuration_handle *cch, *ubufcch;
- struct gru_thread_state *gts;
- int try, cch_locked, cbrcnt = 0, dsrcnt = 0, bytes = 0, ret = 0;
- void *grubase;
-
- memset(&hdr, 0, sizeof(hdr));
- grubase = gru->gs_gru_base_vaddr;
- cch = get_cch(grubase, ctxnum);
- for (try = 0; try < CCH_LOCK_ATTEMPTS; try++) {
- cch_locked = trylock_cch_handle(cch);
- if (cch_locked)
- break;
- msleep(1);
- }
-
- ubuf += sizeof(hdr);
- ubufcch = ubuf;
- if (gru_user_copy_handle(&ubuf, cch))
- goto fail;
- if (cch_locked)
- ubufcch->delresp = 0;
- bytes = sizeof(hdr) + GRU_CACHE_LINE_BYTES;
-
- if (cch_locked || !lock_cch) {
- gts = gru->gs_gts[ctxnum];
- if (gts && gts->ts_vma) {
- hdr.pid = gts->ts_tgid_owner;
- hdr.vaddr = gts->ts_vma->vm_start;
- }
- if (cch->state != CCHSTATE_INACTIVE) {
- cbrcnt = hweight64(cch->cbr_allocation_map) *
- GRU_CBR_AU_SIZE;
- dsrcnt = data_opt ? hweight32(cch->dsr_allocation_map) *
- GRU_DSR_AU_CL : 0;
- }
- bytes += (3 * cbrcnt + dsrcnt) * GRU_CACHE_LINE_BYTES;
- if (bytes > ubufend - ubuf)
- ret = -EFBIG;
- else
- ret = gru_dump_context_data(grubase, cch, ubuf, ctxnum,
- dsrcnt, flush_cbrs);
- }
- if (cch_locked)
- unlock_cch_handle(cch);
- if (ret)
- return ret;
-
- hdr.magic = GRU_DUMP_MAGIC;
- hdr.gid = gru->gs_gid;
- hdr.ctxnum = ctxnum;
- hdr.cbrcnt = cbrcnt;
- hdr.dsrcnt = dsrcnt;
- hdr.cch_locked = cch_locked;
- if (!ret && copy_to_user((void __user *)uhdr, &hdr, sizeof(hdr)))
- ret = -EFAULT;
-
- return ret ? ret : bytes;
-
-fail:
- unlock_cch_handle(cch);
- return -EFAULT;
-}
-
-int gru_dump_chiplet_request(unsigned long arg)
-{
- struct gru_state *gru;
- struct gru_dump_chiplet_state_req req;
- void __user *ubuf;
- void __user *ubufend;
- int ctxnum, ret, cnt = 0;
-
- if (copy_from_user(&req, (void __user *)arg, sizeof(req)))
- return -EFAULT;
-
- /* Currently, only dump by gid is implemented */
- if (req.gid >= gru_max_gids || req.gid < 0)
- return -EINVAL;
-
- gru = GID_TO_GRU(req.gid);
- ubuf = req.buf;
- ubufend = req.buf + req.buflen;
-
- ret = gru_dump_tfm(gru, ubuf, ubufend);
- if (ret < 0)
- goto fail;
- ubuf += ret;
-
- ret = gru_dump_tgh(gru, ubuf, ubufend);
- if (ret < 0)
- goto fail;
- ubuf += ret;
-
- for (ctxnum = 0; ctxnum < GRU_NUM_CCH; ctxnum++) {
- if (req.ctxnum == ctxnum || req.ctxnum < 0) {
- ret = gru_dump_context(gru, ctxnum, ubuf, ubufend,
- req.data_opt, req.lock_cch,
- req.flush_cbrs);
- if (ret < 0)
- goto fail;
- ubuf += ret;
- cnt++;
- }
- }
-
- if (copy_to_user((void __user *)arg, &req, sizeof(req)))
- return -EFAULT;
- return cnt;
-
-fail:
- return ret;
-}
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/grukservices.c b/ANDROID_3.4.5/drivers/misc/sgi-gru/grukservices.c
deleted file mode 100644
index 913de07e..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/grukservices.c
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- * SN Platform GRU Driver
- *
- * KERNEL SERVICES THAT USE THE GRU
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/device.h>
-#include <linux/miscdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/interrupt.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
-#include <linux/export.h>
-#include <asm/io_apic.h>
-#include "gru.h"
-#include "grulib.h"
-#include "grutables.h"
-#include "grukservices.h"
-#include "gru_instructions.h"
-#include <asm/uv/uv_hub.h>
-
-/*
- * Kernel GRU Usage
- *
- * The following is an interim algorithm for management of kernel GRU
- * resources. This will likely be replaced when we better understand the
- * kernel/user requirements.
- *
- * Blade percpu resources reserved for kernel use. These resources are
- * reserved whenever the the kernel context for the blade is loaded. Note
- * that the kernel context is not guaranteed to be always available. It is
- * loaded on demand & can be stolen by a user if the user demand exceeds the
- * kernel demand. The kernel can always reload the kernel context but
- * a SLEEP may be required!!!.
- *
- * Async Overview:
- *
- * Each blade has one "kernel context" that owns GRU kernel resources
- * located on the blade. Kernel drivers use GRU resources in this context
- * for sending messages, zeroing memory, etc.
- *
- * The kernel context is dynamically loaded on demand. If it is not in
- * use by the kernel, the kernel context can be unloaded & given to a user.
- * The kernel context will be reloaded when needed. This may require that
- * a context be stolen from a user.
- * NOTE: frequent unloading/reloading of the kernel context is
- * expensive. We are depending on batch schedulers, cpusets, sane
- * drivers or some other mechanism to prevent the need for frequent
- * stealing/reloading.
- *
- * The kernel context consists of two parts:
- * - 1 CB & a few DSRs that are reserved for each cpu on the blade.
- * Each cpu has it's own private resources & does not share them
- * with other cpus. These resources are used serially, ie,
- * locked, used & unlocked on each call to a function in
- * grukservices.
- * (Now that we have dynamic loading of kernel contexts, I
- * may rethink this & allow sharing between cpus....)
- *
- * - Additional resources can be reserved long term & used directly
- * by UV drivers located in the kernel. Drivers using these GRU
- * resources can use asynchronous GRU instructions that send
- * interrupts on completion.
- * - these resources must be explicitly locked/unlocked
- * - locked resources prevent (obviously) the kernel
- * context from being unloaded.
- * - drivers using these resource directly issue their own
- * GRU instruction and must wait/check completion.
- *
- * When these resources are reserved, the caller can optionally
- * associate a wait_queue with the resources and use asynchronous
- * GRU instructions. When an async GRU instruction completes, the
- * driver will do a wakeup on the event.
- *
- */
-
-
-#define ASYNC_HAN_TO_BID(h) ((h) - 1)
-#define ASYNC_BID_TO_HAN(b) ((b) + 1)
-#define ASYNC_HAN_TO_BS(h) gru_base[ASYNC_HAN_TO_BID(h)]
-
-#define GRU_NUM_KERNEL_CBR 1
-#define GRU_NUM_KERNEL_DSR_BYTES 256
-#define GRU_NUM_KERNEL_DSR_CL (GRU_NUM_KERNEL_DSR_BYTES / \
- GRU_CACHE_LINE_BYTES)
-
-/* GRU instruction attributes for all instructions */
-#define IMA IMA_CB_DELAY
-
-/* GRU cacheline size is always 64 bytes - even on arches with 128 byte lines */
-#define __gru_cacheline_aligned__ \
- __attribute__((__aligned__(GRU_CACHE_LINE_BYTES)))
-
-#define MAGIC 0x1234567887654321UL
-
-/* Default retry count for GRU errors on kernel instructions */
-#define EXCEPTION_RETRY_LIMIT 3
-
-/* Status of message queue sections */
-#define MQS_EMPTY 0
-#define MQS_FULL 1
-#define MQS_NOOP 2
-
-/*----------------- RESOURCE MANAGEMENT -------------------------------------*/
-/* optimized for x86_64 */
-struct message_queue {
- union gru_mesqhead head __gru_cacheline_aligned__; /* CL 0 */
- int qlines; /* DW 1 */
- long hstatus[2];
- void *next __gru_cacheline_aligned__;/* CL 1 */
- void *limit;
- void *start;
- void *start2;
- char data ____cacheline_aligned; /* CL 2 */
-};
-
-/* First word in every message - used by mesq interface */
-struct message_header {
- char present;
- char present2;
- char lines;
- char fill;
-};
-
-#define HSTATUS(mq, h) ((mq) + offsetof(struct message_queue, hstatus[h]))
-
-/*
- * Reload the blade's kernel context into a GRU chiplet. Called holding
- * the bs_kgts_sema for READ. Will steal user contexts if necessary.
- */
-static void gru_load_kernel_context(struct gru_blade_state *bs, int blade_id)
-{
- struct gru_state *gru;
- struct gru_thread_state *kgts;
- void *vaddr;
- int ctxnum, ncpus;
-
- up_read(&bs->bs_kgts_sema);
- down_write(&bs->bs_kgts_sema);
-
- if (!bs->bs_kgts) {
- bs->bs_kgts = gru_alloc_gts(NULL, 0, 0, 0, 0, 0);
- bs->bs_kgts->ts_user_blade_id = blade_id;
- }
- kgts = bs->bs_kgts;
-
- if (!kgts->ts_gru) {
- STAT(load_kernel_context);
- ncpus = uv_blade_nr_possible_cpus(blade_id);
- kgts->ts_cbr_au_count = GRU_CB_COUNT_TO_AU(
- GRU_NUM_KERNEL_CBR * ncpus + bs->bs_async_cbrs);
- kgts->ts_dsr_au_count = GRU_DS_BYTES_TO_AU(
- GRU_NUM_KERNEL_DSR_BYTES * ncpus +
- bs->bs_async_dsr_bytes);
- while (!gru_assign_gru_context(kgts)) {
- msleep(1);
- gru_steal_context(kgts);
- }
- gru_load_context(kgts);
- gru = bs->bs_kgts->ts_gru;
- vaddr = gru->gs_gru_base_vaddr;
- ctxnum = kgts->ts_ctxnum;
- bs->kernel_cb = get_gseg_base_address_cb(vaddr, ctxnum, 0);
- bs->kernel_dsr = get_gseg_base_address_ds(vaddr, ctxnum, 0);
- }
- downgrade_write(&bs->bs_kgts_sema);
-}
-
-/*
- * Free all kernel contexts that are not currently in use.
- * Returns 0 if all freed, else number of inuse context.
- */
-static int gru_free_kernel_contexts(void)
-{
- struct gru_blade_state *bs;
- struct gru_thread_state *kgts;
- int bid, ret = 0;
-
- for (bid = 0; bid < GRU_MAX_BLADES; bid++) {
- bs = gru_base[bid];
- if (!bs)
- continue;
-
- /* Ignore busy contexts. Don't want to block here. */
- if (down_write_trylock(&bs->bs_kgts_sema)) {
- kgts = bs->bs_kgts;
- if (kgts && kgts->ts_gru)
- gru_unload_context(kgts, 0);
- bs->bs_kgts = NULL;
- up_write(&bs->bs_kgts_sema);
- kfree(kgts);
- } else {
- ret++;
- }
- }
- return ret;
-}
-
-/*
- * Lock & load the kernel context for the specified blade.
- */
-static struct gru_blade_state *gru_lock_kernel_context(int blade_id)
-{
- struct gru_blade_state *bs;
- int bid;
-
- STAT(lock_kernel_context);
-again:
- bid = blade_id < 0 ? uv_numa_blade_id() : blade_id;
- bs = gru_base[bid];
-
- /* Handle the case where migration occurred while waiting for the sema */
- down_read(&bs->bs_kgts_sema);
- if (blade_id < 0 && bid != uv_numa_blade_id()) {
- up_read(&bs->bs_kgts_sema);
- goto again;
- }
- if (!bs->bs_kgts || !bs->bs_kgts->ts_gru)
- gru_load_kernel_context(bs, bid);
- return bs;
-
-}
-
-/*
- * Unlock the kernel context for the specified blade. Context is not
- * unloaded but may be stolen before next use.
- */
-static void gru_unlock_kernel_context(int blade_id)
-{
- struct gru_blade_state *bs;
-
- bs = gru_base[blade_id];
- up_read(&bs->bs_kgts_sema);
- STAT(unlock_kernel_context);
-}
-
-/*
- * Reserve & get pointers to the DSR/CBRs reserved for the current cpu.
- * - returns with preemption disabled
- */
-static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr)
-{
- struct gru_blade_state *bs;
- int lcpu;
-
- BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES);
- preempt_disable();
- bs = gru_lock_kernel_context(-1);
- lcpu = uv_blade_processor_id();
- *cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE;
- *dsr = bs->kernel_dsr + lcpu * GRU_NUM_KERNEL_DSR_BYTES;
- return 0;
-}
-
-/*
- * Free the current cpus reserved DSR/CBR resources.
- */
-static void gru_free_cpu_resources(void *cb, void *dsr)
-{
- gru_unlock_kernel_context(uv_numa_blade_id());
- preempt_enable();
-}
-
-/*
- * Reserve GRU resources to be used asynchronously.
- * Note: currently supports only 1 reservation per blade.
- *
- * input:
- * blade_id - blade on which resources should be reserved
- * cbrs - number of CBRs
- * dsr_bytes - number of DSR bytes needed
- * output:
- * handle to identify resource
- * (0 = async resources already reserved)
- */
-unsigned long gru_reserve_async_resources(int blade_id, int cbrs, int dsr_bytes,
- struct completion *cmp)
-{
- struct gru_blade_state *bs;
- struct gru_thread_state *kgts;
- int ret = 0;
-
- bs = gru_base[blade_id];
-
- down_write(&bs->bs_kgts_sema);
-
- /* Verify no resources already reserved */
- if (bs->bs_async_dsr_bytes + bs->bs_async_cbrs)
- goto done;
- bs->bs_async_dsr_bytes = dsr_bytes;
- bs->bs_async_cbrs = cbrs;
- bs->bs_async_wq = cmp;
- kgts = bs->bs_kgts;
-
- /* Resources changed. Unload context if already loaded */
- if (kgts && kgts->ts_gru)
- gru_unload_context(kgts, 0);
- ret = ASYNC_BID_TO_HAN(blade_id);
-
-done:
- up_write(&bs->bs_kgts_sema);
- return ret;
-}
-
-/*
- * Release async resources previously reserved.
- *
- * input:
- * han - handle to identify resources
- */
-void gru_release_async_resources(unsigned long han)
-{
- struct gru_blade_state *bs = ASYNC_HAN_TO_BS(han);
-
- down_write(&bs->bs_kgts_sema);
- bs->bs_async_dsr_bytes = 0;
- bs->bs_async_cbrs = 0;
- bs->bs_async_wq = NULL;
- up_write(&bs->bs_kgts_sema);
-}
-
-/*
- * Wait for async GRU instructions to complete.
- *
- * input:
- * han - handle to identify resources
- */
-void gru_wait_async_cbr(unsigned long han)
-{
- struct gru_blade_state *bs = ASYNC_HAN_TO_BS(han);
-
- wait_for_completion(bs->bs_async_wq);
- mb();
-}
-
-/*
- * Lock previous reserved async GRU resources
- *
- * input:
- * han - handle to identify resources
- * output:
- * cb - pointer to first CBR
- * dsr - pointer to first DSR
- */
-void gru_lock_async_resource(unsigned long han, void **cb, void **dsr)
-{
- struct gru_blade_state *bs = ASYNC_HAN_TO_BS(han);
- int blade_id = ASYNC_HAN_TO_BID(han);
- int ncpus;
-
- gru_lock_kernel_context(blade_id);
- ncpus = uv_blade_nr_possible_cpus(blade_id);
- if (cb)
- *cb = bs->kernel_cb + ncpus * GRU_HANDLE_STRIDE;
- if (dsr)
- *dsr = bs->kernel_dsr + ncpus * GRU_NUM_KERNEL_DSR_BYTES;
-}
-
-/*
- * Unlock previous reserved async GRU resources
- *
- * input:
- * han - handle to identify resources
- */
-void gru_unlock_async_resource(unsigned long han)
-{
- int blade_id = ASYNC_HAN_TO_BID(han);
-
- gru_unlock_kernel_context(blade_id);
-}
-
-/*----------------------------------------------------------------------*/
-int gru_get_cb_exception_detail(void *cb,
- struct control_block_extended_exc_detail *excdet)
-{
- struct gru_control_block_extended *cbe;
- struct gru_thread_state *kgts = NULL;
- unsigned long off;
- int cbrnum, bid;
-
- /*
- * Locate kgts for cb. This algorithm is SLOW but
- * this function is rarely called (ie., almost never).
- * Performance does not matter.
- */
- for_each_possible_blade(bid) {
- if (!gru_base[bid])
- break;
- kgts = gru_base[bid]->bs_kgts;
- if (!kgts || !kgts->ts_gru)
- continue;
- off = cb - kgts->ts_gru->gs_gru_base_vaddr;
- if (off < GRU_SIZE)
- break;
- kgts = NULL;
- }
- BUG_ON(!kgts);
- cbrnum = thread_cbr_number(kgts, get_cb_number(cb));
- cbe = get_cbe(GRUBASE(cb), cbrnum);
- gru_flush_cache(cbe); /* CBE not coherent */
- sync_core();
- excdet->opc = cbe->opccpy;
- excdet->exopc = cbe->exopccpy;
- excdet->ecause = cbe->ecause;
- excdet->exceptdet0 = cbe->idef1upd;
- excdet->exceptdet1 = cbe->idef3upd;
- gru_flush_cache(cbe);
- return 0;
-}
-
-char *gru_get_cb_exception_detail_str(int ret, void *cb,
- char *buf, int size)
-{
- struct gru_control_block_status *gen = (void *)cb;
- struct control_block_extended_exc_detail excdet;
-
- if (ret > 0 && gen->istatus == CBS_EXCEPTION) {
- gru_get_cb_exception_detail(cb, &excdet);
- snprintf(buf, size,
- "GRU:%d exception: cb %p, opc %d, exopc %d, ecause 0x%x,"
- "excdet0 0x%lx, excdet1 0x%x", smp_processor_id(),
- gen, excdet.opc, excdet.exopc, excdet.ecause,
- excdet.exceptdet0, excdet.exceptdet1);
- } else {
- snprintf(buf, size, "No exception");
- }
- return buf;
-}
-
-static int gru_wait_idle_or_exception(struct gru_control_block_status *gen)
-{
- while (gen->istatus >= CBS_ACTIVE) {
- cpu_relax();
- barrier();
- }
- return gen->istatus;
-}
-
-static int gru_retry_exception(void *cb)
-{
- struct gru_control_block_status *gen = (void *)cb;
- struct control_block_extended_exc_detail excdet;
- int retry = EXCEPTION_RETRY_LIMIT;
-
- while (1) {
- if (gru_wait_idle_or_exception(gen) == CBS_IDLE)
- return CBS_IDLE;
- if (gru_get_cb_message_queue_substatus(cb))
- return CBS_EXCEPTION;
- gru_get_cb_exception_detail(cb, &excdet);
- if ((excdet.ecause & ~EXCEPTION_RETRY_BITS) ||
- (excdet.cbrexecstatus & CBR_EXS_ABORT_OCC))
- break;
- if (retry-- == 0)
- break;
- gen->icmd = 1;
- gru_flush_cache(gen);
- }
- return CBS_EXCEPTION;
-}
-
-int gru_check_status_proc(void *cb)
-{
- struct gru_control_block_status *gen = (void *)cb;
- int ret;
-
- ret = gen->istatus;
- if (ret == CBS_EXCEPTION)
- ret = gru_retry_exception(cb);
- rmb();
- return ret;
-
-}
-
-int gru_wait_proc(void *cb)
-{
- struct gru_control_block_status *gen = (void *)cb;
- int ret;
-
- ret = gru_wait_idle_or_exception(gen);
- if (ret == CBS_EXCEPTION)
- ret = gru_retry_exception(cb);
- rmb();
- return ret;
-}
-
-void gru_abort(int ret, void *cb, char *str)
-{
- char buf[GRU_EXC_STR_SIZE];
-
- panic("GRU FATAL ERROR: %s - %s\n", str,
- gru_get_cb_exception_detail_str(ret, cb, buf, sizeof(buf)));
-}
-
-void gru_wait_abort_proc(void *cb)
-{
- int ret;
-
- ret = gru_wait_proc(cb);
- if (ret)
- gru_abort(ret, cb, "gru_wait_abort");
-}
-
-
-/*------------------------------ MESSAGE QUEUES -----------------------------*/
-
-/* Internal status . These are NOT returned to the user. */
-#define MQIE_AGAIN -1 /* try again */
-
-
-/*
- * Save/restore the "present" flag that is in the second line of 2-line
- * messages
- */
-static inline int get_present2(void *p)
-{
- struct message_header *mhdr = p + GRU_CACHE_LINE_BYTES;
- return mhdr->present;
-}
-
-static inline void restore_present2(void *p, int val)
-{
- struct message_header *mhdr = p + GRU_CACHE_LINE_BYTES;
- mhdr->present = val;
-}
-
-/*
- * Create a message queue.
- * qlines - message queue size in cache lines. Includes 2-line header.
- */
-int gru_create_message_queue(struct gru_message_queue_desc *mqd,
- void *p, unsigned int bytes, int nasid, int vector, int apicid)
-{
- struct message_queue *mq = p;
- unsigned int qlines;
-
- qlines = bytes / GRU_CACHE_LINE_BYTES - 2;
- memset(mq, 0, bytes);
- mq->start = &mq->data;
- mq->start2 = &mq->data + (qlines / 2 - 1) * GRU_CACHE_LINE_BYTES;
- mq->next = &mq->data;
- mq->limit = &mq->data + (qlines - 2) * GRU_CACHE_LINE_BYTES;
- mq->qlines = qlines;
- mq->hstatus[0] = 0;
- mq->hstatus[1] = 1;
- mq->head = gru_mesq_head(2, qlines / 2 + 1);
- mqd->mq = mq;
- mqd->mq_gpa = uv_gpa(mq);
- mqd->qlines = qlines;
- mqd->interrupt_pnode = nasid >> 1;
- mqd->interrupt_vector = vector;
- mqd->interrupt_apicid = apicid;
- return 0;
-}
-EXPORT_SYMBOL_GPL(gru_create_message_queue);
-
-/*
- * Send a NOOP message to a message queue
- * Returns:
- * 0 - if queue is full after the send. This is the normal case
- * but various races can change this.
- * -1 - if mesq sent successfully but queue not full
- * >0 - unexpected error. MQE_xxx returned
- */
-static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd,
- void *mesg)
-{
- const struct message_header noop_header = {
- .present = MQS_NOOP, .lines = 1};
- unsigned long m;
- int substatus, ret;
- struct message_header save_mhdr, *mhdr = mesg;
-
- STAT(mesq_noop);
- save_mhdr = *mhdr;
- *mhdr = noop_header;
- gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), 1, IMA);
- ret = gru_wait(cb);
-
- if (ret) {
- substatus = gru_get_cb_message_queue_substatus(cb);
- switch (substatus) {
- case CBSS_NO_ERROR:
- STAT(mesq_noop_unexpected_error);
- ret = MQE_UNEXPECTED_CB_ERR;
- break;
- case CBSS_LB_OVERFLOWED:
- STAT(mesq_noop_lb_overflow);
- ret = MQE_CONGESTION;
- break;
- case CBSS_QLIMIT_REACHED:
- STAT(mesq_noop_qlimit_reached);
- ret = 0;
- break;
- case CBSS_AMO_NACKED:
- STAT(mesq_noop_amo_nacked);
- ret = MQE_CONGESTION;
- break;
- case CBSS_PUT_NACKED:
- STAT(mesq_noop_put_nacked);
- m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
- gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, 1, 1,
- IMA);
- if (gru_wait(cb) == CBS_IDLE)
- ret = MQIE_AGAIN;
- else
- ret = MQE_UNEXPECTED_CB_ERR;
- break;
- case CBSS_PAGE_OVERFLOW:
- STAT(mesq_noop_page_overflow);
- /* fallthru */
- default:
- BUG();
- }
- }
- *mhdr = save_mhdr;
- return ret;
-}
-
-/*
- * Handle a gru_mesq full.
- */
-static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd,
- void *mesg, int lines)
-{
- union gru_mesqhead mqh;
- unsigned int limit, head;
- unsigned long avalue;
- int half, qlines;
-
- /* Determine if switching to first/second half of q */
- avalue = gru_get_amo_value(cb);
- head = gru_get_amo_value_head(cb);
- limit = gru_get_amo_value_limit(cb);
-
- qlines = mqd->qlines;
- half = (limit != qlines);
-
- if (half)
- mqh = gru_mesq_head(qlines / 2 + 1, qlines);
- else
- mqh = gru_mesq_head(2, qlines / 2 + 1);
-
- /* Try to get lock for switching head pointer */
- gru_gamir(cb, EOP_IR_CLR, HSTATUS(mqd->mq_gpa, half), XTYPE_DW, IMA);
- if (gru_wait(cb) != CBS_IDLE)
- goto cberr;
- if (!gru_get_amo_value(cb)) {
- STAT(mesq_qf_locked);
- return MQE_QUEUE_FULL;
- }
-
- /* Got the lock. Send optional NOP if queue not full, */
- if (head != limit) {
- if (send_noop_message(cb, mqd, mesg)) {
- gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half),
- XTYPE_DW, IMA);
- if (gru_wait(cb) != CBS_IDLE)
- goto cberr;
- STAT(mesq_qf_noop_not_full);
- return MQIE_AGAIN;
- }
- avalue++;
- }
-
- /* Then flip queuehead to other half of queue. */
- gru_gamer(cb, EOP_ERR_CSWAP, mqd->mq_gpa, XTYPE_DW, mqh.val, avalue,
- IMA);
- if (gru_wait(cb) != CBS_IDLE)
- goto cberr;
-
- /* If not successfully in swapping queue head, clear the hstatus lock */
- if (gru_get_amo_value(cb) != avalue) {
- STAT(mesq_qf_switch_head_failed);
- gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half), XTYPE_DW,
- IMA);
- if (gru_wait(cb) != CBS_IDLE)
- goto cberr;
- }
- return MQIE_AGAIN;
-cberr:
- STAT(mesq_qf_unexpected_error);
- return MQE_UNEXPECTED_CB_ERR;
-}
-
-/*
- * Handle a PUT failure. Note: if message was a 2-line message, one of the
- * lines might have successfully have been written. Before sending the
- * message, "present" must be cleared in BOTH lines to prevent the receiver
- * from prematurely seeing the full message.
- */
-static int send_message_put_nacked(void *cb, struct gru_message_queue_desc *mqd,
- void *mesg, int lines)
-{
- unsigned long m, *val = mesg, gpa, save;
- int ret;
-
- m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
- if (lines == 2) {
- gru_vset(cb, m, 0, XTYPE_CL, lines, 1, IMA);
- if (gru_wait(cb) != CBS_IDLE)
- return MQE_UNEXPECTED_CB_ERR;
- }
- gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
- if (gru_wait(cb) != CBS_IDLE)
- return MQE_UNEXPECTED_CB_ERR;
-
- if (!mqd->interrupt_vector)
- return MQE_OK;
-
- /*
- * Send a cross-partition interrupt to the SSI that contains the target
- * message queue. Normally, the interrupt is automatically delivered by
- * hardware but some error conditions require explicit delivery.
- * Use the GRU to deliver the interrupt. Otherwise partition failures
- * could cause unrecovered errors.
- */
- gpa = uv_global_gru_mmr_address(mqd->interrupt_pnode, UVH_IPI_INT);
- save = *val;
- *val = uv_hub_ipi_value(mqd->interrupt_apicid, mqd->interrupt_vector,
- dest_Fixed);
- gru_vstore_phys(cb, gpa, gru_get_tri(mesg), IAA_REGISTER, IMA);
- ret = gru_wait(cb);
- *val = save;
- if (ret != CBS_IDLE)
- return MQE_UNEXPECTED_CB_ERR;
- return MQE_OK;
-}
-
-/*
- * Handle a gru_mesq failure. Some of these failures are software recoverable
- * or retryable.
- */
-static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
- void *mesg, int lines)
-{
- int substatus, ret = 0;
-
- substatus = gru_get_cb_message_queue_substatus(cb);
- switch (substatus) {
- case CBSS_NO_ERROR:
- STAT(mesq_send_unexpected_error);
- ret = MQE_UNEXPECTED_CB_ERR;
- break;
- case CBSS_LB_OVERFLOWED:
- STAT(mesq_send_lb_overflow);
- ret = MQE_CONGESTION;
- break;
- case CBSS_QLIMIT_REACHED:
- STAT(mesq_send_qlimit_reached);
- ret = send_message_queue_full(cb, mqd, mesg, lines);
- break;
- case CBSS_AMO_NACKED:
- STAT(mesq_send_amo_nacked);
- ret = MQE_CONGESTION;
- break;
- case CBSS_PUT_NACKED:
- STAT(mesq_send_put_nacked);
- ret = send_message_put_nacked(cb, mqd, mesg, lines);
- break;
- case CBSS_PAGE_OVERFLOW:
- STAT(mesq_page_overflow);
- /* fallthru */
- default:
- BUG();
- }
- return ret;
-}
-
-/*
- * Send a message to a message queue
- * mqd message queue descriptor
- * mesg message. ust be vaddr within a GSEG
- * bytes message size (<= 2 CL)
- */
-int gru_send_message_gpa(struct gru_message_queue_desc *mqd, void *mesg,
- unsigned int bytes)
-{
- struct message_header *mhdr;
- void *cb;
- void *dsr;
- int istatus, clines, ret;
-
- STAT(mesq_send);
- BUG_ON(bytes < sizeof(int) || bytes > 2 * GRU_CACHE_LINE_BYTES);
-
- clines = DIV_ROUND_UP(bytes, GRU_CACHE_LINE_BYTES);
- if (gru_get_cpu_resources(bytes, &cb, &dsr))
- return MQE_BUG_NO_RESOURCES;
- memcpy(dsr, mesg, bytes);
- mhdr = dsr;
- mhdr->present = MQS_FULL;
- mhdr->lines = clines;
- if (clines == 2) {
- mhdr->present2 = get_present2(mhdr);
- restore_present2(mhdr, MQS_FULL);
- }
-
- do {
- ret = MQE_OK;
- gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), clines, IMA);
- istatus = gru_wait(cb);
- if (istatus != CBS_IDLE)
- ret = send_message_failure(cb, mqd, dsr, clines);
- } while (ret == MQIE_AGAIN);
- gru_free_cpu_resources(cb, dsr);
-
- if (ret)
- STAT(mesq_send_failed);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gru_send_message_gpa);
-
-/*
- * Advance the receive pointer for the queue to the next message.
- */
-void gru_free_message(struct gru_message_queue_desc *mqd, void *mesg)
-{
- struct message_queue *mq = mqd->mq;
- struct message_header *mhdr = mq->next;
- void *next, *pnext;
- int half = -1;
- int lines = mhdr->lines;
-
- if (lines == 2)
- restore_present2(mhdr, MQS_EMPTY);
- mhdr->present = MQS_EMPTY;
-
- pnext = mq->next;
- next = pnext + GRU_CACHE_LINE_BYTES * lines;
- if (next == mq->limit) {
- next = mq->start;
- half = 1;
- } else if (pnext < mq->start2 && next >= mq->start2) {
- half = 0;
- }
-
- if (half >= 0)
- mq->hstatus[half] = 1;
- mq->next = next;
-}
-EXPORT_SYMBOL_GPL(gru_free_message);
-
-/*
- * Get next message from message queue. Return NULL if no message
- * present. User must call next_message() to move to next message.
- * rmq message queue
- */
-void *gru_get_next_message(struct gru_message_queue_desc *mqd)
-{
- struct message_queue *mq = mqd->mq;
- struct message_header *mhdr = mq->next;
- int present = mhdr->present;
-
- /* skip NOOP messages */
- while (present == MQS_NOOP) {
- gru_free_message(mqd, mhdr);
- mhdr = mq->next;
- present = mhdr->present;
- }
-
- /* Wait for both halves of 2 line messages */
- if (present == MQS_FULL && mhdr->lines == 2 &&
- get_present2(mhdr) == MQS_EMPTY)
- present = MQS_EMPTY;
-
- if (!present) {
- STAT(mesq_receive_none);
- return NULL;
- }
-
- if (mhdr->lines == 2)
- restore_present2(mhdr, mhdr->present2);
-
- STAT(mesq_receive);
- return mhdr;
-}
-EXPORT_SYMBOL_GPL(gru_get_next_message);
-
-/* ---------------------- GRU DATA COPY FUNCTIONS ---------------------------*/
-
-/*
- * Load a DW from a global GPA. The GPA can be a memory or MMR address.
- */
-int gru_read_gpa(unsigned long *value, unsigned long gpa)
-{
- void *cb;
- void *dsr;
- int ret, iaa;
-
- STAT(read_gpa);
- if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr))
- return MQE_BUG_NO_RESOURCES;
- iaa = gpa >> 62;
- gru_vload_phys(cb, gpa, gru_get_tri(dsr), iaa, IMA);
- ret = gru_wait(cb);
- if (ret == CBS_IDLE)
- *value = *(unsigned long *)dsr;
- gru_free_cpu_resources(cb, dsr);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gru_read_gpa);
-
-
-/*
- * Copy a block of data using the GRU resources
- */
-int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
- unsigned int bytes)
-{
- void *cb;
- void *dsr;
- int ret;
-
- STAT(copy_gpa);
- if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr))
- return MQE_BUG_NO_RESOURCES;
- gru_bcopy(cb, src_gpa, dest_gpa, gru_get_tri(dsr),
- XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_CL, IMA);
- ret = gru_wait(cb);
- gru_free_cpu_resources(cb, dsr);
- return ret;
-}
-EXPORT_SYMBOL_GPL(gru_copy_gpa);
-
-/* ------------------- KERNEL QUICKTESTS RUN AT STARTUP ----------------*/
-/* Temp - will delete after we gain confidence in the GRU */
-
-static int quicktest0(unsigned long arg)
-{
- unsigned long word0;
- unsigned long word1;
- void *cb;
- void *dsr;
- unsigned long *p;
- int ret = -EIO;
-
- if (gru_get_cpu_resources(GRU_CACHE_LINE_BYTES, &cb, &dsr))
- return MQE_BUG_NO_RESOURCES;
- p = dsr;
- word0 = MAGIC;
- word1 = 0;
-
- gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
- if (gru_wait(cb) != CBS_IDLE) {
- printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 1\n", smp_processor_id());
- goto done;
- }
-
- if (*p != MAGIC) {
- printk(KERN_DEBUG "GRU:%d quicktest0 bad magic 0x%lx\n", smp_processor_id(), *p);
- goto done;
- }
- gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
- if (gru_wait(cb) != CBS_IDLE) {
- printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 2\n", smp_processor_id());
- goto done;
- }
-
- if (word0 != word1 || word1 != MAGIC) {
- printk(KERN_DEBUG
- "GRU:%d quicktest0 err: found 0x%lx, expected 0x%lx\n",
- smp_processor_id(), word1, MAGIC);
- goto done;
- }
- ret = 0;
-
-done:
- gru_free_cpu_resources(cb, dsr);
- return ret;
-}
-
-#define ALIGNUP(p, q) ((void *)(((unsigned long)(p) + (q) - 1) & ~(q - 1)))
-
-static int quicktest1(unsigned long arg)
-{
- struct gru_message_queue_desc mqd;
- void *p, *mq;
- unsigned long *dw;
- int i, ret = -EIO;
- char mes[GRU_CACHE_LINE_BYTES], *m;
-
- /* Need 1K cacheline aligned that does not cross page boundary */
- p = kmalloc(4096, 0);
- if (p == NULL)
- return -ENOMEM;
- mq = ALIGNUP(p, 1024);
- memset(mes, 0xee, sizeof(mes));
- dw = mq;
-
- gru_create_message_queue(&mqd, mq, 8 * GRU_CACHE_LINE_BYTES, 0, 0, 0);
- for (i = 0; i < 6; i++) {
- mes[8] = i;
- do {
- ret = gru_send_message_gpa(&mqd, mes, sizeof(mes));
- } while (ret == MQE_CONGESTION);
- if (ret)
- break;
- }
- if (ret != MQE_QUEUE_FULL || i != 4) {
- printk(KERN_DEBUG "GRU:%d quicktest1: unexpect status %d, i %d\n",
- smp_processor_id(), ret, i);
- goto done;
- }
-
- for (i = 0; i < 6; i++) {
- m = gru_get_next_message(&mqd);
- if (!m || m[8] != i)
- break;
- gru_free_message(&mqd, m);
- }
- if (i != 4) {
- printk(KERN_DEBUG "GRU:%d quicktest2: bad message, i %d, m %p, m8 %d\n",
- smp_processor_id(), i, m, m ? m[8] : -1);
- goto done;
- }
- ret = 0;
-
-done:
- kfree(p);
- return ret;
-}
-
-static int quicktest2(unsigned long arg)
-{
- static DECLARE_COMPLETION(cmp);
- unsigned long han;
- int blade_id = 0;
- int numcb = 4;
- int ret = 0;
- unsigned long *buf;
- void *cb0, *cb;
- struct gru_control_block_status *gen;
- int i, k, istatus, bytes;
-
- bytes = numcb * 4 * 8;
- buf = kmalloc(bytes, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- ret = -EBUSY;
- han = gru_reserve_async_resources(blade_id, numcb, 0, &cmp);
- if (!han)
- goto done;
-
- gru_lock_async_resource(han, &cb0, NULL);
- memset(buf, 0xee, bytes);
- for (i = 0; i < numcb; i++)
- gru_vset(cb0 + i * GRU_HANDLE_STRIDE, uv_gpa(&buf[i * 4]), 0,
- XTYPE_DW, 4, 1, IMA_INTERRUPT);
-
- ret = 0;
- k = numcb;
- do {
- gru_wait_async_cbr(han);
- for (i = 0; i < numcb; i++) {
- cb = cb0 + i * GRU_HANDLE_STRIDE;
- istatus = gru_check_status(cb);
- if (istatus != CBS_ACTIVE && istatus != CBS_CALL_OS)
- break;
- }
- if (i == numcb)
- continue;
- if (istatus != CBS_IDLE) {
- printk(KERN_DEBUG "GRU:%d quicktest2: cb %d, exception\n", smp_processor_id(), i);
- ret = -EFAULT;
- } else if (buf[4 * i] || buf[4 * i + 1] || buf[4 * i + 2] ||
- buf[4 * i + 3]) {
- printk(KERN_DEBUG "GRU:%d quicktest2:cb %d, buf 0x%lx, 0x%lx, 0x%lx, 0x%lx\n",
- smp_processor_id(), i, buf[4 * i], buf[4 * i + 1], buf[4 * i + 2], buf[4 * i + 3]);
- ret = -EIO;
- }
- k--;
- gen = cb;
- gen->istatus = CBS_CALL_OS; /* don't handle this CBR again */
- } while (k);
- BUG_ON(cmp.done);
-
- gru_unlock_async_resource(han);
- gru_release_async_resources(han);
-done:
- kfree(buf);
- return ret;
-}
-
-#define BUFSIZE 200
-static int quicktest3(unsigned long arg)
-{
- char buf1[BUFSIZE], buf2[BUFSIZE];
- int ret = 0;
-
- memset(buf2, 0, sizeof(buf2));
- memset(buf1, get_cycles() & 255, sizeof(buf1));
- gru_copy_gpa(uv_gpa(buf2), uv_gpa(buf1), BUFSIZE);
- if (memcmp(buf1, buf2, BUFSIZE)) {
- printk(KERN_DEBUG "GRU:%d quicktest3 error\n", smp_processor_id());
- ret = -EIO;
- }
- return ret;
-}
-
-/*
- * Debugging only. User hook for various kernel tests
- * of driver & gru.
- */
-int gru_ktest(unsigned long arg)
-{
- int ret = -EINVAL;
-
- switch (arg & 0xff) {
- case 0:
- ret = quicktest0(arg);
- break;
- case 1:
- ret = quicktest1(arg);
- break;
- case 2:
- ret = quicktest2(arg);
- break;
- case 3:
- ret = quicktest3(arg);
- break;
- case 99:
- ret = gru_free_kernel_contexts();
- break;
- }
- return ret;
-
-}
-
-int gru_kservices_init(void)
-{
- return 0;
-}
-
-void gru_kservices_exit(void)
-{
- if (gru_free_kernel_contexts())
- BUG();
-}
-
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/grukservices.h b/ANDROID_3.4.5/drivers/misc/sgi-gru/grukservices.h
deleted file mode 100644
index 02aa94d8..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/grukservices.h
+++ /dev/null
@@ -1,214 +0,0 @@
-
-/*
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __GRU_KSERVICES_H_
-#define __GRU_KSERVICES_H_
-
-
-/*
- * Message queues using the GRU to send/receive messages.
- *
- * These function allow the user to create a message queue for
- * sending/receiving 1 or 2 cacheline messages using the GRU.
- *
- * Processes SENDING messages will use a kernel CBR/DSR to send
- * the message. This is transparent to the caller.
- *
- * The receiver does not use any GRU resources.
- *
- * The functions support:
- * - single receiver
- * - multiple senders
- * - cross partition message
- *
- * Missing features ZZZ:
- * - user options for dealing with timeouts, queue full, etc.
- * - gru_create_message_queue() needs interrupt vector info
- */
-
-struct gru_message_queue_desc {
- void *mq; /* message queue vaddress */
- unsigned long mq_gpa; /* global address of mq */
- int qlines; /* queue size in CL */
- int interrupt_vector; /* interrupt vector */
- int interrupt_pnode; /* pnode for interrupt */
- int interrupt_apicid; /* lapicid for interrupt */
-};
-
-/*
- * Initialize a user allocated chunk of memory to be used as
- * a message queue. The caller must ensure that the queue is
- * in contiguous physical memory and is cacheline aligned.
- *
- * Message queue size is the total number of bytes allocated
- * to the queue including a 2 cacheline header that is used
- * to manage the queue.
- *
- * Input:
- * mqd pointer to message queue descriptor
- * p pointer to user allocated mesq memory.
- * bytes size of message queue in bytes
- * vector interrupt vector (zero if no interrupts)
- * nasid nasid of blade where interrupt is delivered
- * apicid apicid of cpu for interrupt
- *
- * Errors:
- * 0 OK
- * >0 error
- */
-extern int gru_create_message_queue(struct gru_message_queue_desc *mqd,
- void *p, unsigned int bytes, int nasid, int vector, int apicid);
-
-/*
- * Send a message to a message queue.
- *
- * Note: The message queue transport mechanism uses the first 32
- * bits of the message. Users should avoid using these bits.
- *
- *
- * Input:
- * mqd pointer to message queue descriptor
- * mesg pointer to message. Must be 64-bit aligned
- * bytes size of message in bytes
- *
- * Output:
- * 0 message sent
- * >0 Send failure - see error codes below
- *
- */
-extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd,
- void *mesg, unsigned int bytes);
-
-/* Status values for gru_send_message() */
-#define MQE_OK 0 /* message sent successfully */
-#define MQE_CONGESTION 1 /* temporary congestion, try again */
-#define MQE_QUEUE_FULL 2 /* queue is full */
-#define MQE_UNEXPECTED_CB_ERR 3 /* unexpected CB error */
-#define MQE_PAGE_OVERFLOW 10 /* BUG - queue overflowed a page */
-#define MQE_BUG_NO_RESOURCES 11 /* BUG - could not alloc GRU cb/dsr */
-
-/*
- * Advance the receive pointer for the message queue to the next message.
- * Note: current API requires messages to be gotten & freed in order. Future
- * API extensions may allow for out-of-order freeing.
- *
- * Input
- * mqd pointer to message queue descriptor
- * mesq message being freed
- */
-extern void gru_free_message(struct gru_message_queue_desc *mqd,
- void *mesq);
-
-/*
- * Get next message from message queue. Returns pointer to
- * message OR NULL if no message present.
- * User must call gru_free_message() after message is processed
- * in order to move the queue pointers to next message.
- *
- * Input
- * mqd pointer to message queue descriptor
- *
- * Output:
- * p pointer to message
- * NULL no message available
- */
-extern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
-
-
-/*
- * Read a GRU global GPA. Source can be located in a remote partition.
- *
- * Input:
- * value memory address where MMR value is returned
- * gpa source numalink physical address of GPA
- *
- * Output:
- * 0 OK
- * >0 error
- */
-int gru_read_gpa(unsigned long *value, unsigned long gpa);
-
-
-/*
- * Copy data using the GRU. Source or destination can be located in a remote
- * partition.
- *
- * Input:
- * dest_gpa destination global physical address
- * src_gpa source global physical address
- * bytes number of bytes to copy
- *
- * Output:
- * 0 OK
- * >0 error
- */
-extern int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
- unsigned int bytes);
-
-/*
- * Reserve GRU resources to be used asynchronously.
- *
- * input:
- * blade_id - blade on which resources should be reserved
- * cbrs - number of CBRs
- * dsr_bytes - number of DSR bytes needed
- * cmp - completion structure for waiting for
- * async completions
- * output:
- * handle to identify resource
- * (0 = no resources)
- */
-extern unsigned long gru_reserve_async_resources(int blade_id, int cbrs, int dsr_bytes,
- struct completion *cmp);
-
-/*
- * Release async resources previously reserved.
- *
- * input:
- * han - handle to identify resources
- */
-extern void gru_release_async_resources(unsigned long han);
-
-/*
- * Wait for async GRU instructions to complete.
- *
- * input:
- * han - handle to identify resources
- */
-extern void gru_wait_async_cbr(unsigned long han);
-
-/*
- * Lock previous reserved async GRU resources
- *
- * input:
- * han - handle to identify resources
- * output:
- * cb - pointer to first CBR
- * dsr - pointer to first DSR
- */
-extern void gru_lock_async_resource(unsigned long han, void **cb, void **dsr);
-
-/*
- * Unlock previous reserved async GRU resources
- *
- * input:
- * han - handle to identify resources
- */
-extern void gru_unlock_async_resource(unsigned long han);
-
-#endif /* __GRU_KSERVICES_H_ */
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/grulib.h b/ANDROID_3.4.5/drivers/misc/sgi-gru/grulib.h
deleted file mode 100644
index e77d1b1f..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/grulib.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __GRULIB_H__
-#define __GRULIB_H__
-
-#define GRU_BASENAME "gru"
-#define GRU_FULLNAME "/dev/gru"
-#define GRU_IOCTL_NUM 'G'
-
-/*
- * Maximum number of GRU segments that a user can have open
- * ZZZ temp - set high for testing. Revisit.
- */
-#define GRU_MAX_OPEN_CONTEXTS 32
-
-/* Set Number of Request Blocks */
-#define GRU_CREATE_CONTEXT _IOWR(GRU_IOCTL_NUM, 1, void *)
-
-/* Set Context Options */
-#define GRU_SET_CONTEXT_OPTION _IOWR(GRU_IOCTL_NUM, 4, void *)
-
-/* Fetch exception detail */
-#define GRU_USER_GET_EXCEPTION_DETAIL _IOWR(GRU_IOCTL_NUM, 6, void *)
-
-/* For user call_os handling - normally a TLB fault */
-#define GRU_USER_CALL_OS _IOWR(GRU_IOCTL_NUM, 8, void *)
-
-/* For user unload context */
-#define GRU_USER_UNLOAD_CONTEXT _IOWR(GRU_IOCTL_NUM, 9, void *)
-
-/* For dumpping GRU chiplet state */
-#define GRU_DUMP_CHIPLET_STATE _IOWR(GRU_IOCTL_NUM, 11, void *)
-
-/* For getting gseg statistics */
-#define GRU_GET_GSEG_STATISTICS _IOWR(GRU_IOCTL_NUM, 12, void *)
-
-/* For user TLB flushing (primarily for tests) */
-#define GRU_USER_FLUSH_TLB _IOWR(GRU_IOCTL_NUM, 50, void *)
-
-/* Get some config options (primarily for tests & emulator) */
-#define GRU_GET_CONFIG_INFO _IOWR(GRU_IOCTL_NUM, 51, void *)
-
-/* Various kernel self-tests */
-#define GRU_KTEST _IOWR(GRU_IOCTL_NUM, 52, void *)
-
-#define CONTEXT_WINDOW_BYTES(th) (GRU_GSEG_PAGESIZE * (th))
-#define THREAD_POINTER(p, th) (p + GRU_GSEG_PAGESIZE * (th))
-#define GSEG_START(cb) ((void *)((unsigned long)(cb) & ~(GRU_GSEG_PAGESIZE - 1)))
-
-struct gru_get_gseg_statistics_req {
- unsigned long gseg;
- struct gru_gseg_statistics stats;
-};
-
-/*
- * Structure used to pass TLB flush parameters to the driver
- */
-struct gru_create_context_req {
- unsigned long gseg;
- unsigned int data_segment_bytes;
- unsigned int control_blocks;
- unsigned int maximum_thread_count;
- unsigned int options;
- unsigned char tlb_preload_count;
-};
-
-/*
- * Structure used to pass unload context parameters to the driver
- */
-struct gru_unload_context_req {
- unsigned long gseg;
-};
-
-/*
- * Structure used to set context options
- */
-enum {sco_gseg_owner, sco_cch_req_slice, sco_blade_chiplet};
-struct gru_set_context_option_req {
- unsigned long gseg;
- int op;
- int val0;
- long val1;
-};
-
-/*
- * Structure used to pass TLB flush parameters to the driver
- */
-struct gru_flush_tlb_req {
- unsigned long gseg;
- unsigned long vaddr;
- size_t len;
-};
-
-/*
- * Structure used to pass TLB flush parameters to the driver
- */
-enum {dcs_pid, dcs_gid};
-struct gru_dump_chiplet_state_req {
- unsigned int op;
- unsigned int gid;
- int ctxnum;
- char data_opt;
- char lock_cch;
- char flush_cbrs;
- char fill[10];
- pid_t pid;
- void *buf;
- size_t buflen;
- /* ---- output --- */
- unsigned int num_contexts;
-};
-
-#define GRU_DUMP_MAGIC 0x3474ab6c
-struct gru_dump_context_header {
- unsigned int magic;
- unsigned int gid;
- unsigned char ctxnum;
- unsigned char cbrcnt;
- unsigned char dsrcnt;
- pid_t pid;
- unsigned long vaddr;
- int cch_locked;
- unsigned long data[0];
-};
-
-/*
- * GRU configuration info (temp - for testing)
- */
-struct gru_config_info {
- int cpus;
- int blades;
- int nodes;
- int chiplets;
- int fill[16];
-};
-
-#endif /* __GRULIB_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/grumain.c b/ANDROID_3.4.5/drivers/misc/sgi-gru/grumain.c
deleted file mode 100644
index ae16c8cb..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/grumain.c
+++ /dev/null
@@ -1,973 +0,0 @@
-/*
- * SN Platform GRU Driver
- *
- * DRIVER TABLE MANAGER + GRU CONTEXT LOAD/UNLOAD
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/err.h>
-#include <linux/prefetch.h>
-#include <asm/uv/uv_hub.h>
-#include "gru.h"
-#include "grutables.h"
-#include "gruhandles.h"
-
-unsigned long gru_options __read_mostly;
-
-static struct device_driver gru_driver = {
- .name = "gru"
-};
-
-static struct device gru_device = {
- .init_name = "",
- .driver = &gru_driver,
-};
-
-struct device *grudev = &gru_device;
-
-/*
- * Select a gru fault map to be used by the current cpu. Note that
- * multiple cpus may be using the same map.
- * ZZZ should be inline but did not work on emulator
- */
-int gru_cpu_fault_map_id(void)
-{
-#ifdef CONFIG_IA64
- return uv_blade_processor_id() % GRU_NUM_TFM;
-#else
- int cpu = smp_processor_id();
- int id, core;
-
- core = uv_cpu_core_number(cpu);
- id = core + UV_MAX_INT_CORES * uv_cpu_socket_number(cpu);
- return id;
-#endif
-}
-
-/*--------- ASID Management -------------------------------------------
- *
- * Initially, assign asids sequentially from MIN_ASID .. MAX_ASID.
- * Once MAX is reached, flush the TLB & start over. However,
- * some asids may still be in use. There won't be many (percentage wise) still
- * in use. Search active contexts & determine the value of the first
- * asid in use ("x"s below). Set "limit" to this value.
- * This defines a block of assignable asids.
- *
- * When "limit" is reached, search forward from limit+1 and determine the
- * next block of assignable asids.
- *
- * Repeat until MAX_ASID is reached, then start over again.
- *
- * Each time MAX_ASID is reached, increment the asid generation. Since
- * the search for in-use asids only checks contexts with GRUs currently
- * assigned, asids in some contexts will be missed. Prior to loading
- * a context, the asid generation of the GTS asid is rechecked. If it
- * doesn't match the current generation, a new asid will be assigned.
- *
- * 0---------------x------------x---------------------x----|
- * ^-next ^-limit ^-MAX_ASID
- *
- * All asid manipulation & context loading/unloading is protected by the
- * gs_lock.
- */
-
-/* Hit the asid limit. Start over */
-static int gru_wrap_asid(struct gru_state *gru)
-{
- gru_dbg(grudev, "gid %d\n", gru->gs_gid);
- STAT(asid_wrap);
- gru->gs_asid_gen++;
- return MIN_ASID;
-}
-
-/* Find the next chunk of unused asids */
-static int gru_reset_asid_limit(struct gru_state *gru, int asid)
-{
- int i, gid, inuse_asid, limit;
-
- gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
- STAT(asid_next);
- limit = MAX_ASID;
- if (asid >= limit)
- asid = gru_wrap_asid(gru);
- gru_flush_all_tlb(gru);
- gid = gru->gs_gid;
-again:
- for (i = 0; i < GRU_NUM_CCH; i++) {
- if (!gru->gs_gts[i] || is_kernel_context(gru->gs_gts[i]))
- continue;
- inuse_asid = gru->gs_gts[i]->ts_gms->ms_asids[gid].mt_asid;
- gru_dbg(grudev, "gid %d, gts %p, gms %p, inuse 0x%x, cxt %d\n",
- gru->gs_gid, gru->gs_gts[i], gru->gs_gts[i]->ts_gms,
- inuse_asid, i);
- if (inuse_asid == asid) {
- asid += ASID_INC;
- if (asid >= limit) {
- /*
- * empty range: reset the range limit and
- * start over
- */
- limit = MAX_ASID;
- if (asid >= MAX_ASID)
- asid = gru_wrap_asid(gru);
- goto again;
- }
- }
-
- if ((inuse_asid > asid) && (inuse_asid < limit))
- limit = inuse_asid;
- }
- gru->gs_asid_limit = limit;
- gru->gs_asid = asid;
- gru_dbg(grudev, "gid %d, new asid 0x%x, new_limit 0x%x\n", gru->gs_gid,
- asid, limit);
- return asid;
-}
-
-/* Assign a new ASID to a thread context. */
-static int gru_assign_asid(struct gru_state *gru)
-{
- int asid;
-
- gru->gs_asid += ASID_INC;
- asid = gru->gs_asid;
- if (asid >= gru->gs_asid_limit)
- asid = gru_reset_asid_limit(gru, asid);
-
- gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
- return asid;
-}
-
-/*
- * Clear n bits in a word. Return a word indicating the bits that were cleared.
- * Optionally, build an array of chars that contain the bit numbers allocated.
- */
-static unsigned long reserve_resources(unsigned long *p, int n, int mmax,
- char *idx)
-{
- unsigned long bits = 0;
- int i;
-
- while (n--) {
- i = find_first_bit(p, mmax);
- if (i == mmax)
- BUG();
- __clear_bit(i, p);
- __set_bit(i, &bits);
- if (idx)
- *idx++ = i;
- }
- return bits;
-}
-
-unsigned long gru_reserve_cb_resources(struct gru_state *gru, int cbr_au_count,
- char *cbmap)
-{
- return reserve_resources(&gru->gs_cbr_map, cbr_au_count, GRU_CBR_AU,
- cbmap);
-}
-
-unsigned long gru_reserve_ds_resources(struct gru_state *gru, int dsr_au_count,
- char *dsmap)
-{
- return reserve_resources(&gru->gs_dsr_map, dsr_au_count, GRU_DSR_AU,
- dsmap);
-}
-
-static void reserve_gru_resources(struct gru_state *gru,
- struct gru_thread_state *gts)
-{
- gru->gs_active_contexts++;
- gts->ts_cbr_map =
- gru_reserve_cb_resources(gru, gts->ts_cbr_au_count,
- gts->ts_cbr_idx);
- gts->ts_dsr_map =
- gru_reserve_ds_resources(gru, gts->ts_dsr_au_count, NULL);
-}
-
-static void free_gru_resources(struct gru_state *gru,
- struct gru_thread_state *gts)
-{
- gru->gs_active_contexts--;
- gru->gs_cbr_map |= gts->ts_cbr_map;
- gru->gs_dsr_map |= gts->ts_dsr_map;
-}
-
-/*
- * Check if a GRU has sufficient free resources to satisfy an allocation
- * request. Note: GRU locks may or may not be held when this is called. If
- * not held, recheck after acquiring the appropriate locks.
- *
- * Returns 1 if sufficient resources, 0 if not
- */
-static int check_gru_resources(struct gru_state *gru, int cbr_au_count,
- int dsr_au_count, int max_active_contexts)
-{
- return hweight64(gru->gs_cbr_map) >= cbr_au_count
- && hweight64(gru->gs_dsr_map) >= dsr_au_count
- && gru->gs_active_contexts < max_active_contexts;
-}
-
-/*
- * TLB manangment requires tracking all GRU chiplets that have loaded a GSEG
- * context.
- */
-static int gru_load_mm_tracker(struct gru_state *gru,
- struct gru_thread_state *gts)
-{
- struct gru_mm_struct *gms = gts->ts_gms;
- struct gru_mm_tracker *asids = &gms->ms_asids[gru->gs_gid];
- unsigned short ctxbitmap = (1 << gts->ts_ctxnum);
- int asid;
-
- spin_lock(&gms->ms_asid_lock);
- asid = asids->mt_asid;
-
- spin_lock(&gru->gs_asid_lock);
- if (asid == 0 || (asids->mt_ctxbitmap == 0 && asids->mt_asid_gen !=
- gru->gs_asid_gen)) {
- asid = gru_assign_asid(gru);
- asids->mt_asid = asid;
- asids->mt_asid_gen = gru->gs_asid_gen;
- STAT(asid_new);
- } else {
- STAT(asid_reuse);
- }
- spin_unlock(&gru->gs_asid_lock);
-
- BUG_ON(asids->mt_ctxbitmap & ctxbitmap);
- asids->mt_ctxbitmap |= ctxbitmap;
- if (!test_bit(gru->gs_gid, gms->ms_asidmap))
- __set_bit(gru->gs_gid, gms->ms_asidmap);
- spin_unlock(&gms->ms_asid_lock);
-
- gru_dbg(grudev,
- "gid %d, gts %p, gms %p, ctxnum %d, asid 0x%x, asidmap 0x%lx\n",
- gru->gs_gid, gts, gms, gts->ts_ctxnum, asid,
- gms->ms_asidmap[0]);
- return asid;
-}
-
-static void gru_unload_mm_tracker(struct gru_state *gru,
- struct gru_thread_state *gts)
-{
- struct gru_mm_struct *gms = gts->ts_gms;
- struct gru_mm_tracker *asids;
- unsigned short ctxbitmap;
-
- asids = &gms->ms_asids[gru->gs_gid];
- ctxbitmap = (1 << gts->ts_ctxnum);
- spin_lock(&gms->ms_asid_lock);
- spin_lock(&gru->gs_asid_lock);
- BUG_ON((asids->mt_ctxbitmap & ctxbitmap) != ctxbitmap);
- asids->mt_ctxbitmap ^= ctxbitmap;
- gru_dbg(grudev, "gid %d, gts %p, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
- gru->gs_gid, gts, gms, gts->ts_ctxnum, gms->ms_asidmap[0]);
- spin_unlock(&gru->gs_asid_lock);
- spin_unlock(&gms->ms_asid_lock);
-}
-
-/*
- * Decrement the reference count on a GTS structure. Free the structure
- * if the reference count goes to zero.
- */
-void gts_drop(struct gru_thread_state *gts)
-{
- if (gts && atomic_dec_return(&gts->ts_refcnt) == 0) {
- if (gts->ts_gms)
- gru_drop_mmu_notifier(gts->ts_gms);
- kfree(gts);
- STAT(gts_free);
- }
-}
-
-/*
- * Locate the GTS structure for the current thread.
- */
-static struct gru_thread_state *gru_find_current_gts_nolock(struct gru_vma_data
- *vdata, int tsid)
-{
- struct gru_thread_state *gts;
-
- list_for_each_entry(gts, &vdata->vd_head, ts_next)
- if (gts->ts_tsid == tsid)
- return gts;
- return NULL;
-}
-
-/*
- * Allocate a thread state structure.
- */
-struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
- int cbr_au_count, int dsr_au_count,
- unsigned char tlb_preload_count, int options, int tsid)
-{
- struct gru_thread_state *gts;
- struct gru_mm_struct *gms;
- int bytes;
-
- bytes = DSR_BYTES(dsr_au_count) + CBR_BYTES(cbr_au_count);
- bytes += sizeof(struct gru_thread_state);
- gts = kmalloc(bytes, GFP_KERNEL);
- if (!gts)
- return ERR_PTR(-ENOMEM);
-
- STAT(gts_alloc);
- memset(gts, 0, sizeof(struct gru_thread_state)); /* zero out header */
- atomic_set(&gts->ts_refcnt, 1);
- mutex_init(&gts->ts_ctxlock);
- gts->ts_cbr_au_count = cbr_au_count;
- gts->ts_dsr_au_count = dsr_au_count;
- gts->ts_tlb_preload_count = tlb_preload_count;
- gts->ts_user_options = options;
- gts->ts_user_blade_id = -1;
- gts->ts_user_chiplet_id = -1;
- gts->ts_tsid = tsid;
- gts->ts_ctxnum = NULLCTX;
- gts->ts_tlb_int_select = -1;
- gts->ts_cch_req_slice = -1;
- gts->ts_sizeavail = GRU_SIZEAVAIL(PAGE_SHIFT);
- if (vma) {
- gts->ts_mm = current->mm;
- gts->ts_vma = vma;
- gms = gru_register_mmu_notifier();
- if (IS_ERR(gms))
- goto err;
- gts->ts_gms = gms;
- }
-
- gru_dbg(grudev, "alloc gts %p\n", gts);
- return gts;
-
-err:
- gts_drop(gts);
- return ERR_CAST(gms);
-}
-
-/*
- * Allocate a vma private data structure.
- */
-struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma, int tsid)
-{
- struct gru_vma_data *vdata = NULL;
-
- vdata = kmalloc(sizeof(*vdata), GFP_KERNEL);
- if (!vdata)
- return NULL;
-
- STAT(vdata_alloc);
- INIT_LIST_HEAD(&vdata->vd_head);
- spin_lock_init(&vdata->vd_lock);
- gru_dbg(grudev, "alloc vdata %p\n", vdata);
- return vdata;
-}
-
-/*
- * Find the thread state structure for the current thread.
- */
-struct gru_thread_state *gru_find_thread_state(struct vm_area_struct *vma,
- int tsid)
-{
- struct gru_vma_data *vdata = vma->vm_private_data;
- struct gru_thread_state *gts;
-
- spin_lock(&vdata->vd_lock);
- gts = gru_find_current_gts_nolock(vdata, tsid);
- spin_unlock(&vdata->vd_lock);
- gru_dbg(grudev, "vma %p, gts %p\n", vma, gts);
- return gts;
-}
-
-/*
- * Allocate a new thread state for a GSEG. Note that races may allow
- * another thread to race to create a gts.
- */
-struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct *vma,
- int tsid)
-{
- struct gru_vma_data *vdata = vma->vm_private_data;
- struct gru_thread_state *gts, *ngts;
-
- gts = gru_alloc_gts(vma, vdata->vd_cbr_au_count,
- vdata->vd_dsr_au_count,
- vdata->vd_tlb_preload_count,
- vdata->vd_user_options, tsid);
- if (IS_ERR(gts))
- return gts;
-
- spin_lock(&vdata->vd_lock);
- ngts = gru_find_current_gts_nolock(vdata, tsid);
- if (ngts) {
- gts_drop(gts);
- gts = ngts;
- STAT(gts_double_allocate);
- } else {
- list_add(&gts->ts_next, &vdata->vd_head);
- }
- spin_unlock(&vdata->vd_lock);
- gru_dbg(grudev, "vma %p, gts %p\n", vma, gts);
- return gts;
-}
-
-/*
- * Free the GRU context assigned to the thread state.
- */
-static void gru_free_gru_context(struct gru_thread_state *gts)
-{
- struct gru_state *gru;
-
- gru = gts->ts_gru;
- gru_dbg(grudev, "gts %p, gid %d\n", gts, gru->gs_gid);
-
- spin_lock(&gru->gs_lock);
- gru->gs_gts[gts->ts_ctxnum] = NULL;
- free_gru_resources(gru, gts);
- BUG_ON(test_bit(gts->ts_ctxnum, &gru->gs_context_map) == 0);
- __clear_bit(gts->ts_ctxnum, &gru->gs_context_map);
- gts->ts_ctxnum = NULLCTX;
- gts->ts_gru = NULL;
- gts->ts_blade = -1;
- spin_unlock(&gru->gs_lock);
-
- gts_drop(gts);
- STAT(free_context);
-}
-
-/*
- * Prefetching cachelines help hardware performance.
- * (Strictly a performance enhancement. Not functionally required).
- */
-static void prefetch_data(void *p, int num, int stride)
-{
- while (num-- > 0) {
- prefetchw(p);
- p += stride;
- }
-}
-
-static inline long gru_copy_handle(void *d, void *s)
-{
- memcpy(d, s, GRU_HANDLE_BYTES);
- return GRU_HANDLE_BYTES;
-}
-
-static void gru_prefetch_context(void *gseg, void *cb, void *cbe,
- unsigned long cbrmap, unsigned long length)
-{
- int i, scr;
-
- prefetch_data(gseg + GRU_DS_BASE, length / GRU_CACHE_LINE_BYTES,
- GRU_CACHE_LINE_BYTES);
-
- for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
- prefetch_data(cb, 1, GRU_CACHE_LINE_BYTES);
- prefetch_data(cbe + i * GRU_HANDLE_STRIDE, 1,
- GRU_CACHE_LINE_BYTES);
- cb += GRU_HANDLE_STRIDE;
- }
-}
-
-static void gru_load_context_data(void *save, void *grubase, int ctxnum,
- unsigned long cbrmap, unsigned long dsrmap,
- int data_valid)
-{
- void *gseg, *cb, *cbe;
- unsigned long length;
- int i, scr;
-
- gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
- cb = gseg + GRU_CB_BASE;
- cbe = grubase + GRU_CBE_BASE;
- length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
- gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
-
- for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
- if (data_valid) {
- save += gru_copy_handle(cb, save);
- save += gru_copy_handle(cbe + i * GRU_HANDLE_STRIDE,
- save);
- } else {
- memset(cb, 0, GRU_CACHE_LINE_BYTES);
- memset(cbe + i * GRU_HANDLE_STRIDE, 0,
- GRU_CACHE_LINE_BYTES);
- }
- /* Flush CBE to hide race in context restart */
- mb();
- gru_flush_cache(cbe + i * GRU_HANDLE_STRIDE);
- cb += GRU_HANDLE_STRIDE;
- }
-
- if (data_valid)
- memcpy(gseg + GRU_DS_BASE, save, length);
- else
- memset(gseg + GRU_DS_BASE, 0, length);
-}
-
-static void gru_unload_context_data(void *save, void *grubase, int ctxnum,
- unsigned long cbrmap, unsigned long dsrmap)
-{
- void *gseg, *cb, *cbe;
- unsigned long length;
- int i, scr;
-
- gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
- cb = gseg + GRU_CB_BASE;
- cbe = grubase + GRU_CBE_BASE;
- length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
-
- /* CBEs may not be coherent. Flush them from cache */
- for_each_cbr_in_allocation_map(i, &cbrmap, scr)
- gru_flush_cache(cbe + i * GRU_HANDLE_STRIDE);
- mb(); /* Let the CL flush complete */
-
- gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
-
- for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
- save += gru_copy_handle(save, cb);
- save += gru_copy_handle(save, cbe + i * GRU_HANDLE_STRIDE);
- cb += GRU_HANDLE_STRIDE;
- }
- memcpy(save, gseg + GRU_DS_BASE, length);
-}
-
-void gru_unload_context(struct gru_thread_state *gts, int savestate)
-{
- struct gru_state *gru = gts->ts_gru;
- struct gru_context_configuration_handle *cch;
- int ctxnum = gts->ts_ctxnum;
-
- if (!is_kernel_context(gts))
- zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE);
- cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
-
- gru_dbg(grudev, "gts %p, cbrmap 0x%lx, dsrmap 0x%lx\n",
- gts, gts->ts_cbr_map, gts->ts_dsr_map);
- lock_cch_handle(cch);
- if (cch_interrupt_sync(cch))
- BUG();
-
- if (!is_kernel_context(gts))
- gru_unload_mm_tracker(gru, gts);
- if (savestate) {
- gru_unload_context_data(gts->ts_gdata, gru->gs_gru_base_vaddr,
- ctxnum, gts->ts_cbr_map,
- gts->ts_dsr_map);
- gts->ts_data_valid = 1;
- }
-
- if (cch_deallocate(cch))
- BUG();
- unlock_cch_handle(cch);
-
- gru_free_gru_context(gts);
-}
-
-/*
- * Load a GRU context by copying it from the thread data structure in memory
- * to the GRU.
- */
-void gru_load_context(struct gru_thread_state *gts)
-{
- struct gru_state *gru = gts->ts_gru;
- struct gru_context_configuration_handle *cch;
- int i, err, asid, ctxnum = gts->ts_ctxnum;
-
- cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
- lock_cch_handle(cch);
- cch->tfm_fault_bit_enable =
- (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
- || gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
- cch->tlb_int_enable = (gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
- if (cch->tlb_int_enable) {
- gts->ts_tlb_int_select = gru_cpu_fault_map_id();
- cch->tlb_int_select = gts->ts_tlb_int_select;
- }
- if (gts->ts_cch_req_slice >= 0) {
- cch->req_slice_set_enable = 1;
- cch->req_slice = gts->ts_cch_req_slice;
- } else {
- cch->req_slice_set_enable =0;
- }
- cch->tfm_done_bit_enable = 0;
- cch->dsr_allocation_map = gts->ts_dsr_map;
- cch->cbr_allocation_map = gts->ts_cbr_map;
-
- if (is_kernel_context(gts)) {
- cch->unmap_enable = 1;
- cch->tfm_done_bit_enable = 1;
- cch->cb_int_enable = 1;
- cch->tlb_int_select = 0; /* For now, ints go to cpu 0 */
- } else {
- cch->unmap_enable = 0;
- cch->tfm_done_bit_enable = 0;
- cch->cb_int_enable = 0;
- asid = gru_load_mm_tracker(gru, gts);
- for (i = 0; i < 8; i++) {
- cch->asid[i] = asid + i;
- cch->sizeavail[i] = gts->ts_sizeavail;
- }
- }
-
- err = cch_allocate(cch);
- if (err) {
- gru_dbg(grudev,
- "err %d: cch %p, gts %p, cbr 0x%lx, dsr 0x%lx\n",
- err, cch, gts, gts->ts_cbr_map, gts->ts_dsr_map);
- BUG();
- }
-
- gru_load_context_data(gts->ts_gdata, gru->gs_gru_base_vaddr, ctxnum,
- gts->ts_cbr_map, gts->ts_dsr_map, gts->ts_data_valid);
-
- if (cch_start(cch))
- BUG();
- unlock_cch_handle(cch);
-
- gru_dbg(grudev, "gid %d, gts %p, cbrmap 0x%lx, dsrmap 0x%lx, tie %d, tis %d\n",
- gts->ts_gru->gs_gid, gts, gts->ts_cbr_map, gts->ts_dsr_map,
- (gts->ts_user_options == GRU_OPT_MISS_FMM_INTR), gts->ts_tlb_int_select);
-}
-
-/*
- * Update fields in an active CCH:
- * - retarget interrupts on local blade
- * - update sizeavail mask
- */
-int gru_update_cch(struct gru_thread_state *gts)
-{
- struct gru_context_configuration_handle *cch;
- struct gru_state *gru = gts->ts_gru;
- int i, ctxnum = gts->ts_ctxnum, ret = 0;
-
- cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
-
- lock_cch_handle(cch);
- if (cch->state == CCHSTATE_ACTIVE) {
- if (gru->gs_gts[gts->ts_ctxnum] != gts)
- goto exit;
- if (cch_interrupt(cch))
- BUG();
- for (i = 0; i < 8; i++)
- cch->sizeavail[i] = gts->ts_sizeavail;
- gts->ts_tlb_int_select = gru_cpu_fault_map_id();
- cch->tlb_int_select = gru_cpu_fault_map_id();
- cch->tfm_fault_bit_enable =
- (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
- || gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
- if (cch_start(cch))
- BUG();
- ret = 1;
- }
-exit:
- unlock_cch_handle(cch);
- return ret;
-}
-
-/*
- * Update CCH tlb interrupt select. Required when all the following is true:
- * - task's GRU context is loaded into a GRU
- * - task is using interrupt notification for TLB faults
- * - task has migrated to a different cpu on the same blade where
- * it was previously running.
- */
-static int gru_retarget_intr(struct gru_thread_state *gts)
-{
- if (gts->ts_tlb_int_select < 0
- || gts->ts_tlb_int_select == gru_cpu_fault_map_id())
- return 0;
-
- gru_dbg(grudev, "retarget from %d to %d\n", gts->ts_tlb_int_select,
- gru_cpu_fault_map_id());
- return gru_update_cch(gts);
-}
-
-/*
- * Check if a GRU context is allowed to use a specific chiplet. By default
- * a context is assigned to any blade-local chiplet. However, users can
- * override this.
- * Returns 1 if assignment allowed, 0 otherwise
- */
-static int gru_check_chiplet_assignment(struct gru_state *gru,
- struct gru_thread_state *gts)
-{
- int blade_id;
- int chiplet_id;
-
- blade_id = gts->ts_user_blade_id;
- if (blade_id < 0)
- blade_id = uv_numa_blade_id();
-
- chiplet_id = gts->ts_user_chiplet_id;
- return gru->gs_blade_id == blade_id &&
- (chiplet_id < 0 || chiplet_id == gru->gs_chiplet_id);
-}
-
-/*
- * Unload the gru context if it is not assigned to the correct blade or
- * chiplet. Misassignment can occur if the process migrates to a different
- * blade or if the user changes the selected blade/chiplet.
- */
-void gru_check_context_placement(struct gru_thread_state *gts)
-{
- struct gru_state *gru;
-
- /*
- * If the current task is the context owner, verify that the
- * context is correctly placed. This test is skipped for non-owner
- * references. Pthread apps use non-owner references to the CBRs.
- */
- gru = gts->ts_gru;
- if (!gru || gts->ts_tgid_owner != current->tgid)
- return;
-
- if (!gru_check_chiplet_assignment(gru, gts)) {
- STAT(check_context_unload);
- gru_unload_context(gts, 1);
- } else if (gru_retarget_intr(gts)) {
- STAT(check_context_retarget_intr);
- }
-}
-
-
-/*
- * Insufficient GRU resources available on the local blade. Steal a context from
- * a process. This is a hack until a _real_ resource scheduler is written....
- */
-#define next_ctxnum(n) ((n) < GRU_NUM_CCH - 2 ? (n) + 1 : 0)
-#define next_gru(b, g) (((g) < &(b)->bs_grus[GRU_CHIPLETS_PER_BLADE - 1]) ? \
- ((g)+1) : &(b)->bs_grus[0])
-
-static int is_gts_stealable(struct gru_thread_state *gts,
- struct gru_blade_state *bs)
-{
- if (is_kernel_context(gts))
- return down_write_trylock(&bs->bs_kgts_sema);
- else
- return mutex_trylock(&gts->ts_ctxlock);
-}
-
-static void gts_stolen(struct gru_thread_state *gts,
- struct gru_blade_state *bs)
-{
- if (is_kernel_context(gts)) {
- up_write(&bs->bs_kgts_sema);
- STAT(steal_kernel_context);
- } else {
- mutex_unlock(&gts->ts_ctxlock);
- STAT(steal_user_context);
- }
-}
-
-void gru_steal_context(struct gru_thread_state *gts)
-{
- struct gru_blade_state *blade;
- struct gru_state *gru, *gru0;
- struct gru_thread_state *ngts = NULL;
- int ctxnum, ctxnum0, flag = 0, cbr, dsr;
- int blade_id;
-
- blade_id = gts->ts_user_blade_id;
- if (blade_id < 0)
- blade_id = uv_numa_blade_id();
- cbr = gts->ts_cbr_au_count;
- dsr = gts->ts_dsr_au_count;
-
- blade = gru_base[blade_id];
- spin_lock(&blade->bs_lock);
-
- ctxnum = next_ctxnum(blade->bs_lru_ctxnum);
- gru = blade->bs_lru_gru;
- if (ctxnum == 0)
- gru = next_gru(blade, gru);
- blade->bs_lru_gru = gru;
- blade->bs_lru_ctxnum = ctxnum;
- ctxnum0 = ctxnum;
- gru0 = gru;
- while (1) {
- if (gru_check_chiplet_assignment(gru, gts)) {
- if (check_gru_resources(gru, cbr, dsr, GRU_NUM_CCH))
- break;
- spin_lock(&gru->gs_lock);
- for (; ctxnum < GRU_NUM_CCH; ctxnum++) {
- if (flag && gru == gru0 && ctxnum == ctxnum0)
- break;
- ngts = gru->gs_gts[ctxnum];
- /*
- * We are grabbing locks out of order, so trylock is
- * needed. GTSs are usually not locked, so the odds of
- * success are high. If trylock fails, try to steal a
- * different GSEG.
- */
- if (ngts && is_gts_stealable(ngts, blade))
- break;
- ngts = NULL;
- }
- spin_unlock(&gru->gs_lock);
- if (ngts || (flag && gru == gru0 && ctxnum == ctxnum0))
- break;
- }
- if (flag && gru == gru0)
- break;
- flag = 1;
- ctxnum = 0;
- gru = next_gru(blade, gru);
- }
- spin_unlock(&blade->bs_lock);
-
- if (ngts) {
- gts->ustats.context_stolen++;
- ngts->ts_steal_jiffies = jiffies;
- gru_unload_context(ngts, is_kernel_context(ngts) ? 0 : 1);
- gts_stolen(ngts, blade);
- } else {
- STAT(steal_context_failed);
- }
- gru_dbg(grudev,
- "stole gid %d, ctxnum %d from gts %p. Need cb %d, ds %d;"
- " avail cb %ld, ds %ld\n",
- gru->gs_gid, ctxnum, ngts, cbr, dsr, hweight64(gru->gs_cbr_map),
- hweight64(gru->gs_dsr_map));
-}
-
-/*
- * Assign a gru context.
- */
-static int gru_assign_context_number(struct gru_state *gru)
-{
- int ctxnum;
-
- ctxnum = find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH);
- __set_bit(ctxnum, &gru->gs_context_map);
- return ctxnum;
-}
-
-/*
- * Scan the GRUs on the local blade & assign a GRU context.
- */
-struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts)
-{
- struct gru_state *gru, *grux;
- int i, max_active_contexts;
- int blade_id = gts->ts_user_blade_id;
-
- if (blade_id < 0)
- blade_id = uv_numa_blade_id();
-again:
- gru = NULL;
- max_active_contexts = GRU_NUM_CCH;
- for_each_gru_on_blade(grux, blade_id, i) {
- if (!gru_check_chiplet_assignment(grux, gts))
- continue;
- if (check_gru_resources(grux, gts->ts_cbr_au_count,
- gts->ts_dsr_au_count,
- max_active_contexts)) {
- gru = grux;
- max_active_contexts = grux->gs_active_contexts;
- if (max_active_contexts == 0)
- break;
- }
- }
-
- if (gru) {
- spin_lock(&gru->gs_lock);
- if (!check_gru_resources(gru, gts->ts_cbr_au_count,
- gts->ts_dsr_au_count, GRU_NUM_CCH)) {
- spin_unlock(&gru->gs_lock);
- goto again;
- }
- reserve_gru_resources(gru, gts);
- gts->ts_gru = gru;
- gts->ts_blade = gru->gs_blade_id;
- gts->ts_ctxnum = gru_assign_context_number(gru);
- atomic_inc(&gts->ts_refcnt);
- gru->gs_gts[gts->ts_ctxnum] = gts;
- spin_unlock(&gru->gs_lock);
-
- STAT(assign_context);
- gru_dbg(grudev,
- "gseg %p, gts %p, gid %d, ctx %d, cbr %d, dsr %d\n",
- gseg_virtual_address(gts->ts_gru, gts->ts_ctxnum), gts,
- gts->ts_gru->gs_gid, gts->ts_ctxnum,
- gts->ts_cbr_au_count, gts->ts_dsr_au_count);
- } else {
- gru_dbg(grudev, "failed to allocate a GTS %s\n", "");
- STAT(assign_context_failed);
- }
-
- return gru;
-}
-
-/*
- * gru_nopage
- *
- * Map the user's GRU segment
- *
- * Note: gru segments alway mmaped on GRU_GSEG_PAGESIZE boundaries.
- */
-int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
- struct gru_thread_state *gts;
- unsigned long paddr, vaddr;
-
- vaddr = (unsigned long)vmf->virtual_address;
- gru_dbg(grudev, "vma %p, vaddr 0x%lx (0x%lx)\n",
- vma, vaddr, GSEG_BASE(vaddr));
- STAT(nopfn);
-
- /* The following check ensures vaddr is a valid address in the VMA */
- gts = gru_find_thread_state(vma, TSID(vaddr, vma));
- if (!gts)
- return VM_FAULT_SIGBUS;
-
-again:
- mutex_lock(&gts->ts_ctxlock);
- preempt_disable();
-
- gru_check_context_placement(gts);
-
- if (!gts->ts_gru) {
- STAT(load_user_context);
- if (!gru_assign_gru_context(gts)) {
- preempt_enable();
- mutex_unlock(&gts->ts_ctxlock);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */
- if (gts->ts_steal_jiffies + GRU_STEAL_DELAY < jiffies)
- gru_steal_context(gts);
- goto again;
- }
- gru_load_context(gts);
- paddr = gseg_physical_address(gts->ts_gru, gts->ts_ctxnum);
- remap_pfn_range(vma, vaddr & ~(GRU_GSEG_PAGESIZE - 1),
- paddr >> PAGE_SHIFT, GRU_GSEG_PAGESIZE,
- vma->vm_page_prot);
- }
-
- preempt_enable();
- mutex_unlock(&gts->ts_ctxlock);
-
- return VM_FAULT_NOPAGE;
-}
-
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/gruprocfs.c b/ANDROID_3.4.5/drivers/misc/sgi-gru/gruprocfs.c
deleted file mode 100644
index 950dbe9e..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/gruprocfs.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * SN Platform GRU Driver
- *
- * PROC INTERFACES
- *
- * This file supports the /proc interfaces for the GRU driver
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/proc_fs.h>
-#include <linux/device.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>
-#include "gru.h"
-#include "grulib.h"
-#include "grutables.h"
-
-#define printstat(s, f) printstat_val(s, &gru_stats.f, #f)
-
-static void printstat_val(struct seq_file *s, atomic_long_t *v, char *id)
-{
- unsigned long val = atomic_long_read(v);
-
- seq_printf(s, "%16lu %s\n", val, id);
-}
-
-static int statistics_show(struct seq_file *s, void *p)
-{
- printstat(s, vdata_alloc);
- printstat(s, vdata_free);
- printstat(s, gts_alloc);
- printstat(s, gts_free);
- printstat(s, gms_alloc);
- printstat(s, gms_free);
- printstat(s, gts_double_allocate);
- printstat(s, assign_context);
- printstat(s, assign_context_failed);
- printstat(s, free_context);
- printstat(s, load_user_context);
- printstat(s, load_kernel_context);
- printstat(s, lock_kernel_context);
- printstat(s, unlock_kernel_context);
- printstat(s, steal_user_context);
- printstat(s, steal_kernel_context);
- printstat(s, steal_context_failed);
- printstat(s, nopfn);
- printstat(s, asid_new);
- printstat(s, asid_next);
- printstat(s, asid_wrap);
- printstat(s, asid_reuse);
- printstat(s, intr);
- printstat(s, intr_cbr);
- printstat(s, intr_tfh);
- printstat(s, intr_spurious);
- printstat(s, intr_mm_lock_failed);
- printstat(s, call_os);
- printstat(s, call_os_wait_queue);
- printstat(s, user_flush_tlb);
- printstat(s, user_unload_context);
- printstat(s, user_exception);
- printstat(s, set_context_option);
- printstat(s, check_context_retarget_intr);
- printstat(s, check_context_unload);
- printstat(s, tlb_dropin);
- printstat(s, tlb_preload_page);
- printstat(s, tlb_dropin_fail_no_asid);
- printstat(s, tlb_dropin_fail_upm);
- printstat(s, tlb_dropin_fail_invalid);
- printstat(s, tlb_dropin_fail_range_active);
- printstat(s, tlb_dropin_fail_idle);
- printstat(s, tlb_dropin_fail_fmm);
- printstat(s, tlb_dropin_fail_no_exception);
- printstat(s, tfh_stale_on_fault);
- printstat(s, mmu_invalidate_range);
- printstat(s, mmu_invalidate_page);
- printstat(s, flush_tlb);
- printstat(s, flush_tlb_gru);
- printstat(s, flush_tlb_gru_tgh);
- printstat(s, flush_tlb_gru_zero_asid);
- printstat(s, copy_gpa);
- printstat(s, read_gpa);
- printstat(s, mesq_receive);
- printstat(s, mesq_receive_none);
- printstat(s, mesq_send);
- printstat(s, mesq_send_failed);
- printstat(s, mesq_noop);
- printstat(s, mesq_send_unexpected_error);
- printstat(s, mesq_send_lb_overflow);
- printstat(s, mesq_send_qlimit_reached);
- printstat(s, mesq_send_amo_nacked);
- printstat(s, mesq_send_put_nacked);
- printstat(s, mesq_qf_locked);
- printstat(s, mesq_qf_noop_not_full);
- printstat(s, mesq_qf_switch_head_failed);
- printstat(s, mesq_qf_unexpected_error);
- printstat(s, mesq_noop_unexpected_error);
- printstat(s, mesq_noop_lb_overflow);
- printstat(s, mesq_noop_qlimit_reached);
- printstat(s, mesq_noop_amo_nacked);
- printstat(s, mesq_noop_put_nacked);
- printstat(s, mesq_noop_page_overflow);
- return 0;
-}
-
-static ssize_t statistics_write(struct file *file, const char __user *userbuf,
- size_t count, loff_t *data)
-{
- memset(&gru_stats, 0, sizeof(gru_stats));
- return count;
-}
-
-static int mcs_statistics_show(struct seq_file *s, void *p)
-{
- int op;
- unsigned long total, count, max;
- static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt",
- "cch_interrupt_sync", "cch_deallocate", "tfh_write_only",
- "tfh_write_restart", "tgh_invalidate"};
-
- seq_printf(s, "%-20s%12s%12s%12s\n", "#id", "count", "aver-clks", "max-clks");
- for (op = 0; op < mcsop_last; op++) {
- count = atomic_long_read(&mcs_op_statistics[op].count);
- total = atomic_long_read(&mcs_op_statistics[op].total);
- max = mcs_op_statistics[op].max;
- seq_printf(s, "%-20s%12ld%12ld%12ld\n", id[op], count,
- count ? total / count : 0, max);
- }
- return 0;
-}
-
-static ssize_t mcs_statistics_write(struct file *file,
- const char __user *userbuf, size_t count, loff_t *data)
-{
- memset(mcs_op_statistics, 0, sizeof(mcs_op_statistics));
- return count;
-}
-
-static int options_show(struct seq_file *s, void *p)
-{
- seq_printf(s, "#bitmask: 1=trace, 2=statistics\n");
- seq_printf(s, "0x%lx\n", gru_options);
- return 0;
-}
-
-static ssize_t options_write(struct file *file, const char __user *userbuf,
- size_t count, loff_t *data)
-{
- char buf[20];
-
- if (count >= sizeof(buf))
- return -EINVAL;
- if (copy_from_user(buf, userbuf, count))
- return -EFAULT;
- buf[count] = '\0';
- if (strict_strtoul(buf, 0, &gru_options))
- return -EINVAL;
-
- return count;
-}
-
-static int cch_seq_show(struct seq_file *file, void *data)
-{
- long gid = *(long *)data;
- int i;
- struct gru_state *gru = GID_TO_GRU(gid);
- struct gru_thread_state *ts;
- const char *mode[] = { "??", "UPM", "INTR", "OS_POLL" };
-
- if (gid == 0)
- seq_printf(file, "#%5s%5s%6s%7s%9s%6s%8s%8s\n", "gid", "bid",
- "ctx#", "asid", "pid", "cbrs", "dsbytes", "mode");
- if (gru)
- for (i = 0; i < GRU_NUM_CCH; i++) {
- ts = gru->gs_gts[i];
- if (!ts)
- continue;
- seq_printf(file, " %5d%5d%6d%7d%9d%6d%8d%8s\n",
- gru->gs_gid, gru->gs_blade_id, i,
- is_kernel_context(ts) ? 0 : ts->ts_gms->ms_asids[gid].mt_asid,
- is_kernel_context(ts) ? 0 : ts->ts_tgid_owner,
- ts->ts_cbr_au_count * GRU_CBR_AU_SIZE,
- ts->ts_cbr_au_count * GRU_DSR_AU_BYTES,
- mode[ts->ts_user_options &
- GRU_OPT_MISS_MASK]);
- }
-
- return 0;
-}
-
-static int gru_seq_show(struct seq_file *file, void *data)
-{
- long gid = *(long *)data, ctxfree, cbrfree, dsrfree;
- struct gru_state *gru = GID_TO_GRU(gid);
-
- if (gid == 0) {
- seq_printf(file, "#%5s%5s%7s%6s%6s%8s%6s%6s\n", "gid", "nid",
- "ctx", "cbr", "dsr", "ctx", "cbr", "dsr");
- seq_printf(file, "#%5s%5s%7s%6s%6s%8s%6s%6s\n", "", "", "busy",
- "busy", "busy", "free", "free", "free");
- }
- if (gru) {
- ctxfree = GRU_NUM_CCH - gru->gs_active_contexts;
- cbrfree = hweight64(gru->gs_cbr_map) * GRU_CBR_AU_SIZE;
- dsrfree = hweight64(gru->gs_dsr_map) * GRU_DSR_AU_BYTES;
- seq_printf(file, " %5d%5d%7ld%6ld%6ld%8ld%6ld%6ld\n",
- gru->gs_gid, gru->gs_blade_id, GRU_NUM_CCH - ctxfree,
- GRU_NUM_CBE - cbrfree, GRU_NUM_DSR_BYTES - dsrfree,
- ctxfree, cbrfree, dsrfree);
- }
-
- return 0;
-}
-
-static void seq_stop(struct seq_file *file, void *data)
-{
-}
-
-static void *seq_start(struct seq_file *file, loff_t *gid)
-{
- if (*gid < gru_max_gids)
- return gid;
- return NULL;
-}
-
-static void *seq_next(struct seq_file *file, void *data, loff_t *gid)
-{
- (*gid)++;
- if (*gid < gru_max_gids)
- return gid;
- return NULL;
-}
-
-static const struct seq_operations cch_seq_ops = {
- .start = seq_start,
- .next = seq_next,
- .stop = seq_stop,
- .show = cch_seq_show
-};
-
-static const struct seq_operations gru_seq_ops = {
- .start = seq_start,
- .next = seq_next,
- .stop = seq_stop,
- .show = gru_seq_show
-};
-
-static int statistics_open(struct inode *inode, struct file *file)
-{
- return single_open(file, statistics_show, NULL);
-}
-
-static int mcs_statistics_open(struct inode *inode, struct file *file)
-{
- return single_open(file, mcs_statistics_show, NULL);
-}
-
-static int options_open(struct inode *inode, struct file *file)
-{
- return single_open(file, options_show, NULL);
-}
-
-static int cch_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &cch_seq_ops);
-}
-
-static int gru_open(struct inode *inode, struct file *file)
-{
- return seq_open(file, &gru_seq_ops);
-}
-
-/* *INDENT-OFF* */
-static const struct file_operations statistics_fops = {
- .open = statistics_open,
- .read = seq_read,
- .write = statistics_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations mcs_statistics_fops = {
- .open = mcs_statistics_open,
- .read = seq_read,
- .write = mcs_statistics_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations options_fops = {
- .open = options_open,
- .read = seq_read,
- .write = options_write,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations cch_fops = {
- .open = cch_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-static const struct file_operations gru_fops = {
- .open = gru_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
-
-static struct proc_entry {
- char *name;
- umode_t mode;
- const struct file_operations *fops;
- struct proc_dir_entry *entry;
-} proc_files[] = {
- {"statistics", 0644, &statistics_fops},
- {"mcs_statistics", 0644, &mcs_statistics_fops},
- {"debug_options", 0644, &options_fops},
- {"cch_status", 0444, &cch_fops},
- {"gru_status", 0444, &gru_fops},
- {NULL}
-};
-/* *INDENT-ON* */
-
-static struct proc_dir_entry *proc_gru __read_mostly;
-
-static int create_proc_file(struct proc_entry *p)
-{
- p->entry = proc_create(p->name, p->mode, proc_gru, p->fops);
- if (!p->entry)
- return -1;
- return 0;
-}
-
-static void delete_proc_files(void)
-{
- struct proc_entry *p;
-
- if (proc_gru) {
- for (p = proc_files; p->name; p++)
- if (p->entry)
- remove_proc_entry(p->name, proc_gru);
- remove_proc_entry("gru", proc_gru->parent);
- }
-}
-
-int gru_proc_init(void)
-{
- struct proc_entry *p;
-
- proc_gru = proc_mkdir("sgi_uv/gru", NULL);
-
- for (p = proc_files; p->name; p++)
- if (create_proc_file(p))
- goto err;
- return 0;
-
-err:
- delete_proc_files();
- return -1;
-}
-
-void gru_proc_exit(void)
-{
- delete_proc_files();
-}
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/grutables.h b/ANDROID_3.4.5/drivers/misc/sgi-gru/grutables.h
deleted file mode 100644
index 5c3ce245..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/grutables.h
+++ /dev/null
@@ -1,678 +0,0 @@
-/*
- * SN Platform GRU Driver
- *
- * GRU DRIVER TABLES, MACROS, externs, etc
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __GRUTABLES_H__
-#define __GRUTABLES_H__
-
-/*
- * GRU Chiplet:
- * The GRU is a user addressible memory accelerator. It provides
- * several forms of load, store, memset, bcopy instructions. In addition, it
- * contains special instructions for AMOs, sending messages to message
- * queues, etc.
- *
- * The GRU is an integral part of the node controller. It connects
- * directly to the cpu socket. In its current implementation, there are 2
- * GRU chiplets in the node controller on each blade (~node).
- *
- * The entire GRU memory space is fully coherent and cacheable by the cpus.
- *
- * Each GRU chiplet has a physical memory map that looks like the following:
- *
- * +-----------------+
- * |/////////////////|
- * |/////////////////|
- * |/////////////////|
- * |/////////////////|
- * |/////////////////|
- * |/////////////////|
- * |/////////////////|
- * |/////////////////|
- * +-----------------+
- * | system control |
- * +-----------------+ _______ +-------------+
- * |/////////////////| / | |
- * |/////////////////| / | |
- * |/////////////////| / | instructions|
- * |/////////////////| / | |
- * |/////////////////| / | |
- * |/////////////////| / |-------------|
- * |/////////////////| / | |
- * +-----------------+ | |
- * | context 15 | | data |
- * +-----------------+ | |
- * | ...... | \ | |
- * +-----------------+ \____________ +-------------+
- * | context 1 |
- * +-----------------+
- * | context 0 |
- * +-----------------+
- *
- * Each of the "contexts" is a chunk of memory that can be mmaped into user
- * space. The context consists of 2 parts:
- *
- * - an instruction space that can be directly accessed by the user
- * to issue GRU instructions and to check instruction status.
- *
- * - a data area that acts as normal RAM.
- *
- * User instructions contain virtual addresses of data to be accessed by the
- * GRU. The GRU contains a TLB that is used to convert these user virtual
- * addresses to physical addresses.
- *
- * The "system control" area of the GRU chiplet is used by the kernel driver
- * to manage user contexts and to perform functions such as TLB dropin and
- * purging.
- *
- * One context may be reserved for the kernel and used for cross-partition
- * communication. The GRU will also be used to asynchronously zero out
- * large blocks of memory (not currently implemented).
- *
- *
- * Tables:
- *
- * VDATA-VMA Data - Holds a few parameters. Head of linked list of
- * GTS tables for threads using the GSEG
- * GTS - Gru Thread State - contains info for managing a GSEG context. A
- * GTS is allocated for each thread accessing a
- * GSEG.
- * GTD - GRU Thread Data - contains shadow copy of GRU data when GSEG is
- * not loaded into a GRU
- * GMS - GRU Memory Struct - Used to manage TLB shootdowns. Tracks GRUs
- * where a GSEG has been loaded. Similar to
- * an mm_struct but for GRU.
- *
- * GS - GRU State - Used to manage the state of a GRU chiplet
- * BS - Blade State - Used to manage state of all GRU chiplets
- * on a blade
- *
- *
- * Normal task tables for task using GRU.
- * - 2 threads in process
- * - 2 GSEGs open in process
- * - GSEG1 is being used by both threads
- * - GSEG2 is used only by thread 2
- *
- * task -->|
- * task ---+---> mm ->------ (notifier) -------+-> gms
- * | |
- * |--> vma -> vdata ---> gts--->| GSEG1 (thread1)
- * | | |
- * | +-> gts--->| GSEG1 (thread2)
- * | |
- * |--> vma -> vdata ---> gts--->| GSEG2 (thread2)
- * .
- * .
- *
- * GSEGs are marked DONTCOPY on fork
- *
- * At open
- * file.private_data -> NULL
- *
- * At mmap,
- * vma -> vdata
- *
- * After gseg reference
- * vma -> vdata ->gts
- *
- * After fork
- * parent
- * vma -> vdata -> gts
- * child
- * (vma is not copied)
- *
- */
-
-#include <linux/rmap.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/wait.h>
-#include <linux/mmu_notifier.h>
-#include "gru.h"
-#include "grulib.h"
-#include "gruhandles.h"
-
-extern struct gru_stats_s gru_stats;
-extern struct gru_blade_state *gru_base[];
-extern unsigned long gru_start_paddr, gru_end_paddr;
-extern void *gru_start_vaddr;
-extern unsigned int gru_max_gids;
-
-#define GRU_MAX_BLADES MAX_NUMNODES
-#define GRU_MAX_GRUS (GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE)
-
-#define GRU_DRIVER_ID_STR "SGI GRU Device Driver"
-#define GRU_DRIVER_VERSION_STR "0.85"
-
-/*
- * GRU statistics.
- */
-struct gru_stats_s {
- atomic_long_t vdata_alloc;
- atomic_long_t vdata_free;
- atomic_long_t gts_alloc;
- atomic_long_t gts_free;
- atomic_long_t gms_alloc;
- atomic_long_t gms_free;
- atomic_long_t gts_double_allocate;
- atomic_long_t assign_context;
- atomic_long_t assign_context_failed;
- atomic_long_t free_context;
- atomic_long_t load_user_context;
- atomic_long_t load_kernel_context;
- atomic_long_t lock_kernel_context;
- atomic_long_t unlock_kernel_context;
- atomic_long_t steal_user_context;
- atomic_long_t steal_kernel_context;
- atomic_long_t steal_context_failed;
- atomic_long_t nopfn;
- atomic_long_t asid_new;
- atomic_long_t asid_next;
- atomic_long_t asid_wrap;
- atomic_long_t asid_reuse;
- atomic_long_t intr;
- atomic_long_t intr_cbr;
- atomic_long_t intr_tfh;
- atomic_long_t intr_spurious;
- atomic_long_t intr_mm_lock_failed;
- atomic_long_t call_os;
- atomic_long_t call_os_wait_queue;
- atomic_long_t user_flush_tlb;
- atomic_long_t user_unload_context;
- atomic_long_t user_exception;
- atomic_long_t set_context_option;
- atomic_long_t check_context_retarget_intr;
- atomic_long_t check_context_unload;
- atomic_long_t tlb_dropin;
- atomic_long_t tlb_preload_page;
- atomic_long_t tlb_dropin_fail_no_asid;
- atomic_long_t tlb_dropin_fail_upm;
- atomic_long_t tlb_dropin_fail_invalid;
- atomic_long_t tlb_dropin_fail_range_active;
- atomic_long_t tlb_dropin_fail_idle;
- atomic_long_t tlb_dropin_fail_fmm;
- atomic_long_t tlb_dropin_fail_no_exception;
- atomic_long_t tfh_stale_on_fault;
- atomic_long_t mmu_invalidate_range;
- atomic_long_t mmu_invalidate_page;
- atomic_long_t flush_tlb;
- atomic_long_t flush_tlb_gru;
- atomic_long_t flush_tlb_gru_tgh;
- atomic_long_t flush_tlb_gru_zero_asid;
-
- atomic_long_t copy_gpa;
- atomic_long_t read_gpa;
-
- atomic_long_t mesq_receive;
- atomic_long_t mesq_receive_none;
- atomic_long_t mesq_send;
- atomic_long_t mesq_send_failed;
- atomic_long_t mesq_noop;
- atomic_long_t mesq_send_unexpected_error;
- atomic_long_t mesq_send_lb_overflow;
- atomic_long_t mesq_send_qlimit_reached;
- atomic_long_t mesq_send_amo_nacked;
- atomic_long_t mesq_send_put_nacked;
- atomic_long_t mesq_page_overflow;
- atomic_long_t mesq_qf_locked;
- atomic_long_t mesq_qf_noop_not_full;
- atomic_long_t mesq_qf_switch_head_failed;
- atomic_long_t mesq_qf_unexpected_error;
- atomic_long_t mesq_noop_unexpected_error;
- atomic_long_t mesq_noop_lb_overflow;
- atomic_long_t mesq_noop_qlimit_reached;
- atomic_long_t mesq_noop_amo_nacked;
- atomic_long_t mesq_noop_put_nacked;
- atomic_long_t mesq_noop_page_overflow;
-
-};
-
-enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync,
- cchop_deallocate, tfhop_write_only, tfhop_write_restart,
- tghop_invalidate, mcsop_last};
-
-struct mcs_op_statistic {
- atomic_long_t count;
- atomic_long_t total;
- unsigned long max;
-};
-
-extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
-
-#define OPT_DPRINT 1
-#define OPT_STATS 2
-
-
-#define IRQ_GRU 110 /* Starting IRQ number for interrupts */
-
-/* Delay in jiffies between attempts to assign a GRU context */
-#define GRU_ASSIGN_DELAY ((HZ * 20) / 1000)
-
-/*
- * If a process has it's context stolen, min delay in jiffies before trying to
- * steal a context from another process.
- */
-#define GRU_STEAL_DELAY ((HZ * 200) / 1000)
-
-#define STAT(id) do { \
- if (gru_options & OPT_STATS) \
- atomic_long_inc(&gru_stats.id); \
- } while (0)
-
-#ifdef CONFIG_SGI_GRU_DEBUG
-#define gru_dbg(dev, fmt, x...) \
- do { \
- if (gru_options & OPT_DPRINT) \
- printk(KERN_DEBUG "GRU:%d %s: " fmt, smp_processor_id(), __func__, x);\
- } while (0)
-#else
-#define gru_dbg(x...)
-#endif
-
-/*-----------------------------------------------------------------------------
- * ASID management
- */
-#define MAX_ASID 0xfffff0
-#define MIN_ASID 8
-#define ASID_INC 8 /* number of regions */
-
-/* Generate a GRU asid value from a GRU base asid & a virtual address. */
-#define VADDR_HI_BIT 64
-#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3)
-#define GRUASID(asid, addr) ((asid) + GRUREGION(addr))
-
-/*------------------------------------------------------------------------------
- * File & VMS Tables
- */
-
-struct gru_state;
-
-/*
- * This structure is pointed to from the mmstruct via the notifier pointer.
- * There is one of these per address space.
- */
-struct gru_mm_tracker { /* pack to reduce size */
- unsigned int mt_asid_gen:24; /* ASID wrap count */
- unsigned int mt_asid:24; /* current base ASID for gru */
- unsigned short mt_ctxbitmap:16;/* bitmap of contexts using
- asid */
-} __attribute__ ((packed));
-
-struct gru_mm_struct {
- struct mmu_notifier ms_notifier;
- atomic_t ms_refcnt;
- spinlock_t ms_asid_lock; /* protects ASID assignment */
- atomic_t ms_range_active;/* num range_invals active */
- char ms_released;
- wait_queue_head_t ms_wait_queue;
- DECLARE_BITMAP(ms_asidmap, GRU_MAX_GRUS);
- struct gru_mm_tracker ms_asids[GRU_MAX_GRUS];
-};
-
-/*
- * One of these structures is allocated when a GSEG is mmaped. The
- * structure is pointed to by the vma->vm_private_data field in the vma struct.
- */
-struct gru_vma_data {
- spinlock_t vd_lock; /* Serialize access to vma */
- struct list_head vd_head; /* head of linked list of gts */
- long vd_user_options;/* misc user option flags */
- int vd_cbr_au_count;
- int vd_dsr_au_count;
- unsigned char vd_tlb_preload_count;
-};
-
-/*
- * One of these is allocated for each thread accessing a mmaped GRU. A linked
- * list of these structure is hung off the struct gru_vma_data in the mm_struct.
- */
-struct gru_thread_state {
- struct list_head ts_next; /* list - head at vma-private */
- struct mutex ts_ctxlock; /* load/unload CTX lock */
- struct mm_struct *ts_mm; /* mm currently mapped to
- context */
- struct vm_area_struct *ts_vma; /* vma of GRU context */
- struct gru_state *ts_gru; /* GRU where the context is
- loaded */
- struct gru_mm_struct *ts_gms; /* asid & ioproc struct */
- unsigned char ts_tlb_preload_count; /* TLB preload pages */
- unsigned long ts_cbr_map; /* map of allocated CBRs */
- unsigned long ts_dsr_map; /* map of allocated DATA
- resources */
- unsigned long ts_steal_jiffies;/* jiffies when context last
- stolen */
- long ts_user_options;/* misc user option flags */
- pid_t ts_tgid_owner; /* task that is using the
- context - for migration */
- short ts_user_blade_id;/* user selected blade */
- char ts_user_chiplet_id;/* user selected chiplet */
- unsigned short ts_sizeavail; /* Pagesizes in use */
- int ts_tsid; /* thread that owns the
- structure */
- int ts_tlb_int_select;/* target cpu if interrupts
- enabled */
- int ts_ctxnum; /* context number where the
- context is loaded */
- atomic_t ts_refcnt; /* reference count GTS */
- unsigned char ts_dsr_au_count;/* Number of DSR resources
- required for contest */
- unsigned char ts_cbr_au_count;/* Number of CBR resources
- required for contest */
- char ts_cch_req_slice;/* CCH packet slice */
- char ts_blade; /* If >= 0, migrate context if
- ref from different blade */
- char ts_force_cch_reload;
- char ts_cbr_idx[GRU_CBR_AU];/* CBR numbers of each
- allocated CB */
- int ts_data_valid; /* Indicates if ts_gdata has
- valid data */
- struct gru_gseg_statistics ustats; /* User statistics */
- unsigned long ts_gdata[0]; /* save area for GRU data (CB,
- DS, CBE) */
-};
-
-/*
- * Threaded programs actually allocate an array of GSEGs when a context is
- * created. Each thread uses a separate GSEG. TSID is the index into the GSEG
- * array.
- */
-#define TSID(a, v) (((a) - (v)->vm_start) / GRU_GSEG_PAGESIZE)
-#define UGRUADDR(gts) ((gts)->ts_vma->vm_start + \
- (gts)->ts_tsid * GRU_GSEG_PAGESIZE)
-
-#define NULLCTX (-1) /* if context not loaded into GRU */
-
-/*-----------------------------------------------------------------------------
- * GRU State Tables
- */
-
-/*
- * One of these exists for each GRU chiplet.
- */
-struct gru_state {
- struct gru_blade_state *gs_blade; /* GRU state for entire
- blade */
- unsigned long gs_gru_base_paddr; /* Physical address of
- gru segments (64) */
- void *gs_gru_base_vaddr; /* Virtual address of
- gru segments (64) */
- unsigned short gs_gid; /* unique GRU number */
- unsigned short gs_blade_id; /* blade of GRU */
- unsigned char gs_chiplet_id; /* blade chiplet of GRU */
- unsigned char gs_tgh_local_shift; /* used to pick TGH for
- local flush */
- unsigned char gs_tgh_first_remote; /* starting TGH# for
- remote flush */
- spinlock_t gs_asid_lock; /* lock used for
- assigning asids */
- spinlock_t gs_lock; /* lock used for
- assigning contexts */
-
- /* -- the following are protected by the gs_asid_lock spinlock ---- */
- unsigned int gs_asid; /* Next availe ASID */
- unsigned int gs_asid_limit; /* Limit of available
- ASIDs */
- unsigned int gs_asid_gen; /* asid generation.
- Inc on wrap */
-
- /* --- the following fields are protected by the gs_lock spinlock --- */
- unsigned long gs_context_map; /* bitmap to manage
- contexts in use */
- unsigned long gs_cbr_map; /* bitmap to manage CB
- resources */
- unsigned long gs_dsr_map; /* bitmap used to manage
- DATA resources */
- unsigned int gs_reserved_cbrs; /* Number of kernel-
- reserved cbrs */
- unsigned int gs_reserved_dsr_bytes; /* Bytes of kernel-
- reserved dsrs */
- unsigned short gs_active_contexts; /* number of contexts
- in use */
- struct gru_thread_state *gs_gts[GRU_NUM_CCH]; /* GTS currently using
- the context */
- int gs_irq[GRU_NUM_TFM]; /* Interrupt irqs */
-};
-
-/*
- * This structure contains the GRU state for all the GRUs on a blade.
- */
-struct gru_blade_state {
- void *kernel_cb; /* First kernel
- reserved cb */
- void *kernel_dsr; /* First kernel
- reserved DSR */
- struct rw_semaphore bs_kgts_sema; /* lock for kgts */
- struct gru_thread_state *bs_kgts; /* GTS for kernel use */
-
- /* ---- the following are used for managing kernel async GRU CBRs --- */
- int bs_async_dsr_bytes; /* DSRs for async */
- int bs_async_cbrs; /* CBRs AU for async */
- struct completion *bs_async_wq;
-
- /* ---- the following are protected by the bs_lock spinlock ---- */
- spinlock_t bs_lock; /* lock used for
- stealing contexts */
- int bs_lru_ctxnum; /* STEAL - last context
- stolen */
- struct gru_state *bs_lru_gru; /* STEAL - last gru
- stolen */
-
- struct gru_state bs_grus[GRU_CHIPLETS_PER_BLADE];
-};
-
-/*-----------------------------------------------------------------------------
- * Address Primitives
- */
-#define get_tfm_for_cpu(g, c) \
- ((struct gru_tlb_fault_map *)get_tfm((g)->gs_gru_base_vaddr, (c)))
-#define get_tfh_by_index(g, i) \
- ((struct gru_tlb_fault_handle *)get_tfh((g)->gs_gru_base_vaddr, (i)))
-#define get_tgh_by_index(g, i) \
- ((struct gru_tlb_global_handle *)get_tgh((g)->gs_gru_base_vaddr, (i)))
-#define get_cbe_by_index(g, i) \
- ((struct gru_control_block_extended *)get_cbe((g)->gs_gru_base_vaddr,\
- (i)))
-
-/*-----------------------------------------------------------------------------
- * Useful Macros
- */
-
-/* Given a blade# & chiplet#, get a pointer to the GRU */
-#define get_gru(b, c) (&gru_base[b]->bs_grus[c])
-
-/* Number of bytes to save/restore when unloading/loading GRU contexts */
-#define DSR_BYTES(dsr) ((dsr) * GRU_DSR_AU_BYTES)
-#define CBR_BYTES(cbr) ((cbr) * GRU_HANDLE_BYTES * GRU_CBR_AU_SIZE * 2)
-
-/* Convert a user CB number to the actual CBRNUM */
-#define thread_cbr_number(gts, n) ((gts)->ts_cbr_idx[(n) / GRU_CBR_AU_SIZE] \
- * GRU_CBR_AU_SIZE + (n) % GRU_CBR_AU_SIZE)
-
-/* Convert a gid to a pointer to the GRU */
-#define GID_TO_GRU(gid) \
- (gru_base[(gid) / GRU_CHIPLETS_PER_BLADE] ? \
- (&gru_base[(gid) / GRU_CHIPLETS_PER_BLADE]-> \
- bs_grus[(gid) % GRU_CHIPLETS_PER_BLADE]) : \
- NULL)
-
-/* Scan all active GRUs in a GRU bitmap */
-#define for_each_gru_in_bitmap(gid, map) \
- for_each_set_bit((gid), (map), GRU_MAX_GRUS)
-
-/* Scan all active GRUs on a specific blade */
-#define for_each_gru_on_blade(gru, nid, i) \
- for ((gru) = gru_base[nid]->bs_grus, (i) = 0; \
- (i) < GRU_CHIPLETS_PER_BLADE; \
- (i)++, (gru)++)
-
-/* Scan all GRUs */
-#define foreach_gid(gid) \
- for ((gid) = 0; (gid) < gru_max_gids; (gid)++)
-
-/* Scan all active GTSs on a gru. Note: must hold ss_lock to use this macro. */
-#define for_each_gts_on_gru(gts, gru, ctxnum) \
- for ((ctxnum) = 0; (ctxnum) < GRU_NUM_CCH; (ctxnum)++) \
- if (((gts) = (gru)->gs_gts[ctxnum]))
-
-/* Scan each CBR whose bit is set in a TFM (or copy of) */
-#define for_each_cbr_in_tfm(i, map) \
- for_each_set_bit((i), (map), GRU_NUM_CBE)
-
-/* Scan each CBR in a CBR bitmap. Note: multiple CBRs in an allocation unit */
-#define for_each_cbr_in_allocation_map(i, map, k) \
- for_each_set_bit((k), (map), GRU_CBR_AU) \
- for ((i) = (k)*GRU_CBR_AU_SIZE; \
- (i) < ((k) + 1) * GRU_CBR_AU_SIZE; (i)++)
-
-/* Scan each DSR in a DSR bitmap. Note: multiple DSRs in an allocation unit */
-#define for_each_dsr_in_allocation_map(i, map, k) \
- for_each_set_bit((k), (const unsigned long *)(map), GRU_DSR_AU) \
- for ((i) = (k) * GRU_DSR_AU_CL; \
- (i) < ((k) + 1) * GRU_DSR_AU_CL; (i)++)
-
-#define gseg_physical_address(gru, ctxnum) \
- ((gru)->gs_gru_base_paddr + ctxnum * GRU_GSEG_STRIDE)
-#define gseg_virtual_address(gru, ctxnum) \
- ((gru)->gs_gru_base_vaddr + ctxnum * GRU_GSEG_STRIDE)
-
-/*-----------------------------------------------------------------------------
- * Lock / Unlock GRU handles
- * Use the "delresp" bit in the handle as a "lock" bit.
- */
-
-/* Lock hierarchy checking enabled only in emulator */
-
-/* 0 = lock failed, 1 = locked */
-static inline int __trylock_handle(void *h)
-{
- return !test_and_set_bit(1, h);
-}
-
-static inline void __lock_handle(void *h)
-{
- while (test_and_set_bit(1, h))
- cpu_relax();
-}
-
-static inline void __unlock_handle(void *h)
-{
- clear_bit(1, h);
-}
-
-static inline int trylock_cch_handle(struct gru_context_configuration_handle *cch)
-{
- return __trylock_handle(cch);
-}
-
-static inline void lock_cch_handle(struct gru_context_configuration_handle *cch)
-{
- __lock_handle(cch);
-}
-
-static inline void unlock_cch_handle(struct gru_context_configuration_handle
- *cch)
-{
- __unlock_handle(cch);
-}
-
-static inline void lock_tgh_handle(struct gru_tlb_global_handle *tgh)
-{
- __lock_handle(tgh);
-}
-
-static inline void unlock_tgh_handle(struct gru_tlb_global_handle *tgh)
-{
- __unlock_handle(tgh);
-}
-
-static inline int is_kernel_context(struct gru_thread_state *gts)
-{
- return !gts->ts_mm;
-}
-
-/*
- * The following are for Nehelem-EX. A more general scheme is needed for
- * future processors.
- */
-#define UV_MAX_INT_CORES 8
-#define uv_cpu_socket_number(p) ((cpu_physical_id(p) >> 5) & 1)
-#define uv_cpu_ht_number(p) (cpu_physical_id(p) & 1)
-#define uv_cpu_core_number(p) (((cpu_physical_id(p) >> 2) & 4) | \
- ((cpu_physical_id(p) >> 1) & 3))
-/*-----------------------------------------------------------------------------
- * Function prototypes & externs
- */
-struct gru_unload_context_req;
-
-extern const struct vm_operations_struct gru_vm_ops;
-extern struct device *grudev;
-
-extern struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma,
- int tsid);
-extern struct gru_thread_state *gru_find_thread_state(struct vm_area_struct
- *vma, int tsid);
-extern struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct
- *vma, int tsid);
-extern struct gru_state *gru_assign_gru_context(struct gru_thread_state *gts);
-extern void gru_load_context(struct gru_thread_state *gts);
-extern void gru_steal_context(struct gru_thread_state *gts);
-extern void gru_unload_context(struct gru_thread_state *gts, int savestate);
-extern int gru_update_cch(struct gru_thread_state *gts);
-extern void gts_drop(struct gru_thread_state *gts);
-extern void gru_tgh_flush_init(struct gru_state *gru);
-extern int gru_kservices_init(void);
-extern void gru_kservices_exit(void);
-extern irqreturn_t gru0_intr(int irq, void *dev_id);
-extern irqreturn_t gru1_intr(int irq, void *dev_id);
-extern irqreturn_t gru_intr_mblade(int irq, void *dev_id);
-extern int gru_dump_chiplet_request(unsigned long arg);
-extern long gru_get_gseg_statistics(unsigned long arg);
-extern int gru_handle_user_call_os(unsigned long address);
-extern int gru_user_flush_tlb(unsigned long arg);
-extern int gru_user_unload_context(unsigned long arg);
-extern int gru_get_exception_detail(unsigned long arg);
-extern int gru_set_context_option(unsigned long address);
-extern void gru_check_context_placement(struct gru_thread_state *gts);
-extern int gru_cpu_fault_map_id(void);
-extern struct vm_area_struct *gru_find_vma(unsigned long vaddr);
-extern void gru_flush_all_tlb(struct gru_state *gru);
-extern int gru_proc_init(void);
-extern void gru_proc_exit(void);
-
-extern struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
- int cbr_au_count, int dsr_au_count,
- unsigned char tlb_preload_count, int options, int tsid);
-extern unsigned long gru_reserve_cb_resources(struct gru_state *gru,
- int cbr_au_count, char *cbmap);
-extern unsigned long gru_reserve_ds_resources(struct gru_state *gru,
- int dsr_au_count, char *dsmap);
-extern int gru_fault(struct vm_area_struct *, struct vm_fault *vmf);
-extern struct gru_mm_struct *gru_register_mmu_notifier(void);
-extern void gru_drop_mmu_notifier(struct gru_mm_struct *gms);
-
-extern int gru_ktest(unsigned long arg);
-extern void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start,
- unsigned long len);
-
-extern unsigned long gru_options;
-
-#endif /* __GRUTABLES_H__ */
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-gru/grutlbpurge.c b/ANDROID_3.4.5/drivers/misc/sgi-gru/grutlbpurge.c
deleted file mode 100644
index 240a6d36..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-gru/grutlbpurge.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * SN Platform GRU Driver
- *
- * MMUOPS callbacks + TLB flushing
- *
- * This file handles emu notifier callbacks from the core kernel. The callbacks
- * are used to update the TLB in the GRU as a result of changes in the
- * state of a process address space. This file also handles TLB invalidates
- * from the GRU driver.
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/hugetlb.h>
-#include <linux/delay.h>
-#include <linux/timex.h>
-#include <linux/srcu.h>
-#include <asm/processor.h>
-#include "gru.h"
-#include "grutables.h"
-#include <asm/uv/uv_hub.h>
-
-#define gru_random() get_cycles()
-
-/* ---------------------------------- TLB Invalidation functions --------
- * get_tgh_handle
- *
- * Find a TGH to use for issuing a TLB invalidate. For GRUs that are on the
- * local blade, use a fixed TGH that is a function of the blade-local cpu
- * number. Normally, this TGH is private to the cpu & no contention occurs for
- * the TGH. For offblade GRUs, select a random TGH in the range above the
- * private TGHs. A spinlock is required to access this TGH & the lock must be
- * released when the invalidate is completes. This sucks, but it is the best we
- * can do.
- *
- * Note that the spinlock is IN the TGH handle so locking does not involve
- * additional cache lines.
- *
- */
-static inline int get_off_blade_tgh(struct gru_state *gru)
-{
- int n;
-
- n = GRU_NUM_TGH - gru->gs_tgh_first_remote;
- n = gru_random() % n;
- n += gru->gs_tgh_first_remote;
- return n;
-}
-
-static inline int get_on_blade_tgh(struct gru_state *gru)
-{
- return uv_blade_processor_id() >> gru->gs_tgh_local_shift;
-}
-
-static struct gru_tlb_global_handle *get_lock_tgh_handle(struct gru_state
- *gru)
-{
- struct gru_tlb_global_handle *tgh;
- int n;
-
- preempt_disable();
- if (uv_numa_blade_id() == gru->gs_blade_id)
- n = get_on_blade_tgh(gru);
- else
- n = get_off_blade_tgh(gru);
- tgh = get_tgh_by_index(gru, n);
- lock_tgh_handle(tgh);
-
- return tgh;
-}
-
-static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh)
-{
- unlock_tgh_handle(tgh);
- preempt_enable();
-}
-
-/*
- * gru_flush_tlb_range
- *
- * General purpose TLB invalidation function. This function scans every GRU in
- * the ENTIRE system (partition) looking for GRUs where the specified MM has
- * been accessed by the GRU. For each GRU found, the TLB must be invalidated OR
- * the ASID invalidated. Invalidating an ASID causes a new ASID to be assigned
- * on the next fault. This effectively flushes the ENTIRE TLB for the MM at the
- * cost of (possibly) a large number of future TLBmisses.
- *
- * The current algorithm is optimized based on the following (somewhat true)
- * assumptions:
- * - GRU contexts are not loaded into a GRU unless a reference is made to
- * the data segment or control block (this is true, not an assumption).
- * If a DS/CB is referenced, the user will also issue instructions that
- * cause TLBmisses. It is not necessary to optimize for the case where
- * contexts are loaded but no instructions cause TLB misses. (I know
- * this will happen but I'm not optimizing for it).
- * - GRU instructions to invalidate TLB entries are SLOOOOWWW - normally
- * a few usec but in unusual cases, it could be longer. Avoid if
- * possible.
- * - intrablade process migration between cpus is not frequent but is
- * common.
- * - a GRU context is not typically migrated to a different GRU on the
- * blade because of intrablade migration
- * - interblade migration is rare. Processes migrate their GRU context to
- * the new blade.
- * - if interblade migration occurs, migration back to the original blade
- * is very very rare (ie., no optimization for this case)
- * - most GRU instruction operate on a subset of the user REGIONS. Code
- * & shared library regions are not likely targets of GRU instructions.
- *
- * To help improve the efficiency of TLB invalidation, the GMS data
- * structure is maintained for EACH address space (MM struct). The GMS is
- * also the structure that contains the pointer to the mmu callout
- * functions. This structure is linked to the mm_struct for the address space
- * using the mmu "register" function. The mmu interfaces are used to
- * provide the callbacks for TLB invalidation. The GMS contains:
- *
- * - asid[maxgrus] array. ASIDs are assigned to a GRU when a context is
- * loaded into the GRU.
- * - asidmap[maxgrus]. bitmap to make it easier to find non-zero asids in
- * the above array
- * - ctxbitmap[maxgrus]. Indicates the contexts that are currently active
- * in the GRU for the address space. This bitmap must be passed to the
- * GRU to do an invalidate.
- *
- * The current algorithm for invalidating TLBs is:
- * - scan the asidmap for GRUs where the context has been loaded, ie,
- * asid is non-zero.
- * - for each gru found:
- * - if the ctxtmap is non-zero, there are active contexts in the
- * GRU. TLB invalidate instructions must be issued to the GRU.
- * - if the ctxtmap is zero, no context is active. Set the ASID to
- * zero to force a full TLB invalidation. This is fast but will
- * cause a lot of TLB misses if the context is reloaded onto the
- * GRU
- *
- */
-
-void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start,
- unsigned long len)
-{
- struct gru_state *gru;
- struct gru_mm_tracker *asids;
- struct gru_tlb_global_handle *tgh;
- unsigned long num;
- int grupagesize, pagesize, pageshift, gid, asid;
-
- /* ZZZ TODO - handle huge pages */
- pageshift = PAGE_SHIFT;
- pagesize = (1UL << pageshift);
- grupagesize = GRU_PAGESIZE(pageshift);
- num = min(((len + pagesize - 1) >> pageshift), GRUMAXINVAL);
-
- STAT(flush_tlb);
- gru_dbg(grudev, "gms %p, start 0x%lx, len 0x%lx, asidmap 0x%lx\n", gms,
- start, len, gms->ms_asidmap[0]);
-
- spin_lock(&gms->ms_asid_lock);
- for_each_gru_in_bitmap(gid, gms->ms_asidmap) {
- STAT(flush_tlb_gru);
- gru = GID_TO_GRU(gid);
- asids = gms->ms_asids + gid;
- asid = asids->mt_asid;
- if (asids->mt_ctxbitmap && asid) {
- STAT(flush_tlb_gru_tgh);
- asid = GRUASID(asid, start);
- gru_dbg(grudev,
- " FLUSH gruid %d, asid 0x%x, vaddr 0x%lx, vamask 0x%x, num %ld, cbmap 0x%x\n",
- gid, asid, start, grupagesize, num, asids->mt_ctxbitmap);
- tgh = get_lock_tgh_handle(gru);
- tgh_invalidate(tgh, start, ~0, asid, grupagesize, 0,
- num - 1, asids->mt_ctxbitmap);
- get_unlock_tgh_handle(tgh);
- } else {
- STAT(flush_tlb_gru_zero_asid);
- asids->mt_asid = 0;
- __clear_bit(gru->gs_gid, gms->ms_asidmap);
- gru_dbg(grudev,
- " CLEARASID gruid %d, asid 0x%x, cbtmap 0x%x, asidmap 0x%lx\n",
- gid, asid, asids->mt_ctxbitmap,
- gms->ms_asidmap[0]);
- }
- }
- spin_unlock(&gms->ms_asid_lock);
-}
-
-/*
- * Flush the entire TLB on a chiplet.
- */
-void gru_flush_all_tlb(struct gru_state *gru)
-{
- struct gru_tlb_global_handle *tgh;
-
- gru_dbg(grudev, "gid %d\n", gru->gs_gid);
- tgh = get_lock_tgh_handle(gru);
- tgh_invalidate(tgh, 0, ~0, 0, 1, 1, GRUMAXINVAL - 1, 0xffff);
- get_unlock_tgh_handle(tgh);
-}
-
-/*
- * MMUOPS notifier callout functions
- */
-static void gru_invalidate_range_start(struct mmu_notifier *mn,
- struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
- ms_notifier);
-
- STAT(mmu_invalidate_range);
- atomic_inc(&gms->ms_range_active);
- gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx, act %d\n", gms,
- start, end, atomic_read(&gms->ms_range_active));
- gru_flush_tlb_range(gms, start, end - start);
-}
-
-static void gru_invalidate_range_end(struct mmu_notifier *mn,
- struct mm_struct *mm, unsigned long start,
- unsigned long end)
-{
- struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
- ms_notifier);
-
- /* ..._and_test() provides needed barrier */
- (void)atomic_dec_and_test(&gms->ms_range_active);
-
- wake_up_all(&gms->ms_wait_queue);
- gru_dbg(grudev, "gms %p, start 0x%lx, end 0x%lx\n", gms, start, end);
-}
-
-static void gru_invalidate_page(struct mmu_notifier *mn, struct mm_struct *mm,
- unsigned long address)
-{
- struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
- ms_notifier);
-
- STAT(mmu_invalidate_page);
- gru_flush_tlb_range(gms, address, PAGE_SIZE);
- gru_dbg(grudev, "gms %p, address 0x%lx\n", gms, address);
-}
-
-static void gru_release(struct mmu_notifier *mn, struct mm_struct *mm)
-{
- struct gru_mm_struct *gms = container_of(mn, struct gru_mm_struct,
- ms_notifier);
-
- gms->ms_released = 1;
- gru_dbg(grudev, "gms %p\n", gms);
-}
-
-
-static const struct mmu_notifier_ops gru_mmuops = {
- .invalidate_page = gru_invalidate_page,
- .invalidate_range_start = gru_invalidate_range_start,
- .invalidate_range_end = gru_invalidate_range_end,
- .release = gru_release,
-};
-
-/* Move this to the basic mmu_notifier file. But for now... */
-static struct mmu_notifier *mmu_find_ops(struct mm_struct *mm,
- const struct mmu_notifier_ops *ops)
-{
- struct mmu_notifier *mn, *gru_mn = NULL;
- struct hlist_node *n;
-
- if (mm->mmu_notifier_mm) {
- rcu_read_lock();
- hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list,
- hlist)
- if (mn->ops == ops) {
- gru_mn = mn;
- break;
- }
- rcu_read_unlock();
- }
- return gru_mn;
-}
-
-struct gru_mm_struct *gru_register_mmu_notifier(void)
-{
- struct gru_mm_struct *gms;
- struct mmu_notifier *mn;
- int err;
-
- mn = mmu_find_ops(current->mm, &gru_mmuops);
- if (mn) {
- gms = container_of(mn, struct gru_mm_struct, ms_notifier);
- atomic_inc(&gms->ms_refcnt);
- } else {
- gms = kzalloc(sizeof(*gms), GFP_KERNEL);
- if (gms) {
- STAT(gms_alloc);
- spin_lock_init(&gms->ms_asid_lock);
- gms->ms_notifier.ops = &gru_mmuops;
- atomic_set(&gms->ms_refcnt, 1);
- init_waitqueue_head(&gms->ms_wait_queue);
- err = __mmu_notifier_register(&gms->ms_notifier, current->mm);
- if (err)
- goto error;
- }
- }
- gru_dbg(grudev, "gms %p, refcnt %d\n", gms,
- atomic_read(&gms->ms_refcnt));
- return gms;
-error:
- kfree(gms);
- return ERR_PTR(err);
-}
-
-void gru_drop_mmu_notifier(struct gru_mm_struct *gms)
-{
- gru_dbg(grudev, "gms %p, refcnt %d, released %d\n", gms,
- atomic_read(&gms->ms_refcnt), gms->ms_released);
- if (atomic_dec_return(&gms->ms_refcnt) == 0) {
- if (!gms->ms_released)
- mmu_notifier_unregister(&gms->ms_notifier, current->mm);
- kfree(gms);
- STAT(gms_free);
- }
-}
-
-/*
- * Setup TGH parameters. There are:
- * - 24 TGH handles per GRU chiplet
- * - a portion (MAX_LOCAL_TGH) of the handles are reserved for
- * use by blade-local cpus
- * - the rest are used by off-blade cpus. This usage is
- * less frequent than blade-local usage.
- *
- * For now, use 16 handles for local flushes, 8 for remote flushes. If the blade
- * has less tan or equal to 16 cpus, each cpu has a unique handle that it can
- * use.
- */
-#define MAX_LOCAL_TGH 16
-
-void gru_tgh_flush_init(struct gru_state *gru)
-{
- int cpus, shift = 0, n;
-
- cpus = uv_blade_nr_possible_cpus(gru->gs_blade_id);
-
- /* n = cpus rounded up to next power of 2 */
- if (cpus) {
- n = 1 << fls(cpus - 1);
-
- /*
- * shift count for converting local cpu# to TGH index
- * 0 if cpus <= MAX_LOCAL_TGH,
- * 1 if cpus <= 2*MAX_LOCAL_TGH,
- * etc
- */
- shift = max(0, fls(n - 1) - fls(MAX_LOCAL_TGH - 1));
- }
- gru->gs_tgh_local_shift = shift;
-
- /* first starting TGH index to use for remote purges */
- gru->gs_tgh_first_remote = (cpus + (1 << shift) - 1) >> shift;
-
-}
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/Makefile b/ANDROID_3.4.5/drivers/misc/sgi-xp/Makefile
deleted file mode 100644
index 4fc40d8e..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Makefile for SGI's XP devices.
-#
-
-obj-$(CONFIG_SGI_XP) += xp.o
-xp-y := xp_main.o
-xp-$(CONFIG_IA64_SGI_SN2) += xp_sn2.o xp_nofault.o
-xp-$(CONFIG_IA64_GENERIC) += xp_sn2.o xp_nofault.o
-xp-$(CONFIG_IA64_SGI_UV) += xp_uv.o
-xp-$(CONFIG_X86_64) += xp_uv.o
-
-obj-$(CONFIG_SGI_XP) += xpc.o
-xpc-y := xpc_main.o xpc_channel.o xpc_partition.o
-xpc-$(CONFIG_IA64_SGI_SN2) += xpc_sn2.o
-xpc-$(CONFIG_IA64_GENERIC) += xpc_sn2.o
-xpc-$(CONFIG_IA64_SGI_UV) += xpc_uv.o
-xpc-$(CONFIG_X86_64) += xpc_uv.o
-
-obj-$(CONFIG_SGI_XP) += xpnet.o
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp.h b/ANDROID_3.4.5/drivers/misc/sgi-xp/xp.h
deleted file mode 100644
index c862cd45..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp.h
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004-2008 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * External Cross Partition (XP) structures and defines.
- */
-
-#ifndef _DRIVERS_MISC_SGIXP_XP_H
-#define _DRIVERS_MISC_SGIXP_XP_H
-
-#include <linux/mutex.h>
-
-#if defined CONFIG_X86_UV || defined CONFIG_IA64_SGI_UV
-#include <asm/uv/uv.h>
-#define is_uv() is_uv_system()
-#endif
-
-#ifndef is_uv
-#define is_uv() 0
-#endif
-
-#if defined CONFIG_IA64
-#include <asm/sn/arch.h> /* defines is_shub1() and is_shub2() */
-#define is_shub() ia64_platform_is("sn2")
-#endif
-
-#ifndef is_shub1
-#define is_shub1() 0
-#endif
-
-#ifndef is_shub2
-#define is_shub2() 0
-#endif
-
-#ifndef is_shub
-#define is_shub() 0
-#endif
-
-#ifdef USE_DBUG_ON
-#define DBUG_ON(condition) BUG_ON(condition)
-#else
-#define DBUG_ON(condition)
-#endif
-
-/*
- * Define the maximum number of partitions the system can possibly support.
- * It is based on the maximum number of hardware partitionable regions. The
- * term 'region' in this context refers to the minimum number of nodes that
- * can comprise an access protection grouping. The access protection is in
- * regards to memory, IPI and IOI.
- *
- * The maximum number of hardware partitionable regions is equal to the
- * maximum number of nodes in the entire system divided by the minimum number
- * of nodes that comprise an access protection grouping.
- */
-#define XP_MAX_NPARTITIONS_SN2 64
-#define XP_MAX_NPARTITIONS_UV 256
-
-/*
- * XPC establishes channel connections between the local partition and any
- * other partition that is currently up. Over these channels, kernel-level
- * `users' can communicate with their counterparts on the other partitions.
- *
- * If the need for additional channels arises, one can simply increase
- * XPC_MAX_NCHANNELS accordingly. If the day should come where that number
- * exceeds the absolute MAXIMUM number of channels possible (eight), then one
- * will need to make changes to the XPC code to accommodate for this.
- *
- * The absolute maximum number of channels possible is limited to eight for
- * performance reasons on sn2 hardware. The internal cross partition structures
- * require sixteen bytes per channel, and eight allows all of this
- * interface-shared info to fit in one 128-byte cacheline.
- */
-#define XPC_MEM_CHANNEL 0 /* memory channel number */
-#define XPC_NET_CHANNEL 1 /* network channel number */
-
-#define XPC_MAX_NCHANNELS 2 /* max #of channels allowed */
-
-#if XPC_MAX_NCHANNELS > 8
-#error XPC_MAX_NCHANNELS exceeds absolute MAXIMUM possible.
-#endif
-
-/*
- * Define macro, XPC_MSG_SIZE(), is provided for the user
- * that wants to fit as many msg entries as possible in a given memory size
- * (e.g. a memory page).
- */
-#define XPC_MSG_MAX_SIZE 128
-#define XPC_MSG_HDR_MAX_SIZE 16
-#define XPC_MSG_PAYLOAD_MAX_SIZE (XPC_MSG_MAX_SIZE - XPC_MSG_HDR_MAX_SIZE)
-
-#define XPC_MSG_SIZE(_payload_size) \
- ALIGN(XPC_MSG_HDR_MAX_SIZE + (_payload_size), \
- is_uv() ? 64 : 128)
-
-
-/*
- * Define the return values and values passed to user's callout functions.
- * (It is important to add new value codes at the end just preceding
- * xpUnknownReason, which must have the highest numerical value.)
- */
-enum xp_retval {
- xpSuccess = 0,
-
- xpNotConnected, /* 1: channel is not connected */
- xpConnected, /* 2: channel connected (opened) */
- xpRETIRED1, /* 3: (formerly xpDisconnected) */
-
- xpMsgReceived, /* 4: message received */
- xpMsgDelivered, /* 5: message delivered and acknowledged */
-
- xpRETIRED2, /* 6: (formerly xpTransferFailed) */
-
- xpNoWait, /* 7: operation would require wait */
- xpRetry, /* 8: retry operation */
- xpTimeout, /* 9: timeout in xpc_allocate_msg_wait() */
- xpInterrupted, /* 10: interrupted wait */
-
- xpUnequalMsgSizes, /* 11: message size disparity between sides */
- xpInvalidAddress, /* 12: invalid address */
-
- xpNoMemory, /* 13: no memory available for XPC structures */
- xpLackOfResources, /* 14: insufficient resources for operation */
- xpUnregistered, /* 15: channel is not registered */
- xpAlreadyRegistered, /* 16: channel is already registered */
-
- xpPartitionDown, /* 17: remote partition is down */
- xpNotLoaded, /* 18: XPC module is not loaded */
- xpUnloading, /* 19: this side is unloading XPC module */
-
- xpBadMagic, /* 20: XPC MAGIC string not found */
-
- xpReactivating, /* 21: remote partition was reactivated */
-
- xpUnregistering, /* 22: this side is unregistering channel */
- xpOtherUnregistering, /* 23: other side is unregistering channel */
-
- xpCloneKThread, /* 24: cloning kernel thread */
- xpCloneKThreadFailed, /* 25: cloning kernel thread failed */
-
- xpNoHeartbeat, /* 26: remote partition has no heartbeat */
-
- xpPioReadError, /* 27: PIO read error */
- xpPhysAddrRegFailed, /* 28: registration of phys addr range failed */
-
- xpRETIRED3, /* 29: (formerly xpBteDirectoryError) */
- xpRETIRED4, /* 30: (formerly xpBtePoisonError) */
- xpRETIRED5, /* 31: (formerly xpBteWriteError) */
- xpRETIRED6, /* 32: (formerly xpBteAccessError) */
- xpRETIRED7, /* 33: (formerly xpBtePWriteError) */
- xpRETIRED8, /* 34: (formerly xpBtePReadError) */
- xpRETIRED9, /* 35: (formerly xpBteTimeOutError) */
- xpRETIRED10, /* 36: (formerly xpBteXtalkError) */
- xpRETIRED11, /* 37: (formerly xpBteNotAvailable) */
- xpRETIRED12, /* 38: (formerly xpBteUnmappedError) */
-
- xpBadVersion, /* 39: bad version number */
- xpVarsNotSet, /* 40: the XPC variables are not set up */
- xpNoRsvdPageAddr, /* 41: unable to get rsvd page's phys addr */
- xpInvalidPartid, /* 42: invalid partition ID */
- xpLocalPartid, /* 43: local partition ID */
-
- xpOtherGoingDown, /* 44: other side going down, reason unknown */
- xpSystemGoingDown, /* 45: system is going down, reason unknown */
- xpSystemHalt, /* 46: system is being halted */
- xpSystemReboot, /* 47: system is being rebooted */
- xpSystemPoweroff, /* 48: system is being powered off */
-
- xpDisconnecting, /* 49: channel disconnecting (closing) */
-
- xpOpenCloseError, /* 50: channel open/close protocol error */
-
- xpDisconnected, /* 51: channel disconnected (closed) */
-
- xpBteCopyError, /* 52: bte_copy() returned error */
- xpSalError, /* 53: sn SAL error */
- xpRsvdPageNotSet, /* 54: the reserved page is not set up */
- xpPayloadTooBig, /* 55: payload too large for message slot */
-
- xpUnsupported, /* 56: unsupported functionality or resource */
- xpNeedMoreInfo, /* 57: more info is needed by SAL */
-
- xpGruCopyError, /* 58: gru_copy_gru() returned error */
- xpGruSendMqError, /* 59: gru send message queue related error */
-
- xpBadChannelNumber, /* 60: invalid channel number */
- xpBadMsgType, /* 61: invalid message type */
- xpBiosError, /* 62: BIOS error */
-
- xpUnknownReason /* 63: unknown reason - must be last in enum */
-};
-
-/*
- * Define the callout function type used by XPC to update the user on
- * connection activity and state changes via the user function registered
- * by xpc_connect().
- *
- * Arguments:
- *
- * reason - reason code.
- * partid - partition ID associated with condition.
- * ch_number - channel # associated with condition.
- * data - pointer to optional data.
- * key - pointer to optional user-defined value provided as the "key"
- * argument to xpc_connect().
- *
- * A reason code of xpConnected indicates that a connection has been
- * established to the specified partition on the specified channel. The data
- * argument indicates the max number of entries allowed in the message queue.
- *
- * A reason code of xpMsgReceived indicates that a XPC message arrived from
- * the specified partition on the specified channel. The data argument
- * specifies the address of the message's payload. The user must call
- * xpc_received() when finished with the payload.
- *
- * All other reason codes indicate failure. The data argmument is NULL.
- * When a failure reason code is received, one can assume that the channel
- * is not connected.
- */
-typedef void (*xpc_channel_func) (enum xp_retval reason, short partid,
- int ch_number, void *data, void *key);
-
-/*
- * Define the callout function type used by XPC to notify the user of
- * messages received and delivered via the user function registered by
- * xpc_send_notify().
- *
- * Arguments:
- *
- * reason - reason code.
- * partid - partition ID associated with condition.
- * ch_number - channel # associated with condition.
- * key - pointer to optional user-defined value provided as the "key"
- * argument to xpc_send_notify().
- *
- * A reason code of xpMsgDelivered indicates that the message was delivered
- * to the intended recipient and that they have acknowledged its receipt by
- * calling xpc_received().
- *
- * All other reason codes indicate failure.
- *
- * NOTE: The user defined function must be callable by an interrupt handler
- * and thus cannot block.
- */
-typedef void (*xpc_notify_func) (enum xp_retval reason, short partid,
- int ch_number, void *key);
-
-/*
- * The following is a registration entry. There is a global array of these,
- * one per channel. It is used to record the connection registration made
- * by the users of XPC. As long as a registration entry exists, for any
- * partition that comes up, XPC will attempt to establish a connection on
- * that channel. Notification that a connection has been made will occur via
- * the xpc_channel_func function.
- *
- * The 'func' field points to the function to call when aynchronous
- * notification is required for such events as: a connection established/lost,
- * or an incoming message received, or an error condition encountered. A
- * non-NULL 'func' field indicates that there is an active registration for
- * the channel.
- */
-struct xpc_registration {
- struct mutex mutex;
- xpc_channel_func func; /* function to call */
- void *key; /* pointer to user's key */
- u16 nentries; /* #of msg entries in local msg queue */
- u16 entry_size; /* message queue's message entry size */
- u32 assigned_limit; /* limit on #of assigned kthreads */
- u32 idle_limit; /* limit on #of idle kthreads */
-} ____cacheline_aligned;
-
-#define XPC_CHANNEL_REGISTERED(_c) (xpc_registrations[_c].func != NULL)
-
-/* the following are valid xpc_send() or xpc_send_notify() flags */
-#define XPC_WAIT 0 /* wait flag */
-#define XPC_NOWAIT 1 /* no wait flag */
-
-struct xpc_interface {
- void (*connect) (int);
- void (*disconnect) (int);
- enum xp_retval (*send) (short, int, u32, void *, u16);
- enum xp_retval (*send_notify) (short, int, u32, void *, u16,
- xpc_notify_func, void *);
- void (*received) (short, int, void *);
- enum xp_retval (*partid_to_nasids) (short, void *);
-};
-
-extern struct xpc_interface xpc_interface;
-
-extern void xpc_set_interface(void (*)(int),
- void (*)(int),
- enum xp_retval (*)(short, int, u32, void *, u16),
- enum xp_retval (*)(short, int, u32, void *, u16,
- xpc_notify_func, void *),
- void (*)(short, int, void *),
- enum xp_retval (*)(short, void *));
-extern void xpc_clear_interface(void);
-
-extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16,
- u16, u32, u32);
-extern void xpc_disconnect(int);
-
-static inline enum xp_retval
-xpc_send(short partid, int ch_number, u32 flags, void *payload,
- u16 payload_size)
-{
- return xpc_interface.send(partid, ch_number, flags, payload,
- payload_size);
-}
-
-static inline enum xp_retval
-xpc_send_notify(short partid, int ch_number, u32 flags, void *payload,
- u16 payload_size, xpc_notify_func func, void *key)
-{
- return xpc_interface.send_notify(partid, ch_number, flags, payload,
- payload_size, func, key);
-}
-
-static inline void
-xpc_received(short partid, int ch_number, void *payload)
-{
- return xpc_interface.received(partid, ch_number, payload);
-}
-
-static inline enum xp_retval
-xpc_partid_to_nasids(short partid, void *nasids)
-{
- return xpc_interface.partid_to_nasids(partid, nasids);
-}
-
-extern short xp_max_npartitions;
-extern short xp_partition_id;
-extern u8 xp_region_size;
-
-extern unsigned long (*xp_pa) (void *);
-extern unsigned long (*xp_socket_pa) (unsigned long);
-extern enum xp_retval (*xp_remote_memcpy) (unsigned long, const unsigned long,
- size_t);
-extern int (*xp_cpu_to_nasid) (int);
-extern enum xp_retval (*xp_expand_memprotect) (unsigned long, unsigned long);
-extern enum xp_retval (*xp_restrict_memprotect) (unsigned long, unsigned long);
-
-extern u64 xp_nofault_PIOR_target;
-extern int xp_nofault_PIOR(void *);
-extern int xp_error_PIOR(void);
-
-extern struct device *xp;
-extern enum xp_retval xp_init_sn2(void);
-extern enum xp_retval xp_init_uv(void);
-extern void xp_exit_sn2(void);
-extern void xp_exit_uv(void);
-
-#endif /* _DRIVERS_MISC_SGIXP_XP_H */
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_main.c b/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_main.c
deleted file mode 100644
index 01be66d0..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_main.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * Cross Partition (XP) base.
- *
- * XP provides a base from which its users can interact
- * with XPC, yet not be dependent on XPC.
- *
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include "xp.h"
-
-/* define the XP debug device structures to be used with dev_dbg() et al */
-
-struct device_driver xp_dbg_name = {
- .name = "xp"
-};
-
-struct device xp_dbg_subname = {
- .init_name = "", /* set to "" */
- .driver = &xp_dbg_name
-};
-
-struct device *xp = &xp_dbg_subname;
-
-/* max #of partitions possible */
-short xp_max_npartitions;
-EXPORT_SYMBOL_GPL(xp_max_npartitions);
-
-short xp_partition_id;
-EXPORT_SYMBOL_GPL(xp_partition_id);
-
-u8 xp_region_size;
-EXPORT_SYMBOL_GPL(xp_region_size);
-
-unsigned long (*xp_pa) (void *addr);
-EXPORT_SYMBOL_GPL(xp_pa);
-
-unsigned long (*xp_socket_pa) (unsigned long gpa);
-EXPORT_SYMBOL_GPL(xp_socket_pa);
-
-enum xp_retval (*xp_remote_memcpy) (unsigned long dst_gpa,
- const unsigned long src_gpa, size_t len);
-EXPORT_SYMBOL_GPL(xp_remote_memcpy);
-
-int (*xp_cpu_to_nasid) (int cpuid);
-EXPORT_SYMBOL_GPL(xp_cpu_to_nasid);
-
-enum xp_retval (*xp_expand_memprotect) (unsigned long phys_addr,
- unsigned long size);
-EXPORT_SYMBOL_GPL(xp_expand_memprotect);
-enum xp_retval (*xp_restrict_memprotect) (unsigned long phys_addr,
- unsigned long size);
-EXPORT_SYMBOL_GPL(xp_restrict_memprotect);
-
-/*
- * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
- * users of XPC.
- */
-struct xpc_registration xpc_registrations[XPC_MAX_NCHANNELS];
-EXPORT_SYMBOL_GPL(xpc_registrations);
-
-/*
- * Initialize the XPC interface to indicate that XPC isn't loaded.
- */
-static enum xp_retval
-xpc_notloaded(void)
-{
- return xpNotLoaded;
-}
-
-struct xpc_interface xpc_interface = {
- (void (*)(int))xpc_notloaded,
- (void (*)(int))xpc_notloaded,
- (enum xp_retval(*)(short, int, u32, void *, u16))xpc_notloaded,
- (enum xp_retval(*)(short, int, u32, void *, u16, xpc_notify_func,
- void *))xpc_notloaded,
- (void (*)(short, int, void *))xpc_notloaded,
- (enum xp_retval(*)(short, void *))xpc_notloaded
-};
-EXPORT_SYMBOL_GPL(xpc_interface);
-
-/*
- * XPC calls this when it (the XPC module) has been loaded.
- */
-void
-xpc_set_interface(void (*connect) (int),
- void (*disconnect) (int),
- enum xp_retval (*send) (short, int, u32, void *, u16),
- enum xp_retval (*send_notify) (short, int, u32, void *, u16,
- xpc_notify_func, void *),
- void (*received) (short, int, void *),
- enum xp_retval (*partid_to_nasids) (short, void *))
-{
- xpc_interface.connect = connect;
- xpc_interface.disconnect = disconnect;
- xpc_interface.send = send;
- xpc_interface.send_notify = send_notify;
- xpc_interface.received = received;
- xpc_interface.partid_to_nasids = partid_to_nasids;
-}
-EXPORT_SYMBOL_GPL(xpc_set_interface);
-
-/*
- * XPC calls this when it (the XPC module) is being unloaded.
- */
-void
-xpc_clear_interface(void)
-{
- xpc_interface.connect = (void (*)(int))xpc_notloaded;
- xpc_interface.disconnect = (void (*)(int))xpc_notloaded;
- xpc_interface.send = (enum xp_retval(*)(short, int, u32, void *, u16))
- xpc_notloaded;
- xpc_interface.send_notify = (enum xp_retval(*)(short, int, u32, void *,
- u16, xpc_notify_func,
- void *))xpc_notloaded;
- xpc_interface.received = (void (*)(short, int, void *))
- xpc_notloaded;
- xpc_interface.partid_to_nasids = (enum xp_retval(*)(short, void *))
- xpc_notloaded;
-}
-EXPORT_SYMBOL_GPL(xpc_clear_interface);
-
-/*
- * Register for automatic establishment of a channel connection whenever
- * a partition comes up.
- *
- * Arguments:
- *
- * ch_number - channel # to register for connection.
- * func - function to call for asynchronous notification of channel
- * state changes (i.e., connection, disconnection, error) and
- * the arrival of incoming messages.
- * key - pointer to optional user-defined value that gets passed back
- * to the user on any callouts made to func.
- * payload_size - size in bytes of the XPC message's payload area which
- * contains a user-defined message. The user should make
- * this large enough to hold their largest message.
- * nentries - max #of XPC message entries a message queue can contain.
- * The actual number, which is determined when a connection
- * is established and may be less then requested, will be
- * passed to the user via the xpConnected callout.
- * assigned_limit - max number of kthreads allowed to be processing
- * messages (per connection) at any given instant.
- * idle_limit - max number of kthreads allowed to be idle at any given
- * instant.
- */
-enum xp_retval
-xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
- u16 nentries, u32 assigned_limit, u32 idle_limit)
-{
- struct xpc_registration *registration;
-
- DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);
- DBUG_ON(payload_size == 0 || nentries == 0);
- DBUG_ON(func == NULL);
- DBUG_ON(assigned_limit == 0 || idle_limit > assigned_limit);
-
- if (XPC_MSG_SIZE(payload_size) > XPC_MSG_MAX_SIZE)
- return xpPayloadTooBig;
-
- registration = &xpc_registrations[ch_number];
-
- if (mutex_lock_interruptible(&registration->mutex) != 0)
- return xpInterrupted;
-
- /* if XPC_CHANNEL_REGISTERED(ch_number) */
- if (registration->func != NULL) {
- mutex_unlock(&registration->mutex);
- return xpAlreadyRegistered;
- }
-
- /* register the channel for connection */
- registration->entry_size = XPC_MSG_SIZE(payload_size);
- registration->nentries = nentries;
- registration->assigned_limit = assigned_limit;
- registration->idle_limit = idle_limit;
- registration->key = key;
- registration->func = func;
-
- mutex_unlock(&registration->mutex);
-
- xpc_interface.connect(ch_number);
-
- return xpSuccess;
-}
-EXPORT_SYMBOL_GPL(xpc_connect);
-
-/*
- * Remove the registration for automatic connection of the specified channel
- * when a partition comes up.
- *
- * Before returning this xpc_disconnect() will wait for all connections on the
- * specified channel have been closed/torndown. So the caller can be assured
- * that they will not be receiving any more callouts from XPC to their
- * function registered via xpc_connect().
- *
- * Arguments:
- *
- * ch_number - channel # to unregister.
- */
-void
-xpc_disconnect(int ch_number)
-{
- struct xpc_registration *registration;
-
- DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);
-
- registration = &xpc_registrations[ch_number];
-
- /*
- * We've decided not to make this a down_interruptible(), since we
- * figured XPC's users will just turn around and call xpc_disconnect()
- * again anyways, so we might as well wait, if need be.
- */
- mutex_lock(&registration->mutex);
-
- /* if !XPC_CHANNEL_REGISTERED(ch_number) */
- if (registration->func == NULL) {
- mutex_unlock(&registration->mutex);
- return;
- }
-
- /* remove the connection registration for the specified channel */
- registration->func = NULL;
- registration->key = NULL;
- registration->nentries = 0;
- registration->entry_size = 0;
- registration->assigned_limit = 0;
- registration->idle_limit = 0;
-
- xpc_interface.disconnect(ch_number);
-
- mutex_unlock(&registration->mutex);
-
- return;
-}
-EXPORT_SYMBOL_GPL(xpc_disconnect);
-
-int __init
-xp_init(void)
-{
- enum xp_retval ret;
- int ch_number;
-
- /* initialize the connection registration mutex */
- for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++)
- mutex_init(&xpc_registrations[ch_number].mutex);
-
- if (is_shub())
- ret = xp_init_sn2();
- else if (is_uv())
- ret = xp_init_uv();
- else
- ret = 0;
-
- if (ret != xpSuccess)
- return ret;
-
- return 0;
-}
-
-module_init(xp_init);
-
-void __exit
-xp_exit(void)
-{
- if (is_shub())
- xp_exit_sn2();
- else if (is_uv())
- xp_exit_uv();
-}
-
-module_exit(xp_exit);
-
-MODULE_AUTHOR("Silicon Graphics, Inc.");
-MODULE_DESCRIPTION("Cross Partition (XP) base");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_nofault.S b/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_nofault.S
deleted file mode 100644
index e38d4331..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_nofault.S
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * The xp_nofault_PIOR function takes a pointer to a remote PIO register
- * and attempts to load and consume a value from it. This function
- * will be registered as a nofault code block. In the event that the
- * PIO read fails, the MCA handler will force the error to look
- * corrected and vector to the xp_error_PIOR which will return an error.
- *
- * The definition of "consumption" and the time it takes for an MCA
- * to surface is processor implementation specific. This code
- * is sufficient on Itanium through the Montvale processor family.
- * It may need to be adjusted for future processor implementations.
- *
- * extern int xp_nofault_PIOR(void *remote_register);
- */
-
- .global xp_nofault_PIOR
-xp_nofault_PIOR:
- mov r8=r0 // Stage a success return value
- ld8.acq r9=[r32];; // PIO Read the specified register
- adds r9=1,r9;; // Add to force consumption
- srlz.i;; // Allow time for MCA to surface
- br.ret.sptk.many b0;; // Return success
-
- .global xp_error_PIOR
-xp_error_PIOR:
- mov r8=1 // Return value of 1
- br.ret.sptk.many b0;; // Return failure
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_sn2.c b/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_sn2.c
deleted file mode 100644
index d8e463f8..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_sn2.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * Cross Partition (XP) sn2-based functions.
- *
- * Architecture specific implementation of common functions.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <asm/sn/bte.h>
-#include <asm/sn/sn_sal.h>
-#include "xp.h"
-
-/*
- * The export of xp_nofault_PIOR needs to happen here since it is defined
- * in drivers/misc/sgi-xp/xp_nofault.S. The target of the nofault read is
- * defined here.
- */
-EXPORT_SYMBOL_GPL(xp_nofault_PIOR);
-
-u64 xp_nofault_PIOR_target;
-EXPORT_SYMBOL_GPL(xp_nofault_PIOR_target);
-
-/*
- * Register a nofault code region which performs a cross-partition PIO read.
- * If the PIO read times out, the MCA handler will consume the error and
- * return to a kernel-provided instruction to indicate an error. This PIO read
- * exists because it is guaranteed to timeout if the destination is down
- * (amo operations do not timeout on at least some CPUs on Shubs <= v1.2,
- * which unfortunately we have to work around).
- */
-static enum xp_retval
-xp_register_nofault_code_sn2(void)
-{
- int ret;
- u64 func_addr;
- u64 err_func_addr;
-
- func_addr = *(u64 *)xp_nofault_PIOR;
- err_func_addr = *(u64 *)xp_error_PIOR;
- ret = sn_register_nofault_code(func_addr, err_func_addr, err_func_addr,
- 1, 1);
- if (ret != 0) {
- dev_err(xp, "can't register nofault code, error=%d\n", ret);
- return xpSalError;
- }
- /*
- * Setup the nofault PIO read target. (There is no special reason why
- * SH_IPI_ACCESS was selected.)
- */
- if (is_shub1())
- xp_nofault_PIOR_target = SH1_IPI_ACCESS;
- else if (is_shub2())
- xp_nofault_PIOR_target = SH2_IPI_ACCESS0;
-
- return xpSuccess;
-}
-
-static void
-xp_unregister_nofault_code_sn2(void)
-{
- u64 func_addr = *(u64 *)xp_nofault_PIOR;
- u64 err_func_addr = *(u64 *)xp_error_PIOR;
-
- /* unregister the PIO read nofault code region */
- (void)sn_register_nofault_code(func_addr, err_func_addr,
- err_func_addr, 1, 0);
-}
-
-/*
- * Convert a virtual memory address to a physical memory address.
- */
-static unsigned long
-xp_pa_sn2(void *addr)
-{
- return __pa(addr);
-}
-
-/*
- * Convert a global physical to a socket physical address.
- */
-static unsigned long
-xp_socket_pa_sn2(unsigned long gpa)
-{
- return gpa;
-}
-
-/*
- * Wrapper for bte_copy().
- *
- * dst_pa - physical address of the destination of the transfer.
- * src_pa - physical address of the source of the transfer.
- * len - number of bytes to transfer from source to destination.
- *
- * Note: xp_remote_memcpy_sn2() should never be called while holding a spinlock.
- */
-static enum xp_retval
-xp_remote_memcpy_sn2(unsigned long dst_pa, const unsigned long src_pa,
- size_t len)
-{
- bte_result_t ret;
-
- ret = bte_copy(src_pa, dst_pa, len, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
- if (ret == BTE_SUCCESS)
- return xpSuccess;
-
- if (is_shub2()) {
- dev_err(xp, "bte_copy() on shub2 failed, error=0x%x dst_pa="
- "0x%016lx src_pa=0x%016lx len=%ld\\n", ret, dst_pa,
- src_pa, len);
- } else {
- dev_err(xp, "bte_copy() failed, error=%d dst_pa=0x%016lx "
- "src_pa=0x%016lx len=%ld\\n", ret, dst_pa, src_pa, len);
- }
-
- return xpBteCopyError;
-}
-
-static int
-xp_cpu_to_nasid_sn2(int cpuid)
-{
- return cpuid_to_nasid(cpuid);
-}
-
-static enum xp_retval
-xp_expand_memprotect_sn2(unsigned long phys_addr, unsigned long size)
-{
- u64 nasid_array = 0;
- int ret;
-
- ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
- &nasid_array);
- if (ret != 0) {
- dev_err(xp, "sn_change_memprotect(,, "
- "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
- return xpSalError;
- }
- return xpSuccess;
-}
-
-static enum xp_retval
-xp_restrict_memprotect_sn2(unsigned long phys_addr, unsigned long size)
-{
- u64 nasid_array = 0;
- int ret;
-
- ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
- &nasid_array);
- if (ret != 0) {
- dev_err(xp, "sn_change_memprotect(,, "
- "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
- return xpSalError;
- }
- return xpSuccess;
-}
-
-enum xp_retval
-xp_init_sn2(void)
-{
- BUG_ON(!is_shub());
-
- xp_max_npartitions = XP_MAX_NPARTITIONS_SN2;
- xp_partition_id = sn_partition_id;
- xp_region_size = sn_region_size;
-
- xp_pa = xp_pa_sn2;
- xp_socket_pa = xp_socket_pa_sn2;
- xp_remote_memcpy = xp_remote_memcpy_sn2;
- xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
- xp_expand_memprotect = xp_expand_memprotect_sn2;
- xp_restrict_memprotect = xp_restrict_memprotect_sn2;
-
- return xp_register_nofault_code_sn2();
-}
-
-void
-xp_exit_sn2(void)
-{
- BUG_ON(!is_shub());
-
- xp_unregister_nofault_code_sn2();
-}
-
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_uv.c b/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_uv.c
deleted file mode 100644
index a0d09327..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xp_uv.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * Cross Partition (XP) uv-based functions.
- *
- * Architecture specific implementation of common functions.
- *
- */
-
-#include <linux/device.h>
-#include <asm/uv/uv_hub.h>
-#if defined CONFIG_X86_64
-#include <asm/uv/bios.h>
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
-#include <asm/sn/sn_sal.h>
-#endif
-#include "../sgi-gru/grukservices.h"
-#include "xp.h"
-
-/*
- * Convert a virtual memory address to a physical memory address.
- */
-static unsigned long
-xp_pa_uv(void *addr)
-{
- return uv_gpa(addr);
-}
-
-/*
- * Convert a global physical to socket physical address.
- */
-static unsigned long
-xp_socket_pa_uv(unsigned long gpa)
-{
- return uv_gpa_to_soc_phys_ram(gpa);
-}
-
-static enum xp_retval
-xp_remote_mmr_read(unsigned long dst_gpa, const unsigned long src_gpa,
- size_t len)
-{
- int ret;
- unsigned long *dst_va = __va(uv_gpa_to_soc_phys_ram(dst_gpa));
-
- BUG_ON(!uv_gpa_in_mmr_space(src_gpa));
- BUG_ON(len != 8);
-
- ret = gru_read_gpa(dst_va, src_gpa);
- if (ret == 0)
- return xpSuccess;
-
- dev_err(xp, "gru_read_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
- "len=%ld\n", dst_gpa, src_gpa, len);
- return xpGruCopyError;
-}
-
-
-static enum xp_retval
-xp_remote_memcpy_uv(unsigned long dst_gpa, const unsigned long src_gpa,
- size_t len)
-{
- int ret;
-
- if (uv_gpa_in_mmr_space(src_gpa))
- return xp_remote_mmr_read(dst_gpa, src_gpa, len);
-
- ret = gru_copy_gpa(dst_gpa, src_gpa, len);
- if (ret == 0)
- return xpSuccess;
-
- dev_err(xp, "gru_copy_gpa() failed, dst_gpa=0x%016lx src_gpa=0x%016lx "
- "len=%ld\n", dst_gpa, src_gpa, len);
- return xpGruCopyError;
-}
-
-static int
-xp_cpu_to_nasid_uv(int cpuid)
-{
- /* ??? Is this same as sn2 nasid in mach/part bitmaps set up by SAL? */
- return UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpuid));
-}
-
-static enum xp_retval
-xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
-{
- int ret;
-
-#if defined CONFIG_X86_64
- ret = uv_bios_change_memprotect(phys_addr, size, UV_MEMPROT_ALLOW_RW);
- if (ret != BIOS_STATUS_SUCCESS) {
- dev_err(xp, "uv_bios_change_memprotect(,, "
- "UV_MEMPROT_ALLOW_RW) failed, ret=%d\n", ret);
- return xpBiosError;
- }
-
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- u64 nasid_array;
-
- ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
- &nasid_array);
- if (ret != 0) {
- dev_err(xp, "sn_change_memprotect(,, "
- "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
- return xpSalError;
- }
-#else
- #error not a supported configuration
-#endif
- return xpSuccess;
-}
-
-static enum xp_retval
-xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
-{
- int ret;
-
-#if defined CONFIG_X86_64
- ret = uv_bios_change_memprotect(phys_addr, size,
- UV_MEMPROT_RESTRICT_ACCESS);
- if (ret != BIOS_STATUS_SUCCESS) {
- dev_err(xp, "uv_bios_change_memprotect(,, "
- "UV_MEMPROT_RESTRICT_ACCESS) failed, ret=%d\n", ret);
- return xpBiosError;
- }
-
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- u64 nasid_array;
-
- ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
- &nasid_array);
- if (ret != 0) {
- dev_err(xp, "sn_change_memprotect(,, "
- "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
- return xpSalError;
- }
-#else
- #error not a supported configuration
-#endif
- return xpSuccess;
-}
-
-enum xp_retval
-xp_init_uv(void)
-{
- BUG_ON(!is_uv());
-
- xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
- xp_partition_id = sn_partition_id;
- xp_region_size = sn_region_size;
-
- xp_pa = xp_pa_uv;
- xp_socket_pa = xp_socket_pa_uv;
- xp_remote_memcpy = xp_remote_memcpy_uv;
- xp_cpu_to_nasid = xp_cpu_to_nasid_uv;
- xp_expand_memprotect = xp_expand_memprotect_uv;
- xp_restrict_memprotect = xp_restrict_memprotect_uv;
-
- return xpSuccess;
-}
-
-void
-xp_exit_uv(void)
-{
- BUG_ON(!is_uv());
-}
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc.h b/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc.h
deleted file mode 100644
index b94d5f76..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc.h
+++ /dev/null
@@ -1,1004 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * Cross Partition Communication (XPC) structures and macros.
- */
-
-#ifndef _DRIVERS_MISC_SGIXP_XPC_H
-#define _DRIVERS_MISC_SGIXP_XPC_H
-
-#include <linux/wait.h>
-#include <linux/completion.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-#include "xp.h"
-
-/*
- * XPC Version numbers consist of a major and minor number. XPC can always
- * talk to versions with same major #, and never talk to versions with a
- * different major #.
- */
-#define _XPC_VERSION(_maj, _min) (((_maj) << 4) | ((_min) & 0xf))
-#define XPC_VERSION_MAJOR(_v) ((_v) >> 4)
-#define XPC_VERSION_MINOR(_v) ((_v) & 0xf)
-
-/* define frequency of the heartbeat and frequency how often it's checked */
-#define XPC_HB_DEFAULT_INTERVAL 5 /* incr HB every x secs */
-#define XPC_HB_CHECK_DEFAULT_INTERVAL 20 /* check HB every x secs */
-
-/* define the process name of HB checker and the CPU it is pinned to */
-#define XPC_HB_CHECK_THREAD_NAME "xpc_hb"
-#define XPC_HB_CHECK_CPU 0
-
-/* define the process name of the discovery thread */
-#define XPC_DISCOVERY_THREAD_NAME "xpc_discovery"
-
-/*
- * the reserved page
- *
- * SAL reserves one page of memory per partition for XPC. Though a full page
- * in length (16384 bytes), its starting address is not page aligned, but it
- * is cacheline aligned. The reserved page consists of the following:
- *
- * reserved page header
- *
- * The first two 64-byte cachelines of the reserved page contain the
- * header (struct xpc_rsvd_page). Before SAL initialization has completed,
- * SAL has set up the following fields of the reserved page header:
- * SAL_signature, SAL_version, SAL_partid, and SAL_nasids_size. The
- * other fields are set up by XPC. (xpc_rsvd_page points to the local
- * partition's reserved page.)
- *
- * part_nasids mask
- * mach_nasids mask
- *
- * SAL also sets up two bitmaps (or masks), one that reflects the actual
- * nasids in this partition (part_nasids), and the other that reflects
- * the actual nasids in the entire machine (mach_nasids). We're only
- * interested in the even numbered nasids (which contain the processors
- * and/or memory), so we only need half as many bits to represent the
- * nasids. When mapping nasid to bit in a mask (or bit to nasid) be sure
- * to either divide or multiply by 2. The part_nasids mask is located
- * starting at the first cacheline following the reserved page header. The
- * mach_nasids mask follows right after the part_nasids mask. The size in
- * bytes of each mask is reflected by the reserved page header field
- * 'SAL_nasids_size'. (Local partition's mask pointers are xpc_part_nasids
- * and xpc_mach_nasids.)
- *
- * vars (ia64-sn2 only)
- * vars part (ia64-sn2 only)
- *
- * Immediately following the mach_nasids mask are the XPC variables
- * required by other partitions. First are those that are generic to all
- * partitions (vars), followed on the next available cacheline by those
- * which are partition specific (vars part). These are setup by XPC.
- * (Local partition's vars pointers are xpc_vars and xpc_vars_part.)
- *
- * Note: Until 'ts_jiffies' is set non-zero, the partition XPC code has not been
- * initialized.
- */
-struct xpc_rsvd_page {
- u64 SAL_signature; /* SAL: unique signature */
- u64 SAL_version; /* SAL: version */
- short SAL_partid; /* SAL: partition ID */
- short max_npartitions; /* value of XPC_MAX_PARTITIONS */
- u8 version;
- u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */
- unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
- union {
- struct {
- unsigned long vars_pa; /* phys addr */
- } sn2;
- struct {
- unsigned long heartbeat_gpa; /* phys addr */
- unsigned long activate_gru_mq_desc_gpa; /* phys addr */
- } uv;
- } sn;
- u64 pad2[9]; /* align to last u64 in 2nd 64-byte cacheline */
- u64 SAL_nasids_size; /* SAL: size of each nasid mask in bytes */
-};
-
-#define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */
-
-/*
- * Define the structures by which XPC variables can be exported to other
- * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
- */
-
-/*
- * The following structure describes the partition generic variables
- * needed by other partitions in order to properly initialize.
- *
- * struct xpc_vars version number also applies to struct xpc_vars_part.
- * Changes to either structure and/or related functionality should be
- * reflected by incrementing either the major or minor version numbers
- * of struct xpc_vars.
- */
-struct xpc_vars_sn2 {
- u8 version;
- u64 heartbeat;
- DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
- u64 heartbeat_offline; /* if 0, heartbeat should be changing */
- int activate_IRQ_nasid;
- int activate_IRQ_phys_cpuid;
- unsigned long vars_part_pa;
- unsigned long amos_page_pa;/* paddr of page of amos from MSPEC driver */
- struct amo *amos_page; /* vaddr of page of amos from MSPEC driver */
-};
-
-#define XPC_V_VERSION _XPC_VERSION(3, 1) /* version 3.1 of the cross vars */
-
-/*
- * The following structure describes the per partition specific variables.
- *
- * An array of these structures, one per partition, will be defined. As a
- * partition becomes active XPC will copy the array entry corresponding to
- * itself from that partition. It is desirable that the size of this structure
- * evenly divides into a 128-byte cacheline, such that none of the entries in
- * this array crosses a 128-byte cacheline boundary. As it is now, each entry
- * occupies 64-bytes.
- */
-struct xpc_vars_part_sn2 {
- u64 magic;
-
- unsigned long openclose_args_pa; /* phys addr of open and close args */
- unsigned long GPs_pa; /* physical address of Get/Put values */
-
- unsigned long chctl_amo_pa; /* physical address of chctl flags' amo */
-
- int notify_IRQ_nasid; /* nasid of where to send notify IRQs */
- int notify_IRQ_phys_cpuid; /* CPUID of where to send notify IRQs */
-
- u8 nchannels; /* #of defined channels supported */
-
- u8 reserved[23]; /* pad to a full 64 bytes */
-};
-
-/*
- * The vars_part MAGIC numbers play a part in the first contact protocol.
- *
- * MAGIC1 indicates that the per partition specific variables for a remote
- * partition have been initialized by this partition.
- *
- * MAGIC2 indicates that this partition has pulled the remote partititions
- * per partition variables that pertain to this partition.
- */
-#define XPC_VP_MAGIC1_SN2 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */
-#define XPC_VP_MAGIC2_SN2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */
-
-/* the reserved page sizes and offsets */
-
-#define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
-#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2))
-
-#define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
- XPC_RP_HEADER_SIZE))
-#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
- xpc_nasid_mask_nlongs)
-#define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *) \
- (XPC_RP_MACH_NASIDS(_rp) + \
- xpc_nasid_mask_nlongs))
-
-
-/*
- * The following structure describes the partition's heartbeat info which
- * will be periodically read by other partitions to determine whether this
- * XPC is still 'alive'.
- */
-struct xpc_heartbeat_uv {
- unsigned long value;
- unsigned long offline; /* if 0, heartbeat should be changing */
-};
-
-/*
- * Info pertinent to a GRU message queue using a watch list for irq generation.
- */
-struct xpc_gru_mq_uv {
- void *address; /* address of GRU message queue */
- unsigned int order; /* size of GRU message queue as a power of 2 */
- int irq; /* irq raised when message is received in mq */
- int mmr_blade; /* blade where watchlist was allocated from */
- unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */
- unsigned long mmr_value; /* value of irq mmr located on mmr_blade */
- int watchlist_num; /* number of watchlist allocatd by BIOS */
- void *gru_mq_desc; /* opaque structure used by the GRU driver */
-};
-
-/*
- * The activate_mq is used to send/receive GRU messages that affect XPC's
- * partition active state and channel state. This is uv only.
- */
-struct xpc_activate_mq_msghdr_uv {
- unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
- short partid; /* sender's partid */
- u8 act_state; /* sender's act_state at time msg sent */
- u8 type; /* message's type */
- unsigned long rp_ts_jiffies; /* timestamp of sender's rp setup by XPC */
-};
-
-/* activate_mq defined message types */
-#define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV 0
-
-#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 1
-#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 2
-
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 3
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 4
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 5
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 6
-#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV 7
-
-#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 8
-#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 9
-
-struct xpc_activate_mq_msg_uv {
- struct xpc_activate_mq_msghdr_uv hdr;
-};
-
-struct xpc_activate_mq_msg_activate_req_uv {
- struct xpc_activate_mq_msghdr_uv hdr;
- unsigned long rp_gpa;
- unsigned long heartbeat_gpa;
- unsigned long activate_gru_mq_desc_gpa;
-};
-
-struct xpc_activate_mq_msg_deactivate_req_uv {
- struct xpc_activate_mq_msghdr_uv hdr;
- enum xp_retval reason;
-};
-
-struct xpc_activate_mq_msg_chctl_closerequest_uv {
- struct xpc_activate_mq_msghdr_uv hdr;
- short ch_number;
- enum xp_retval reason;
-};
-
-struct xpc_activate_mq_msg_chctl_closereply_uv {
- struct xpc_activate_mq_msghdr_uv hdr;
- short ch_number;
-};
-
-struct xpc_activate_mq_msg_chctl_openrequest_uv {
- struct xpc_activate_mq_msghdr_uv hdr;
- short ch_number;
- short entry_size; /* size of notify_mq's GRU messages */
- short local_nentries; /* ??? Is this needed? What is? */
-};
-
-struct xpc_activate_mq_msg_chctl_openreply_uv {
- struct xpc_activate_mq_msghdr_uv hdr;
- short ch_number;
- short remote_nentries; /* ??? Is this needed? What is? */
- short local_nentries; /* ??? Is this needed? What is? */
- unsigned long notify_gru_mq_desc_gpa;
-};
-
-struct xpc_activate_mq_msg_chctl_opencomplete_uv {
- struct xpc_activate_mq_msghdr_uv hdr;
- short ch_number;
-};
-
-/*
- * Functions registered by add_timer() or called by kernel_thread() only
- * allow for a single 64-bit argument. The following macros can be used to
- * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from
- * the passed argument.
- */
-#define XPC_PACK_ARGS(_arg1, _arg2) \
- ((((u64)_arg1) & 0xffffffff) | \
- ((((u64)_arg2) & 0xffffffff) << 32))
-
-#define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff)
-#define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)
-
-/*
- * Define a Get/Put value pair (pointers) used with a message queue.
- */
-struct xpc_gp_sn2 {
- s64 get; /* Get value */
- s64 put; /* Put value */
-};
-
-#define XPC_GP_SIZE \
- L1_CACHE_ALIGN(sizeof(struct xpc_gp_sn2) * XPC_MAX_NCHANNELS)
-
-/*
- * Define a structure that contains arguments associated with opening and
- * closing a channel.
- */
-struct xpc_openclose_args {
- u16 reason; /* reason why channel is closing */
- u16 entry_size; /* sizeof each message entry */
- u16 remote_nentries; /* #of message entries in remote msg queue */
- u16 local_nentries; /* #of message entries in local msg queue */
- unsigned long local_msgqueue_pa; /* phys addr of local message queue */
-};
-
-#define XPC_OPENCLOSE_ARGS_SIZE \
- L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
- XPC_MAX_NCHANNELS)
-
-
-/*
- * Structures to define a fifo singly-linked list.
- */
-
-struct xpc_fifo_entry_uv {
- struct xpc_fifo_entry_uv *next;
-};
-
-struct xpc_fifo_head_uv {
- struct xpc_fifo_entry_uv *first;
- struct xpc_fifo_entry_uv *last;
- spinlock_t lock;
- int n_entries;
-};
-
-/*
- * Define a sn2 styled message.
- *
- * A user-defined message resides in the payload area. The max size of the
- * payload is defined by the user via xpc_connect().
- *
- * The size of a message entry (within a message queue) must be a 128-byte
- * cacheline sized multiple in order to facilitate the BTE transfer of messages
- * from one message queue to another.
- */
-struct xpc_msg_sn2 {
- u8 flags; /* FOR XPC INTERNAL USE ONLY */
- u8 reserved[7]; /* FOR XPC INTERNAL USE ONLY */
- s64 number; /* FOR XPC INTERNAL USE ONLY */
-
- u64 payload; /* user defined portion of message */
-};
-
-/* struct xpc_msg_sn2 flags */
-
-#define XPC_M_SN2_DONE 0x01 /* msg has been received/consumed */
-#define XPC_M_SN2_READY 0x02 /* msg is ready to be sent */
-#define XPC_M_SN2_INTERRUPT 0x04 /* send interrupt when msg consumed */
-
-/*
- * The format of a uv XPC notify_mq GRU message is as follows:
- *
- * A user-defined message resides in the payload area. The max size of the
- * payload is defined by the user via xpc_connect().
- *
- * The size of a message (payload and header) sent via the GRU must be either 1
- * or 2 GRU_CACHE_LINE_BYTES in length.
- */
-
-struct xpc_notify_mq_msghdr_uv {
- union {
- unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
- struct xpc_fifo_entry_uv next; /* FOR XPC INTERNAL USE ONLY */
- } u;
- short partid; /* FOR XPC INTERNAL USE ONLY */
- u8 ch_number; /* FOR XPC INTERNAL USE ONLY */
- u8 size; /* FOR XPC INTERNAL USE ONLY */
- unsigned int msg_slot_number; /* FOR XPC INTERNAL USE ONLY */
-};
-
-struct xpc_notify_mq_msg_uv {
- struct xpc_notify_mq_msghdr_uv hdr;
- unsigned long payload;
-};
-
-/*
- * Define sn2's notify entry.
- *
- * This is used to notify a message's sender that their message was received
- * and consumed by the intended recipient.
- */
-struct xpc_notify_sn2 {
- u8 type; /* type of notification */
-
- /* the following two fields are only used if type == XPC_N_CALL */
- xpc_notify_func func; /* user's notify function */
- void *key; /* pointer to user's key */
-};
-
-/* struct xpc_notify_sn2 type of notification */
-
-#define XPC_N_CALL 0x01 /* notify function provided by user */
-
-/*
- * Define uv's version of the notify entry. It additionally is used to allocate
- * a msg slot on the remote partition into which is copied a sent message.
- */
-struct xpc_send_msg_slot_uv {
- struct xpc_fifo_entry_uv next;
- unsigned int msg_slot_number;
- xpc_notify_func func; /* user's notify function */
- void *key; /* pointer to user's key */
-};
-
-/*
- * Define the structure that manages all the stuff required by a channel. In
- * particular, they are used to manage the messages sent across the channel.
- *
- * This structure is private to a partition, and is NOT shared across the
- * partition boundary.
- *
- * There is an array of these structures for each remote partition. It is
- * allocated at the time a partition becomes active. The array contains one
- * of these structures for each potential channel connection to that partition.
- */
-
-/*
- * The following is sn2 only.
- *
- * Each channel structure manages two message queues (circular buffers).
- * They are allocated at the time a channel connection is made. One of
- * these message queues (local_msgqueue) holds the locally created messages
- * that are destined for the remote partition. The other of these message
- * queues (remote_msgqueue) is a locally cached copy of the remote partition's
- * own local_msgqueue.
- *
- * The following is a description of the Get/Put pointers used to manage these
- * two message queues. Consider the local_msgqueue to be on one partition
- * and the remote_msgqueue to be its cached copy on another partition. A
- * description of what each of the lettered areas contains is included.
- *
- *
- * local_msgqueue remote_msgqueue
- *
- * |/////////| |/////////|
- * w_remote_GP.get --> +---------+ |/////////|
- * | F | |/////////|
- * remote_GP.get --> +---------+ +---------+ <-- local_GP->get
- * | | | |
- * | | | E |
- * | | | |
- * | | +---------+ <-- w_local_GP.get
- * | B | |/////////|
- * | | |////D////|
- * | | |/////////|
- * | | +---------+ <-- w_remote_GP.put
- * | | |////C////|
- * local_GP->put --> +---------+ +---------+ <-- remote_GP.put
- * | | |/////////|
- * | A | |/////////|
- * | | |/////////|
- * w_local_GP.put --> +---------+ |/////////|
- * |/////////| |/////////|
- *
- *
- * ( remote_GP.[get|put] are cached copies of the remote
- * partition's local_GP->[get|put], and thus their values can
- * lag behind their counterparts on the remote partition. )
- *
- *
- * A - Messages that have been allocated, but have not yet been sent to the
- * remote partition.
- *
- * B - Messages that have been sent, but have not yet been acknowledged by the
- * remote partition as having been received.
- *
- * C - Area that needs to be prepared for the copying of sent messages, by
- * the clearing of the message flags of any previously received messages.
- *
- * D - Area into which sent messages are to be copied from the remote
- * partition's local_msgqueue and then delivered to their intended
- * recipients. [ To allow for a multi-message copy, another pointer
- * (next_msg_to_pull) has been added to keep track of the next message
- * number needing to be copied (pulled). It chases after w_remote_GP.put.
- * Any messages lying between w_local_GP.get and next_msg_to_pull have
- * been copied and are ready to be delivered. ]
- *
- * E - Messages that have been copied and delivered, but have not yet been
- * acknowledged by the recipient as having been received.
- *
- * F - Messages that have been acknowledged, but XPC has not yet notified the
- * sender that the message was received by its intended recipient.
- * This is also an area that needs to be prepared for the allocating of
- * new messages, by the clearing of the message flags of the acknowledged
- * messages.
- */
-
-struct xpc_channel_sn2 {
- struct xpc_openclose_args *local_openclose_args; /* args passed on */
- /* opening or closing of channel */
-
- void *local_msgqueue_base; /* base address of kmalloc'd space */
- struct xpc_msg_sn2 *local_msgqueue; /* local message queue */
- void *remote_msgqueue_base; /* base address of kmalloc'd space */
- struct xpc_msg_sn2 *remote_msgqueue; /* cached copy of remote */
- /* partition's local message queue */
- unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */
- /* local message queue */
-
- struct xpc_notify_sn2 *notify_queue;/* notify queue for messages sent */
-
- /* various flavors of local and remote Get/Put values */
-
- struct xpc_gp_sn2 *local_GP; /* local Get/Put values */
- struct xpc_gp_sn2 remote_GP; /* remote Get/Put values */
- struct xpc_gp_sn2 w_local_GP; /* working local Get/Put values */
- struct xpc_gp_sn2 w_remote_GP; /* working remote Get/Put values */
- s64 next_msg_to_pull; /* Put value of next msg to pull */
-
- struct mutex msg_to_pull_mutex; /* next msg to pull serialization */
-};
-
-struct xpc_channel_uv {
- void *cached_notify_gru_mq_desc; /* remote partition's notify mq's */
- /* gru mq descriptor */
-
- struct xpc_send_msg_slot_uv *send_msg_slots;
- void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */
- /* structure plus the user's payload */
-
- struct xpc_fifo_head_uv msg_slot_free_list;
- struct xpc_fifo_head_uv recv_msg_list; /* deliverable payloads */
-};
-
-struct xpc_channel {
- short partid; /* ID of remote partition connected */
- spinlock_t lock; /* lock for updating this structure */
- unsigned int flags; /* general flags */
-
- enum xp_retval reason; /* reason why channel is disconnect'g */
- int reason_line; /* line# disconnect initiated from */
-
- u16 number; /* channel # */
-
- u16 entry_size; /* sizeof each msg entry */
- u16 local_nentries; /* #of msg entries in local msg queue */
- u16 remote_nentries; /* #of msg entries in remote msg queue */
-
- atomic_t references; /* #of external references to queues */
-
- atomic_t n_on_msg_allocate_wq; /* #on msg allocation wait queue */
- wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */
-
- u8 delayed_chctl_flags; /* chctl flags received, but delayed */
- /* action until channel disconnected */
-
- atomic_t n_to_notify; /* #of msg senders to notify */
-
- xpc_channel_func func; /* user's channel function */
- void *key; /* pointer to user's key */
-
- struct completion wdisconnect_wait; /* wait for channel disconnect */
-
- /* kthread management related fields */
-
- atomic_t kthreads_assigned; /* #of kthreads assigned to channel */
- u32 kthreads_assigned_limit; /* limit on #of kthreads assigned */
- atomic_t kthreads_idle; /* #of kthreads idle waiting for work */
- u32 kthreads_idle_limit; /* limit on #of kthreads idle */
- atomic_t kthreads_active; /* #of kthreads actively working */
-
- wait_queue_head_t idle_wq; /* idle kthread wait queue */
-
- union {
- struct xpc_channel_sn2 sn2;
- struct xpc_channel_uv uv;
- } sn;
-
-} ____cacheline_aligned;
-
-/* struct xpc_channel flags */
-
-#define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */
-
-#define XPC_C_ROPENCOMPLETE 0x00000002 /* remote open channel complete */
-#define XPC_C_OPENCOMPLETE 0x00000004 /* local open channel complete */
-#define XPC_C_ROPENREPLY 0x00000008 /* remote open channel reply */
-#define XPC_C_OPENREPLY 0x00000010 /* local open channel reply */
-#define XPC_C_ROPENREQUEST 0x00000020 /* remote open channel request */
-#define XPC_C_OPENREQUEST 0x00000040 /* local open channel request */
-
-#define XPC_C_SETUP 0x00000080 /* channel's msgqueues are alloc'd */
-#define XPC_C_CONNECTEDCALLOUT 0x00000100 /* connected callout initiated */
-#define XPC_C_CONNECTEDCALLOUT_MADE \
- 0x00000200 /* connected callout completed */
-#define XPC_C_CONNECTED 0x00000400 /* local channel is connected */
-#define XPC_C_CONNECTING 0x00000800 /* channel is being connected */
-
-#define XPC_C_RCLOSEREPLY 0x00001000 /* remote close channel reply */
-#define XPC_C_CLOSEREPLY 0x00002000 /* local close channel reply */
-#define XPC_C_RCLOSEREQUEST 0x00004000 /* remote close channel request */
-#define XPC_C_CLOSEREQUEST 0x00008000 /* local close channel request */
-
-#define XPC_C_DISCONNECTED 0x00010000 /* channel is disconnected */
-#define XPC_C_DISCONNECTING 0x00020000 /* channel is being disconnected */
-#define XPC_C_DISCONNECTINGCALLOUT \
- 0x00040000 /* disconnecting callout initiated */
-#define XPC_C_DISCONNECTINGCALLOUT_MADE \
- 0x00080000 /* disconnecting callout completed */
-#define XPC_C_WDISCONNECT 0x00100000 /* waiting for channel disconnect */
-
-/*
- * The channel control flags (chctl) union consists of a 64-bit variable which
- * is divided up into eight bytes, ordered from right to left. Byte zero
- * pertains to channel 0, byte one to channel 1, and so on. Each channel's byte
- * can have one or more of the chctl flags set in it.
- */
-
-union xpc_channel_ctl_flags {
- u64 all_flags;
- u8 flags[XPC_MAX_NCHANNELS];
-};
-
-/* chctl flags */
-#define XPC_CHCTL_CLOSEREQUEST 0x01
-#define XPC_CHCTL_CLOSEREPLY 0x02
-#define XPC_CHCTL_OPENREQUEST 0x04
-#define XPC_CHCTL_OPENREPLY 0x08
-#define XPC_CHCTL_OPENCOMPLETE 0x10
-#define XPC_CHCTL_MSGREQUEST 0x20
-
-#define XPC_OPENCLOSE_CHCTL_FLAGS \
- (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
- XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \
- XPC_CHCTL_OPENCOMPLETE)
-#define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST
-
-static inline int
-xpc_any_openclose_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
-{
- int ch_number;
-
- for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
- if (chctl->flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS)
- return 1;
- }
- return 0;
-}
-
-static inline int
-xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
-{
- int ch_number;
-
- for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
- if (chctl->flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
- return 1;
- }
- return 0;
-}
-
-/*
- * Manage channels on a partition basis. There is one of these structures
- * for each partition (a partition will never utilize the structure that
- * represents itself).
- */
-
-struct xpc_partition_sn2 {
- unsigned long remote_amos_page_pa; /* paddr of partition's amos page */
- int activate_IRQ_nasid; /* active partition's act/deact nasid */
- int activate_IRQ_phys_cpuid; /* active part's act/deact phys cpuid */
-
- unsigned long remote_vars_pa; /* phys addr of partition's vars */
- unsigned long remote_vars_part_pa; /* paddr of partition's vars part */
- u8 remote_vars_version; /* version# of partition's vars */
-
- void *local_GPs_base; /* base address of kmalloc'd space */
- struct xpc_gp_sn2 *local_GPs; /* local Get/Put values */
- void *remote_GPs_base; /* base address of kmalloc'd space */
- struct xpc_gp_sn2 *remote_GPs; /* copy of remote partition's local */
- /* Get/Put values */
- unsigned long remote_GPs_pa; /* phys addr of remote partition's local */
- /* Get/Put values */
-
- void *local_openclose_args_base; /* base address of kmalloc'd space */
- struct xpc_openclose_args *local_openclose_args; /* local's args */
- unsigned long remote_openclose_args_pa; /* phys addr of remote's args */
-
- int notify_IRQ_nasid; /* nasid of where to send notify IRQs */
- int notify_IRQ_phys_cpuid; /* CPUID of where to send notify IRQs */
- char notify_IRQ_owner[8]; /* notify IRQ's owner's name */
-
- struct amo *remote_chctl_amo_va; /* addr of remote chctl flags' amo */
- struct amo *local_chctl_amo_va; /* address of chctl flags' amo */
-
- struct timer_list dropped_notify_IRQ_timer; /* dropped IRQ timer */
-};
-
-struct xpc_partition_uv {
- unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */
- struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */
- /* partition's heartbeat */
- unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */
- /* activate mq's gru mq */
- /* descriptor */
- void *cached_activate_gru_mq_desc; /* cached copy of partition's */
- /* activate mq's gru mq descriptor */
- struct mutex cached_activate_gru_mq_desc_mutex;
- spinlock_t flags_lock; /* protect updating of flags */
- unsigned int flags; /* general flags */
- u8 remote_act_state; /* remote partition's act_state */
- u8 act_state_req; /* act_state request from remote partition */
- enum xp_retval reason; /* reason for deactivate act_state request */
-};
-
-/* struct xpc_partition_uv flags */
-
-#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000001
-#define XPC_P_ENGAGED_UV 0x00000002
-
-/* struct xpc_partition_uv act_state change requests */
-
-#define XPC_P_ASR_ACTIVATE_UV 0x01
-#define XPC_P_ASR_REACTIVATE_UV 0x02
-#define XPC_P_ASR_DEACTIVATE_UV 0x03
-
-struct xpc_partition {
-
- /* XPC HB infrastructure */
-
- u8 remote_rp_version; /* version# of partition's rsvd pg */
- unsigned long remote_rp_ts_jiffies; /* timestamp when rsvd pg setup */
- unsigned long remote_rp_pa; /* phys addr of partition's rsvd pg */
- u64 last_heartbeat; /* HB at last read */
- u32 activate_IRQ_rcvd; /* IRQs since activation */
- spinlock_t act_lock; /* protect updating of act_state */
- u8 act_state; /* from XPC HB viewpoint */
- enum xp_retval reason; /* reason partition is deactivating */
- int reason_line; /* line# deactivation initiated from */
-
- unsigned long disengage_timeout; /* timeout in jiffies */
- struct timer_list disengage_timer;
-
- /* XPC infrastructure referencing and teardown control */
-
- u8 setup_state; /* infrastructure setup state */
- wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */
- atomic_t references; /* #of references to infrastructure */
-
- u8 nchannels; /* #of defined channels supported */
- atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */
- atomic_t nchannels_engaged; /* #of channels engaged with remote part */
- struct xpc_channel *channels; /* array of channel structures */
-
- /* fields used for managing channel avialability and activity */
-
- union xpc_channel_ctl_flags chctl; /* chctl flags yet to be processed */
- spinlock_t chctl_lock; /* chctl flags lock */
-
- void *remote_openclose_args_base; /* base address of kmalloc'd space */
- struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
- /* args */
-
- /* channel manager related fields */
-
- atomic_t channel_mgr_requests; /* #of requests to activate chan mgr */
- wait_queue_head_t channel_mgr_wq; /* channel mgr's wait queue */
-
- union {
- struct xpc_partition_sn2 sn2;
- struct xpc_partition_uv uv;
- } sn;
-
-} ____cacheline_aligned;
-
-struct xpc_arch_operations {
- int (*setup_partitions) (void);
- void (*teardown_partitions) (void);
- void (*process_activate_IRQ_rcvd) (void);
- enum xp_retval (*get_partition_rsvd_page_pa)
- (void *, u64 *, unsigned long *, size_t *);
- int (*setup_rsvd_page) (struct xpc_rsvd_page *);
-
- void (*allow_hb) (short);
- void (*disallow_hb) (short);
- void (*disallow_all_hbs) (void);
- void (*increment_heartbeat) (void);
- void (*offline_heartbeat) (void);
- void (*online_heartbeat) (void);
- void (*heartbeat_init) (void);
- void (*heartbeat_exit) (void);
- enum xp_retval (*get_remote_heartbeat) (struct xpc_partition *);
-
- void (*request_partition_activation) (struct xpc_rsvd_page *,
- unsigned long, int);
- void (*request_partition_reactivation) (struct xpc_partition *);
- void (*request_partition_deactivation) (struct xpc_partition *);
- void (*cancel_partition_deactivation_request) (struct xpc_partition *);
- enum xp_retval (*setup_ch_structures) (struct xpc_partition *);
- void (*teardown_ch_structures) (struct xpc_partition *);
-
- enum xp_retval (*make_first_contact) (struct xpc_partition *);
-
- u64 (*get_chctl_all_flags) (struct xpc_partition *);
- void (*send_chctl_closerequest) (struct xpc_channel *, unsigned long *);
- void (*send_chctl_closereply) (struct xpc_channel *, unsigned long *);
- void (*send_chctl_openrequest) (struct xpc_channel *, unsigned long *);
- void (*send_chctl_openreply) (struct xpc_channel *, unsigned long *);
- void (*send_chctl_opencomplete) (struct xpc_channel *, unsigned long *);
- void (*process_msg_chctl_flags) (struct xpc_partition *, int);
-
- enum xp_retval (*save_remote_msgqueue_pa) (struct xpc_channel *,
- unsigned long);
-
- enum xp_retval (*setup_msg_structures) (struct xpc_channel *);
- void (*teardown_msg_structures) (struct xpc_channel *);
-
- void (*indicate_partition_engaged) (struct xpc_partition *);
- void (*indicate_partition_disengaged) (struct xpc_partition *);
- void (*assume_partition_disengaged) (short);
- int (*partition_engaged) (short);
- int (*any_partition_engaged) (void);
-
- int (*n_of_deliverable_payloads) (struct xpc_channel *);
- enum xp_retval (*send_payload) (struct xpc_channel *, u32, void *,
- u16, u8, xpc_notify_func, void *);
- void *(*get_deliverable_payload) (struct xpc_channel *);
- void (*received_payload) (struct xpc_channel *, void *);
- void (*notify_senders_of_disconnect) (struct xpc_channel *);
-};
-
-/* struct xpc_partition act_state values (for XPC HB) */
-
-#define XPC_P_AS_INACTIVE 0x00 /* partition is not active */
-#define XPC_P_AS_ACTIVATION_REQ 0x01 /* created thread to activate */
-#define XPC_P_AS_ACTIVATING 0x02 /* activation thread started */
-#define XPC_P_AS_ACTIVE 0x03 /* xpc_partition_up() was called */
-#define XPC_P_AS_DEACTIVATING 0x04 /* partition deactivation initiated */
-
-#define XPC_DEACTIVATE_PARTITION(_p, _reason) \
- xpc_deactivate_partition(__LINE__, (_p), (_reason))
-
-/* struct xpc_partition setup_state values */
-
-#define XPC_P_SS_UNSET 0x00 /* infrastructure was never setup */
-#define XPC_P_SS_SETUP 0x01 /* infrastructure is setup */
-#define XPC_P_SS_WTEARDOWN 0x02 /* waiting to teardown infrastructure */
-#define XPC_P_SS_TORNDOWN 0x03 /* infrastructure is torndown */
-
-/*
- * struct xpc_partition_sn2's dropped notify IRQ timer is set to wait the
- * following interval #of seconds before checking for dropped notify IRQs.
- * These can occur whenever an IRQ's associated amo write doesn't complete
- * until after the IRQ was received.
- */
-#define XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL (0.25 * HZ)
-
-/* number of seconds to wait for other partitions to disengage */
-#define XPC_DISENGAGE_DEFAULT_TIMELIMIT 90
-
-/* interval in seconds to print 'waiting deactivation' messages */
-#define XPC_DEACTIVATE_PRINTMSG_INTERVAL 10
-
-#define XPC_PARTID(_p) ((short)((_p) - &xpc_partitions[0]))
-
-/* found in xp_main.c */
-extern struct xpc_registration xpc_registrations[];
-
-/* found in xpc_main.c */
-extern struct device *xpc_part;
-extern struct device *xpc_chan;
-extern struct xpc_arch_operations xpc_arch_ops;
-extern int xpc_disengage_timelimit;
-extern int xpc_disengage_timedout;
-extern int xpc_activate_IRQ_rcvd;
-extern spinlock_t xpc_activate_IRQ_rcvd_lock;
-extern wait_queue_head_t xpc_activate_IRQ_wq;
-extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
-extern void xpc_activate_partition(struct xpc_partition *);
-extern void xpc_activate_kthreads(struct xpc_channel *, int);
-extern void xpc_create_kthreads(struct xpc_channel *, int, int);
-extern void xpc_disconnect_wait(int);
-
-/* found in xpc_sn2.c */
-extern int xpc_init_sn2(void);
-extern void xpc_exit_sn2(void);
-
-/* found in xpc_uv.c */
-extern int xpc_init_uv(void);
-extern void xpc_exit_uv(void);
-
-/* found in xpc_partition.c */
-extern int xpc_exiting;
-extern int xpc_nasid_mask_nlongs;
-extern struct xpc_rsvd_page *xpc_rsvd_page;
-extern unsigned long *xpc_mach_nasids;
-extern struct xpc_partition *xpc_partitions;
-extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
-extern int xpc_setup_rsvd_page(void);
-extern void xpc_teardown_rsvd_page(void);
-extern int xpc_identify_activate_IRQ_sender(void);
-extern int xpc_partition_disengaged(struct xpc_partition *);
-extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
-extern void xpc_mark_partition_inactive(struct xpc_partition *);
-extern void xpc_discovery(void);
-extern enum xp_retval xpc_get_remote_rp(int, unsigned long *,
- struct xpc_rsvd_page *,
- unsigned long *);
-extern void xpc_deactivate_partition(const int, struct xpc_partition *,
- enum xp_retval);
-extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
-
-/* found in xpc_channel.c */
-extern void xpc_initiate_connect(int);
-extern void xpc_initiate_disconnect(int);
-extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
-extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16);
-extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
- xpc_notify_func, void *);
-extern void xpc_initiate_received(short, int, void *);
-extern void xpc_process_sent_chctl_flags(struct xpc_partition *);
-extern void xpc_connected_callout(struct xpc_channel *);
-extern void xpc_deliver_payload(struct xpc_channel *);
-extern void xpc_disconnect_channel(const int, struct xpc_channel *,
- enum xp_retval, unsigned long *);
-extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
-extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
-
-static inline void
-xpc_wakeup_channel_mgr(struct xpc_partition *part)
-{
- if (atomic_inc_return(&part->channel_mgr_requests) == 1)
- wake_up(&part->channel_mgr_wq);
-}
-
-/*
- * These next two inlines are used to keep us from tearing down a channel's
- * msg queues while a thread may be referencing them.
- */
-static inline void
-xpc_msgqueue_ref(struct xpc_channel *ch)
-{
- atomic_inc(&ch->references);
-}
-
-static inline void
-xpc_msgqueue_deref(struct xpc_channel *ch)
-{
- s32 refs = atomic_dec_return(&ch->references);
-
- DBUG_ON(refs < 0);
- if (refs == 0)
- xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
-}
-
-#define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
- xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
-
-/*
- * These two inlines are used to keep us from tearing down a partition's
- * setup infrastructure while a thread may be referencing it.
- */
-static inline void
-xpc_part_deref(struct xpc_partition *part)
-{
- s32 refs = atomic_dec_return(&part->references);
-
- DBUG_ON(refs < 0);
- if (refs == 0 && part->setup_state == XPC_P_SS_WTEARDOWN)
- wake_up(&part->teardown_wq);
-}
-
-static inline int
-xpc_part_ref(struct xpc_partition *part)
-{
- int setup;
-
- atomic_inc(&part->references);
- setup = (part->setup_state == XPC_P_SS_SETUP);
- if (!setup)
- xpc_part_deref(part);
-
- return setup;
-}
-
-/*
- * The following macro is to be used for the setting of the reason and
- * reason_line fields in both the struct xpc_channel and struct xpc_partition
- * structures.
- */
-#define XPC_SET_REASON(_p, _reason, _line) \
- { \
- (_p)->reason = _reason; \
- (_p)->reason_line = _line; \
- }
-
-#endif /* _DRIVERS_MISC_SGIXP_XPC_H */
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_channel.c b/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_channel.c
deleted file mode 100644
index 652593fc..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_channel.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * Cross Partition Communication (XPC) channel support.
- *
- * This is the part of XPC that manages the channels and
- * sends/receives messages across them to/from other partitions.
- *
- */
-
-#include <linux/device.h>
-#include "xpc.h"
-
-/*
- * Process a connect message from a remote partition.
- *
- * Note: xpc_process_connect() is expecting to be called with the
- * spin_lock_irqsave held and will leave it locked upon return.
- */
-static void
-xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- enum xp_retval ret;
-
- DBUG_ON(!spin_is_locked(&ch->lock));
-
- if (!(ch->flags & XPC_C_OPENREQUEST) ||
- !(ch->flags & XPC_C_ROPENREQUEST)) {
- /* nothing more to do for now */
- return;
- }
- DBUG_ON(!(ch->flags & XPC_C_CONNECTING));
-
- if (!(ch->flags & XPC_C_SETUP)) {
- spin_unlock_irqrestore(&ch->lock, *irq_flags);
- ret = xpc_arch_ops.setup_msg_structures(ch);
- spin_lock_irqsave(&ch->lock, *irq_flags);
-
- if (ret != xpSuccess)
- XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags);
- else
- ch->flags |= XPC_C_SETUP;
-
- if (ch->flags & XPC_C_DISCONNECTING)
- return;
- }
-
- if (!(ch->flags & XPC_C_OPENREPLY)) {
- ch->flags |= XPC_C_OPENREPLY;
- xpc_arch_ops.send_chctl_openreply(ch, irq_flags);
- }
-
- if (!(ch->flags & XPC_C_ROPENREPLY))
- return;
-
- if (!(ch->flags & XPC_C_OPENCOMPLETE)) {
- ch->flags |= (XPC_C_OPENCOMPLETE | XPC_C_CONNECTED);
- xpc_arch_ops.send_chctl_opencomplete(ch, irq_flags);
- }
-
- if (!(ch->flags & XPC_C_ROPENCOMPLETE))
- return;
-
- dev_info(xpc_chan, "channel %d to partition %d connected\n",
- ch->number, ch->partid);
-
- ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */
-}
-
-/*
- * spin_lock_irqsave() is expected to be held on entry.
- */
-static void
-xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- struct xpc_partition *part = &xpc_partitions[ch->partid];
- u32 channel_was_connected = (ch->flags & XPC_C_WASCONNECTED);
-
- DBUG_ON(!spin_is_locked(&ch->lock));
-
- if (!(ch->flags & XPC_C_DISCONNECTING))
- return;
-
- DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
-
- /* make sure all activity has settled down first */
-
- if (atomic_read(&ch->kthreads_assigned) > 0 ||
- atomic_read(&ch->references) > 0) {
- return;
- }
- DBUG_ON((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
- !(ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE));
-
- if (part->act_state == XPC_P_AS_DEACTIVATING) {
- /* can't proceed until the other side disengages from us */
- if (xpc_arch_ops.partition_engaged(ch->partid))
- return;
-
- } else {
-
- /* as long as the other side is up do the full protocol */
-
- if (!(ch->flags & XPC_C_RCLOSEREQUEST))
- return;
-
- if (!(ch->flags & XPC_C_CLOSEREPLY)) {
- ch->flags |= XPC_C_CLOSEREPLY;
- xpc_arch_ops.send_chctl_closereply(ch, irq_flags);
- }
-
- if (!(ch->flags & XPC_C_RCLOSEREPLY))
- return;
- }
-
- /* wake those waiting for notify completion */
- if (atomic_read(&ch->n_to_notify) > 0) {
- /* we do callout while holding ch->lock, callout can't block */
- xpc_arch_ops.notify_senders_of_disconnect(ch);
- }
-
- /* both sides are disconnected now */
-
- if (ch->flags & XPC_C_DISCONNECTINGCALLOUT_MADE) {
- spin_unlock_irqrestore(&ch->lock, *irq_flags);
- xpc_disconnect_callout(ch, xpDisconnected);
- spin_lock_irqsave(&ch->lock, *irq_flags);
- }
-
- DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
-
- /* it's now safe to free the channel's message queues */
- xpc_arch_ops.teardown_msg_structures(ch);
-
- ch->func = NULL;
- ch->key = NULL;
- ch->entry_size = 0;
- ch->local_nentries = 0;
- ch->remote_nentries = 0;
- ch->kthreads_assigned_limit = 0;
- ch->kthreads_idle_limit = 0;
-
- /*
- * Mark the channel disconnected and clear all other flags, including
- * XPC_C_SETUP (because of call to
- * xpc_arch_ops.teardown_msg_structures()) but not including
- * XPC_C_WDISCONNECT (if it was set).
- */
- ch->flags = (XPC_C_DISCONNECTED | (ch->flags & XPC_C_WDISCONNECT));
-
- atomic_dec(&part->nchannels_active);
-
- if (channel_was_connected) {
- dev_info(xpc_chan, "channel %d to partition %d disconnected, "
- "reason=%d\n", ch->number, ch->partid, ch->reason);
- }
-
- if (ch->flags & XPC_C_WDISCONNECT) {
- /* we won't lose the CPU since we're holding ch->lock */
- complete(&ch->wdisconnect_wait);
- } else if (ch->delayed_chctl_flags) {
- if (part->act_state != XPC_P_AS_DEACTIVATING) {
- /* time to take action on any delayed chctl flags */
- spin_lock(&part->chctl_lock);
- part->chctl.flags[ch->number] |=
- ch->delayed_chctl_flags;
- spin_unlock(&part->chctl_lock);
- }
- ch->delayed_chctl_flags = 0;
- }
-}
-
-/*
- * Process a change in the channel's remote connection state.
- */
-static void
-xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number,
- u8 chctl_flags)
-{
- unsigned long irq_flags;
- struct xpc_openclose_args *args =
- &part->remote_openclose_args[ch_number];
- struct xpc_channel *ch = &part->channels[ch_number];
- enum xp_retval reason;
- enum xp_retval ret;
- int create_kthread = 0;
-
- spin_lock_irqsave(&ch->lock, irq_flags);
-
-again:
-
- if ((ch->flags & XPC_C_DISCONNECTED) &&
- (ch->flags & XPC_C_WDISCONNECT)) {
- /*
- * Delay processing chctl flags until thread waiting disconnect
- * has had a chance to see that the channel is disconnected.
- */
- ch->delayed_chctl_flags |= chctl_flags;
- goto out;
- }
-
- if (chctl_flags & XPC_CHCTL_CLOSEREQUEST) {
-
- dev_dbg(xpc_chan, "XPC_CHCTL_CLOSEREQUEST (reason=%d) received "
- "from partid=%d, channel=%d\n", args->reason,
- ch->partid, ch->number);
-
- /*
- * If RCLOSEREQUEST is set, we're probably waiting for
- * RCLOSEREPLY. We should find it and a ROPENREQUEST packed
- * with this RCLOSEREQUEST in the chctl_flags.
- */
-
- if (ch->flags & XPC_C_RCLOSEREQUEST) {
- DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING));
- DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
- DBUG_ON(!(ch->flags & XPC_C_CLOSEREPLY));
- DBUG_ON(ch->flags & XPC_C_RCLOSEREPLY);
-
- DBUG_ON(!(chctl_flags & XPC_CHCTL_CLOSEREPLY));
- chctl_flags &= ~XPC_CHCTL_CLOSEREPLY;
- ch->flags |= XPC_C_RCLOSEREPLY;
-
- /* both sides have finished disconnecting */
- xpc_process_disconnect(ch, &irq_flags);
- DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
- goto again;
- }
-
- if (ch->flags & XPC_C_DISCONNECTED) {
- if (!(chctl_flags & XPC_CHCTL_OPENREQUEST)) {
- if (part->chctl.flags[ch_number] &
- XPC_CHCTL_OPENREQUEST) {
-
- DBUG_ON(ch->delayed_chctl_flags != 0);
- spin_lock(&part->chctl_lock);
- part->chctl.flags[ch_number] |=
- XPC_CHCTL_CLOSEREQUEST;
- spin_unlock(&part->chctl_lock);
- }
- goto out;
- }
-
- XPC_SET_REASON(ch, 0, 0);
- ch->flags &= ~XPC_C_DISCONNECTED;
-
- atomic_inc(&part->nchannels_active);
- ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST);
- }
-
- chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY |
- XPC_CHCTL_OPENCOMPLETE);
-
- /*
- * The meaningful CLOSEREQUEST connection state fields are:
- * reason = reason connection is to be closed
- */
-
- ch->flags |= XPC_C_RCLOSEREQUEST;
-
- if (!(ch->flags & XPC_C_DISCONNECTING)) {
- reason = args->reason;
- if (reason <= xpSuccess || reason > xpUnknownReason)
- reason = xpUnknownReason;
- else if (reason == xpUnregistering)
- reason = xpOtherUnregistering;
-
- XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
-
- DBUG_ON(chctl_flags & XPC_CHCTL_CLOSEREPLY);
- goto out;
- }
-
- xpc_process_disconnect(ch, &irq_flags);
- }
-
- if (chctl_flags & XPC_CHCTL_CLOSEREPLY) {
-
- dev_dbg(xpc_chan, "XPC_CHCTL_CLOSEREPLY received from partid="
- "%d, channel=%d\n", ch->partid, ch->number);
-
- if (ch->flags & XPC_C_DISCONNECTED) {
- DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING);
- goto out;
- }
-
- DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
-
- if (!(ch->flags & XPC_C_RCLOSEREQUEST)) {
- if (part->chctl.flags[ch_number] &
- XPC_CHCTL_CLOSEREQUEST) {
-
- DBUG_ON(ch->delayed_chctl_flags != 0);
- spin_lock(&part->chctl_lock);
- part->chctl.flags[ch_number] |=
- XPC_CHCTL_CLOSEREPLY;
- spin_unlock(&part->chctl_lock);
- }
- goto out;
- }
-
- ch->flags |= XPC_C_RCLOSEREPLY;
-
- if (ch->flags & XPC_C_CLOSEREPLY) {
- /* both sides have finished disconnecting */
- xpc_process_disconnect(ch, &irq_flags);
- }
- }
-
- if (chctl_flags & XPC_CHCTL_OPENREQUEST) {
-
- dev_dbg(xpc_chan, "XPC_CHCTL_OPENREQUEST (entry_size=%d, "
- "local_nentries=%d) received from partid=%d, "
- "channel=%d\n", args->entry_size, args->local_nentries,
- ch->partid, ch->number);
-
- if (part->act_state == XPC_P_AS_DEACTIVATING ||
- (ch->flags & XPC_C_ROPENREQUEST)) {
- goto out;
- }
-
- if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) {
- ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST;
- goto out;
- }
- DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED |
- XPC_C_OPENREQUEST)));
- DBUG_ON(ch->flags & (XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
- XPC_C_OPENREPLY | XPC_C_CONNECTED));
-
- /*
- * The meaningful OPENREQUEST connection state fields are:
- * entry_size = size of channel's messages in bytes
- * local_nentries = remote partition's local_nentries
- */
- if (args->entry_size == 0 || args->local_nentries == 0) {
- /* assume OPENREQUEST was delayed by mistake */
- goto out;
- }
-
- ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING);
- ch->remote_nentries = args->local_nentries;
-
- if (ch->flags & XPC_C_OPENREQUEST) {
- if (args->entry_size != ch->entry_size) {
- XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
- &irq_flags);
- goto out;
- }
- } else {
- ch->entry_size = args->entry_size;
-
- XPC_SET_REASON(ch, 0, 0);
- ch->flags &= ~XPC_C_DISCONNECTED;
-
- atomic_inc(&part->nchannels_active);
- }
-
- xpc_process_connect(ch, &irq_flags);
- }
-
- if (chctl_flags & XPC_CHCTL_OPENREPLY) {
-
- dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY (local_msgqueue_pa="
- "0x%lx, local_nentries=%d, remote_nentries=%d) "
- "received from partid=%d, channel=%d\n",
- args->local_msgqueue_pa, args->local_nentries,
- args->remote_nentries, ch->partid, ch->number);
-
- if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
- goto out;
-
- if (!(ch->flags & XPC_C_OPENREQUEST)) {
- XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
- &irq_flags);
- goto out;
- }
-
- DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
- DBUG_ON(ch->flags & XPC_C_CONNECTED);
-
- /*
- * The meaningful OPENREPLY connection state fields are:
- * local_msgqueue_pa = physical address of remote
- * partition's local_msgqueue
- * local_nentries = remote partition's local_nentries
- * remote_nentries = remote partition's remote_nentries
- */
- DBUG_ON(args->local_msgqueue_pa == 0);
- DBUG_ON(args->local_nentries == 0);
- DBUG_ON(args->remote_nentries == 0);
-
- ret = xpc_arch_ops.save_remote_msgqueue_pa(ch,
- args->local_msgqueue_pa);
- if (ret != xpSuccess) {
- XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags);
- goto out;
- }
- ch->flags |= XPC_C_ROPENREPLY;
-
- if (args->local_nentries < ch->remote_nentries) {
- dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new "
- "remote_nentries=%d, old remote_nentries=%d, "
- "partid=%d, channel=%d\n",
- args->local_nentries, ch->remote_nentries,
- ch->partid, ch->number);
-
- ch->remote_nentries = args->local_nentries;
- }
- if (args->remote_nentries < ch->local_nentries) {
- dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new "
- "local_nentries=%d, old local_nentries=%d, "
- "partid=%d, channel=%d\n",
- args->remote_nentries, ch->local_nentries,
- ch->partid, ch->number);
-
- ch->local_nentries = args->remote_nentries;
- }
-
- xpc_process_connect(ch, &irq_flags);
- }
-
- if (chctl_flags & XPC_CHCTL_OPENCOMPLETE) {
-
- dev_dbg(xpc_chan, "XPC_CHCTL_OPENCOMPLETE received from "
- "partid=%d, channel=%d\n", ch->partid, ch->number);
-
- if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
- goto out;
-
- if (!(ch->flags & XPC_C_OPENREQUEST) ||
- !(ch->flags & XPC_C_OPENREPLY)) {
- XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError,
- &irq_flags);
- goto out;
- }
-
- DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST));
- DBUG_ON(!(ch->flags & XPC_C_ROPENREPLY));
- DBUG_ON(!(ch->flags & XPC_C_CONNECTED));
-
- ch->flags |= XPC_C_ROPENCOMPLETE;
-
- xpc_process_connect(ch, &irq_flags);
- create_kthread = 1;
- }
-
-out:
- spin_unlock_irqrestore(&ch->lock, irq_flags);
-
- if (create_kthread)
- xpc_create_kthreads(ch, 1, 0);
-}
-
-/*
- * Attempt to establish a channel connection to a remote partition.
- */
-static enum xp_retval
-xpc_connect_channel(struct xpc_channel *ch)
-{
- unsigned long irq_flags;
- struct xpc_registration *registration = &xpc_registrations[ch->number];
-
- if (mutex_trylock(&registration->mutex) == 0)
- return xpRetry;
-
- if (!XPC_CHANNEL_REGISTERED(ch->number)) {
- mutex_unlock(&registration->mutex);
- return xpUnregistered;
- }
-
- spin_lock_irqsave(&ch->lock, irq_flags);
-
- DBUG_ON(ch->flags & XPC_C_CONNECTED);
- DBUG_ON(ch->flags & XPC_C_OPENREQUEST);
-
- if (ch->flags & XPC_C_DISCONNECTING) {
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- mutex_unlock(&registration->mutex);
- return ch->reason;
- }
-
- /* add info from the channel connect registration to the channel */
-
- ch->kthreads_assigned_limit = registration->assigned_limit;
- ch->kthreads_idle_limit = registration->idle_limit;
- DBUG_ON(atomic_read(&ch->kthreads_assigned) != 0);
- DBUG_ON(atomic_read(&ch->kthreads_idle) != 0);
- DBUG_ON(atomic_read(&ch->kthreads_active) != 0);
-
- ch->func = registration->func;
- DBUG_ON(registration->func == NULL);
- ch->key = registration->key;
-
- ch->local_nentries = registration->nentries;
-
- if (ch->flags & XPC_C_ROPENREQUEST) {
- if (registration->entry_size != ch->entry_size) {
- /* the local and remote sides aren't the same */
-
- /*
- * Because XPC_DISCONNECT_CHANNEL() can block we're
- * forced to up the registration sema before we unlock
- * the channel lock. But that's okay here because we're
- * done with the part that required the registration
- * sema. XPC_DISCONNECT_CHANNEL() requires that the
- * channel lock be locked and will unlock and relock
- * the channel lock as needed.
- */
- mutex_unlock(&registration->mutex);
- XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes,
- &irq_flags);
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return xpUnequalMsgSizes;
- }
- } else {
- ch->entry_size = registration->entry_size;
-
- XPC_SET_REASON(ch, 0, 0);
- ch->flags &= ~XPC_C_DISCONNECTED;
-
- atomic_inc(&xpc_partitions[ch->partid].nchannels_active);
- }
-
- mutex_unlock(&registration->mutex);
-
- /* initiate the connection */
-
- ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
- xpc_arch_ops.send_chctl_openrequest(ch, &irq_flags);
-
- xpc_process_connect(ch, &irq_flags);
-
- spin_unlock_irqrestore(&ch->lock, irq_flags);
-
- return xpSuccess;
-}
-
-void
-xpc_process_sent_chctl_flags(struct xpc_partition *part)
-{
- unsigned long irq_flags;
- union xpc_channel_ctl_flags chctl;
- struct xpc_channel *ch;
- int ch_number;
- u32 ch_flags;
-
- chctl.all_flags = xpc_arch_ops.get_chctl_all_flags(part);
-
- /*
- * Initiate channel connections for registered channels.
- *
- * For each connected channel that has pending messages activate idle
- * kthreads and/or create new kthreads as needed.
- */
-
- for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
- ch = &part->channels[ch_number];
-
- /*
- * Process any open or close related chctl flags, and then deal
- * with connecting or disconnecting the channel as required.
- */
-
- if (chctl.flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS) {
- xpc_process_openclose_chctl_flags(part, ch_number,
- chctl.flags[ch_number]);
- }
-
- ch_flags = ch->flags; /* need an atomic snapshot of flags */
-
- if (ch_flags & XPC_C_DISCONNECTING) {
- spin_lock_irqsave(&ch->lock, irq_flags);
- xpc_process_disconnect(ch, &irq_flags);
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- continue;
- }
-
- if (part->act_state == XPC_P_AS_DEACTIVATING)
- continue;
-
- if (!(ch_flags & XPC_C_CONNECTED)) {
- if (!(ch_flags & XPC_C_OPENREQUEST)) {
- DBUG_ON(ch_flags & XPC_C_SETUP);
- (void)xpc_connect_channel(ch);
- }
- continue;
- }
-
- /*
- * Process any message related chctl flags, this may involve
- * the activation of kthreads to deliver any pending messages
- * sent from the other partition.
- */
-
- if (chctl.flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
- xpc_arch_ops.process_msg_chctl_flags(part, ch_number);
- }
-}
-
-/*
- * XPC's heartbeat code calls this function to inform XPC that a partition is
- * going down. XPC responds by tearing down the XPartition Communication
- * infrastructure used for the just downed partition.
- *
- * XPC's heartbeat code will never call this function and xpc_partition_up()
- * at the same time. Nor will it ever make multiple calls to either function
- * at the same time.
- */
-void
-xpc_partition_going_down(struct xpc_partition *part, enum xp_retval reason)
-{
- unsigned long irq_flags;
- int ch_number;
- struct xpc_channel *ch;
-
- dev_dbg(xpc_chan, "deactivating partition %d, reason=%d\n",
- XPC_PARTID(part), reason);
-
- if (!xpc_part_ref(part)) {
- /* infrastructure for this partition isn't currently set up */
- return;
- }
-
- /* disconnect channels associated with the partition going down */
-
- for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
- ch = &part->channels[ch_number];
-
- xpc_msgqueue_ref(ch);
- spin_lock_irqsave(&ch->lock, irq_flags);
-
- XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
-
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- xpc_msgqueue_deref(ch);
- }
-
- xpc_wakeup_channel_mgr(part);
-
- xpc_part_deref(part);
-}
-
-/*
- * Called by XP at the time of channel connection registration to cause
- * XPC to establish connections to all currently active partitions.
- */
-void
-xpc_initiate_connect(int ch_number)
-{
- short partid;
- struct xpc_partition *part;
- struct xpc_channel *ch;
-
- DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);
-
- for (partid = 0; partid < xp_max_npartitions; partid++) {
- part = &xpc_partitions[partid];
-
- if (xpc_part_ref(part)) {
- ch = &part->channels[ch_number];
-
- /*
- * Initiate the establishment of a connection on the
- * newly registered channel to the remote partition.
- */
- xpc_wakeup_channel_mgr(part);
- xpc_part_deref(part);
- }
- }
-}
-
-void
-xpc_connected_callout(struct xpc_channel *ch)
-{
- /* let the registerer know that a connection has been established */
-
- if (ch->func != NULL) {
- dev_dbg(xpc_chan, "ch->func() called, reason=xpConnected, "
- "partid=%d, channel=%d\n", ch->partid, ch->number);
-
- ch->func(xpConnected, ch->partid, ch->number,
- (void *)(u64)ch->local_nentries, ch->key);
-
- dev_dbg(xpc_chan, "ch->func() returned, reason=xpConnected, "
- "partid=%d, channel=%d\n", ch->partid, ch->number);
- }
-}
-
-/*
- * Called by XP at the time of channel connection unregistration to cause
- * XPC to teardown all current connections for the specified channel.
- *
- * Before returning xpc_initiate_disconnect() will wait until all connections
- * on the specified channel have been closed/torndown. So the caller can be
- * assured that they will not be receiving any more callouts from XPC to the
- * function they registered via xpc_connect().
- *
- * Arguments:
- *
- * ch_number - channel # to unregister.
- */
-void
-xpc_initiate_disconnect(int ch_number)
-{
- unsigned long irq_flags;
- short partid;
- struct xpc_partition *part;
- struct xpc_channel *ch;
-
- DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);
-
- /* initiate the channel disconnect for every active partition */
- for (partid = 0; partid < xp_max_npartitions; partid++) {
- part = &xpc_partitions[partid];
-
- if (xpc_part_ref(part)) {
- ch = &part->channels[ch_number];
- xpc_msgqueue_ref(ch);
-
- spin_lock_irqsave(&ch->lock, irq_flags);
-
- if (!(ch->flags & XPC_C_DISCONNECTED)) {
- ch->flags |= XPC_C_WDISCONNECT;
-
- XPC_DISCONNECT_CHANNEL(ch, xpUnregistering,
- &irq_flags);
- }
-
- spin_unlock_irqrestore(&ch->lock, irq_flags);
-
- xpc_msgqueue_deref(ch);
- xpc_part_deref(part);
- }
- }
-
- xpc_disconnect_wait(ch_number);
-}
-
-/*
- * To disconnect a channel, and reflect it back to all who may be waiting.
- *
- * An OPEN is not allowed until XPC_C_DISCONNECTING is cleared by
- * xpc_process_disconnect(), and if set, XPC_C_WDISCONNECT is cleared by
- * xpc_disconnect_wait().
- *
- * THE CHANNEL IS TO BE LOCKED BY THE CALLER AND WILL REMAIN LOCKED UPON RETURN.
- */
-void
-xpc_disconnect_channel(const int line, struct xpc_channel *ch,
- enum xp_retval reason, unsigned long *irq_flags)
-{
- u32 channel_was_connected = (ch->flags & XPC_C_CONNECTED);
-
- DBUG_ON(!spin_is_locked(&ch->lock));
-
- if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED))
- return;
-
- DBUG_ON(!(ch->flags & (XPC_C_CONNECTING | XPC_C_CONNECTED)));
-
- dev_dbg(xpc_chan, "reason=%d, line=%d, partid=%d, channel=%d\n",
- reason, line, ch->partid, ch->number);
-
- XPC_SET_REASON(ch, reason, line);
-
- ch->flags |= (XPC_C_CLOSEREQUEST | XPC_C_DISCONNECTING);
- /* some of these may not have been set */
- ch->flags &= ~(XPC_C_OPENREQUEST | XPC_C_OPENREPLY |
- XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
- XPC_C_CONNECTING | XPC_C_CONNECTED);
-
- xpc_arch_ops.send_chctl_closerequest(ch, irq_flags);
-
- if (channel_was_connected)
- ch->flags |= XPC_C_WASCONNECTED;
-
- spin_unlock_irqrestore(&ch->lock, *irq_flags);
-
- /* wake all idle kthreads so they can exit */
- if (atomic_read(&ch->kthreads_idle) > 0) {
- wake_up_all(&ch->idle_wq);
-
- } else if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
- !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
- /* start a kthread that will do the xpDisconnecting callout */
- xpc_create_kthreads(ch, 1, 1);
- }
-
- /* wake those waiting to allocate an entry from the local msg queue */
- if (atomic_read(&ch->n_on_msg_allocate_wq) > 0)
- wake_up(&ch->msg_allocate_wq);
-
- spin_lock_irqsave(&ch->lock, *irq_flags);
-}
-
-void
-xpc_disconnect_callout(struct xpc_channel *ch, enum xp_retval reason)
-{
- /*
- * Let the channel's registerer know that the channel is being
- * disconnected. We don't want to do this if the registerer was never
- * informed of a connection being made.
- */
-
- if (ch->func != NULL) {
- dev_dbg(xpc_chan, "ch->func() called, reason=%d, partid=%d, "
- "channel=%d\n", reason, ch->partid, ch->number);
-
- ch->func(reason, ch->partid, ch->number, NULL, ch->key);
-
- dev_dbg(xpc_chan, "ch->func() returned, reason=%d, partid=%d, "
- "channel=%d\n", reason, ch->partid, ch->number);
- }
-}
-
-/*
- * Wait for a message entry to become available for the specified channel,
- * but don't wait any longer than 1 jiffy.
- */
-enum xp_retval
-xpc_allocate_msg_wait(struct xpc_channel *ch)
-{
- enum xp_retval ret;
-
- if (ch->flags & XPC_C_DISCONNECTING) {
- DBUG_ON(ch->reason == xpInterrupted);
- return ch->reason;
- }
-
- atomic_inc(&ch->n_on_msg_allocate_wq);
- ret = interruptible_sleep_on_timeout(&ch->msg_allocate_wq, 1);
- atomic_dec(&ch->n_on_msg_allocate_wq);
-
- if (ch->flags & XPC_C_DISCONNECTING) {
- ret = ch->reason;
- DBUG_ON(ch->reason == xpInterrupted);
- } else if (ret == 0) {
- ret = xpTimeout;
- } else {
- ret = xpInterrupted;
- }
-
- return ret;
-}
-
-/*
- * Send a message that contains the user's payload on the specified channel
- * connected to the specified partition.
- *
- * NOTE that this routine can sleep waiting for a message entry to become
- * available. To not sleep, pass in the XPC_NOWAIT flag.
- *
- * Once sent, this routine will not wait for the message to be received, nor
- * will notification be given when it does happen.
- *
- * Arguments:
- *
- * partid - ID of partition to which the channel is connected.
- * ch_number - channel # to send message on.
- * flags - see xp.h for valid flags.
- * payload - pointer to the payload which is to be sent.
- * payload_size - size of the payload in bytes.
- */
-enum xp_retval
-xpc_initiate_send(short partid, int ch_number, u32 flags, void *payload,
- u16 payload_size)
-{
- struct xpc_partition *part = &xpc_partitions[partid];
- enum xp_retval ret = xpUnknownReason;
-
- dev_dbg(xpc_chan, "payload=0x%p, partid=%d, channel=%d\n", payload,
- partid, ch_number);
-
- DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
- DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
- DBUG_ON(payload == NULL);
-
- if (xpc_part_ref(part)) {
- ret = xpc_arch_ops.send_payload(&part->channels[ch_number],
- flags, payload, payload_size, 0, NULL, NULL);
- xpc_part_deref(part);
- }
-
- return ret;
-}
-
-/*
- * Send a message that contains the user's payload on the specified channel
- * connected to the specified partition.
- *
- * NOTE that this routine can sleep waiting for a message entry to become
- * available. To not sleep, pass in the XPC_NOWAIT flag.
- *
- * This routine will not wait for the message to be sent or received.
- *
- * Once the remote end of the channel has received the message, the function
- * passed as an argument to xpc_initiate_send_notify() will be called. This
- * allows the sender to free up or re-use any buffers referenced by the
- * message, but does NOT mean the message has been processed at the remote
- * end by a receiver.
- *
- * If this routine returns an error, the caller's function will NOT be called.
- *
- * Arguments:
- *
- * partid - ID of partition to which the channel is connected.
- * ch_number - channel # to send message on.
- * flags - see xp.h for valid flags.
- * payload - pointer to the payload which is to be sent.
- * payload_size - size of the payload in bytes.
- * func - function to call with asynchronous notification of message
- * receipt. THIS FUNCTION MUST BE NON-BLOCKING.
- * key - user-defined key to be passed to the function when it's called.
- */
-enum xp_retval
-xpc_initiate_send_notify(short partid, int ch_number, u32 flags, void *payload,
- u16 payload_size, xpc_notify_func func, void *key)
-{
- struct xpc_partition *part = &xpc_partitions[partid];
- enum xp_retval ret = xpUnknownReason;
-
- dev_dbg(xpc_chan, "payload=0x%p, partid=%d, channel=%d\n", payload,
- partid, ch_number);
-
- DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
- DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
- DBUG_ON(payload == NULL);
- DBUG_ON(func == NULL);
-
- if (xpc_part_ref(part)) {
- ret = xpc_arch_ops.send_payload(&part->channels[ch_number],
- flags, payload, payload_size, XPC_N_CALL, func, key);
- xpc_part_deref(part);
- }
- return ret;
-}
-
-/*
- * Deliver a message's payload to its intended recipient.
- */
-void
-xpc_deliver_payload(struct xpc_channel *ch)
-{
- void *payload;
-
- payload = xpc_arch_ops.get_deliverable_payload(ch);
- if (payload != NULL) {
-
- /*
- * This ref is taken to protect the payload itself from being
- * freed before the user is finished with it, which the user
- * indicates by calling xpc_initiate_received().
- */
- xpc_msgqueue_ref(ch);
-
- atomic_inc(&ch->kthreads_active);
-
- if (ch->func != NULL) {
- dev_dbg(xpc_chan, "ch->func() called, payload=0x%p "
- "partid=%d channel=%d\n", payload, ch->partid,
- ch->number);
-
- /* deliver the message to its intended recipient */
- ch->func(xpMsgReceived, ch->partid, ch->number, payload,
- ch->key);
-
- dev_dbg(xpc_chan, "ch->func() returned, payload=0x%p "
- "partid=%d channel=%d\n", payload, ch->partid,
- ch->number);
- }
-
- atomic_dec(&ch->kthreads_active);
- }
-}
-
-/*
- * Acknowledge receipt of a delivered message's payload.
- *
- * This function, although called by users, does not call xpc_part_ref() to
- * ensure that the partition infrastructure is in place. It relies on the
- * fact that we called xpc_msgqueue_ref() in xpc_deliver_payload().
- *
- * Arguments:
- *
- * partid - ID of partition to which the channel is connected.
- * ch_number - channel # message received on.
- * payload - pointer to the payload area allocated via
- * xpc_initiate_send() or xpc_initiate_send_notify().
- */
-void
-xpc_initiate_received(short partid, int ch_number, void *payload)
-{
- struct xpc_partition *part = &xpc_partitions[partid];
- struct xpc_channel *ch;
-
- DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
- DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
-
- ch = &part->channels[ch_number];
- xpc_arch_ops.received_payload(ch, payload);
-
- /* the call to xpc_msgqueue_ref() was done by xpc_deliver_payload() */
- xpc_msgqueue_deref(ch);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_main.c b/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_main.c
deleted file mode 100644
index 8d082b46..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_main.c
+++ /dev/null
@@ -1,1344 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * Cross Partition Communication (XPC) support - standard version.
- *
- * XPC provides a message passing capability that crosses partition
- * boundaries. This module is made up of two parts:
- *
- * partition This part detects the presence/absence of other
- * partitions. It provides a heartbeat and monitors
- * the heartbeats of other partitions.
- *
- * channel This part manages the channels and sends/receives
- * messages across them to/from other partitions.
- *
- * There are a couple of additional functions residing in XP, which
- * provide an interface to XPC for its users.
- *
- *
- * Caveats:
- *
- * . Currently on sn2, we have no way to determine which nasid an IRQ
- * came from. Thus, xpc_send_IRQ_sn2() does a remote amo write
- * followed by an IPI. The amo indicates where data is to be pulled
- * from, so after the IPI arrives, the remote partition checks the amo
- * word. The IPI can actually arrive before the amo however, so other
- * code must periodically check for this case. Also, remote amo
- * operations do not reliably time out. Thus we do a remote PIO read
- * solely to know whether the remote partition is down and whether we
- * should stop sending IPIs to it. This remote PIO read operation is
- * set up in a special nofault region so SAL knows to ignore (and
- * cleanup) any errors due to the remote amo write, PIO read, and/or
- * PIO write operations.
- *
- * If/when new hardware solves this IPI problem, we should abandon
- * the current approach.
- *
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/sysctl.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/kdebug.h>
-#include <linux/kthread.h>
-#include "xpc.h"
-
-/* define two XPC debug device structures to be used with dev_dbg() et al */
-
-struct device_driver xpc_dbg_name = {
- .name = "xpc"
-};
-
-struct device xpc_part_dbg_subname = {
- .init_name = "", /* set to "part" at xpc_init() time */
- .driver = &xpc_dbg_name
-};
-
-struct device xpc_chan_dbg_subname = {
- .init_name = "", /* set to "chan" at xpc_init() time */
- .driver = &xpc_dbg_name
-};
-
-struct device *xpc_part = &xpc_part_dbg_subname;
-struct device *xpc_chan = &xpc_chan_dbg_subname;
-
-static int xpc_kdebug_ignore;
-
-/* systune related variables for /proc/sys directories */
-
-static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
-static int xpc_hb_min_interval = 1;
-static int xpc_hb_max_interval = 10;
-
-static int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_INTERVAL;
-static int xpc_hb_check_min_interval = 10;
-static int xpc_hb_check_max_interval = 120;
-
-int xpc_disengage_timelimit = XPC_DISENGAGE_DEFAULT_TIMELIMIT;
-static int xpc_disengage_min_timelimit; /* = 0 */
-static int xpc_disengage_max_timelimit = 120;
-
-static ctl_table xpc_sys_xpc_hb_dir[] = {
- {
- .procname = "hb_interval",
- .data = &xpc_hb_interval,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec_minmax,
- .extra1 = &xpc_hb_min_interval,
- .extra2 = &xpc_hb_max_interval},
- {
- .procname = "hb_check_interval",
- .data = &xpc_hb_check_interval,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec_minmax,
- .extra1 = &xpc_hb_check_min_interval,
- .extra2 = &xpc_hb_check_max_interval},
- {}
-};
-static ctl_table xpc_sys_xpc_dir[] = {
- {
- .procname = "hb",
- .mode = 0555,
- .child = xpc_sys_xpc_hb_dir},
- {
- .procname = "disengage_timelimit",
- .data = &xpc_disengage_timelimit,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec_minmax,
- .extra1 = &xpc_disengage_min_timelimit,
- .extra2 = &xpc_disengage_max_timelimit},
- {}
-};
-static ctl_table xpc_sys_dir[] = {
- {
- .procname = "xpc",
- .mode = 0555,
- .child = xpc_sys_xpc_dir},
- {}
-};
-static struct ctl_table_header *xpc_sysctl;
-
-/* non-zero if any remote partition disengage was timed out */
-int xpc_disengage_timedout;
-
-/* #of activate IRQs received and not yet processed */
-int xpc_activate_IRQ_rcvd;
-DEFINE_SPINLOCK(xpc_activate_IRQ_rcvd_lock);
-
-/* IRQ handler notifies this wait queue on receipt of an IRQ */
-DECLARE_WAIT_QUEUE_HEAD(xpc_activate_IRQ_wq);
-
-static unsigned long xpc_hb_check_timeout;
-static struct timer_list xpc_hb_timer;
-
-/* notification that the xpc_hb_checker thread has exited */
-static DECLARE_COMPLETION(xpc_hb_checker_exited);
-
-/* notification that the xpc_discovery thread has exited */
-static DECLARE_COMPLETION(xpc_discovery_exited);
-
-static void xpc_kthread_waitmsgs(struct xpc_partition *, struct xpc_channel *);
-
-static int xpc_system_reboot(struct notifier_block *, unsigned long, void *);
-static struct notifier_block xpc_reboot_notifier = {
- .notifier_call = xpc_system_reboot,
-};
-
-static int xpc_system_die(struct notifier_block *, unsigned long, void *);
-static struct notifier_block xpc_die_notifier = {
- .notifier_call = xpc_system_die,
-};
-
-struct xpc_arch_operations xpc_arch_ops;
-
-/*
- * Timer function to enforce the timelimit on the partition disengage.
- */
-static void
-xpc_timeout_partition_disengage(unsigned long data)
-{
- struct xpc_partition *part = (struct xpc_partition *)data;
-
- DBUG_ON(time_is_after_jiffies(part->disengage_timeout));
-
- (void)xpc_partition_disengaged(part);
-
- DBUG_ON(part->disengage_timeout != 0);
- DBUG_ON(xpc_arch_ops.partition_engaged(XPC_PARTID(part)));
-}
-
-/*
- * Timer to produce the heartbeat. The timer structures function is
- * already set when this is initially called. A tunable is used to
- * specify when the next timeout should occur.
- */
-static void
-xpc_hb_beater(unsigned long dummy)
-{
- xpc_arch_ops.increment_heartbeat();
-
- if (time_is_before_eq_jiffies(xpc_hb_check_timeout))
- wake_up_interruptible(&xpc_activate_IRQ_wq);
-
- xpc_hb_timer.expires = jiffies + (xpc_hb_interval * HZ);
- add_timer(&xpc_hb_timer);
-}
-
-static void
-xpc_start_hb_beater(void)
-{
- xpc_arch_ops.heartbeat_init();
- init_timer(&xpc_hb_timer);
- xpc_hb_timer.function = xpc_hb_beater;
- xpc_hb_beater(0);
-}
-
-static void
-xpc_stop_hb_beater(void)
-{
- del_timer_sync(&xpc_hb_timer);
- xpc_arch_ops.heartbeat_exit();
-}
-
-/*
- * At periodic intervals, scan through all active partitions and ensure
- * their heartbeat is still active. If not, the partition is deactivated.
- */
-static void
-xpc_check_remote_hb(void)
-{
- struct xpc_partition *part;
- short partid;
- enum xp_retval ret;
-
- for (partid = 0; partid < xp_max_npartitions; partid++) {
-
- if (xpc_exiting)
- break;
-
- if (partid == xp_partition_id)
- continue;
-
- part = &xpc_partitions[partid];
-
- if (part->act_state == XPC_P_AS_INACTIVE ||
- part->act_state == XPC_P_AS_DEACTIVATING) {
- continue;
- }
-
- ret = xpc_arch_ops.get_remote_heartbeat(part);
- if (ret != xpSuccess)
- XPC_DEACTIVATE_PARTITION(part, ret);
- }
-}
-
-/*
- * This thread is responsible for nearly all of the partition
- * activation/deactivation.
- */
-static int
-xpc_hb_checker(void *ignore)
-{
- int force_IRQ = 0;
-
- /* this thread was marked active by xpc_hb_init() */
-
- set_cpus_allowed_ptr(current, cpumask_of(XPC_HB_CHECK_CPU));
-
- /* set our heartbeating to other partitions into motion */
- xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
- xpc_start_hb_beater();
-
- while (!xpc_exiting) {
-
- dev_dbg(xpc_part, "woke up with %d ticks rem; %d IRQs have "
- "been received\n",
- (int)(xpc_hb_check_timeout - jiffies),
- xpc_activate_IRQ_rcvd);
-
- /* checking of remote heartbeats is skewed by IRQ handling */
- if (time_is_before_eq_jiffies(xpc_hb_check_timeout)) {
- xpc_hb_check_timeout = jiffies +
- (xpc_hb_check_interval * HZ);
-
- dev_dbg(xpc_part, "checking remote heartbeats\n");
- xpc_check_remote_hb();
-
- /*
- * On sn2 we need to periodically recheck to ensure no
- * IRQ/amo pairs have been missed.
- */
- if (is_shub())
- force_IRQ = 1;
- }
-
- /* check for outstanding IRQs */
- if (xpc_activate_IRQ_rcvd > 0 || force_IRQ != 0) {
- force_IRQ = 0;
- dev_dbg(xpc_part, "processing activate IRQs "
- "received\n");
- xpc_arch_ops.process_activate_IRQ_rcvd();
- }
-
- /* wait for IRQ or timeout */
- (void)wait_event_interruptible(xpc_activate_IRQ_wq,
- (time_is_before_eq_jiffies(
- xpc_hb_check_timeout) ||
- xpc_activate_IRQ_rcvd > 0 ||
- xpc_exiting));
- }
-
- xpc_stop_hb_beater();
-
- dev_dbg(xpc_part, "heartbeat checker is exiting\n");
-
- /* mark this thread as having exited */
- complete(&xpc_hb_checker_exited);
- return 0;
-}
-
-/*
- * This thread will attempt to discover other partitions to activate
- * based on info provided by SAL. This new thread is short lived and
- * will exit once discovery is complete.
- */
-static int
-xpc_initiate_discovery(void *ignore)
-{
- xpc_discovery();
-
- dev_dbg(xpc_part, "discovery thread is exiting\n");
-
- /* mark this thread as having exited */
- complete(&xpc_discovery_exited);
- return 0;
-}
-
-/*
- * The first kthread assigned to a newly activated partition is the one
- * created by XPC HB with which it calls xpc_activating(). XPC hangs on to
- * that kthread until the partition is brought down, at which time that kthread
- * returns back to XPC HB. (The return of that kthread will signify to XPC HB
- * that XPC has dismantled all communication infrastructure for the associated
- * partition.) This kthread becomes the channel manager for that partition.
- *
- * Each active partition has a channel manager, who, besides connecting and
- * disconnecting channels, will ensure that each of the partition's connected
- * channels has the required number of assigned kthreads to get the work done.
- */
-static void
-xpc_channel_mgr(struct xpc_partition *part)
-{
- while (part->act_state != XPC_P_AS_DEACTIVATING ||
- atomic_read(&part->nchannels_active) > 0 ||
- !xpc_partition_disengaged(part)) {
-
- xpc_process_sent_chctl_flags(part);
-
- /*
- * Wait until we've been requested to activate kthreads or
- * all of the channel's message queues have been torn down or
- * a signal is pending.
- *
- * The channel_mgr_requests is set to 1 after being awakened,
- * This is done to prevent the channel mgr from making one pass
- * through the loop for each request, since he will
- * be servicing all the requests in one pass. The reason it's
- * set to 1 instead of 0 is so that other kthreads will know
- * that the channel mgr is running and won't bother trying to
- * wake him up.
- */
- atomic_dec(&part->channel_mgr_requests);
- (void)wait_event_interruptible(part->channel_mgr_wq,
- (atomic_read(&part->channel_mgr_requests) > 0 ||
- part->chctl.all_flags != 0 ||
- (part->act_state == XPC_P_AS_DEACTIVATING &&
- atomic_read(&part->nchannels_active) == 0 &&
- xpc_partition_disengaged(part))));
- atomic_set(&part->channel_mgr_requests, 1);
- }
-}
-
-/*
- * Guarantee that the kzalloc'd memory is cacheline aligned.
- */
-void *
-xpc_kzalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
-{
- /* see if kzalloc will give us cachline aligned memory by default */
- *base = kzalloc(size, flags);
- if (*base == NULL)
- return NULL;
-
- if ((u64)*base == L1_CACHE_ALIGN((u64)*base))
- return *base;
-
- kfree(*base);
-
- /* nope, we'll have to do it ourselves */
- *base = kzalloc(size + L1_CACHE_BYTES, flags);
- if (*base == NULL)
- return NULL;
-
- return (void *)L1_CACHE_ALIGN((u64)*base);
-}
-
-/*
- * Setup the channel structures necessary to support XPartition Communication
- * between the specified remote partition and the local one.
- */
-static enum xp_retval
-xpc_setup_ch_structures(struct xpc_partition *part)
-{
- enum xp_retval ret;
- int ch_number;
- struct xpc_channel *ch;
- short partid = XPC_PARTID(part);
-
- /*
- * Allocate all of the channel structures as a contiguous chunk of
- * memory.
- */
- DBUG_ON(part->channels != NULL);
- part->channels = kzalloc(sizeof(struct xpc_channel) * XPC_MAX_NCHANNELS,
- GFP_KERNEL);
- if (part->channels == NULL) {
- dev_err(xpc_chan, "can't get memory for channels\n");
- return xpNoMemory;
- }
-
- /* allocate the remote open and close args */
-
- part->remote_openclose_args =
- xpc_kzalloc_cacheline_aligned(XPC_OPENCLOSE_ARGS_SIZE,
- GFP_KERNEL, &part->
- remote_openclose_args_base);
- if (part->remote_openclose_args == NULL) {
- dev_err(xpc_chan, "can't get memory for remote connect args\n");
- ret = xpNoMemory;
- goto out_1;
- }
-
- part->chctl.all_flags = 0;
- spin_lock_init(&part->chctl_lock);
-
- atomic_set(&part->channel_mgr_requests, 1);
- init_waitqueue_head(&part->channel_mgr_wq);
-
- part->nchannels = XPC_MAX_NCHANNELS;
-
- atomic_set(&part->nchannels_active, 0);
- atomic_set(&part->nchannels_engaged, 0);
-
- for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
- ch = &part->channels[ch_number];
-
- ch->partid = partid;
- ch->number = ch_number;
- ch->flags = XPC_C_DISCONNECTED;
-
- atomic_set(&ch->kthreads_assigned, 0);
- atomic_set(&ch->kthreads_idle, 0);
- atomic_set(&ch->kthreads_active, 0);
-
- atomic_set(&ch->references, 0);
- atomic_set(&ch->n_to_notify, 0);
-
- spin_lock_init(&ch->lock);
- init_completion(&ch->wdisconnect_wait);
-
- atomic_set(&ch->n_on_msg_allocate_wq, 0);
- init_waitqueue_head(&ch->msg_allocate_wq);
- init_waitqueue_head(&ch->idle_wq);
- }
-
- ret = xpc_arch_ops.setup_ch_structures(part);
- if (ret != xpSuccess)
- goto out_2;
-
- /*
- * With the setting of the partition setup_state to XPC_P_SS_SETUP,
- * we're declaring that this partition is ready to go.
- */
- part->setup_state = XPC_P_SS_SETUP;
-
- return xpSuccess;
-
- /* setup of ch structures failed */
-out_2:
- kfree(part->remote_openclose_args_base);
- part->remote_openclose_args = NULL;
-out_1:
- kfree(part->channels);
- part->channels = NULL;
- return ret;
-}
-
-/*
- * Teardown the channel structures necessary to support XPartition Communication
- * between the specified remote partition and the local one.
- */
-static void
-xpc_teardown_ch_structures(struct xpc_partition *part)
-{
- DBUG_ON(atomic_read(&part->nchannels_engaged) != 0);
- DBUG_ON(atomic_read(&part->nchannels_active) != 0);
-
- /*
- * Make this partition inaccessible to local processes by marking it
- * as no longer setup. Then wait before proceeding with the teardown
- * until all existing references cease.
- */
- DBUG_ON(part->setup_state != XPC_P_SS_SETUP);
- part->setup_state = XPC_P_SS_WTEARDOWN;
-
- wait_event(part->teardown_wq, (atomic_read(&part->references) == 0));
-
- /* now we can begin tearing down the infrastructure */
-
- xpc_arch_ops.teardown_ch_structures(part);
-
- kfree(part->remote_openclose_args_base);
- part->remote_openclose_args = NULL;
- kfree(part->channels);
- part->channels = NULL;
-
- part->setup_state = XPC_P_SS_TORNDOWN;
-}
-
-/*
- * When XPC HB determines that a partition has come up, it will create a new
- * kthread and that kthread will call this function to attempt to set up the
- * basic infrastructure used for Cross Partition Communication with the newly
- * upped partition.
- *
- * The kthread that was created by XPC HB and which setup the XPC
- * infrastructure will remain assigned to the partition becoming the channel
- * manager for that partition until the partition is deactivating, at which
- * time the kthread will teardown the XPC infrastructure and then exit.
- */
-static int
-xpc_activating(void *__partid)
-{
- short partid = (u64)__partid;
- struct xpc_partition *part = &xpc_partitions[partid];
- unsigned long irq_flags;
-
- DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
-
- spin_lock_irqsave(&part->act_lock, irq_flags);
-
- if (part->act_state == XPC_P_AS_DEACTIVATING) {
- part->act_state = XPC_P_AS_INACTIVE;
- spin_unlock_irqrestore(&part->act_lock, irq_flags);
- part->remote_rp_pa = 0;
- return 0;
- }
-
- /* indicate the thread is activating */
- DBUG_ON(part->act_state != XPC_P_AS_ACTIVATION_REQ);
- part->act_state = XPC_P_AS_ACTIVATING;
-
- XPC_SET_REASON(part, 0, 0);
- spin_unlock_irqrestore(&part->act_lock, irq_flags);
-
- dev_dbg(xpc_part, "activating partition %d\n", partid);
-
- xpc_arch_ops.allow_hb(partid);
-
- if (xpc_setup_ch_structures(part) == xpSuccess) {
- (void)xpc_part_ref(part); /* this will always succeed */
-
- if (xpc_arch_ops.make_first_contact(part) == xpSuccess) {
- xpc_mark_partition_active(part);
- xpc_channel_mgr(part);
- /* won't return until partition is deactivating */
- }
-
- xpc_part_deref(part);
- xpc_teardown_ch_structures(part);
- }
-
- xpc_arch_ops.disallow_hb(partid);
- xpc_mark_partition_inactive(part);
-
- if (part->reason == xpReactivating) {
- /* interrupting ourselves results in activating partition */
- xpc_arch_ops.request_partition_reactivation(part);
- }
-
- return 0;
-}
-
-void
-xpc_activate_partition(struct xpc_partition *part)
-{
- short partid = XPC_PARTID(part);
- unsigned long irq_flags;
- struct task_struct *kthread;
-
- spin_lock_irqsave(&part->act_lock, irq_flags);
-
- DBUG_ON(part->act_state != XPC_P_AS_INACTIVE);
-
- part->act_state = XPC_P_AS_ACTIVATION_REQ;
- XPC_SET_REASON(part, xpCloneKThread, __LINE__);
-
- spin_unlock_irqrestore(&part->act_lock, irq_flags);
-
- kthread = kthread_run(xpc_activating, (void *)((u64)partid), "xpc%02d",
- partid);
- if (IS_ERR(kthread)) {
- spin_lock_irqsave(&part->act_lock, irq_flags);
- part->act_state = XPC_P_AS_INACTIVE;
- XPC_SET_REASON(part, xpCloneKThreadFailed, __LINE__);
- spin_unlock_irqrestore(&part->act_lock, irq_flags);
- }
-}
-
-void
-xpc_activate_kthreads(struct xpc_channel *ch, int needed)
-{
- int idle = atomic_read(&ch->kthreads_idle);
- int assigned = atomic_read(&ch->kthreads_assigned);
- int wakeup;
-
- DBUG_ON(needed <= 0);
-
- if (idle > 0) {
- wakeup = (needed > idle) ? idle : needed;
- needed -= wakeup;
-
- dev_dbg(xpc_chan, "wakeup %d idle kthreads, partid=%d, "
- "channel=%d\n", wakeup, ch->partid, ch->number);
-
- /* only wakeup the requested number of kthreads */
- wake_up_nr(&ch->idle_wq, wakeup);
- }
-
- if (needed <= 0)
- return;
-
- if (needed + assigned > ch->kthreads_assigned_limit) {
- needed = ch->kthreads_assigned_limit - assigned;
- if (needed <= 0)
- return;
- }
-
- dev_dbg(xpc_chan, "create %d new kthreads, partid=%d, channel=%d\n",
- needed, ch->partid, ch->number);
-
- xpc_create_kthreads(ch, needed, 0);
-}
-
-/*
- * This function is where XPC's kthreads wait for messages to deliver.
- */
-static void
-xpc_kthread_waitmsgs(struct xpc_partition *part, struct xpc_channel *ch)
-{
- int (*n_of_deliverable_payloads) (struct xpc_channel *) =
- xpc_arch_ops.n_of_deliverable_payloads;
-
- do {
- /* deliver messages to their intended recipients */
-
- while (n_of_deliverable_payloads(ch) > 0 &&
- !(ch->flags & XPC_C_DISCONNECTING)) {
- xpc_deliver_payload(ch);
- }
-
- if (atomic_inc_return(&ch->kthreads_idle) >
- ch->kthreads_idle_limit) {
- /* too many idle kthreads on this channel */
- atomic_dec(&ch->kthreads_idle);
- break;
- }
-
- dev_dbg(xpc_chan, "idle kthread calling "
- "wait_event_interruptible_exclusive()\n");
-
- (void)wait_event_interruptible_exclusive(ch->idle_wq,
- (n_of_deliverable_payloads(ch) > 0 ||
- (ch->flags & XPC_C_DISCONNECTING)));
-
- atomic_dec(&ch->kthreads_idle);
-
- } while (!(ch->flags & XPC_C_DISCONNECTING));
-}
-
-static int
-xpc_kthread_start(void *args)
-{
- short partid = XPC_UNPACK_ARG1(args);
- u16 ch_number = XPC_UNPACK_ARG2(args);
- struct xpc_partition *part = &xpc_partitions[partid];
- struct xpc_channel *ch;
- int n_needed;
- unsigned long irq_flags;
- int (*n_of_deliverable_payloads) (struct xpc_channel *) =
- xpc_arch_ops.n_of_deliverable_payloads;
-
- dev_dbg(xpc_chan, "kthread starting, partid=%d, channel=%d\n",
- partid, ch_number);
-
- ch = &part->channels[ch_number];
-
- if (!(ch->flags & XPC_C_DISCONNECTING)) {
-
- /* let registerer know that connection has been established */
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- if (!(ch->flags & XPC_C_CONNECTEDCALLOUT)) {
- ch->flags |= XPC_C_CONNECTEDCALLOUT;
- spin_unlock_irqrestore(&ch->lock, irq_flags);
-
- xpc_connected_callout(ch);
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- ch->flags |= XPC_C_CONNECTEDCALLOUT_MADE;
- spin_unlock_irqrestore(&ch->lock, irq_flags);
-
- /*
- * It is possible that while the callout was being
- * made that the remote partition sent some messages.
- * If that is the case, we may need to activate
- * additional kthreads to help deliver them. We only
- * need one less than total #of messages to deliver.
- */
- n_needed = n_of_deliverable_payloads(ch) - 1;
- if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING))
- xpc_activate_kthreads(ch, n_needed);
-
- } else {
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- }
-
- xpc_kthread_waitmsgs(part, ch);
- }
-
- /* let registerer know that connection is disconnecting */
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- if ((ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) &&
- !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) {
- ch->flags |= XPC_C_DISCONNECTINGCALLOUT;
- spin_unlock_irqrestore(&ch->lock, irq_flags);
-
- xpc_disconnect_callout(ch, xpDisconnecting);
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- ch->flags |= XPC_C_DISCONNECTINGCALLOUT_MADE;
- }
- spin_unlock_irqrestore(&ch->lock, irq_flags);
-
- if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
- atomic_dec_return(&part->nchannels_engaged) == 0) {
- xpc_arch_ops.indicate_partition_disengaged(part);
- }
-
- xpc_msgqueue_deref(ch);
-
- dev_dbg(xpc_chan, "kthread exiting, partid=%d, channel=%d\n",
- partid, ch_number);
-
- xpc_part_deref(part);
- return 0;
-}
-
-/*
- * For each partition that XPC has established communications with, there is
- * a minimum of one kernel thread assigned to perform any operation that
- * may potentially sleep or block (basically the callouts to the asynchronous
- * functions registered via xpc_connect()).
- *
- * Additional kthreads are created and destroyed by XPC as the workload
- * demands.
- *
- * A kthread is assigned to one of the active channels that exists for a given
- * partition.
- */
-void
-xpc_create_kthreads(struct xpc_channel *ch, int needed,
- int ignore_disconnecting)
-{
- unsigned long irq_flags;
- u64 args = XPC_PACK_ARGS(ch->partid, ch->number);
- struct xpc_partition *part = &xpc_partitions[ch->partid];
- struct task_struct *kthread;
- void (*indicate_partition_disengaged) (struct xpc_partition *) =
- xpc_arch_ops.indicate_partition_disengaged;
-
- while (needed-- > 0) {
-
- /*
- * The following is done on behalf of the newly created
- * kthread. That kthread is responsible for doing the
- * counterpart to the following before it exits.
- */
- if (ignore_disconnecting) {
- if (!atomic_inc_not_zero(&ch->kthreads_assigned)) {
- /* kthreads assigned had gone to zero */
- BUG_ON(!(ch->flags &
- XPC_C_DISCONNECTINGCALLOUT_MADE));
- break;
- }
-
- } else if (ch->flags & XPC_C_DISCONNECTING) {
- break;
-
- } else if (atomic_inc_return(&ch->kthreads_assigned) == 1 &&
- atomic_inc_return(&part->nchannels_engaged) == 1) {
- xpc_arch_ops.indicate_partition_engaged(part);
- }
- (void)xpc_part_ref(part);
- xpc_msgqueue_ref(ch);
-
- kthread = kthread_run(xpc_kthread_start, (void *)args,
- "xpc%02dc%d", ch->partid, ch->number);
- if (IS_ERR(kthread)) {
- /* the fork failed */
-
- /*
- * NOTE: if (ignore_disconnecting &&
- * !(ch->flags & XPC_C_DISCONNECTINGCALLOUT)) is true,
- * then we'll deadlock if all other kthreads assigned
- * to this channel are blocked in the channel's
- * registerer, because the only thing that will unblock
- * them is the xpDisconnecting callout that this
- * failed kthread_run() would have made.
- */
-
- if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
- atomic_dec_return(&part->nchannels_engaged) == 0) {
- indicate_partition_disengaged(part);
- }
- xpc_msgqueue_deref(ch);
- xpc_part_deref(part);
-
- if (atomic_read(&ch->kthreads_assigned) <
- ch->kthreads_idle_limit) {
- /*
- * Flag this as an error only if we have an
- * insufficient #of kthreads for the channel
- * to function.
- */
- spin_lock_irqsave(&ch->lock, irq_flags);
- XPC_DISCONNECT_CHANNEL(ch, xpLackOfResources,
- &irq_flags);
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- }
- break;
- }
- }
-}
-
-void
-xpc_disconnect_wait(int ch_number)
-{
- unsigned long irq_flags;
- short partid;
- struct xpc_partition *part;
- struct xpc_channel *ch;
- int wakeup_channel_mgr;
-
- /* now wait for all callouts to the caller's function to cease */
- for (partid = 0; partid < xp_max_npartitions; partid++) {
- part = &xpc_partitions[partid];
-
- if (!xpc_part_ref(part))
- continue;
-
- ch = &part->channels[ch_number];
-
- if (!(ch->flags & XPC_C_WDISCONNECT)) {
- xpc_part_deref(part);
- continue;
- }
-
- wait_for_completion(&ch->wdisconnect_wait);
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- DBUG_ON(!(ch->flags & XPC_C_DISCONNECTED));
- wakeup_channel_mgr = 0;
-
- if (ch->delayed_chctl_flags) {
- if (part->act_state != XPC_P_AS_DEACTIVATING) {
- spin_lock(&part->chctl_lock);
- part->chctl.flags[ch->number] |=
- ch->delayed_chctl_flags;
- spin_unlock(&part->chctl_lock);
- wakeup_channel_mgr = 1;
- }
- ch->delayed_chctl_flags = 0;
- }
-
- ch->flags &= ~XPC_C_WDISCONNECT;
- spin_unlock_irqrestore(&ch->lock, irq_flags);
-
- if (wakeup_channel_mgr)
- xpc_wakeup_channel_mgr(part);
-
- xpc_part_deref(part);
- }
-}
-
-static int
-xpc_setup_partitions(void)
-{
- short partid;
- struct xpc_partition *part;
-
- xpc_partitions = kzalloc(sizeof(struct xpc_partition) *
- xp_max_npartitions, GFP_KERNEL);
- if (xpc_partitions == NULL) {
- dev_err(xpc_part, "can't get memory for partition structure\n");
- return -ENOMEM;
- }
-
- /*
- * The first few fields of each entry of xpc_partitions[] need to
- * be initialized now so that calls to xpc_connect() and
- * xpc_disconnect() can be made prior to the activation of any remote
- * partition. NOTE THAT NONE OF THE OTHER FIELDS BELONGING TO THESE
- * ENTRIES ARE MEANINGFUL UNTIL AFTER AN ENTRY'S CORRESPONDING
- * PARTITION HAS BEEN ACTIVATED.
- */
- for (partid = 0; partid < xp_max_npartitions; partid++) {
- part = &xpc_partitions[partid];
-
- DBUG_ON((u64)part != L1_CACHE_ALIGN((u64)part));
-
- part->activate_IRQ_rcvd = 0;
- spin_lock_init(&part->act_lock);
- part->act_state = XPC_P_AS_INACTIVE;
- XPC_SET_REASON(part, 0, 0);
-
- init_timer(&part->disengage_timer);
- part->disengage_timer.function =
- xpc_timeout_partition_disengage;
- part->disengage_timer.data = (unsigned long)part;
-
- part->setup_state = XPC_P_SS_UNSET;
- init_waitqueue_head(&part->teardown_wq);
- atomic_set(&part->references, 0);
- }
-
- return xpc_arch_ops.setup_partitions();
-}
-
-static void
-xpc_teardown_partitions(void)
-{
- xpc_arch_ops.teardown_partitions();
- kfree(xpc_partitions);
-}
-
-static void
-xpc_do_exit(enum xp_retval reason)
-{
- short partid;
- int active_part_count, printed_waiting_msg = 0;
- struct xpc_partition *part;
- unsigned long printmsg_time, disengage_timeout = 0;
-
- /* a 'rmmod XPC' and a 'reboot' cannot both end up here together */
- DBUG_ON(xpc_exiting == 1);
-
- /*
- * Let the heartbeat checker thread and the discovery thread
- * (if one is running) know that they should exit. Also wake up
- * the heartbeat checker thread in case it's sleeping.
- */
- xpc_exiting = 1;
- wake_up_interruptible(&xpc_activate_IRQ_wq);
-
- /* wait for the discovery thread to exit */
- wait_for_completion(&xpc_discovery_exited);
-
- /* wait for the heartbeat checker thread to exit */
- wait_for_completion(&xpc_hb_checker_exited);
-
- /* sleep for a 1/3 of a second or so */
- (void)msleep_interruptible(300);
-
- /* wait for all partitions to become inactive */
-
- printmsg_time = jiffies + (XPC_DEACTIVATE_PRINTMSG_INTERVAL * HZ);
- xpc_disengage_timedout = 0;
-
- do {
- active_part_count = 0;
-
- for (partid = 0; partid < xp_max_npartitions; partid++) {
- part = &xpc_partitions[partid];
-
- if (xpc_partition_disengaged(part) &&
- part->act_state == XPC_P_AS_INACTIVE) {
- continue;
- }
-
- active_part_count++;
-
- XPC_DEACTIVATE_PARTITION(part, reason);
-
- if (part->disengage_timeout > disengage_timeout)
- disengage_timeout = part->disengage_timeout;
- }
-
- if (xpc_arch_ops.any_partition_engaged()) {
- if (time_is_before_jiffies(printmsg_time)) {
- dev_info(xpc_part, "waiting for remote "
- "partitions to deactivate, timeout in "
- "%ld seconds\n", (disengage_timeout -
- jiffies) / HZ);
- printmsg_time = jiffies +
- (XPC_DEACTIVATE_PRINTMSG_INTERVAL * HZ);
- printed_waiting_msg = 1;
- }
-
- } else if (active_part_count > 0) {
- if (printed_waiting_msg) {
- dev_info(xpc_part, "waiting for local partition"
- " to deactivate\n");
- printed_waiting_msg = 0;
- }
-
- } else {
- if (!xpc_disengage_timedout) {
- dev_info(xpc_part, "all partitions have "
- "deactivated\n");
- }
- break;
- }
-
- /* sleep for a 1/3 of a second or so */
- (void)msleep_interruptible(300);
-
- } while (1);
-
- DBUG_ON(xpc_arch_ops.any_partition_engaged());
-
- xpc_teardown_rsvd_page();
-
- if (reason == xpUnloading) {
- (void)unregister_die_notifier(&xpc_die_notifier);
- (void)unregister_reboot_notifier(&xpc_reboot_notifier);
- }
-
- /* clear the interface to XPC's functions */
- xpc_clear_interface();
-
- if (xpc_sysctl)
- unregister_sysctl_table(xpc_sysctl);
-
- xpc_teardown_partitions();
-
- if (is_shub())
- xpc_exit_sn2();
- else if (is_uv())
- xpc_exit_uv();
-}
-
-/*
- * This function is called when the system is being rebooted.
- */
-static int
-xpc_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
-{
- enum xp_retval reason;
-
- switch (event) {
- case SYS_RESTART:
- reason = xpSystemReboot;
- break;
- case SYS_HALT:
- reason = xpSystemHalt;
- break;
- case SYS_POWER_OFF:
- reason = xpSystemPoweroff;
- break;
- default:
- reason = xpSystemGoingDown;
- }
-
- xpc_do_exit(reason);
- return NOTIFY_DONE;
-}
-
-/*
- * Notify other partitions to deactivate from us by first disengaging from all
- * references to our memory.
- */
-static void
-xpc_die_deactivate(void)
-{
- struct xpc_partition *part;
- short partid;
- int any_engaged;
- long keep_waiting;
- long wait_to_print;
-
- /* keep xpc_hb_checker thread from doing anything (just in case) */
- xpc_exiting = 1;
-
- xpc_arch_ops.disallow_all_hbs(); /*indicate we're deactivated */
-
- for (partid = 0; partid < xp_max_npartitions; partid++) {
- part = &xpc_partitions[partid];
-
- if (xpc_arch_ops.partition_engaged(partid) ||
- part->act_state != XPC_P_AS_INACTIVE) {
- xpc_arch_ops.request_partition_deactivation(part);
- xpc_arch_ops.indicate_partition_disengaged(part);
- }
- }
-
- /*
- * Though we requested that all other partitions deactivate from us,
- * we only wait until they've all disengaged or we've reached the
- * defined timelimit.
- *
- * Given that one iteration through the following while-loop takes
- * approximately 200 microseconds, calculate the #of loops to take
- * before bailing and the #of loops before printing a waiting message.
- */
- keep_waiting = xpc_disengage_timelimit * 1000 * 5;
- wait_to_print = XPC_DEACTIVATE_PRINTMSG_INTERVAL * 1000 * 5;
-
- while (1) {
- any_engaged = xpc_arch_ops.any_partition_engaged();
- if (!any_engaged) {
- dev_info(xpc_part, "all partitions have deactivated\n");
- break;
- }
-
- if (!keep_waiting--) {
- for (partid = 0; partid < xp_max_npartitions;
- partid++) {
- if (xpc_arch_ops.partition_engaged(partid)) {
- dev_info(xpc_part, "deactivate from "
- "remote partition %d timed "
- "out\n", partid);
- }
- }
- break;
- }
-
- if (!wait_to_print--) {
- dev_info(xpc_part, "waiting for remote partitions to "
- "deactivate, timeout in %ld seconds\n",
- keep_waiting / (1000 * 5));
- wait_to_print = XPC_DEACTIVATE_PRINTMSG_INTERVAL *
- 1000 * 5;
- }
-
- udelay(200);
- }
-}
-
-/*
- * This function is called when the system is being restarted or halted due
- * to some sort of system failure. If this is the case we need to notify the
- * other partitions to disengage from all references to our memory.
- * This function can also be called when our heartbeater could be offlined
- * for a time. In this case we need to notify other partitions to not worry
- * about the lack of a heartbeat.
- */
-static int
-xpc_system_die(struct notifier_block *nb, unsigned long event, void *unused)
-{
-#ifdef CONFIG_IA64 /* !!! temporary kludge */
- switch (event) {
- case DIE_MACHINE_RESTART:
- case DIE_MACHINE_HALT:
- xpc_die_deactivate();
- break;
-
- case DIE_KDEBUG_ENTER:
- /* Should lack of heartbeat be ignored by other partitions? */
- if (!xpc_kdebug_ignore)
- break;
-
- /* fall through */
- case DIE_MCA_MONARCH_ENTER:
- case DIE_INIT_MONARCH_ENTER:
- xpc_arch_ops.offline_heartbeat();
- break;
-
- case DIE_KDEBUG_LEAVE:
- /* Is lack of heartbeat being ignored by other partitions? */
- if (!xpc_kdebug_ignore)
- break;
-
- /* fall through */
- case DIE_MCA_MONARCH_LEAVE:
- case DIE_INIT_MONARCH_LEAVE:
- xpc_arch_ops.online_heartbeat();
- break;
- }
-#else
- xpc_die_deactivate();
-#endif
-
- return NOTIFY_DONE;
-}
-
-int __init
-xpc_init(void)
-{
- int ret;
- struct task_struct *kthread;
-
- dev_set_name(xpc_part, "part");
- dev_set_name(xpc_chan, "chan");
-
- if (is_shub()) {
- /*
- * The ia64-sn2 architecture supports at most 64 partitions.
- * And the inability to unregister remote amos restricts us
- * further to only support exactly 64 partitions on this
- * architecture, no less.
- */
- if (xp_max_npartitions != 64) {
- dev_err(xpc_part, "max #of partitions not set to 64\n");
- ret = -EINVAL;
- } else {
- ret = xpc_init_sn2();
- }
-
- } else if (is_uv()) {
- ret = xpc_init_uv();
-
- } else {
- ret = -ENODEV;
- }
-
- if (ret != 0)
- return ret;
-
- ret = xpc_setup_partitions();
- if (ret != 0) {
- dev_err(xpc_part, "can't get memory for partition structure\n");
- goto out_1;
- }
-
- xpc_sysctl = register_sysctl_table(xpc_sys_dir);
-
- /*
- * Fill the partition reserved page with the information needed by
- * other partitions to discover we are alive and establish initial
- * communications.
- */
- ret = xpc_setup_rsvd_page();
- if (ret != 0) {
- dev_err(xpc_part, "can't setup our reserved page\n");
- goto out_2;
- }
-
- /* add ourselves to the reboot_notifier_list */
- ret = register_reboot_notifier(&xpc_reboot_notifier);
- if (ret != 0)
- dev_warn(xpc_part, "can't register reboot notifier\n");
-
- /* add ourselves to the die_notifier list */
- ret = register_die_notifier(&xpc_die_notifier);
- if (ret != 0)
- dev_warn(xpc_part, "can't register die notifier\n");
-
- /*
- * The real work-horse behind xpc. This processes incoming
- * interrupts and monitors remote heartbeats.
- */
- kthread = kthread_run(xpc_hb_checker, NULL, XPC_HB_CHECK_THREAD_NAME);
- if (IS_ERR(kthread)) {
- dev_err(xpc_part, "failed while forking hb check thread\n");
- ret = -EBUSY;
- goto out_3;
- }
-
- /*
- * Startup a thread that will attempt to discover other partitions to
- * activate based on info provided by SAL. This new thread is short
- * lived and will exit once discovery is complete.
- */
- kthread = kthread_run(xpc_initiate_discovery, NULL,
- XPC_DISCOVERY_THREAD_NAME);
- if (IS_ERR(kthread)) {
- dev_err(xpc_part, "failed while forking discovery thread\n");
-
- /* mark this new thread as a non-starter */
- complete(&xpc_discovery_exited);
-
- xpc_do_exit(xpUnloading);
- return -EBUSY;
- }
-
- /* set the interface to point at XPC's functions */
- xpc_set_interface(xpc_initiate_connect, xpc_initiate_disconnect,
- xpc_initiate_send, xpc_initiate_send_notify,
- xpc_initiate_received, xpc_initiate_partid_to_nasids);
-
- return 0;
-
- /* initialization was not successful */
-out_3:
- xpc_teardown_rsvd_page();
-
- (void)unregister_die_notifier(&xpc_die_notifier);
- (void)unregister_reboot_notifier(&xpc_reboot_notifier);
-out_2:
- if (xpc_sysctl)
- unregister_sysctl_table(xpc_sysctl);
-
- xpc_teardown_partitions();
-out_1:
- if (is_shub())
- xpc_exit_sn2();
- else if (is_uv())
- xpc_exit_uv();
- return ret;
-}
-
-module_init(xpc_init);
-
-void __exit
-xpc_exit(void)
-{
- xpc_do_exit(xpUnloading);
-}
-
-module_exit(xpc_exit);
-
-MODULE_AUTHOR("Silicon Graphics, Inc.");
-MODULE_DESCRIPTION("Cross Partition Communication (XPC) support");
-MODULE_LICENSE("GPL");
-
-module_param(xpc_hb_interval, int, 0);
-MODULE_PARM_DESC(xpc_hb_interval, "Number of seconds between "
- "heartbeat increments.");
-
-module_param(xpc_hb_check_interval, int, 0);
-MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between "
- "heartbeat checks.");
-
-module_param(xpc_disengage_timelimit, int, 0);
-MODULE_PARM_DESC(xpc_disengage_timelimit, "Number of seconds to wait "
- "for disengage to complete.");
-
-module_param(xpc_kdebug_ignore, int, 0);
-MODULE_PARM_DESC(xpc_kdebug_ignore, "Should lack of heartbeat be ignored by "
- "other partitions when dropping into kdebug.");
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_partition.c b/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_partition.c
deleted file mode 100644
index 6956f7e7..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_partition.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * Cross Partition Communication (XPC) partition support.
- *
- * This is the part of XPC that detects the presence/absence of
- * other partitions. It provides a heartbeat and monitors the
- * heartbeats of other partitions.
- *
- */
-
-#include <linux/device.h>
-#include <linux/hardirq.h>
-#include <linux/slab.h>
-#include "xpc.h"
-#include <asm/uv/uv_hub.h>
-
-/* XPC is exiting flag */
-int xpc_exiting;
-
-/* this partition's reserved page pointers */
-struct xpc_rsvd_page *xpc_rsvd_page;
-static unsigned long *xpc_part_nasids;
-unsigned long *xpc_mach_nasids;
-
-static int xpc_nasid_mask_nbytes; /* #of bytes in nasid mask */
-int xpc_nasid_mask_nlongs; /* #of longs in nasid mask */
-
-struct xpc_partition *xpc_partitions;
-
-/*
- * Guarantee that the kmalloc'd memory is cacheline aligned.
- */
-void *
-xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
-{
- /* see if kmalloc will give us cachline aligned memory by default */
- *base = kmalloc(size, flags);
- if (*base == NULL)
- return NULL;
-
- if ((u64)*base == L1_CACHE_ALIGN((u64)*base))
- return *base;
-
- kfree(*base);
-
- /* nope, we'll have to do it ourselves */
- *base = kmalloc(size + L1_CACHE_BYTES, flags);
- if (*base == NULL)
- return NULL;
-
- return (void *)L1_CACHE_ALIGN((u64)*base);
-}
-
-/*
- * Given a nasid, get the physical address of the partition's reserved page
- * for that nasid. This function returns 0 on any error.
- */
-static unsigned long
-xpc_get_rsvd_page_pa(int nasid)
-{
- enum xp_retval ret;
- u64 cookie = 0;
- unsigned long rp_pa = nasid; /* seed with nasid */
- size_t len = 0;
- size_t buf_len = 0;
- void *buf = buf;
- void *buf_base = NULL;
- enum xp_retval (*get_partition_rsvd_page_pa)
- (void *, u64 *, unsigned long *, size_t *) =
- xpc_arch_ops.get_partition_rsvd_page_pa;
-
- while (1) {
-
- /* !!! rp_pa will need to be _gpa on UV.
- * ??? So do we save it into the architecture specific parts
- * ??? of the xpc_partition structure? Do we rename this
- * ??? function or have two versions? Rename rp_pa for UV to
- * ??? rp_gpa?
- */
- ret = get_partition_rsvd_page_pa(buf, &cookie, &rp_pa, &len);
-
- dev_dbg(xpc_part, "SAL returned with ret=%d, cookie=0x%016lx, "
- "address=0x%016lx, len=0x%016lx\n", ret,
- (unsigned long)cookie, rp_pa, len);
-
- if (ret != xpNeedMoreInfo)
- break;
-
- /* !!! L1_CACHE_ALIGN() is only a sn2-bte_copy requirement */
- if (is_shub())
- len = L1_CACHE_ALIGN(len);
-
- if (len > buf_len) {
- if (buf_base != NULL)
- kfree(buf_base);
- buf_len = L1_CACHE_ALIGN(len);
- buf = xpc_kmalloc_cacheline_aligned(buf_len, GFP_KERNEL,
- &buf_base);
- if (buf_base == NULL) {
- dev_err(xpc_part, "unable to kmalloc "
- "len=0x%016lx\n", buf_len);
- ret = xpNoMemory;
- break;
- }
- }
-
- ret = xp_remote_memcpy(xp_pa(buf), rp_pa, len);
- if (ret != xpSuccess) {
- dev_dbg(xpc_part, "xp_remote_memcpy failed %d\n", ret);
- break;
- }
- }
-
- kfree(buf_base);
-
- if (ret != xpSuccess)
- rp_pa = 0;
-
- dev_dbg(xpc_part, "reserved page at phys address 0x%016lx\n", rp_pa);
- return rp_pa;
-}
-
-/*
- * Fill the partition reserved page with the information needed by
- * other partitions to discover we are alive and establish initial
- * communications.
- */
-int
-xpc_setup_rsvd_page(void)
-{
- int ret;
- struct xpc_rsvd_page *rp;
- unsigned long rp_pa;
- unsigned long new_ts_jiffies;
-
- /* get the local reserved page's address */
-
- preempt_disable();
- rp_pa = xpc_get_rsvd_page_pa(xp_cpu_to_nasid(smp_processor_id()));
- preempt_enable();
- if (rp_pa == 0) {
- dev_err(xpc_part, "SAL failed to locate the reserved page\n");
- return -ESRCH;
- }
- rp = (struct xpc_rsvd_page *)__va(xp_socket_pa(rp_pa));
-
- if (rp->SAL_version < 3) {
- /* SAL_versions < 3 had a SAL_partid defined as a u8 */
- rp->SAL_partid &= 0xff;
- }
- BUG_ON(rp->SAL_partid != xp_partition_id);
-
- if (rp->SAL_partid < 0 || rp->SAL_partid >= xp_max_npartitions) {
- dev_err(xpc_part, "the reserved page's partid of %d is outside "
- "supported range (< 0 || >= %d)\n", rp->SAL_partid,
- xp_max_npartitions);
- return -EINVAL;
- }
-
- rp->version = XPC_RP_VERSION;
- rp->max_npartitions = xp_max_npartitions;
-
- /* establish the actual sizes of the nasid masks */
- if (rp->SAL_version == 1) {
- /* SAL_version 1 didn't set the nasids_size field */
- rp->SAL_nasids_size = 128;
- }
- xpc_nasid_mask_nbytes = rp->SAL_nasids_size;
- xpc_nasid_mask_nlongs = BITS_TO_LONGS(rp->SAL_nasids_size *
- BITS_PER_BYTE);
-
- /* setup the pointers to the various items in the reserved page */
- xpc_part_nasids = XPC_RP_PART_NASIDS(rp);
- xpc_mach_nasids = XPC_RP_MACH_NASIDS(rp);
-
- ret = xpc_arch_ops.setup_rsvd_page(rp);
- if (ret != 0)
- return ret;
-
- /*
- * Set timestamp of when reserved page was setup by XPC.
- * This signifies to the remote partition that our reserved
- * page is initialized.
- */
- new_ts_jiffies = jiffies;
- if (new_ts_jiffies == 0 || new_ts_jiffies == rp->ts_jiffies)
- new_ts_jiffies++;
- rp->ts_jiffies = new_ts_jiffies;
-
- xpc_rsvd_page = rp;
- return 0;
-}
-
-void
-xpc_teardown_rsvd_page(void)
-{
- /* a zero timestamp indicates our rsvd page is not initialized */
- xpc_rsvd_page->ts_jiffies = 0;
-}
-
-/*
- * Get a copy of a portion of the remote partition's rsvd page.
- *
- * remote_rp points to a buffer that is cacheline aligned for BTE copies and
- * is large enough to contain a copy of their reserved page header and
- * part_nasids mask.
- */
-enum xp_retval
-xpc_get_remote_rp(int nasid, unsigned long *discovered_nasids,
- struct xpc_rsvd_page *remote_rp, unsigned long *remote_rp_pa)
-{
- int l;
- enum xp_retval ret;
-
- /* get the reserved page's physical address */
-
- *remote_rp_pa = xpc_get_rsvd_page_pa(nasid);
- if (*remote_rp_pa == 0)
- return xpNoRsvdPageAddr;
-
- /* pull over the reserved page header and part_nasids mask */
- ret = xp_remote_memcpy(xp_pa(remote_rp), *remote_rp_pa,
- XPC_RP_HEADER_SIZE + xpc_nasid_mask_nbytes);
- if (ret != xpSuccess)
- return ret;
-
- if (discovered_nasids != NULL) {
- unsigned long *remote_part_nasids =
- XPC_RP_PART_NASIDS(remote_rp);
-
- for (l = 0; l < xpc_nasid_mask_nlongs; l++)
- discovered_nasids[l] |= remote_part_nasids[l];
- }
-
- /* zero timestamp indicates the reserved page has not been setup */
- if (remote_rp->ts_jiffies == 0)
- return xpRsvdPageNotSet;
-
- if (XPC_VERSION_MAJOR(remote_rp->version) !=
- XPC_VERSION_MAJOR(XPC_RP_VERSION)) {
- return xpBadVersion;
- }
-
- /* check that both remote and local partids are valid for each side */
- if (remote_rp->SAL_partid < 0 ||
- remote_rp->SAL_partid >= xp_max_npartitions ||
- remote_rp->max_npartitions <= xp_partition_id) {
- return xpInvalidPartid;
- }
-
- if (remote_rp->SAL_partid == xp_partition_id)
- return xpLocalPartid;
-
- return xpSuccess;
-}
-
-/*
- * See if the other side has responded to a partition deactivate request
- * from us. Though we requested the remote partition to deactivate with regard
- * to us, we really only need to wait for the other side to disengage from us.
- */
-int
-xpc_partition_disengaged(struct xpc_partition *part)
-{
- short partid = XPC_PARTID(part);
- int disengaged;
-
- disengaged = !xpc_arch_ops.partition_engaged(partid);
- if (part->disengage_timeout) {
- if (!disengaged) {
- if (time_is_after_jiffies(part->disengage_timeout)) {
- /* timelimit hasn't been reached yet */
- return 0;
- }
-
- /*
- * Other side hasn't responded to our deactivate
- * request in a timely fashion, so assume it's dead.
- */
-
- dev_info(xpc_part, "deactivate request to remote "
- "partition %d timed out\n", partid);
- xpc_disengage_timedout = 1;
- xpc_arch_ops.assume_partition_disengaged(partid);
- disengaged = 1;
- }
- part->disengage_timeout = 0;
-
- /* cancel the timer function, provided it's not us */
- if (!in_interrupt())
- del_singleshot_timer_sync(&part->disengage_timer);
-
- DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING &&
- part->act_state != XPC_P_AS_INACTIVE);
- if (part->act_state != XPC_P_AS_INACTIVE)
- xpc_wakeup_channel_mgr(part);
-
- xpc_arch_ops.cancel_partition_deactivation_request(part);
- }
- return disengaged;
-}
-
-/*
- * Mark specified partition as active.
- */
-enum xp_retval
-xpc_mark_partition_active(struct xpc_partition *part)
-{
- unsigned long irq_flags;
- enum xp_retval ret;
-
- dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part));
-
- spin_lock_irqsave(&part->act_lock, irq_flags);
- if (part->act_state == XPC_P_AS_ACTIVATING) {
- part->act_state = XPC_P_AS_ACTIVE;
- ret = xpSuccess;
- } else {
- DBUG_ON(part->reason == xpSuccess);
- ret = part->reason;
- }
- spin_unlock_irqrestore(&part->act_lock, irq_flags);
-
- return ret;
-}
-
-/*
- * Start the process of deactivating the specified partition.
- */
-void
-xpc_deactivate_partition(const int line, struct xpc_partition *part,
- enum xp_retval reason)
-{
- unsigned long irq_flags;
-
- spin_lock_irqsave(&part->act_lock, irq_flags);
-
- if (part->act_state == XPC_P_AS_INACTIVE) {
- XPC_SET_REASON(part, reason, line);
- spin_unlock_irqrestore(&part->act_lock, irq_flags);
- if (reason == xpReactivating) {
- /* we interrupt ourselves to reactivate partition */
- xpc_arch_ops.request_partition_reactivation(part);
- }
- return;
- }
- if (part->act_state == XPC_P_AS_DEACTIVATING) {
- if ((part->reason == xpUnloading && reason != xpUnloading) ||
- reason == xpReactivating) {
- XPC_SET_REASON(part, reason, line);
- }
- spin_unlock_irqrestore(&part->act_lock, irq_flags);
- return;
- }
-
- part->act_state = XPC_P_AS_DEACTIVATING;
- XPC_SET_REASON(part, reason, line);
-
- spin_unlock_irqrestore(&part->act_lock, irq_flags);
-
- /* ask remote partition to deactivate with regard to us */
- xpc_arch_ops.request_partition_deactivation(part);
-
- /* set a timelimit on the disengage phase of the deactivation request */
- part->disengage_timeout = jiffies + (xpc_disengage_timelimit * HZ);
- part->disengage_timer.expires = part->disengage_timeout;
- add_timer(&part->disengage_timer);
-
- dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n",
- XPC_PARTID(part), reason);
-
- xpc_partition_going_down(part, reason);
-}
-
-/*
- * Mark specified partition as inactive.
- */
-void
-xpc_mark_partition_inactive(struct xpc_partition *part)
-{
- unsigned long irq_flags;
-
- dev_dbg(xpc_part, "setting partition %d to INACTIVE\n",
- XPC_PARTID(part));
-
- spin_lock_irqsave(&part->act_lock, irq_flags);
- part->act_state = XPC_P_AS_INACTIVE;
- spin_unlock_irqrestore(&part->act_lock, irq_flags);
- part->remote_rp_pa = 0;
-}
-
-/*
- * SAL has provided a partition and machine mask. The partition mask
- * contains a bit for each even nasid in our partition. The machine
- * mask contains a bit for each even nasid in the entire machine.
- *
- * Using those two bit arrays, we can determine which nasids are
- * known in the machine. Each should also have a reserved page
- * initialized if they are available for partitioning.
- */
-void
-xpc_discovery(void)
-{
- void *remote_rp_base;
- struct xpc_rsvd_page *remote_rp;
- unsigned long remote_rp_pa;
- int region;
- int region_size;
- int max_regions;
- int nasid;
- struct xpc_rsvd_page *rp;
- unsigned long *discovered_nasids;
- enum xp_retval ret;
-
- remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
- xpc_nasid_mask_nbytes,
- GFP_KERNEL, &remote_rp_base);
- if (remote_rp == NULL)
- return;
-
- discovered_nasids = kzalloc(sizeof(long) * xpc_nasid_mask_nlongs,
- GFP_KERNEL);
- if (discovered_nasids == NULL) {
- kfree(remote_rp_base);
- return;
- }
-
- rp = (struct xpc_rsvd_page *)xpc_rsvd_page;
-
- /*
- * The term 'region' in this context refers to the minimum number of
- * nodes that can comprise an access protection grouping. The access
- * protection is in regards to memory, IOI and IPI.
- */
- region_size = xp_region_size;
-
- if (is_uv())
- max_regions = 256;
- else {
- max_regions = 64;
-
- switch (region_size) {
- case 128:
- max_regions *= 2;
- case 64:
- max_regions *= 2;
- case 32:
- max_regions *= 2;
- region_size = 16;
- DBUG_ON(!is_shub2());
- }
- }
-
- for (region = 0; region < max_regions; region++) {
-
- if (xpc_exiting)
- break;
-
- dev_dbg(xpc_part, "searching region %d\n", region);
-
- for (nasid = (region * region_size * 2);
- nasid < ((region + 1) * region_size * 2); nasid += 2) {
-
- if (xpc_exiting)
- break;
-
- dev_dbg(xpc_part, "checking nasid %d\n", nasid);
-
- if (test_bit(nasid / 2, xpc_part_nasids)) {
- dev_dbg(xpc_part, "PROM indicates Nasid %d is "
- "part of the local partition; skipping "
- "region\n", nasid);
- break;
- }
-
- if (!(test_bit(nasid / 2, xpc_mach_nasids))) {
- dev_dbg(xpc_part, "PROM indicates Nasid %d was "
- "not on Numa-Link network at reset\n",
- nasid);
- continue;
- }
-
- if (test_bit(nasid / 2, discovered_nasids)) {
- dev_dbg(xpc_part, "Nasid %d is part of a "
- "partition which was previously "
- "discovered\n", nasid);
- continue;
- }
-
- /* pull over the rsvd page header & part_nasids mask */
-
- ret = xpc_get_remote_rp(nasid, discovered_nasids,
- remote_rp, &remote_rp_pa);
- if (ret != xpSuccess) {
- dev_dbg(xpc_part, "unable to get reserved page "
- "from nasid %d, reason=%d\n", nasid,
- ret);
-
- if (ret == xpLocalPartid)
- break;
-
- continue;
- }
-
- xpc_arch_ops.request_partition_activation(remote_rp,
- remote_rp_pa, nasid);
- }
- }
-
- kfree(discovered_nasids);
- kfree(remote_rp_base);
-}
-
-/*
- * Given a partid, get the nasids owned by that partition from the
- * remote partition's reserved page.
- */
-enum xp_retval
-xpc_initiate_partid_to_nasids(short partid, void *nasid_mask)
-{
- struct xpc_partition *part;
- unsigned long part_nasid_pa;
-
- part = &xpc_partitions[partid];
- if (part->remote_rp_pa == 0)
- return xpPartitionDown;
-
- memset(nasid_mask, 0, xpc_nasid_mask_nbytes);
-
- part_nasid_pa = (unsigned long)XPC_RP_PART_NASIDS(part->remote_rp_pa);
-
- return xp_remote_memcpy(xp_pa(nasid_mask), part_nasid_pa,
- xpc_nasid_mask_nbytes);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_sn2.c b/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_sn2.c
deleted file mode 100644
index 7d71c04f..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_sn2.c
+++ /dev/null
@@ -1,2462 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * Cross Partition Communication (XPC) sn2-based functions.
- *
- * Architecture specific implementation of common functions.
- *
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <asm/uncached.h>
-#include <asm/sn/mspec.h>
-#include <asm/sn/sn_sal.h>
-#include "xpc.h"
-
-/*
- * Define the number of u64s required to represent all the C-brick nasids
- * as a bitmap. The cross-partition kernel modules deal only with
- * C-brick nasids, thus the need for bitmaps which don't account for
- * odd-numbered (non C-brick) nasids.
- */
-#define XPC_MAX_PHYSNODES_SN2 (MAX_NUMALINK_NODES / 2)
-#define XP_NASID_MASK_BYTES_SN2 ((XPC_MAX_PHYSNODES_SN2 + 7) / 8)
-#define XP_NASID_MASK_WORDS_SN2 ((XPC_MAX_PHYSNODES_SN2 + 63) / 64)
-
-/*
- * Memory for XPC's amo variables is allocated by the MSPEC driver. These
- * pages are located in the lowest granule. The lowest granule uses 4k pages
- * for cached references and an alternate TLB handler to never provide a
- * cacheable mapping for the entire region. This will prevent speculative
- * reading of cached copies of our lines from being issued which will cause
- * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
- * amo variables (based on XP_MAX_NPARTITIONS_SN2) to identify the senders of
- * NOTIFY IRQs, 128 amo variables (based on XP_NASID_MASK_WORDS_SN2) to identify
- * the senders of ACTIVATE IRQs, 1 amo variable to identify which remote
- * partitions (i.e., XPCs) consider themselves currently engaged with the
- * local XPC and 1 amo variable to request partition deactivation.
- */
-#define XPC_NOTIFY_IRQ_AMOS_SN2 0
-#define XPC_ACTIVATE_IRQ_AMOS_SN2 (XPC_NOTIFY_IRQ_AMOS_SN2 + \
- XP_MAX_NPARTITIONS_SN2)
-#define XPC_ENGAGED_PARTITIONS_AMO_SN2 (XPC_ACTIVATE_IRQ_AMOS_SN2 + \
- XP_NASID_MASK_WORDS_SN2)
-#define XPC_DEACTIVATE_REQUEST_AMO_SN2 (XPC_ENGAGED_PARTITIONS_AMO_SN2 + 1)
-
-/*
- * Buffer used to store a local copy of portions of a remote partition's
- * reserved page (either its header and part_nasids mask, or its vars).
- */
-static void *xpc_remote_copy_buffer_base_sn2;
-static char *xpc_remote_copy_buffer_sn2;
-
-static struct xpc_vars_sn2 *xpc_vars_sn2;
-static struct xpc_vars_part_sn2 *xpc_vars_part_sn2;
-
-static int
-xpc_setup_partitions_sn2(void)
-{
- /* nothing needs to be done */
- return 0;
-}
-
-static void
-xpc_teardown_partitions_sn2(void)
-{
- /* nothing needs to be done */
-}
-
-/* SH_IPI_ACCESS shub register value on startup */
-static u64 xpc_sh1_IPI_access_sn2;
-static u64 xpc_sh2_IPI_access0_sn2;
-static u64 xpc_sh2_IPI_access1_sn2;
-static u64 xpc_sh2_IPI_access2_sn2;
-static u64 xpc_sh2_IPI_access3_sn2;
-
-/*
- * Change protections to allow IPI operations.
- */
-static void
-xpc_allow_IPI_ops_sn2(void)
-{
- int node;
- int nasid;
-
- /* !!! The following should get moved into SAL. */
- if (is_shub2()) {
- xpc_sh2_IPI_access0_sn2 =
- (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS0));
- xpc_sh2_IPI_access1_sn2 =
- (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS1));
- xpc_sh2_IPI_access2_sn2 =
- (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS2));
- xpc_sh2_IPI_access3_sn2 =
- (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS3));
-
- for_each_online_node(node) {
- nasid = cnodeid_to_nasid(node);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
- -1UL);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
- -1UL);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
- -1UL);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
- -1UL);
- }
- } else {
- xpc_sh1_IPI_access_sn2 =
- (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH1_IPI_ACCESS));
-
- for_each_online_node(node) {
- nasid = cnodeid_to_nasid(node);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
- -1UL);
- }
- }
-}
-
-/*
- * Restrict protections to disallow IPI operations.
- */
-static void
-xpc_disallow_IPI_ops_sn2(void)
-{
- int node;
- int nasid;
-
- /* !!! The following should get moved into SAL. */
- if (is_shub2()) {
- for_each_online_node(node) {
- nasid = cnodeid_to_nasid(node);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
- xpc_sh2_IPI_access0_sn2);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
- xpc_sh2_IPI_access1_sn2);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
- xpc_sh2_IPI_access2_sn2);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
- xpc_sh2_IPI_access3_sn2);
- }
- } else {
- for_each_online_node(node) {
- nasid = cnodeid_to_nasid(node);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
- xpc_sh1_IPI_access_sn2);
- }
- }
-}
-
-/*
- * The following set of functions are used for the sending and receiving of
- * IRQs (also known as IPIs). There are two flavors of IRQs, one that is
- * associated with partition activity (SGI_XPC_ACTIVATE) and the other that
- * is associated with channel activity (SGI_XPC_NOTIFY).
- */
-
-static u64
-xpc_receive_IRQ_amo_sn2(struct amo *amo)
-{
- return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_CLEAR);
-}
-
-static enum xp_retval
-xpc_send_IRQ_sn2(struct amo *amo, u64 flag, int nasid, int phys_cpuid,
- int vector)
-{
- int ret = 0;
- unsigned long irq_flags;
-
- local_irq_save(irq_flags);
-
- FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR, flag);
- sn_send_IPI_phys(nasid, phys_cpuid, vector, 0);
-
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IRQs and amos to it until the heartbeat times out.
- */
- ret = xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->variable),
- xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
-
- return (ret == 0) ? xpSuccess : xpPioReadError;
-}
-
-static struct amo *
-xpc_init_IRQ_amo_sn2(int index)
-{
- struct amo *amo = xpc_vars_sn2->amos_page + index;
-
- (void)xpc_receive_IRQ_amo_sn2(amo); /* clear amo variable */
- return amo;
-}
-
-/*
- * Functions associated with SGI_XPC_ACTIVATE IRQ.
- */
-
-/*
- * Notify the heartbeat check thread that an activate IRQ has been received.
- */
-static irqreturn_t
-xpc_handle_activate_IRQ_sn2(int irq, void *dev_id)
-{
- unsigned long irq_flags;
-
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- xpc_activate_IRQ_rcvd++;
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- wake_up_interruptible(&xpc_activate_IRQ_wq);
- return IRQ_HANDLED;
-}
-
-/*
- * Flag the appropriate amo variable and send an IRQ to the specified node.
- */
-static void
-xpc_send_activate_IRQ_sn2(unsigned long amos_page_pa, int from_nasid,
- int to_nasid, int to_phys_cpuid)
-{
- struct amo *amos = (struct amo *)__va(amos_page_pa +
- (XPC_ACTIVATE_IRQ_AMOS_SN2 *
- sizeof(struct amo)));
-
- (void)xpc_send_IRQ_sn2(&amos[BIT_WORD(from_nasid / 2)],
- BIT_MASK(from_nasid / 2), to_nasid,
- to_phys_cpuid, SGI_XPC_ACTIVATE);
-}
-
-static void
-xpc_send_local_activate_IRQ_sn2(int from_nasid)
-{
- unsigned long irq_flags;
- struct amo *amos = (struct amo *)__va(xpc_vars_sn2->amos_page_pa +
- (XPC_ACTIVATE_IRQ_AMOS_SN2 *
- sizeof(struct amo)));
-
- /* fake the sending and receipt of an activate IRQ from remote nasid */
- FETCHOP_STORE_OP(TO_AMO((u64)&amos[BIT_WORD(from_nasid / 2)].variable),
- FETCHOP_OR, BIT_MASK(from_nasid / 2));
-
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- xpc_activate_IRQ_rcvd++;
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- wake_up_interruptible(&xpc_activate_IRQ_wq);
-}
-
-/*
- * Functions associated with SGI_XPC_NOTIFY IRQ.
- */
-
-/*
- * Check to see if any chctl flags were sent from the specified partition.
- */
-static void
-xpc_check_for_sent_chctl_flags_sn2(struct xpc_partition *part)
-{
- union xpc_channel_ctl_flags chctl;
- unsigned long irq_flags;
-
- chctl.all_flags = xpc_receive_IRQ_amo_sn2(part->sn.sn2.
- local_chctl_amo_va);
- if (chctl.all_flags == 0)
- return;
-
- spin_lock_irqsave(&part->chctl_lock, irq_flags);
- part->chctl.all_flags |= chctl.all_flags;
- spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
- dev_dbg(xpc_chan, "received notify IRQ from partid=%d, chctl.all_flags="
- "0x%llx\n", XPC_PARTID(part), chctl.all_flags);
-
- xpc_wakeup_channel_mgr(part);
-}
-
-/*
- * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified
- * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more
- * than one partition, we use an amo structure per partition to indicate
- * whether a partition has sent an IRQ or not. If it has, then wake up the
- * associated kthread to handle it.
- *
- * All SGI_XPC_NOTIFY IRQs received by XPC are the result of IRQs sent by XPC
- * running on other partitions.
- *
- * Noteworthy Arguments:
- *
- * irq - Interrupt ReQuest number. NOT USED.
- *
- * dev_id - partid of IRQ's potential sender.
- */
-static irqreturn_t
-xpc_handle_notify_IRQ_sn2(int irq, void *dev_id)
-{
- short partid = (short)(u64)dev_id;
- struct xpc_partition *part = &xpc_partitions[partid];
-
- DBUG_ON(partid < 0 || partid >= XP_MAX_NPARTITIONS_SN2);
-
- if (xpc_part_ref(part)) {
- xpc_check_for_sent_chctl_flags_sn2(part);
-
- xpc_part_deref(part);
- }
- return IRQ_HANDLED;
-}
-
-/*
- * Check to see if xpc_handle_notify_IRQ_sn2() dropped any IRQs on the floor
- * because the write to their associated amo variable completed after the IRQ
- * was received.
- */
-static void
-xpc_check_for_dropped_notify_IRQ_sn2(struct xpc_partition *part)
-{
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-
- if (xpc_part_ref(part)) {
- xpc_check_for_sent_chctl_flags_sn2(part);
-
- part_sn2->dropped_notify_IRQ_timer.expires = jiffies +
- XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL;
- add_timer(&part_sn2->dropped_notify_IRQ_timer);
- xpc_part_deref(part);
- }
-}
-
-/*
- * Send a notify IRQ to the remote partition that is associated with the
- * specified channel.
- */
-static void
-xpc_send_notify_IRQ_sn2(struct xpc_channel *ch, u8 chctl_flag,
- char *chctl_flag_string, unsigned long *irq_flags)
-{
- struct xpc_partition *part = &xpc_partitions[ch->partid];
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
- union xpc_channel_ctl_flags chctl = { 0 };
- enum xp_retval ret;
-
- if (likely(part->act_state != XPC_P_AS_DEACTIVATING)) {
- chctl.flags[ch->number] = chctl_flag;
- ret = xpc_send_IRQ_sn2(part_sn2->remote_chctl_amo_va,
- chctl.all_flags,
- part_sn2->notify_IRQ_nasid,
- part_sn2->notify_IRQ_phys_cpuid,
- SGI_XPC_NOTIFY);
- dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
- chctl_flag_string, ch->partid, ch->number, ret);
- if (unlikely(ret != xpSuccess)) {
- if (irq_flags != NULL)
- spin_unlock_irqrestore(&ch->lock, *irq_flags);
- XPC_DEACTIVATE_PARTITION(part, ret);
- if (irq_flags != NULL)
- spin_lock_irqsave(&ch->lock, *irq_flags);
- }
- }
-}
-
-#define XPC_SEND_NOTIFY_IRQ_SN2(_ch, _ipi_f, _irq_f) \
- xpc_send_notify_IRQ_sn2(_ch, _ipi_f, #_ipi_f, _irq_f)
-
-/*
- * Make it look like the remote partition, which is associated with the
- * specified channel, sent us a notify IRQ. This faked IRQ will be handled
- * by xpc_check_for_dropped_notify_IRQ_sn2().
- */
-static void
-xpc_send_local_notify_IRQ_sn2(struct xpc_channel *ch, u8 chctl_flag,
- char *chctl_flag_string)
-{
- struct xpc_partition *part = &xpc_partitions[ch->partid];
- union xpc_channel_ctl_flags chctl = { 0 };
-
- chctl.flags[ch->number] = chctl_flag;
- FETCHOP_STORE_OP(TO_AMO((u64)&part->sn.sn2.local_chctl_amo_va->
- variable), FETCHOP_OR, chctl.all_flags);
- dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n",
- chctl_flag_string, ch->partid, ch->number);
-}
-
-#define XPC_SEND_LOCAL_NOTIFY_IRQ_SN2(_ch, _ipi_f) \
- xpc_send_local_notify_IRQ_sn2(_ch, _ipi_f, #_ipi_f)
-
-static void
-xpc_send_chctl_closerequest_sn2(struct xpc_channel *ch,
- unsigned long *irq_flags)
-{
- struct xpc_openclose_args *args = ch->sn.sn2.local_openclose_args;
-
- args->reason = ch->reason;
- XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_CLOSEREQUEST, irq_flags);
-}
-
-static void
-xpc_send_chctl_closereply_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_CLOSEREPLY, irq_flags);
-}
-
-static void
-xpc_send_chctl_openrequest_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- struct xpc_openclose_args *args = ch->sn.sn2.local_openclose_args;
-
- args->entry_size = ch->entry_size;
- args->local_nentries = ch->local_nentries;
- XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENREQUEST, irq_flags);
-}
-
-static void
-xpc_send_chctl_openreply_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- struct xpc_openclose_args *args = ch->sn.sn2.local_openclose_args;
-
- args->remote_nentries = ch->remote_nentries;
- args->local_nentries = ch->local_nentries;
- args->local_msgqueue_pa = xp_pa(ch->sn.sn2.local_msgqueue);
- XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENREPLY, irq_flags);
-}
-
-static void
-xpc_send_chctl_opencomplete_sn2(struct xpc_channel *ch,
- unsigned long *irq_flags)
-{
- XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENCOMPLETE, irq_flags);
-}
-
-static void
-xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch)
-{
- XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST, NULL);
-}
-
-static void
-xpc_send_chctl_local_msgrequest_sn2(struct xpc_channel *ch)
-{
- XPC_SEND_LOCAL_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST);
-}
-
-static enum xp_retval
-xpc_save_remote_msgqueue_pa_sn2(struct xpc_channel *ch,
- unsigned long msgqueue_pa)
-{
- ch->sn.sn2.remote_msgqueue_pa = msgqueue_pa;
- return xpSuccess;
-}
-
-/*
- * This next set of functions are used to keep track of when a partition is
- * potentially engaged in accessing memory belonging to another partition.
- */
-
-static void
-xpc_indicate_partition_engaged_sn2(struct xpc_partition *part)
-{
- unsigned long irq_flags;
- struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa +
- (XPC_ENGAGED_PARTITIONS_AMO_SN2 *
- sizeof(struct amo)));
-
- local_irq_save(irq_flags);
-
- /* set bit corresponding to our partid in remote partition's amo */
- FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
- BIT(sn_partition_id));
-
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IRQs and amos to it until the heartbeat times out.
- */
- (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
- variable),
- xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
-}
-
-static void
-xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part)
-{
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
- unsigned long irq_flags;
- struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa +
- (XPC_ENGAGED_PARTITIONS_AMO_SN2 *
- sizeof(struct amo)));
-
- local_irq_save(irq_flags);
-
- /* clear bit corresponding to our partid in remote partition's amo */
- FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
- ~BIT(sn_partition_id));
-
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IRQs and amos to it until the heartbeat times out.
- */
- (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
- variable),
- xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
-
- /*
- * Send activate IRQ to get other side to see that we've cleared our
- * bit in their engaged partitions amo.
- */
- xpc_send_activate_IRQ_sn2(part_sn2->remote_amos_page_pa,
- cnodeid_to_nasid(0),
- part_sn2->activate_IRQ_nasid,
- part_sn2->activate_IRQ_phys_cpuid);
-}
-
-static void
-xpc_assume_partition_disengaged_sn2(short partid)
-{
- struct amo *amo = xpc_vars_sn2->amos_page +
- XPC_ENGAGED_PARTITIONS_AMO_SN2;
-
- /* clear bit(s) based on partid mask in our partition's amo */
- FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
- ~BIT(partid));
-}
-
-static int
-xpc_partition_engaged_sn2(short partid)
-{
- struct amo *amo = xpc_vars_sn2->amos_page +
- XPC_ENGAGED_PARTITIONS_AMO_SN2;
-
- /* our partition's amo variable ANDed with partid mask */
- return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
- BIT(partid)) != 0;
-}
-
-static int
-xpc_any_partition_engaged_sn2(void)
-{
- struct amo *amo = xpc_vars_sn2->amos_page +
- XPC_ENGAGED_PARTITIONS_AMO_SN2;
-
- /* our partition's amo variable */
- return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0;
-}
-
-/* original protection values for each node */
-static u64 xpc_prot_vec_sn2[MAX_NUMNODES];
-
-/*
- * Change protections to allow amo operations on non-Shub 1.1 systems.
- */
-static enum xp_retval
-xpc_allow_amo_ops_sn2(struct amo *amos_page)
-{
- enum xp_retval ret = xpSuccess;
-
- /*
- * On SHUB 1.1, we cannot call sn_change_memprotect() since the BIST
- * collides with memory operations. On those systems we call
- * xpc_allow_amo_ops_shub_wars_1_1_sn2() instead.
- */
- if (!enable_shub_wars_1_1())
- ret = xp_expand_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE);
-
- return ret;
-}
-
-/*
- * Change protections to allow amo operations on Shub 1.1 systems.
- */
-static void
-xpc_allow_amo_ops_shub_wars_1_1_sn2(void)
-{
- int node;
- int nasid;
-
- if (!enable_shub_wars_1_1())
- return;
-
- for_each_online_node(node) {
- nasid = cnodeid_to_nasid(node);
- /* save current protection values */
- xpc_prot_vec_sn2[node] =
- (u64)HUB_L((u64 *)GLOBAL_MMR_ADDR(nasid,
- SH1_MD_DQLP_MMR_DIR_PRIVEC0));
- /* open up everything */
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid,
- SH1_MD_DQLP_MMR_DIR_PRIVEC0),
- -1UL);
- HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid,
- SH1_MD_DQRP_MMR_DIR_PRIVEC0),
- -1UL);
- }
-}
-
-static enum xp_retval
-xpc_get_partition_rsvd_page_pa_sn2(void *buf, u64 *cookie, unsigned long *rp_pa,
- size_t *len)
-{
- s64 status;
- enum xp_retval ret;
-
- status = sn_partition_reserved_page_pa((u64)buf, cookie,
- (u64 *)rp_pa, (u64 *)len);
- if (status == SALRET_OK)
- ret = xpSuccess;
- else if (status == SALRET_MORE_PASSES)
- ret = xpNeedMoreInfo;
- else
- ret = xpSalError;
-
- return ret;
-}
-
-
-static int
-xpc_setup_rsvd_page_sn2(struct xpc_rsvd_page *rp)
-{
- struct amo *amos_page;
- int i;
- int ret;
-
- xpc_vars_sn2 = XPC_RP_VARS(rp);
-
- rp->sn.sn2.vars_pa = xp_pa(xpc_vars_sn2);
-
- /* vars_part array follows immediately after vars */
- xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) +
- XPC_RP_VARS_SIZE);
-
- /*
- * Before clearing xpc_vars_sn2, see if a page of amos had been
- * previously allocated. If not we'll need to allocate one and set
- * permissions so that cross-partition amos are allowed.
- *
- * The allocated amo page needs MCA reporting to remain disabled after
- * XPC has unloaded. To make this work, we keep a copy of the pointer
- * to this page (i.e., amos_page) in the struct xpc_vars_sn2 structure,
- * which is pointed to by the reserved page, and re-use that saved copy
- * on subsequent loads of XPC. This amo page is never freed, and its
- * memory protections are never restricted.
- */
- amos_page = xpc_vars_sn2->amos_page;
- if (amos_page == NULL) {
- amos_page = (struct amo *)TO_AMO(uncached_alloc_page(0, 1));
- if (amos_page == NULL) {
- dev_err(xpc_part, "can't allocate page of amos\n");
- return -ENOMEM;
- }
-
- /*
- * Open up amo-R/W to cpu. This is done on Shub 1.1 systems
- * when xpc_allow_amo_ops_shub_wars_1_1_sn2() is called.
- */
- ret = xpc_allow_amo_ops_sn2(amos_page);
- if (ret != xpSuccess) {
- dev_err(xpc_part, "can't allow amo operations\n");
- uncached_free_page(__IA64_UNCACHED_OFFSET |
- TO_PHYS((u64)amos_page), 1);
- return -EPERM;
- }
- }
-
- /* clear xpc_vars_sn2 */
- memset(xpc_vars_sn2, 0, sizeof(struct xpc_vars_sn2));
-
- xpc_vars_sn2->version = XPC_V_VERSION;
- xpc_vars_sn2->activate_IRQ_nasid = cpuid_to_nasid(0);
- xpc_vars_sn2->activate_IRQ_phys_cpuid = cpu_physical_id(0);
- xpc_vars_sn2->vars_part_pa = xp_pa(xpc_vars_part_sn2);
- xpc_vars_sn2->amos_page_pa = ia64_tpa((u64)amos_page);
- xpc_vars_sn2->amos_page = amos_page; /* save for next load of XPC */
-
- /* clear xpc_vars_part_sn2 */
- memset((u64 *)xpc_vars_part_sn2, 0, sizeof(struct xpc_vars_part_sn2) *
- XP_MAX_NPARTITIONS_SN2);
-
- /* initialize the activate IRQ related amo variables */
- for (i = 0; i < xpc_nasid_mask_nlongs; i++)
- (void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS_SN2 + i);
-
- /* initialize the engaged remote partitions related amo variables */
- (void)xpc_init_IRQ_amo_sn2(XPC_ENGAGED_PARTITIONS_AMO_SN2);
- (void)xpc_init_IRQ_amo_sn2(XPC_DEACTIVATE_REQUEST_AMO_SN2);
-
- return 0;
-}
-
-static int
-xpc_hb_allowed_sn2(short partid, void *heartbeating_to_mask)
-{
- return test_bit(partid, heartbeating_to_mask);
-}
-
-static void
-xpc_allow_hb_sn2(short partid)
-{
- DBUG_ON(xpc_vars_sn2 == NULL);
- set_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
-}
-
-static void
-xpc_disallow_hb_sn2(short partid)
-{
- DBUG_ON(xpc_vars_sn2 == NULL);
- clear_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
-}
-
-static void
-xpc_disallow_all_hbs_sn2(void)
-{
- DBUG_ON(xpc_vars_sn2 == NULL);
- bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, xp_max_npartitions);
-}
-
-static void
-xpc_increment_heartbeat_sn2(void)
-{
- xpc_vars_sn2->heartbeat++;
-}
-
-static void
-xpc_offline_heartbeat_sn2(void)
-{
- xpc_increment_heartbeat_sn2();
- xpc_vars_sn2->heartbeat_offline = 1;
-}
-
-static void
-xpc_online_heartbeat_sn2(void)
-{
- xpc_increment_heartbeat_sn2();
- xpc_vars_sn2->heartbeat_offline = 0;
-}
-
-static void
-xpc_heartbeat_init_sn2(void)
-{
- DBUG_ON(xpc_vars_sn2 == NULL);
-
- bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
- xpc_online_heartbeat_sn2();
-}
-
-static void
-xpc_heartbeat_exit_sn2(void)
-{
- xpc_offline_heartbeat_sn2();
-}
-
-static enum xp_retval
-xpc_get_remote_heartbeat_sn2(struct xpc_partition *part)
-{
- struct xpc_vars_sn2 *remote_vars;
- enum xp_retval ret;
-
- remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2;
-
- /* pull the remote vars structure that contains the heartbeat */
- ret = xp_remote_memcpy(xp_pa(remote_vars),
- part->sn.sn2.remote_vars_pa,
- XPC_RP_VARS_SIZE);
- if (ret != xpSuccess)
- return ret;
-
- dev_dbg(xpc_part, "partid=%d, heartbeat=%lld, last_heartbeat=%lld, "
- "heartbeat_offline=%lld, HB_mask[0]=0x%lx\n", XPC_PARTID(part),
- remote_vars->heartbeat, part->last_heartbeat,
- remote_vars->heartbeat_offline,
- remote_vars->heartbeating_to_mask[0]);
-
- if ((remote_vars->heartbeat == part->last_heartbeat &&
- !remote_vars->heartbeat_offline) ||
- !xpc_hb_allowed_sn2(sn_partition_id,
- remote_vars->heartbeating_to_mask)) {
- ret = xpNoHeartbeat;
- } else {
- part->last_heartbeat = remote_vars->heartbeat;
- }
-
- return ret;
-}
-
-/*
- * Get a copy of the remote partition's XPC variables from the reserved page.
- *
- * remote_vars points to a buffer that is cacheline aligned for BTE copies and
- * assumed to be of size XPC_RP_VARS_SIZE.
- */
-static enum xp_retval
-xpc_get_remote_vars_sn2(unsigned long remote_vars_pa,
- struct xpc_vars_sn2 *remote_vars)
-{
- enum xp_retval ret;
-
- if (remote_vars_pa == 0)
- return xpVarsNotSet;
-
- /* pull over the cross partition variables */
- ret = xp_remote_memcpy(xp_pa(remote_vars), remote_vars_pa,
- XPC_RP_VARS_SIZE);
- if (ret != xpSuccess)
- return ret;
-
- if (XPC_VERSION_MAJOR(remote_vars->version) !=
- XPC_VERSION_MAJOR(XPC_V_VERSION)) {
- return xpBadVersion;
- }
-
- return xpSuccess;
-}
-
-static void
-xpc_request_partition_activation_sn2(struct xpc_rsvd_page *remote_rp,
- unsigned long remote_rp_pa, int nasid)
-{
- xpc_send_local_activate_IRQ_sn2(nasid);
-}
-
-static void
-xpc_request_partition_reactivation_sn2(struct xpc_partition *part)
-{
- xpc_send_local_activate_IRQ_sn2(part->sn.sn2.activate_IRQ_nasid);
-}
-
-static void
-xpc_request_partition_deactivation_sn2(struct xpc_partition *part)
-{
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
- unsigned long irq_flags;
- struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa +
- (XPC_DEACTIVATE_REQUEST_AMO_SN2 *
- sizeof(struct amo)));
-
- local_irq_save(irq_flags);
-
- /* set bit corresponding to our partid in remote partition's amo */
- FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
- BIT(sn_partition_id));
-
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IRQs and amos to it until the heartbeat times out.
- */
- (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
- variable),
- xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
-
- /*
- * Send activate IRQ to get other side to see that we've set our
- * bit in their deactivate request amo.
- */
- xpc_send_activate_IRQ_sn2(part_sn2->remote_amos_page_pa,
- cnodeid_to_nasid(0),
- part_sn2->activate_IRQ_nasid,
- part_sn2->activate_IRQ_phys_cpuid);
-}
-
-static void
-xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part)
-{
- unsigned long irq_flags;
- struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa +
- (XPC_DEACTIVATE_REQUEST_AMO_SN2 *
- sizeof(struct amo)));
-
- local_irq_save(irq_flags);
-
- /* clear bit corresponding to our partid in remote partition's amo */
- FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
- ~BIT(sn_partition_id));
-
- /*
- * We must always use the nofault function regardless of whether we
- * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
- * didn't, we'd never know that the other partition is down and would
- * keep sending IRQs and amos to it until the heartbeat times out.
- */
- (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
- variable),
- xp_nofault_PIOR_target));
-
- local_irq_restore(irq_flags);
-}
-
-static int
-xpc_partition_deactivation_requested_sn2(short partid)
-{
- struct amo *amo = xpc_vars_sn2->amos_page +
- XPC_DEACTIVATE_REQUEST_AMO_SN2;
-
- /* our partition's amo variable ANDed with partid mask */
- return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
- BIT(partid)) != 0;
-}
-
-/*
- * Update the remote partition's info.
- */
-static void
-xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version,
- unsigned long *remote_rp_ts_jiffies,
- unsigned long remote_rp_pa,
- unsigned long remote_vars_pa,
- struct xpc_vars_sn2 *remote_vars)
-{
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-
- part->remote_rp_version = remote_rp_version;
- dev_dbg(xpc_part, " remote_rp_version = 0x%016x\n",
- part->remote_rp_version);
-
- part->remote_rp_ts_jiffies = *remote_rp_ts_jiffies;
- dev_dbg(xpc_part, " remote_rp_ts_jiffies = 0x%016lx\n",
- part->remote_rp_ts_jiffies);
-
- part->remote_rp_pa = remote_rp_pa;
- dev_dbg(xpc_part, " remote_rp_pa = 0x%016lx\n", part->remote_rp_pa);
-
- part_sn2->remote_vars_pa = remote_vars_pa;
- dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n",
- part_sn2->remote_vars_pa);
-
- part->last_heartbeat = remote_vars->heartbeat - 1;
- dev_dbg(xpc_part, " last_heartbeat = 0x%016llx\n",
- part->last_heartbeat);
-
- part_sn2->remote_vars_part_pa = remote_vars->vars_part_pa;
- dev_dbg(xpc_part, " remote_vars_part_pa = 0x%016lx\n",
- part_sn2->remote_vars_part_pa);
-
- part_sn2->activate_IRQ_nasid = remote_vars->activate_IRQ_nasid;
- dev_dbg(xpc_part, " activate_IRQ_nasid = 0x%x\n",
- part_sn2->activate_IRQ_nasid);
-
- part_sn2->activate_IRQ_phys_cpuid =
- remote_vars->activate_IRQ_phys_cpuid;
- dev_dbg(xpc_part, " activate_IRQ_phys_cpuid = 0x%x\n",
- part_sn2->activate_IRQ_phys_cpuid);
-
- part_sn2->remote_amos_page_pa = remote_vars->amos_page_pa;
- dev_dbg(xpc_part, " remote_amos_page_pa = 0x%lx\n",
- part_sn2->remote_amos_page_pa);
-
- part_sn2->remote_vars_version = remote_vars->version;
- dev_dbg(xpc_part, " remote_vars_version = 0x%x\n",
- part_sn2->remote_vars_version);
-}
-
-/*
- * Prior code has determined the nasid which generated a activate IRQ.
- * Inspect that nasid to determine if its partition needs to be activated
- * or deactivated.
- *
- * A partition is considered "awaiting activation" if our partition
- * flags indicate it is not active and it has a heartbeat. A
- * partition is considered "awaiting deactivation" if our partition
- * flags indicate it is active but it has no heartbeat or it is not
- * sending its heartbeat to us.
- *
- * To determine the heartbeat, the remote nasid must have a properly
- * initialized reserved page.
- */
-static void
-xpc_identify_activate_IRQ_req_sn2(int nasid)
-{
- struct xpc_rsvd_page *remote_rp;
- struct xpc_vars_sn2 *remote_vars;
- unsigned long remote_rp_pa;
- unsigned long remote_vars_pa;
- int remote_rp_version;
- int reactivate = 0;
- unsigned long remote_rp_ts_jiffies = 0;
- short partid;
- struct xpc_partition *part;
- struct xpc_partition_sn2 *part_sn2;
- enum xp_retval ret;
-
- /* pull over the reserved page structure */
-
- remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer_sn2;
-
- ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
- if (ret != xpSuccess) {
- dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
- "which sent interrupt, reason=%d\n", nasid, ret);
- return;
- }
-
- remote_vars_pa = remote_rp->sn.sn2.vars_pa;
- remote_rp_version = remote_rp->version;
- remote_rp_ts_jiffies = remote_rp->ts_jiffies;
-
- partid = remote_rp->SAL_partid;
- part = &xpc_partitions[partid];
- part_sn2 = &part->sn.sn2;
-
- /* pull over the cross partition variables */
-
- remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2;
-
- ret = xpc_get_remote_vars_sn2(remote_vars_pa, remote_vars);
- if (ret != xpSuccess) {
- dev_warn(xpc_part, "unable to get XPC variables from nasid %d, "
- "which sent interrupt, reason=%d\n", nasid, ret);
-
- XPC_DEACTIVATE_PARTITION(part, ret);
- return;
- }
-
- part->activate_IRQ_rcvd++;
-
- dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = "
- "%lld:0x%lx\n", (int)nasid, (int)partid,
- part->activate_IRQ_rcvd,
- remote_vars->heartbeat, remote_vars->heartbeating_to_mask[0]);
-
- if (xpc_partition_disengaged(part) &&
- part->act_state == XPC_P_AS_INACTIVE) {
-
- xpc_update_partition_info_sn2(part, remote_rp_version,
- &remote_rp_ts_jiffies,
- remote_rp_pa, remote_vars_pa,
- remote_vars);
-
- if (xpc_partition_deactivation_requested_sn2(partid)) {
- /*
- * Other side is waiting on us to deactivate even though
- * we already have.
- */
- return;
- }
-
- xpc_activate_partition(part);
- return;
- }
-
- DBUG_ON(part->remote_rp_version == 0);
- DBUG_ON(part_sn2->remote_vars_version == 0);
-
- if (remote_rp_ts_jiffies != part->remote_rp_ts_jiffies) {
-
- /* the other side rebooted */
-
- DBUG_ON(xpc_partition_engaged_sn2(partid));
- DBUG_ON(xpc_partition_deactivation_requested_sn2(partid));
-
- xpc_update_partition_info_sn2(part, remote_rp_version,
- &remote_rp_ts_jiffies,
- remote_rp_pa, remote_vars_pa,
- remote_vars);
- reactivate = 1;
- }
-
- if (part->disengage_timeout > 0 && !xpc_partition_disengaged(part)) {
- /* still waiting on other side to disengage from us */
- return;
- }
-
- if (reactivate)
- XPC_DEACTIVATE_PARTITION(part, xpReactivating);
- else if (xpc_partition_deactivation_requested_sn2(partid))
- XPC_DEACTIVATE_PARTITION(part, xpOtherGoingDown);
-}
-
-/*
- * Loop through the activation amo variables and process any bits
- * which are set. Each bit indicates a nasid sending a partition
- * activation or deactivation request.
- *
- * Return #of IRQs detected.
- */
-int
-xpc_identify_activate_IRQ_sender_sn2(void)
-{
- int l;
- int b;
- unsigned long nasid_mask_long;
- u64 nasid; /* remote nasid */
- int n_IRQs_detected = 0;
- struct amo *act_amos;
-
- act_amos = xpc_vars_sn2->amos_page + XPC_ACTIVATE_IRQ_AMOS_SN2;
-
- /* scan through activate amo variables looking for non-zero entries */
- for (l = 0; l < xpc_nasid_mask_nlongs; l++) {
-
- if (xpc_exiting)
- break;
-
- nasid_mask_long = xpc_receive_IRQ_amo_sn2(&act_amos[l]);
-
- b = find_first_bit(&nasid_mask_long, BITS_PER_LONG);
- if (b >= BITS_PER_LONG) {
- /* no IRQs from nasids in this amo variable */
- continue;
- }
-
- dev_dbg(xpc_part, "amo[%d] gave back 0x%lx\n", l,
- nasid_mask_long);
-
- /*
- * If this nasid has been added to the machine since
- * our partition was reset, this will retain the
- * remote nasid in our reserved pages machine mask.
- * This is used in the event of module reload.
- */
- xpc_mach_nasids[l] |= nasid_mask_long;
-
- /* locate the nasid(s) which sent interrupts */
-
- do {
- n_IRQs_detected++;
- nasid = (l * BITS_PER_LONG + b) * 2;
- dev_dbg(xpc_part, "interrupt from nasid %lld\n", nasid);
- xpc_identify_activate_IRQ_req_sn2(nasid);
-
- b = find_next_bit(&nasid_mask_long, BITS_PER_LONG,
- b + 1);
- } while (b < BITS_PER_LONG);
- }
- return n_IRQs_detected;
-}
-
-static void
-xpc_process_activate_IRQ_rcvd_sn2(void)
-{
- unsigned long irq_flags;
- int n_IRQs_expected;
- int n_IRQs_detected;
-
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- n_IRQs_expected = xpc_activate_IRQ_rcvd;
- xpc_activate_IRQ_rcvd = 0;
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- n_IRQs_detected = xpc_identify_activate_IRQ_sender_sn2();
- if (n_IRQs_detected < n_IRQs_expected) {
- /* retry once to help avoid missing amo */
- (void)xpc_identify_activate_IRQ_sender_sn2();
- }
-}
-
-/*
- * Setup the channel structures that are sn2 specific.
- */
-static enum xp_retval
-xpc_setup_ch_structures_sn2(struct xpc_partition *part)
-{
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
- struct xpc_channel_sn2 *ch_sn2;
- enum xp_retval retval;
- int ret;
- int cpuid;
- int ch_number;
- struct timer_list *timer;
- short partid = XPC_PARTID(part);
-
- /* allocate all the required GET/PUT values */
-
- part_sn2->local_GPs =
- xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE, GFP_KERNEL,
- &part_sn2->local_GPs_base);
- if (part_sn2->local_GPs == NULL) {
- dev_err(xpc_chan, "can't get memory for local get/put "
- "values\n");
- return xpNoMemory;
- }
-
- part_sn2->remote_GPs =
- xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE, GFP_KERNEL,
- &part_sn2->remote_GPs_base);
- if (part_sn2->remote_GPs == NULL) {
- dev_err(xpc_chan, "can't get memory for remote get/put "
- "values\n");
- retval = xpNoMemory;
- goto out_1;
- }
-
- part_sn2->remote_GPs_pa = 0;
-
- /* allocate all the required open and close args */
-
- part_sn2->local_openclose_args =
- xpc_kzalloc_cacheline_aligned(XPC_OPENCLOSE_ARGS_SIZE,
- GFP_KERNEL, &part_sn2->
- local_openclose_args_base);
- if (part_sn2->local_openclose_args == NULL) {
- dev_err(xpc_chan, "can't get memory for local connect args\n");
- retval = xpNoMemory;
- goto out_2;
- }
-
- part_sn2->remote_openclose_args_pa = 0;
-
- part_sn2->local_chctl_amo_va = xpc_init_IRQ_amo_sn2(partid);
-
- part_sn2->notify_IRQ_nasid = 0;
- part_sn2->notify_IRQ_phys_cpuid = 0;
- part_sn2->remote_chctl_amo_va = NULL;
-
- sprintf(part_sn2->notify_IRQ_owner, "xpc%02d", partid);
- ret = request_irq(SGI_XPC_NOTIFY, xpc_handle_notify_IRQ_sn2,
- IRQF_SHARED, part_sn2->notify_IRQ_owner,
- (void *)(u64)partid);
- if (ret != 0) {
- dev_err(xpc_chan, "can't register NOTIFY IRQ handler, "
- "errno=%d\n", -ret);
- retval = xpLackOfResources;
- goto out_3;
- }
-
- /* Setup a timer to check for dropped notify IRQs */
- timer = &part_sn2->dropped_notify_IRQ_timer;
- init_timer(timer);
- timer->function =
- (void (*)(unsigned long))xpc_check_for_dropped_notify_IRQ_sn2;
- timer->data = (unsigned long)part;
- timer->expires = jiffies + XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL;
- add_timer(timer);
-
- for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
- ch_sn2 = &part->channels[ch_number].sn.sn2;
-
- ch_sn2->local_GP = &part_sn2->local_GPs[ch_number];
- ch_sn2->local_openclose_args =
- &part_sn2->local_openclose_args[ch_number];
-
- mutex_init(&ch_sn2->msg_to_pull_mutex);
- }
-
- /*
- * Setup the per partition specific variables required by the
- * remote partition to establish channel connections with us.
- *
- * The setting of the magic # indicates that these per partition
- * specific variables are ready to be used.
- */
- xpc_vars_part_sn2[partid].GPs_pa = xp_pa(part_sn2->local_GPs);
- xpc_vars_part_sn2[partid].openclose_args_pa =
- xp_pa(part_sn2->local_openclose_args);
- xpc_vars_part_sn2[partid].chctl_amo_pa =
- xp_pa(part_sn2->local_chctl_amo_va);
- cpuid = raw_smp_processor_id(); /* any CPU in this partition will do */
- xpc_vars_part_sn2[partid].notify_IRQ_nasid = cpuid_to_nasid(cpuid);
- xpc_vars_part_sn2[partid].notify_IRQ_phys_cpuid =
- cpu_physical_id(cpuid);
- xpc_vars_part_sn2[partid].nchannels = part->nchannels;
- xpc_vars_part_sn2[partid].magic = XPC_VP_MAGIC1_SN2;
-
- return xpSuccess;
-
- /* setup of ch structures failed */
-out_3:
- kfree(part_sn2->local_openclose_args_base);
- part_sn2->local_openclose_args = NULL;
-out_2:
- kfree(part_sn2->remote_GPs_base);
- part_sn2->remote_GPs = NULL;
-out_1:
- kfree(part_sn2->local_GPs_base);
- part_sn2->local_GPs = NULL;
- return retval;
-}
-
-/*
- * Teardown the channel structures that are sn2 specific.
- */
-static void
-xpc_teardown_ch_structures_sn2(struct xpc_partition *part)
-{
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
- short partid = XPC_PARTID(part);
-
- /*
- * Indicate that the variables specific to the remote partition are no
- * longer available for its use.
- */
- xpc_vars_part_sn2[partid].magic = 0;
-
- /* in case we've still got outstanding timers registered... */
- del_timer_sync(&part_sn2->dropped_notify_IRQ_timer);
- free_irq(SGI_XPC_NOTIFY, (void *)(u64)partid);
-
- kfree(part_sn2->local_openclose_args_base);
- part_sn2->local_openclose_args = NULL;
- kfree(part_sn2->remote_GPs_base);
- part_sn2->remote_GPs = NULL;
- kfree(part_sn2->local_GPs_base);
- part_sn2->local_GPs = NULL;
- part_sn2->local_chctl_amo_va = NULL;
-}
-
-/*
- * Create a wrapper that hides the underlying mechanism for pulling a cacheline
- * (or multiple cachelines) from a remote partition.
- *
- * src_pa must be a cacheline aligned physical address on the remote partition.
- * dst must be a cacheline aligned virtual address on this partition.
- * cnt must be cacheline sized
- */
-/* ??? Replace this function by call to xp_remote_memcpy() or bte_copy()? */
-static enum xp_retval
-xpc_pull_remote_cachelines_sn2(struct xpc_partition *part, void *dst,
- const unsigned long src_pa, size_t cnt)
-{
- enum xp_retval ret;
-
- DBUG_ON(src_pa != L1_CACHE_ALIGN(src_pa));
- DBUG_ON((unsigned long)dst != L1_CACHE_ALIGN((unsigned long)dst));
- DBUG_ON(cnt != L1_CACHE_ALIGN(cnt));
-
- if (part->act_state == XPC_P_AS_DEACTIVATING)
- return part->reason;
-
- ret = xp_remote_memcpy(xp_pa(dst), src_pa, cnt);
- if (ret != xpSuccess) {
- dev_dbg(xpc_chan, "xp_remote_memcpy() from partition %d failed,"
- " ret=%d\n", XPC_PARTID(part), ret);
- }
- return ret;
-}
-
-/*
- * Pull the remote per partition specific variables from the specified
- * partition.
- */
-static enum xp_retval
-xpc_pull_remote_vars_part_sn2(struct xpc_partition *part)
-{
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
- u8 buffer[L1_CACHE_BYTES * 2];
- struct xpc_vars_part_sn2 *pulled_entry_cacheline =
- (struct xpc_vars_part_sn2 *)L1_CACHE_ALIGN((u64)buffer);
- struct xpc_vars_part_sn2 *pulled_entry;
- unsigned long remote_entry_cacheline_pa;
- unsigned long remote_entry_pa;
- short partid = XPC_PARTID(part);
- enum xp_retval ret;
-
- /* pull the cacheline that contains the variables we're interested in */
-
- DBUG_ON(part_sn2->remote_vars_part_pa !=
- L1_CACHE_ALIGN(part_sn2->remote_vars_part_pa));
- DBUG_ON(sizeof(struct xpc_vars_part_sn2) != L1_CACHE_BYTES / 2);
-
- remote_entry_pa = part_sn2->remote_vars_part_pa +
- sn_partition_id * sizeof(struct xpc_vars_part_sn2);
-
- remote_entry_cacheline_pa = (remote_entry_pa & ~(L1_CACHE_BYTES - 1));
-
- pulled_entry = (struct xpc_vars_part_sn2 *)((u64)pulled_entry_cacheline
- + (remote_entry_pa &
- (L1_CACHE_BYTES - 1)));
-
- ret = xpc_pull_remote_cachelines_sn2(part, pulled_entry_cacheline,
- remote_entry_cacheline_pa,
- L1_CACHE_BYTES);
- if (ret != xpSuccess) {
- dev_dbg(xpc_chan, "failed to pull XPC vars_part from "
- "partition %d, ret=%d\n", partid, ret);
- return ret;
- }
-
- /* see if they've been set up yet */
-
- if (pulled_entry->magic != XPC_VP_MAGIC1_SN2 &&
- pulled_entry->magic != XPC_VP_MAGIC2_SN2) {
-
- if (pulled_entry->magic != 0) {
- dev_dbg(xpc_chan, "partition %d's XPC vars_part for "
- "partition %d has bad magic value (=0x%llx)\n",
- partid, sn_partition_id, pulled_entry->magic);
- return xpBadMagic;
- }
-
- /* they've not been initialized yet */
- return xpRetry;
- }
-
- if (xpc_vars_part_sn2[partid].magic == XPC_VP_MAGIC1_SN2) {
-
- /* validate the variables */
-
- if (pulled_entry->GPs_pa == 0 ||
- pulled_entry->openclose_args_pa == 0 ||
- pulled_entry->chctl_amo_pa == 0) {
-
- dev_err(xpc_chan, "partition %d's XPC vars_part for "
- "partition %d are not valid\n", partid,
- sn_partition_id);
- return xpInvalidAddress;
- }
-
- /* the variables we imported look to be valid */
-
- part_sn2->remote_GPs_pa = pulled_entry->GPs_pa;
- part_sn2->remote_openclose_args_pa =
- pulled_entry->openclose_args_pa;
- part_sn2->remote_chctl_amo_va =
- (struct amo *)__va(pulled_entry->chctl_amo_pa);
- part_sn2->notify_IRQ_nasid = pulled_entry->notify_IRQ_nasid;
- part_sn2->notify_IRQ_phys_cpuid =
- pulled_entry->notify_IRQ_phys_cpuid;
-
- if (part->nchannels > pulled_entry->nchannels)
- part->nchannels = pulled_entry->nchannels;
-
- /* let the other side know that we've pulled their variables */
-
- xpc_vars_part_sn2[partid].magic = XPC_VP_MAGIC2_SN2;
- }
-
- if (pulled_entry->magic == XPC_VP_MAGIC1_SN2)
- return xpRetry;
-
- return xpSuccess;
-}
-
-/*
- * Establish first contact with the remote partititon. This involves pulling
- * the XPC per partition variables from the remote partition and waiting for
- * the remote partition to pull ours.
- */
-static enum xp_retval
-xpc_make_first_contact_sn2(struct xpc_partition *part)
-{
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
- enum xp_retval ret;
-
- /*
- * Register the remote partition's amos with SAL so it can handle
- * and cleanup errors within that address range should the remote
- * partition go down. We don't unregister this range because it is
- * difficult to tell when outstanding writes to the remote partition
- * are finished and thus when it is safe to unregister. This should
- * not result in wasted space in the SAL xp_addr_region table because
- * we should get the same page for remote_amos_page_pa after module
- * reloads and system reboots.
- */
- if (sn_register_xp_addr_region(part_sn2->remote_amos_page_pa,
- PAGE_SIZE, 1) < 0) {
- dev_warn(xpc_part, "xpc_activating(%d) failed to register "
- "xp_addr region\n", XPC_PARTID(part));
-
- ret = xpPhysAddrRegFailed;
- XPC_DEACTIVATE_PARTITION(part, ret);
- return ret;
- }
-
- /*
- * Send activate IRQ to get other side to activate if they've not
- * already begun to do so.
- */
- xpc_send_activate_IRQ_sn2(part_sn2->remote_amos_page_pa,
- cnodeid_to_nasid(0),
- part_sn2->activate_IRQ_nasid,
- part_sn2->activate_IRQ_phys_cpuid);
-
- while ((ret = xpc_pull_remote_vars_part_sn2(part)) != xpSuccess) {
- if (ret != xpRetry) {
- XPC_DEACTIVATE_PARTITION(part, ret);
- return ret;
- }
-
- dev_dbg(xpc_part, "waiting to make first contact with "
- "partition %d\n", XPC_PARTID(part));
-
- /* wait a 1/4 of a second or so */
- (void)msleep_interruptible(250);
-
- if (part->act_state == XPC_P_AS_DEACTIVATING)
- return part->reason;
- }
-
- return xpSuccess;
-}
-
-/*
- * Get the chctl flags and pull the openclose args and/or remote GPs as needed.
- */
-static u64
-xpc_get_chctl_all_flags_sn2(struct xpc_partition *part)
-{
- struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
- unsigned long irq_flags;
- union xpc_channel_ctl_flags chctl;
- enum xp_retval ret;
-
- /*
- * See if there are any chctl flags to be handled.
- */
-
- spin_lock_irqsave(&part->chctl_lock, irq_flags);
- chctl = part->chctl;
- if (chctl.all_flags != 0)
- part->chctl.all_flags = 0;
-
- spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
- if (xpc_any_openclose_chctl_flags_set(&chctl)) {
- ret = xpc_pull_remote_cachelines_sn2(part, part->
- remote_openclose_args,
- part_sn2->
- remote_openclose_args_pa,
- XPC_OPENCLOSE_ARGS_SIZE);
- if (ret != xpSuccess) {
- XPC_DEACTIVATE_PARTITION(part, ret);
-
- dev_dbg(xpc_chan, "failed to pull openclose args from "
- "partition %d, ret=%d\n", XPC_PARTID(part),
- ret);
-
- /* don't bother processing chctl flags anymore */
- chctl.all_flags = 0;
- }
- }
-
- if (xpc_any_msg_chctl_flags_set(&chctl)) {
- ret = xpc_pull_remote_cachelines_sn2(part, part_sn2->remote_GPs,
- part_sn2->remote_GPs_pa,
- XPC_GP_SIZE);
- if (ret != xpSuccess) {
- XPC_DEACTIVATE_PARTITION(part, ret);
-
- dev_dbg(xpc_chan, "failed to pull GPs from partition "
- "%d, ret=%d\n", XPC_PARTID(part), ret);
-
- /* don't bother processing chctl flags anymore */
- chctl.all_flags = 0;
- }
- }
-
- return chctl.all_flags;
-}
-
-/*
- * Allocate the local message queue and the notify queue.
- */
-static enum xp_retval
-xpc_allocate_local_msgqueue_sn2(struct xpc_channel *ch)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- unsigned long irq_flags;
- int nentries;
- size_t nbytes;
-
- for (nentries = ch->local_nentries; nentries > 0; nentries--) {
-
- nbytes = nentries * ch->entry_size;
- ch_sn2->local_msgqueue =
- xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL,
- &ch_sn2->local_msgqueue_base);
- if (ch_sn2->local_msgqueue == NULL)
- continue;
-
- nbytes = nentries * sizeof(struct xpc_notify_sn2);
- ch_sn2->notify_queue = kzalloc(nbytes, GFP_KERNEL);
- if (ch_sn2->notify_queue == NULL) {
- kfree(ch_sn2->local_msgqueue_base);
- ch_sn2->local_msgqueue = NULL;
- continue;
- }
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- if (nentries < ch->local_nentries) {
- dev_dbg(xpc_chan, "nentries=%d local_nentries=%d, "
- "partid=%d, channel=%d\n", nentries,
- ch->local_nentries, ch->partid, ch->number);
-
- ch->local_nentries = nentries;
- }
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return xpSuccess;
- }
-
- dev_dbg(xpc_chan, "can't get memory for local message queue and notify "
- "queue, partid=%d, channel=%d\n", ch->partid, ch->number);
- return xpNoMemory;
-}
-
-/*
- * Allocate the cached remote message queue.
- */
-static enum xp_retval
-xpc_allocate_remote_msgqueue_sn2(struct xpc_channel *ch)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- unsigned long irq_flags;
- int nentries;
- size_t nbytes;
-
- DBUG_ON(ch->remote_nentries <= 0);
-
- for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
-
- nbytes = nentries * ch->entry_size;
- ch_sn2->remote_msgqueue =
- xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL, &ch_sn2->
- remote_msgqueue_base);
- if (ch_sn2->remote_msgqueue == NULL)
- continue;
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- if (nentries < ch->remote_nentries) {
- dev_dbg(xpc_chan, "nentries=%d remote_nentries=%d, "
- "partid=%d, channel=%d\n", nentries,
- ch->remote_nentries, ch->partid, ch->number);
-
- ch->remote_nentries = nentries;
- }
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return xpSuccess;
- }
-
- dev_dbg(xpc_chan, "can't get memory for cached remote message queue, "
- "partid=%d, channel=%d\n", ch->partid, ch->number);
- return xpNoMemory;
-}
-
-/*
- * Allocate message queues and other stuff associated with a channel.
- *
- * Note: Assumes all of the channel sizes are filled in.
- */
-static enum xp_retval
-xpc_setup_msg_structures_sn2(struct xpc_channel *ch)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- enum xp_retval ret;
-
- DBUG_ON(ch->flags & XPC_C_SETUP);
-
- ret = xpc_allocate_local_msgqueue_sn2(ch);
- if (ret == xpSuccess) {
-
- ret = xpc_allocate_remote_msgqueue_sn2(ch);
- if (ret != xpSuccess) {
- kfree(ch_sn2->local_msgqueue_base);
- ch_sn2->local_msgqueue = NULL;
- kfree(ch_sn2->notify_queue);
- ch_sn2->notify_queue = NULL;
- }
- }
- return ret;
-}
-
-/*
- * Free up message queues and other stuff that were allocated for the specified
- * channel.
- */
-static void
-xpc_teardown_msg_structures_sn2(struct xpc_channel *ch)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-
- DBUG_ON(!spin_is_locked(&ch->lock));
-
- ch_sn2->remote_msgqueue_pa = 0;
-
- ch_sn2->local_GP->get = 0;
- ch_sn2->local_GP->put = 0;
- ch_sn2->remote_GP.get = 0;
- ch_sn2->remote_GP.put = 0;
- ch_sn2->w_local_GP.get = 0;
- ch_sn2->w_local_GP.put = 0;
- ch_sn2->w_remote_GP.get = 0;
- ch_sn2->w_remote_GP.put = 0;
- ch_sn2->next_msg_to_pull = 0;
-
- if (ch->flags & XPC_C_SETUP) {
- dev_dbg(xpc_chan, "ch->flags=0x%x, partid=%d, channel=%d\n",
- ch->flags, ch->partid, ch->number);
-
- kfree(ch_sn2->local_msgqueue_base);
- ch_sn2->local_msgqueue = NULL;
- kfree(ch_sn2->remote_msgqueue_base);
- ch_sn2->remote_msgqueue = NULL;
- kfree(ch_sn2->notify_queue);
- ch_sn2->notify_queue = NULL;
- }
-}
-
-/*
- * Notify those who wanted to be notified upon delivery of their message.
- */
-static void
-xpc_notify_senders_sn2(struct xpc_channel *ch, enum xp_retval reason, s64 put)
-{
- struct xpc_notify_sn2 *notify;
- u8 notify_type;
- s64 get = ch->sn.sn2.w_remote_GP.get - 1;
-
- while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
-
- notify = &ch->sn.sn2.notify_queue[get % ch->local_nentries];
-
- /*
- * See if the notify entry indicates it was associated with
- * a message who's sender wants to be notified. It is possible
- * that it is, but someone else is doing or has done the
- * notification.
- */
- notify_type = notify->type;
- if (notify_type == 0 ||
- cmpxchg(&notify->type, notify_type, 0) != notify_type) {
- continue;
- }
-
- DBUG_ON(notify_type != XPC_N_CALL);
-
- atomic_dec(&ch->n_to_notify);
-
- if (notify->func != NULL) {
- dev_dbg(xpc_chan, "notify->func() called, notify=0x%p "
- "msg_number=%lld partid=%d channel=%d\n",
- (void *)notify, get, ch->partid, ch->number);
-
- notify->func(reason, ch->partid, ch->number,
- notify->key);
-
- dev_dbg(xpc_chan, "notify->func() returned, notify=0x%p"
- " msg_number=%lld partid=%d channel=%d\n",
- (void *)notify, get, ch->partid, ch->number);
- }
- }
-}
-
-static void
-xpc_notify_senders_of_disconnect_sn2(struct xpc_channel *ch)
-{
- xpc_notify_senders_sn2(ch, ch->reason, ch->sn.sn2.w_local_GP.put);
-}
-
-/*
- * Clear some of the msg flags in the local message queue.
- */
-static inline void
-xpc_clear_local_msgqueue_flags_sn2(struct xpc_channel *ch)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- struct xpc_msg_sn2 *msg;
- s64 get;
-
- get = ch_sn2->w_remote_GP.get;
- do {
- msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue +
- (get % ch->local_nentries) *
- ch->entry_size);
- DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
- msg->flags = 0;
- } while (++get < ch_sn2->remote_GP.get);
-}
-
-/*
- * Clear some of the msg flags in the remote message queue.
- */
-static inline void
-xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- struct xpc_msg_sn2 *msg;
- s64 put, remote_nentries = ch->remote_nentries;
-
- /* flags are zeroed when the buffer is allocated */
- if (ch_sn2->remote_GP.put < remote_nentries)
- return;
-
- put = max(ch_sn2->w_remote_GP.put, remote_nentries);
- do {
- msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
- (put % remote_nentries) *
- ch->entry_size);
- DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
- DBUG_ON(!(msg->flags & XPC_M_SN2_DONE));
- DBUG_ON(msg->number != put - remote_nentries);
- msg->flags = 0;
- } while (++put < ch_sn2->remote_GP.put);
-}
-
-static int
-xpc_n_of_deliverable_payloads_sn2(struct xpc_channel *ch)
-{
- return ch->sn.sn2.w_remote_GP.put - ch->sn.sn2.w_local_GP.get;
-}
-
-static void
-xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
-{
- struct xpc_channel *ch = &part->channels[ch_number];
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- int npayloads_sent;
-
- ch_sn2->remote_GP = part->sn.sn2.remote_GPs[ch_number];
-
- /* See what, if anything, has changed for each connected channel */
-
- xpc_msgqueue_ref(ch);
-
- if (ch_sn2->w_remote_GP.get == ch_sn2->remote_GP.get &&
- ch_sn2->w_remote_GP.put == ch_sn2->remote_GP.put) {
- /* nothing changed since GPs were last pulled */
- xpc_msgqueue_deref(ch);
- return;
- }
-
- if (!(ch->flags & XPC_C_CONNECTED)) {
- xpc_msgqueue_deref(ch);
- return;
- }
-
- /*
- * First check to see if messages recently sent by us have been
- * received by the other side. (The remote GET value will have
- * changed since we last looked at it.)
- */
-
- if (ch_sn2->w_remote_GP.get != ch_sn2->remote_GP.get) {
-
- /*
- * We need to notify any senders that want to be notified
- * that their sent messages have been received by their
- * intended recipients. We need to do this before updating
- * w_remote_GP.get so that we don't allocate the same message
- * queue entries prematurely (see xpc_allocate_msg()).
- */
- if (atomic_read(&ch->n_to_notify) > 0) {
- /*
- * Notify senders that messages sent have been
- * received and delivered by the other side.
- */
- xpc_notify_senders_sn2(ch, xpMsgDelivered,
- ch_sn2->remote_GP.get);
- }
-
- /*
- * Clear msg->flags in previously sent messages, so that
- * they're ready for xpc_allocate_msg().
- */
- xpc_clear_local_msgqueue_flags_sn2(ch);
-
- ch_sn2->w_remote_GP.get = ch_sn2->remote_GP.get;
-
- dev_dbg(xpc_chan, "w_remote_GP.get changed to %lld, partid=%d, "
- "channel=%d\n", ch_sn2->w_remote_GP.get, ch->partid,
- ch->number);
-
- /*
- * If anyone was waiting for message queue entries to become
- * available, wake them up.
- */
- if (atomic_read(&ch->n_on_msg_allocate_wq) > 0)
- wake_up(&ch->msg_allocate_wq);
- }
-
- /*
- * Now check for newly sent messages by the other side. (The remote
- * PUT value will have changed since we last looked at it.)
- */
-
- if (ch_sn2->w_remote_GP.put != ch_sn2->remote_GP.put) {
- /*
- * Clear msg->flags in previously received messages, so that
- * they're ready for xpc_get_deliverable_payload_sn2().
- */
- xpc_clear_remote_msgqueue_flags_sn2(ch);
-
- smp_wmb(); /* ensure flags have been cleared before bte_copy */
- ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put;
-
- dev_dbg(xpc_chan, "w_remote_GP.put changed to %lld, partid=%d, "
- "channel=%d\n", ch_sn2->w_remote_GP.put, ch->partid,
- ch->number);
-
- npayloads_sent = xpc_n_of_deliverable_payloads_sn2(ch);
- if (npayloads_sent > 0) {
- dev_dbg(xpc_chan, "msgs waiting to be copied and "
- "delivered=%d, partid=%d, channel=%d\n",
- npayloads_sent, ch->partid, ch->number);
-
- if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)
- xpc_activate_kthreads(ch, npayloads_sent);
- }
- }
-
- xpc_msgqueue_deref(ch);
-}
-
-static struct xpc_msg_sn2 *
-xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get)
-{
- struct xpc_partition *part = &xpc_partitions[ch->partid];
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- unsigned long remote_msg_pa;
- struct xpc_msg_sn2 *msg;
- u32 msg_index;
- u32 nmsgs;
- u64 msg_offset;
- enum xp_retval ret;
-
- if (mutex_lock_interruptible(&ch_sn2->msg_to_pull_mutex) != 0) {
- /* we were interrupted by a signal */
- return NULL;
- }
-
- while (get >= ch_sn2->next_msg_to_pull) {
-
- /* pull as many messages as are ready and able to be pulled */
-
- msg_index = ch_sn2->next_msg_to_pull % ch->remote_nentries;
-
- DBUG_ON(ch_sn2->next_msg_to_pull >= ch_sn2->w_remote_GP.put);
- nmsgs = ch_sn2->w_remote_GP.put - ch_sn2->next_msg_to_pull;
- if (msg_index + nmsgs > ch->remote_nentries) {
- /* ignore the ones that wrap the msg queue for now */
- nmsgs = ch->remote_nentries - msg_index;
- }
-
- msg_offset = msg_index * ch->entry_size;
- msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
- msg_offset);
- remote_msg_pa = ch_sn2->remote_msgqueue_pa + msg_offset;
-
- ret = xpc_pull_remote_cachelines_sn2(part, msg, remote_msg_pa,
- nmsgs * ch->entry_size);
- if (ret != xpSuccess) {
-
- dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
- " msg %lld from partition %d, channel=%d, "
- "ret=%d\n", nmsgs, ch_sn2->next_msg_to_pull,
- ch->partid, ch->number, ret);
-
- XPC_DEACTIVATE_PARTITION(part, ret);
-
- mutex_unlock(&ch_sn2->msg_to_pull_mutex);
- return NULL;
- }
-
- ch_sn2->next_msg_to_pull += nmsgs;
- }
-
- mutex_unlock(&ch_sn2->msg_to_pull_mutex);
-
- /* return the message we were looking for */
- msg_offset = (get % ch->remote_nentries) * ch->entry_size;
- msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue + msg_offset);
-
- return msg;
-}
-
-/*
- * Get the next deliverable message's payload.
- */
-static void *
-xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- struct xpc_msg_sn2 *msg;
- void *payload = NULL;
- s64 get;
-
- do {
- if (ch->flags & XPC_C_DISCONNECTING)
- break;
-
- get = ch_sn2->w_local_GP.get;
- smp_rmb(); /* guarantee that .get loads before .put */
- if (get == ch_sn2->w_remote_GP.put)
- break;
-
- /* There are messages waiting to be pulled and delivered.
- * We need to try to secure one for ourselves. We'll do this
- * by trying to increment w_local_GP.get and hope that no one
- * else beats us to it. If they do, we'll we'll simply have
- * to try again for the next one.
- */
-
- if (cmpxchg(&ch_sn2->w_local_GP.get, get, get + 1) == get) {
- /* we got the entry referenced by get */
-
- dev_dbg(xpc_chan, "w_local_GP.get changed to %lld, "
- "partid=%d, channel=%d\n", get + 1,
- ch->partid, ch->number);
-
- /* pull the message from the remote partition */
-
- msg = xpc_pull_remote_msg_sn2(ch, get);
-
- if (msg != NULL) {
- DBUG_ON(msg->number != get);
- DBUG_ON(msg->flags & XPC_M_SN2_DONE);
- DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
-
- payload = &msg->payload;
- }
- break;
- }
-
- } while (1);
-
- return payload;
-}
-
-/*
- * Now we actually send the messages that are ready to be sent by advancing
- * the local message queue's Put value and then send a chctl msgrequest to the
- * recipient partition.
- */
-static void
-xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- struct xpc_msg_sn2 *msg;
- s64 put = initial_put + 1;
- int send_msgrequest = 0;
-
- while (1) {
-
- while (1) {
- if (put == ch_sn2->w_local_GP.put)
- break;
-
- msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->
- local_msgqueue + (put %
- ch->local_nentries) *
- ch->entry_size);
-
- if (!(msg->flags & XPC_M_SN2_READY))
- break;
-
- put++;
- }
-
- if (put == initial_put) {
- /* nothing's changed */
- break;
- }
-
- if (cmpxchg_rel(&ch_sn2->local_GP->put, initial_put, put) !=
- initial_put) {
- /* someone else beat us to it */
- DBUG_ON(ch_sn2->local_GP->put < initial_put);
- break;
- }
-
- /* we just set the new value of local_GP->put */
-
- dev_dbg(xpc_chan, "local_GP->put changed to %lld, partid=%d, "
- "channel=%d\n", put, ch->partid, ch->number);
-
- send_msgrequest = 1;
-
- /*
- * We need to ensure that the message referenced by
- * local_GP->put is not XPC_M_SN2_READY or that local_GP->put
- * equals w_local_GP.put, so we'll go have a look.
- */
- initial_put = put;
- }
-
- if (send_msgrequest)
- xpc_send_chctl_msgrequest_sn2(ch);
-}
-
-/*
- * Allocate an entry for a message from the message queue associated with the
- * specified channel.
- */
-static enum xp_retval
-xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
- struct xpc_msg_sn2 **address_of_msg)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- struct xpc_msg_sn2 *msg;
- enum xp_retval ret;
- s64 put;
-
- /*
- * Get the next available message entry from the local message queue.
- * If none are available, we'll make sure that we grab the latest
- * GP values.
- */
- ret = xpTimeout;
-
- while (1) {
-
- put = ch_sn2->w_local_GP.put;
- smp_rmb(); /* guarantee that .put loads before .get */
- if (put - ch_sn2->w_remote_GP.get < ch->local_nentries) {
-
- /* There are available message entries. We need to try
- * to secure one for ourselves. We'll do this by trying
- * to increment w_local_GP.put as long as someone else
- * doesn't beat us to it. If they do, we'll have to
- * try again.
- */
- if (cmpxchg(&ch_sn2->w_local_GP.put, put, put + 1) ==
- put) {
- /* we got the entry referenced by put */
- break;
- }
- continue; /* try again */
- }
-
- /*
- * There aren't any available msg entries at this time.
- *
- * In waiting for a message entry to become available,
- * we set a timeout in case the other side is not sending
- * completion interrupts. This lets us fake a notify IRQ
- * that will cause the notify IRQ handler to fetch the latest
- * GP values as if an interrupt was sent by the other side.
- */
- if (ret == xpTimeout)
- xpc_send_chctl_local_msgrequest_sn2(ch);
-
- if (flags & XPC_NOWAIT)
- return xpNoWait;
-
- ret = xpc_allocate_msg_wait(ch);
- if (ret != xpInterrupted && ret != xpTimeout)
- return ret;
- }
-
- /* get the message's address and initialize it */
- msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue +
- (put % ch->local_nentries) *
- ch->entry_size);
-
- DBUG_ON(msg->flags != 0);
- msg->number = put;
-
- dev_dbg(xpc_chan, "w_local_GP.put changed to %lld; msg=0x%p, "
- "msg_number=%lld, partid=%d, channel=%d\n", put + 1,
- (void *)msg, msg->number, ch->partid, ch->number);
-
- *address_of_msg = msg;
- return xpSuccess;
-}
-
-/*
- * Common code that does the actual sending of the message by advancing the
- * local message queue's Put value and sends a chctl msgrequest to the
- * partition the message is being sent to.
- */
-static enum xp_retval
-xpc_send_payload_sn2(struct xpc_channel *ch, u32 flags, void *payload,
- u16 payload_size, u8 notify_type, xpc_notify_func func,
- void *key)
-{
- enum xp_retval ret = xpSuccess;
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- struct xpc_msg_sn2 *msg = msg;
- struct xpc_notify_sn2 *notify = notify;
- s64 msg_number;
- s64 put;
-
- DBUG_ON(notify_type == XPC_N_CALL && func == NULL);
-
- if (XPC_MSG_SIZE(payload_size) > ch->entry_size)
- return xpPayloadTooBig;
-
- xpc_msgqueue_ref(ch);
-
- if (ch->flags & XPC_C_DISCONNECTING) {
- ret = ch->reason;
- goto out_1;
- }
- if (!(ch->flags & XPC_C_CONNECTED)) {
- ret = xpNotConnected;
- goto out_1;
- }
-
- ret = xpc_allocate_msg_sn2(ch, flags, &msg);
- if (ret != xpSuccess)
- goto out_1;
-
- msg_number = msg->number;
-
- if (notify_type != 0) {
- /*
- * Tell the remote side to send an ACK interrupt when the
- * message has been delivered.
- */
- msg->flags |= XPC_M_SN2_INTERRUPT;
-
- atomic_inc(&ch->n_to_notify);
-
- notify = &ch_sn2->notify_queue[msg_number % ch->local_nentries];
- notify->func = func;
- notify->key = key;
- notify->type = notify_type;
-
- /* ??? Is a mb() needed here? */
-
- if (ch->flags & XPC_C_DISCONNECTING) {
- /*
- * An error occurred between our last error check and
- * this one. We will try to clear the type field from
- * the notify entry. If we succeed then
- * xpc_disconnect_channel() didn't already process
- * the notify entry.
- */
- if (cmpxchg(&notify->type, notify_type, 0) ==
- notify_type) {
- atomic_dec(&ch->n_to_notify);
- ret = ch->reason;
- }
- goto out_1;
- }
- }
-
- memcpy(&msg->payload, payload, payload_size);
-
- msg->flags |= XPC_M_SN2_READY;
-
- /*
- * The preceding store of msg->flags must occur before the following
- * load of local_GP->put.
- */
- smp_mb();
-
- /* see if the message is next in line to be sent, if so send it */
-
- put = ch_sn2->local_GP->put;
- if (put == msg_number)
- xpc_send_msgs_sn2(ch, put);
-
-out_1:
- xpc_msgqueue_deref(ch);
- return ret;
-}
-
-/*
- * Now we actually acknowledge the messages that have been delivered and ack'd
- * by advancing the cached remote message queue's Get value and if requested
- * send a chctl msgrequest to the message sender's partition.
- *
- * If a message has XPC_M_SN2_INTERRUPT set, send an interrupt to the partition
- * that sent the message.
- */
-static void
-xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
-{
- struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
- struct xpc_msg_sn2 *msg;
- s64 get = initial_get + 1;
- int send_msgrequest = 0;
-
- while (1) {
-
- while (1) {
- if (get == ch_sn2->w_local_GP.get)
- break;
-
- msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->
- remote_msgqueue + (get %
- ch->remote_nentries) *
- ch->entry_size);
-
- if (!(msg->flags & XPC_M_SN2_DONE))
- break;
-
- msg_flags |= msg->flags;
- get++;
- }
-
- if (get == initial_get) {
- /* nothing's changed */
- break;
- }
-
- if (cmpxchg_rel(&ch_sn2->local_GP->get, initial_get, get) !=
- initial_get) {
- /* someone else beat us to it */
- DBUG_ON(ch_sn2->local_GP->get <= initial_get);
- break;
- }
-
- /* we just set the new value of local_GP->get */
-
- dev_dbg(xpc_chan, "local_GP->get changed to %lld, partid=%d, "
- "channel=%d\n", get, ch->partid, ch->number);
-
- send_msgrequest = (msg_flags & XPC_M_SN2_INTERRUPT);
-
- /*
- * We need to ensure that the message referenced by
- * local_GP->get is not XPC_M_SN2_DONE or that local_GP->get
- * equals w_local_GP.get, so we'll go have a look.
- */
- initial_get = get;
- }
-
- if (send_msgrequest)
- xpc_send_chctl_msgrequest_sn2(ch);
-}
-
-static void
-xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
-{
- struct xpc_msg_sn2 *msg;
- s64 msg_number;
- s64 get;
-
- msg = container_of(payload, struct xpc_msg_sn2, payload);
- msg_number = msg->number;
-
- dev_dbg(xpc_chan, "msg=0x%p, msg_number=%lld, partid=%d, channel=%d\n",
- (void *)msg, msg_number, ch->partid, ch->number);
-
- DBUG_ON((((u64)msg - (u64)ch->sn.sn2.remote_msgqueue) / ch->entry_size) !=
- msg_number % ch->remote_nentries);
- DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
- DBUG_ON(msg->flags & XPC_M_SN2_DONE);
-
- msg->flags |= XPC_M_SN2_DONE;
-
- /*
- * The preceding store of msg->flags must occur before the following
- * load of local_GP->get.
- */
- smp_mb();
-
- /*
- * See if this message is next in line to be acknowledged as having
- * been delivered.
- */
- get = ch->sn.sn2.local_GP->get;
- if (get == msg_number)
- xpc_acknowledge_msgs_sn2(ch, get, msg->flags);
-}
-
-static struct xpc_arch_operations xpc_arch_ops_sn2 = {
- .setup_partitions = xpc_setup_partitions_sn2,
- .teardown_partitions = xpc_teardown_partitions_sn2,
- .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2,
- .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2,
- .setup_rsvd_page = xpc_setup_rsvd_page_sn2,
-
- .allow_hb = xpc_allow_hb_sn2,
- .disallow_hb = xpc_disallow_hb_sn2,
- .disallow_all_hbs = xpc_disallow_all_hbs_sn2,
- .increment_heartbeat = xpc_increment_heartbeat_sn2,
- .offline_heartbeat = xpc_offline_heartbeat_sn2,
- .online_heartbeat = xpc_online_heartbeat_sn2,
- .heartbeat_init = xpc_heartbeat_init_sn2,
- .heartbeat_exit = xpc_heartbeat_exit_sn2,
- .get_remote_heartbeat = xpc_get_remote_heartbeat_sn2,
-
- .request_partition_activation =
- xpc_request_partition_activation_sn2,
- .request_partition_reactivation =
- xpc_request_partition_reactivation_sn2,
- .request_partition_deactivation =
- xpc_request_partition_deactivation_sn2,
- .cancel_partition_deactivation_request =
- xpc_cancel_partition_deactivation_request_sn2,
-
- .setup_ch_structures = xpc_setup_ch_structures_sn2,
- .teardown_ch_structures = xpc_teardown_ch_structures_sn2,
-
- .make_first_contact = xpc_make_first_contact_sn2,
-
- .get_chctl_all_flags = xpc_get_chctl_all_flags_sn2,
- .send_chctl_closerequest = xpc_send_chctl_closerequest_sn2,
- .send_chctl_closereply = xpc_send_chctl_closereply_sn2,
- .send_chctl_openrequest = xpc_send_chctl_openrequest_sn2,
- .send_chctl_openreply = xpc_send_chctl_openreply_sn2,
- .send_chctl_opencomplete = xpc_send_chctl_opencomplete_sn2,
- .process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2,
-
- .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2,
-
- .setup_msg_structures = xpc_setup_msg_structures_sn2,
- .teardown_msg_structures = xpc_teardown_msg_structures_sn2,
-
- .indicate_partition_engaged = xpc_indicate_partition_engaged_sn2,
- .indicate_partition_disengaged = xpc_indicate_partition_disengaged_sn2,
- .partition_engaged = xpc_partition_engaged_sn2,
- .any_partition_engaged = xpc_any_partition_engaged_sn2,
- .assume_partition_disengaged = xpc_assume_partition_disengaged_sn2,
-
- .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2,
- .send_payload = xpc_send_payload_sn2,
- .get_deliverable_payload = xpc_get_deliverable_payload_sn2,
- .received_payload = xpc_received_payload_sn2,
- .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2,
-};
-
-int
-xpc_init_sn2(void)
-{
- int ret;
- size_t buf_size;
-
- xpc_arch_ops = xpc_arch_ops_sn2;
-
- if (offsetof(struct xpc_msg_sn2, payload) > XPC_MSG_HDR_MAX_SIZE) {
- dev_err(xpc_part, "header portion of struct xpc_msg_sn2 is "
- "larger than %d\n", XPC_MSG_HDR_MAX_SIZE);
- return -E2BIG;
- }
-
- buf_size = max(XPC_RP_VARS_SIZE,
- XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES_SN2);
- xpc_remote_copy_buffer_sn2 = xpc_kmalloc_cacheline_aligned(buf_size,
- GFP_KERNEL,
- &xpc_remote_copy_buffer_base_sn2);
- if (xpc_remote_copy_buffer_sn2 == NULL) {
- dev_err(xpc_part, "can't get memory for remote copy buffer\n");
- return -ENOMEM;
- }
-
- /* open up protections for IPI and [potentially] amo operations */
- xpc_allow_IPI_ops_sn2();
- xpc_allow_amo_ops_shub_wars_1_1_sn2();
-
- /*
- * This is safe to do before the xpc_hb_checker thread has started
- * because the handler releases a wait queue. If an interrupt is
- * received before the thread is waiting, it will not go to sleep,
- * but rather immediately process the interrupt.
- */
- ret = request_irq(SGI_XPC_ACTIVATE, xpc_handle_activate_IRQ_sn2, 0,
- "xpc hb", NULL);
- if (ret != 0) {
- dev_err(xpc_part, "can't register ACTIVATE IRQ handler, "
- "errno=%d\n", -ret);
- xpc_disallow_IPI_ops_sn2();
- kfree(xpc_remote_copy_buffer_base_sn2);
- }
- return ret;
-}
-
-void
-xpc_exit_sn2(void)
-{
- free_irq(SGI_XPC_ACTIVATE, NULL);
- xpc_disallow_IPI_ops_sn2();
- kfree(xpc_remote_copy_buffer_base_sn2);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_uv.c b/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_uv.c
deleted file mode 100644
index 17bbacb1..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpc_uv.c
+++ /dev/null
@@ -1,1767 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved.
- */
-
-/*
- * Cross Partition Communication (XPC) uv-based functions.
- *
- * Architecture specific implementation of common functions.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <asm/uv/uv_hub.h>
-#if defined CONFIG_X86_64
-#include <asm/uv/bios.h>
-#include <asm/uv/uv_irq.h>
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
-#include <asm/sn/intr.h>
-#include <asm/sn/sn_sal.h>
-#endif
-#include "../sgi-gru/gru.h"
-#include "../sgi-gru/grukservices.h"
-#include "xpc.h"
-
-#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
-struct uv_IO_APIC_route_entry {
- __u64 vector : 8,
- delivery_mode : 3,
- dest_mode : 1,
- delivery_status : 1,
- polarity : 1,
- __reserved_1 : 1,
- trigger : 1,
- mask : 1,
- __reserved_2 : 15,
- dest : 32;
-};
-#endif
-
-static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
-
-#define XPC_ACTIVATE_MSG_SIZE_UV (1 * GRU_CACHE_LINE_BYTES)
-#define XPC_ACTIVATE_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \
- XPC_ACTIVATE_MSG_SIZE_UV)
-#define XPC_ACTIVATE_IRQ_NAME "xpc_activate"
-
-#define XPC_NOTIFY_MSG_SIZE_UV (2 * GRU_CACHE_LINE_BYTES)
-#define XPC_NOTIFY_MQ_SIZE_UV (4 * XP_MAX_NPARTITIONS_UV * \
- XPC_NOTIFY_MSG_SIZE_UV)
-#define XPC_NOTIFY_IRQ_NAME "xpc_notify"
-
-static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
-static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
-
-static int
-xpc_setup_partitions_uv(void)
-{
- short partid;
- struct xpc_partition_uv *part_uv;
-
- for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
- part_uv = &xpc_partitions[partid].sn.uv;
-
- mutex_init(&part_uv->cached_activate_gru_mq_desc_mutex);
- spin_lock_init(&part_uv->flags_lock);
- part_uv->remote_act_state = XPC_P_AS_INACTIVE;
- }
- return 0;
-}
-
-static void
-xpc_teardown_partitions_uv(void)
-{
- short partid;
- struct xpc_partition_uv *part_uv;
- unsigned long irq_flags;
-
- for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
- part_uv = &xpc_partitions[partid].sn.uv;
-
- if (part_uv->cached_activate_gru_mq_desc != NULL) {
- mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
- spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
- part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
- spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
- kfree(part_uv->cached_activate_gru_mq_desc);
- part_uv->cached_activate_gru_mq_desc = NULL;
- mutex_unlock(&part_uv->
- cached_activate_gru_mq_desc_mutex);
- }
- }
-}
-
-static int
-xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
-{
- int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
-
-#if defined CONFIG_X86_64
- mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset,
- UV_AFFINITY_CPU);
- if (mq->irq < 0) {
- dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
- -mq->irq);
- return mq->irq;
- }
-
- mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
-
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0)
- mq->irq = SGI_XPC_ACTIVATE;
- else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0)
- mq->irq = SGI_XPC_NOTIFY;
- else
- return -EINVAL;
-
- mq->mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
- uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mq->mmr_value);
-#else
- #error not a supported configuration
-#endif
-
- return 0;
-}
-
-static void
-xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq)
-{
-#if defined CONFIG_X86_64
- uv_teardown_irq(mq->irq);
-
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- int mmr_pnode;
- unsigned long mmr_value;
-
- mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
- mmr_value = 1UL << 16;
-
- uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
-#else
- #error not a supported configuration
-#endif
-}
-
-static int
-xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
-{
- int ret;
-
-#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
-
- ret = sn_mq_watchlist_alloc(mmr_pnode, (void *)uv_gpa(mq->address),
- mq->order, &mq->mmr_offset);
- if (ret < 0) {
- dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
- ret);
- return -EBUSY;
- }
-#elif defined CONFIG_X86_64
- ret = uv_bios_mq_watchlist_alloc(uv_gpa(mq->address),
- mq->order, &mq->mmr_offset);
- if (ret < 0) {
- dev_err(xpc_part, "uv_bios_mq_watchlist_alloc() failed, "
- "ret=%d\n", ret);
- return ret;
- }
-#else
- #error not a supported configuration
-#endif
-
- mq->watchlist_num = ret;
- return 0;
-}
-
-static void
-xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq)
-{
- int ret;
- int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
-
-#if defined CONFIG_X86_64
- ret = uv_bios_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
- BUG_ON(ret != BIOS_STATUS_SUCCESS);
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- ret = sn_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
- BUG_ON(ret != SALRET_OK);
-#else
- #error not a supported configuration
-#endif
-}
-
-static struct xpc_gru_mq_uv *
-xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
- irq_handler_t irq_handler)
-{
- enum xp_retval xp_ret;
- int ret;
- int nid;
- int nasid;
- int pg_order;
- struct page *page;
- struct xpc_gru_mq_uv *mq;
- struct uv_IO_APIC_route_entry *mmr_value;
-
- mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL);
- if (mq == NULL) {
- dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
- "a xpc_gru_mq_uv structure\n");
- ret = -ENOMEM;
- goto out_0;
- }
-
- mq->gru_mq_desc = kzalloc(sizeof(struct gru_message_queue_desc),
- GFP_KERNEL);
- if (mq->gru_mq_desc == NULL) {
- dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
- "a gru_message_queue_desc structure\n");
- ret = -ENOMEM;
- goto out_1;
- }
-
- pg_order = get_order(mq_size);
- mq->order = pg_order + PAGE_SHIFT;
- mq_size = 1UL << mq->order;
-
- mq->mmr_blade = uv_cpu_to_blade_id(cpu);
-
- nid = cpu_to_node(cpu);
- page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
- pg_order);
- if (page == NULL) {
- dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d "
- "bytes of memory on nid=%d for GRU mq\n", mq_size, nid);
- ret = -ENOMEM;
- goto out_2;
- }
- mq->address = page_address(page);
-
- /* enable generation of irq when GRU mq operation occurs to this mq */
- ret = xpc_gru_mq_watchlist_alloc_uv(mq);
- if (ret != 0)
- goto out_3;
-
- ret = xpc_get_gru_mq_irq_uv(mq, cpu, irq_name);
- if (ret != 0)
- goto out_4;
-
- ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL);
- if (ret != 0) {
- dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n",
- mq->irq, -ret);
- goto out_5;
- }
-
- nasid = UV_PNODE_TO_NASID(uv_cpu_to_pnode(cpu));
-
- mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value;
- ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size,
- nasid, mmr_value->vector, mmr_value->dest);
- if (ret != 0) {
- dev_err(xpc_part, "gru_create_message_queue() returned "
- "error=%d\n", ret);
- ret = -EINVAL;
- goto out_6;
- }
-
- /* allow other partitions to access this GRU mq */
- xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size);
- if (xp_ret != xpSuccess) {
- ret = -EACCES;
- goto out_6;
- }
-
- return mq;
-
- /* something went wrong */
-out_6:
- free_irq(mq->irq, NULL);
-out_5:
- xpc_release_gru_mq_irq_uv(mq);
-out_4:
- xpc_gru_mq_watchlist_free_uv(mq);
-out_3:
- free_pages((unsigned long)mq->address, pg_order);
-out_2:
- kfree(mq->gru_mq_desc);
-out_1:
- kfree(mq);
-out_0:
- return ERR_PTR(ret);
-}
-
-static void
-xpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq)
-{
- unsigned int mq_size;
- int pg_order;
- int ret;
-
- /* disallow other partitions to access GRU mq */
- mq_size = 1UL << mq->order;
- ret = xp_restrict_memprotect(xp_pa(mq->address), mq_size);
- BUG_ON(ret != xpSuccess);
-
- /* unregister irq handler and release mq irq/vector mapping */
- free_irq(mq->irq, NULL);
- xpc_release_gru_mq_irq_uv(mq);
-
- /* disable generation of irq when GRU mq op occurs to this mq */
- xpc_gru_mq_watchlist_free_uv(mq);
-
- pg_order = mq->order - PAGE_SHIFT;
- free_pages((unsigned long)mq->address, pg_order);
-
- kfree(mq);
-}
-
-static enum xp_retval
-xpc_send_gru_msg(struct gru_message_queue_desc *gru_mq_desc, void *msg,
- size_t msg_size)
-{
- enum xp_retval xp_ret;
- int ret;
-
- while (1) {
- ret = gru_send_message_gpa(gru_mq_desc, msg, msg_size);
- if (ret == MQE_OK) {
- xp_ret = xpSuccess;
- break;
- }
-
- if (ret == MQE_QUEUE_FULL) {
- dev_dbg(xpc_chan, "gru_send_message_gpa() returned "
- "error=MQE_QUEUE_FULL\n");
- /* !!! handle QLimit reached; delay & try again */
- /* ??? Do we add a limit to the number of retries? */
- (void)msleep_interruptible(10);
- } else if (ret == MQE_CONGESTION) {
- dev_dbg(xpc_chan, "gru_send_message_gpa() returned "
- "error=MQE_CONGESTION\n");
- /* !!! handle LB Overflow; simply try again */
- /* ??? Do we add a limit to the number of retries? */
- } else {
- /* !!! Currently this is MQE_UNEXPECTED_CB_ERR */
- dev_err(xpc_chan, "gru_send_message_gpa() returned "
- "error=%d\n", ret);
- xp_ret = xpGruSendMqError;
- break;
- }
- }
- return xp_ret;
-}
-
-static void
-xpc_process_activate_IRQ_rcvd_uv(void)
-{
- unsigned long irq_flags;
- short partid;
- struct xpc_partition *part;
- u8 act_state_req;
-
- DBUG_ON(xpc_activate_IRQ_rcvd == 0);
-
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
- part = &xpc_partitions[partid];
-
- if (part->sn.uv.act_state_req == 0)
- continue;
-
- xpc_activate_IRQ_rcvd--;
- BUG_ON(xpc_activate_IRQ_rcvd < 0);
-
- act_state_req = part->sn.uv.act_state_req;
- part->sn.uv.act_state_req = 0;
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- if (act_state_req == XPC_P_ASR_ACTIVATE_UV) {
- if (part->act_state == XPC_P_AS_INACTIVE)
- xpc_activate_partition(part);
- else if (part->act_state == XPC_P_AS_DEACTIVATING)
- XPC_DEACTIVATE_PARTITION(part, xpReactivating);
-
- } else if (act_state_req == XPC_P_ASR_REACTIVATE_UV) {
- if (part->act_state == XPC_P_AS_INACTIVE)
- xpc_activate_partition(part);
- else
- XPC_DEACTIVATE_PARTITION(part, xpReactivating);
-
- } else if (act_state_req == XPC_P_ASR_DEACTIVATE_UV) {
- XPC_DEACTIVATE_PARTITION(part, part->sn.uv.reason);
-
- } else {
- BUG();
- }
-
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- if (xpc_activate_IRQ_rcvd == 0)
- break;
- }
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
-}
-
-static void
-xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
- struct xpc_activate_mq_msghdr_uv *msg_hdr,
- int part_setup,
- int *wakeup_hb_checker)
-{
- unsigned long irq_flags;
- struct xpc_partition_uv *part_uv = &part->sn.uv;
- struct xpc_openclose_args *args;
-
- part_uv->remote_act_state = msg_hdr->act_state;
-
- switch (msg_hdr->type) {
- case XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV:
- /* syncing of remote_act_state was just done above */
- break;
-
- case XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV: {
- struct xpc_activate_mq_msg_activate_req_uv *msg;
-
- /*
- * ??? Do we deal here with ts_jiffies being different
- * ??? if act_state != XPC_P_AS_INACTIVE instead of
- * ??? below?
- */
- msg = container_of(msg_hdr, struct
- xpc_activate_mq_msg_activate_req_uv, hdr);
-
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- if (part_uv->act_state_req == 0)
- xpc_activate_IRQ_rcvd++;
- part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV;
- part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */
- part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies;
- part_uv->heartbeat_gpa = msg->heartbeat_gpa;
-
- if (msg->activate_gru_mq_desc_gpa !=
- part_uv->activate_gru_mq_desc_gpa) {
- spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
- part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
- spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
- part_uv->activate_gru_mq_desc_gpa =
- msg->activate_gru_mq_desc_gpa;
- }
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- (*wakeup_hb_checker)++;
- break;
- }
- case XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV: {
- struct xpc_activate_mq_msg_deactivate_req_uv *msg;
-
- msg = container_of(msg_hdr, struct
- xpc_activate_mq_msg_deactivate_req_uv, hdr);
-
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- if (part_uv->act_state_req == 0)
- xpc_activate_IRQ_rcvd++;
- part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV;
- part_uv->reason = msg->reason;
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- (*wakeup_hb_checker)++;
- return;
- }
- case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: {
- struct xpc_activate_mq_msg_chctl_closerequest_uv *msg;
-
- if (!part_setup)
- break;
-
- msg = container_of(msg_hdr, struct
- xpc_activate_mq_msg_chctl_closerequest_uv,
- hdr);
- args = &part->remote_openclose_args[msg->ch_number];
- args->reason = msg->reason;
-
- spin_lock_irqsave(&part->chctl_lock, irq_flags);
- part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREQUEST;
- spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
- xpc_wakeup_channel_mgr(part);
- break;
- }
- case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: {
- struct xpc_activate_mq_msg_chctl_closereply_uv *msg;
-
- if (!part_setup)
- break;
-
- msg = container_of(msg_hdr, struct
- xpc_activate_mq_msg_chctl_closereply_uv,
- hdr);
-
- spin_lock_irqsave(&part->chctl_lock, irq_flags);
- part->chctl.flags[msg->ch_number] |= XPC_CHCTL_CLOSEREPLY;
- spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
- xpc_wakeup_channel_mgr(part);
- break;
- }
- case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: {
- struct xpc_activate_mq_msg_chctl_openrequest_uv *msg;
-
- if (!part_setup)
- break;
-
- msg = container_of(msg_hdr, struct
- xpc_activate_mq_msg_chctl_openrequest_uv,
- hdr);
- args = &part->remote_openclose_args[msg->ch_number];
- args->entry_size = msg->entry_size;
- args->local_nentries = msg->local_nentries;
-
- spin_lock_irqsave(&part->chctl_lock, irq_flags);
- part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREQUEST;
- spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
- xpc_wakeup_channel_mgr(part);
- break;
- }
- case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: {
- struct xpc_activate_mq_msg_chctl_openreply_uv *msg;
-
- if (!part_setup)
- break;
-
- msg = container_of(msg_hdr, struct
- xpc_activate_mq_msg_chctl_openreply_uv, hdr);
- args = &part->remote_openclose_args[msg->ch_number];
- args->remote_nentries = msg->remote_nentries;
- args->local_nentries = msg->local_nentries;
- args->local_msgqueue_pa = msg->notify_gru_mq_desc_gpa;
-
- spin_lock_irqsave(&part->chctl_lock, irq_flags);
- part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREPLY;
- spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
- xpc_wakeup_channel_mgr(part);
- break;
- }
- case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: {
- struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg;
-
- if (!part_setup)
- break;
-
- msg = container_of(msg_hdr, struct
- xpc_activate_mq_msg_chctl_opencomplete_uv, hdr);
- spin_lock_irqsave(&part->chctl_lock, irq_flags);
- part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENCOMPLETE;
- spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
- xpc_wakeup_channel_mgr(part);
- }
- case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV:
- spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
- part_uv->flags |= XPC_P_ENGAGED_UV;
- spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
- break;
-
- case XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV:
- spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
- part_uv->flags &= ~XPC_P_ENGAGED_UV;
- spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
- break;
-
- default:
- dev_err(xpc_part, "received unknown activate_mq msg type=%d "
- "from partition=%d\n", msg_hdr->type, XPC_PARTID(part));
-
- /* get hb checker to deactivate from the remote partition */
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- if (part_uv->act_state_req == 0)
- xpc_activate_IRQ_rcvd++;
- part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV;
- part_uv->reason = xpBadMsgType;
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- (*wakeup_hb_checker)++;
- return;
- }
-
- if (msg_hdr->rp_ts_jiffies != part->remote_rp_ts_jiffies &&
- part->remote_rp_ts_jiffies != 0) {
- /*
- * ??? Does what we do here need to be sensitive to
- * ??? act_state or remote_act_state?
- */
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- if (part_uv->act_state_req == 0)
- xpc_activate_IRQ_rcvd++;
- part_uv->act_state_req = XPC_P_ASR_REACTIVATE_UV;
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- (*wakeup_hb_checker)++;
- }
-}
-
-static irqreturn_t
-xpc_handle_activate_IRQ_uv(int irq, void *dev_id)
-{
- struct xpc_activate_mq_msghdr_uv *msg_hdr;
- short partid;
- struct xpc_partition *part;
- int wakeup_hb_checker = 0;
- int part_referenced;
-
- while (1) {
- msg_hdr = gru_get_next_message(xpc_activate_mq_uv->gru_mq_desc);
- if (msg_hdr == NULL)
- break;
-
- partid = msg_hdr->partid;
- if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) {
- dev_err(xpc_part, "xpc_handle_activate_IRQ_uv() "
- "received invalid partid=0x%x in message\n",
- partid);
- } else {
- part = &xpc_partitions[partid];
-
- part_referenced = xpc_part_ref(part);
- xpc_handle_activate_mq_msg_uv(part, msg_hdr,
- part_referenced,
- &wakeup_hb_checker);
- if (part_referenced)
- xpc_part_deref(part);
- }
-
- gru_free_message(xpc_activate_mq_uv->gru_mq_desc, msg_hdr);
- }
-
- if (wakeup_hb_checker)
- wake_up_interruptible(&xpc_activate_IRQ_wq);
-
- return IRQ_HANDLED;
-}
-
-static enum xp_retval
-xpc_cache_remote_gru_mq_desc_uv(struct gru_message_queue_desc *gru_mq_desc,
- unsigned long gru_mq_desc_gpa)
-{
- enum xp_retval ret;
-
- ret = xp_remote_memcpy(uv_gpa(gru_mq_desc), gru_mq_desc_gpa,
- sizeof(struct gru_message_queue_desc));
- if (ret == xpSuccess)
- gru_mq_desc->mq = NULL;
-
- return ret;
-}
-
-static enum xp_retval
-xpc_send_activate_IRQ_uv(struct xpc_partition *part, void *msg, size_t msg_size,
- int msg_type)
-{
- struct xpc_activate_mq_msghdr_uv *msg_hdr = msg;
- struct xpc_partition_uv *part_uv = &part->sn.uv;
- struct gru_message_queue_desc *gru_mq_desc;
- unsigned long irq_flags;
- enum xp_retval ret;
-
- DBUG_ON(msg_size > XPC_ACTIVATE_MSG_SIZE_UV);
-
- msg_hdr->type = msg_type;
- msg_hdr->partid = xp_partition_id;
- msg_hdr->act_state = part->act_state;
- msg_hdr->rp_ts_jiffies = xpc_rsvd_page->ts_jiffies;
-
- mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
-again:
- if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) {
- gru_mq_desc = part_uv->cached_activate_gru_mq_desc;
- if (gru_mq_desc == NULL) {
- gru_mq_desc = kmalloc(sizeof(struct
- gru_message_queue_desc),
- GFP_KERNEL);
- if (gru_mq_desc == NULL) {
- ret = xpNoMemory;
- goto done;
- }
- part_uv->cached_activate_gru_mq_desc = gru_mq_desc;
- }
-
- ret = xpc_cache_remote_gru_mq_desc_uv(gru_mq_desc,
- part_uv->
- activate_gru_mq_desc_gpa);
- if (ret != xpSuccess)
- goto done;
-
- spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
- part_uv->flags |= XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
- spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
- }
-
- /* ??? Is holding a spin_lock (ch->lock) during this call a bad idea? */
- ret = xpc_send_gru_msg(part_uv->cached_activate_gru_mq_desc, msg,
- msg_size);
- if (ret != xpSuccess) {
- smp_rmb(); /* ensure a fresh copy of part_uv->flags */
- if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV))
- goto again;
- }
-done:
- mutex_unlock(&part_uv->cached_activate_gru_mq_desc_mutex);
- return ret;
-}
-
-static void
-xpc_send_activate_IRQ_part_uv(struct xpc_partition *part, void *msg,
- size_t msg_size, int msg_type)
-{
- enum xp_retval ret;
-
- ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type);
- if (unlikely(ret != xpSuccess))
- XPC_DEACTIVATE_PARTITION(part, ret);
-}
-
-static void
-xpc_send_activate_IRQ_ch_uv(struct xpc_channel *ch, unsigned long *irq_flags,
- void *msg, size_t msg_size, int msg_type)
-{
- struct xpc_partition *part = &xpc_partitions[ch->partid];
- enum xp_retval ret;
-
- ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type);
- if (unlikely(ret != xpSuccess)) {
- if (irq_flags != NULL)
- spin_unlock_irqrestore(&ch->lock, *irq_flags);
-
- XPC_DEACTIVATE_PARTITION(part, ret);
-
- if (irq_flags != NULL)
- spin_lock_irqsave(&ch->lock, *irq_flags);
- }
-}
-
-static void
-xpc_send_local_activate_IRQ_uv(struct xpc_partition *part, int act_state_req)
-{
- unsigned long irq_flags;
- struct xpc_partition_uv *part_uv = &part->sn.uv;
-
- /*
- * !!! Make our side think that the remote partition sent an activate
- * !!! mq message our way by doing what the activate IRQ handler would
- * !!! do had one really been sent.
- */
-
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- if (part_uv->act_state_req == 0)
- xpc_activate_IRQ_rcvd++;
- part_uv->act_state_req = act_state_req;
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- wake_up_interruptible(&xpc_activate_IRQ_wq);
-}
-
-static enum xp_retval
-xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
- size_t *len)
-{
- s64 status;
- enum xp_retval ret;
-
-#if defined CONFIG_X86_64
- status = uv_bios_reserved_page_pa((u64)buf, cookie, (u64 *)rp_pa,
- (u64 *)len);
- if (status == BIOS_STATUS_SUCCESS)
- ret = xpSuccess;
- else if (status == BIOS_STATUS_MORE_PASSES)
- ret = xpNeedMoreInfo;
- else
- ret = xpBiosError;
-
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len);
- if (status == SALRET_OK)
- ret = xpSuccess;
- else if (status == SALRET_MORE_PASSES)
- ret = xpNeedMoreInfo;
- else
- ret = xpSalError;
-
-#else
- #error not a supported configuration
-#endif
-
- return ret;
-}
-
-static int
-xpc_setup_rsvd_page_uv(struct xpc_rsvd_page *rp)
-{
- xpc_heartbeat_uv =
- &xpc_partitions[sn_partition_id].sn.uv.cached_heartbeat;
- rp->sn.uv.heartbeat_gpa = uv_gpa(xpc_heartbeat_uv);
- rp->sn.uv.activate_gru_mq_desc_gpa =
- uv_gpa(xpc_activate_mq_uv->gru_mq_desc);
- return 0;
-}
-
-static void
-xpc_allow_hb_uv(short partid)
-{
-}
-
-static void
-xpc_disallow_hb_uv(short partid)
-{
-}
-
-static void
-xpc_disallow_all_hbs_uv(void)
-{
-}
-
-static void
-xpc_increment_heartbeat_uv(void)
-{
- xpc_heartbeat_uv->value++;
-}
-
-static void
-xpc_offline_heartbeat_uv(void)
-{
- xpc_increment_heartbeat_uv();
- xpc_heartbeat_uv->offline = 1;
-}
-
-static void
-xpc_online_heartbeat_uv(void)
-{
- xpc_increment_heartbeat_uv();
- xpc_heartbeat_uv->offline = 0;
-}
-
-static void
-xpc_heartbeat_init_uv(void)
-{
- xpc_heartbeat_uv->value = 1;
- xpc_heartbeat_uv->offline = 0;
-}
-
-static void
-xpc_heartbeat_exit_uv(void)
-{
- xpc_offline_heartbeat_uv();
-}
-
-static enum xp_retval
-xpc_get_remote_heartbeat_uv(struct xpc_partition *part)
-{
- struct xpc_partition_uv *part_uv = &part->sn.uv;
- enum xp_retval ret;
-
- ret = xp_remote_memcpy(uv_gpa(&part_uv->cached_heartbeat),
- part_uv->heartbeat_gpa,
- sizeof(struct xpc_heartbeat_uv));
- if (ret != xpSuccess)
- return ret;
-
- if (part_uv->cached_heartbeat.value == part->last_heartbeat &&
- !part_uv->cached_heartbeat.offline) {
-
- ret = xpNoHeartbeat;
- } else {
- part->last_heartbeat = part_uv->cached_heartbeat.value;
- }
- return ret;
-}
-
-static void
-xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
- unsigned long remote_rp_gpa, int nasid)
-{
- short partid = remote_rp->SAL_partid;
- struct xpc_partition *part = &xpc_partitions[partid];
- struct xpc_activate_mq_msg_activate_req_uv msg;
-
- part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */
- part->remote_rp_ts_jiffies = remote_rp->ts_jiffies;
- part->sn.uv.heartbeat_gpa = remote_rp->sn.uv.heartbeat_gpa;
- part->sn.uv.activate_gru_mq_desc_gpa =
- remote_rp->sn.uv.activate_gru_mq_desc_gpa;
-
- /*
- * ??? Is it a good idea to make this conditional on what is
- * ??? potentially stale state information?
- */
- if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) {
- msg.rp_gpa = uv_gpa(xpc_rsvd_page);
- msg.heartbeat_gpa = xpc_rsvd_page->sn.uv.heartbeat_gpa;
- msg.activate_gru_mq_desc_gpa =
- xpc_rsvd_page->sn.uv.activate_gru_mq_desc_gpa;
- xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV);
- }
-
- if (part->act_state == XPC_P_AS_INACTIVE)
- xpc_send_local_activate_IRQ_uv(part, XPC_P_ASR_ACTIVATE_UV);
-}
-
-static void
-xpc_request_partition_reactivation_uv(struct xpc_partition *part)
-{
- xpc_send_local_activate_IRQ_uv(part, XPC_P_ASR_ACTIVATE_UV);
-}
-
-static void
-xpc_request_partition_deactivation_uv(struct xpc_partition *part)
-{
- struct xpc_activate_mq_msg_deactivate_req_uv msg;
-
- /*
- * ??? Is it a good idea to make this conditional on what is
- * ??? potentially stale state information?
- */
- if (part->sn.uv.remote_act_state != XPC_P_AS_DEACTIVATING &&
- part->sn.uv.remote_act_state != XPC_P_AS_INACTIVE) {
-
- msg.reason = part->reason;
- xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV);
- }
-}
-
-static void
-xpc_cancel_partition_deactivation_request_uv(struct xpc_partition *part)
-{
- /* nothing needs to be done */
- return;
-}
-
-static void
-xpc_init_fifo_uv(struct xpc_fifo_head_uv *head)
-{
- head->first = NULL;
- head->last = NULL;
- spin_lock_init(&head->lock);
- head->n_entries = 0;
-}
-
-static void *
-xpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head)
-{
- unsigned long irq_flags;
- struct xpc_fifo_entry_uv *first;
-
- spin_lock_irqsave(&head->lock, irq_flags);
- first = head->first;
- if (head->first != NULL) {
- head->first = first->next;
- if (head->first == NULL)
- head->last = NULL;
-
- head->n_entries--;
- BUG_ON(head->n_entries < 0);
-
- first->next = NULL;
- }
- spin_unlock_irqrestore(&head->lock, irq_flags);
- return first;
-}
-
-static void
-xpc_put_fifo_entry_uv(struct xpc_fifo_head_uv *head,
- struct xpc_fifo_entry_uv *last)
-{
- unsigned long irq_flags;
-
- last->next = NULL;
- spin_lock_irqsave(&head->lock, irq_flags);
- if (head->last != NULL)
- head->last->next = last;
- else
- head->first = last;
- head->last = last;
- head->n_entries++;
- spin_unlock_irqrestore(&head->lock, irq_flags);
-}
-
-static int
-xpc_n_of_fifo_entries_uv(struct xpc_fifo_head_uv *head)
-{
- return head->n_entries;
-}
-
-/*
- * Setup the channel structures that are uv specific.
- */
-static enum xp_retval
-xpc_setup_ch_structures_uv(struct xpc_partition *part)
-{
- struct xpc_channel_uv *ch_uv;
- int ch_number;
-
- for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
- ch_uv = &part->channels[ch_number].sn.uv;
-
- xpc_init_fifo_uv(&ch_uv->msg_slot_free_list);
- xpc_init_fifo_uv(&ch_uv->recv_msg_list);
- }
-
- return xpSuccess;
-}
-
-/*
- * Teardown the channel structures that are uv specific.
- */
-static void
-xpc_teardown_ch_structures_uv(struct xpc_partition *part)
-{
- /* nothing needs to be done */
- return;
-}
-
-static enum xp_retval
-xpc_make_first_contact_uv(struct xpc_partition *part)
-{
- struct xpc_activate_mq_msg_uv msg;
-
- /*
- * We send a sync msg to get the remote partition's remote_act_state
- * updated to our current act_state which at this point should
- * be XPC_P_AS_ACTIVATING.
- */
- xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV);
-
- while (!((part->sn.uv.remote_act_state == XPC_P_AS_ACTIVATING) ||
- (part->sn.uv.remote_act_state == XPC_P_AS_ACTIVE))) {
-
- dev_dbg(xpc_part, "waiting to make first contact with "
- "partition %d\n", XPC_PARTID(part));
-
- /* wait a 1/4 of a second or so */
- (void)msleep_interruptible(250);
-
- if (part->act_state == XPC_P_AS_DEACTIVATING)
- return part->reason;
- }
-
- return xpSuccess;
-}
-
-static u64
-xpc_get_chctl_all_flags_uv(struct xpc_partition *part)
-{
- unsigned long irq_flags;
- union xpc_channel_ctl_flags chctl;
-
- spin_lock_irqsave(&part->chctl_lock, irq_flags);
- chctl = part->chctl;
- if (chctl.all_flags != 0)
- part->chctl.all_flags = 0;
-
- spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
- return chctl.all_flags;
-}
-
-static enum xp_retval
-xpc_allocate_send_msg_slot_uv(struct xpc_channel *ch)
-{
- struct xpc_channel_uv *ch_uv = &ch->sn.uv;
- struct xpc_send_msg_slot_uv *msg_slot;
- unsigned long irq_flags;
- int nentries;
- int entry;
- size_t nbytes;
-
- for (nentries = ch->local_nentries; nentries > 0; nentries--) {
- nbytes = nentries * sizeof(struct xpc_send_msg_slot_uv);
- ch_uv->send_msg_slots = kzalloc(nbytes, GFP_KERNEL);
- if (ch_uv->send_msg_slots == NULL)
- continue;
-
- for (entry = 0; entry < nentries; entry++) {
- msg_slot = &ch_uv->send_msg_slots[entry];
-
- msg_slot->msg_slot_number = entry;
- xpc_put_fifo_entry_uv(&ch_uv->msg_slot_free_list,
- &msg_slot->next);
- }
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- if (nentries < ch->local_nentries)
- ch->local_nentries = nentries;
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return xpSuccess;
- }
-
- return xpNoMemory;
-}
-
-static enum xp_retval
-xpc_allocate_recv_msg_slot_uv(struct xpc_channel *ch)
-{
- struct xpc_channel_uv *ch_uv = &ch->sn.uv;
- struct xpc_notify_mq_msg_uv *msg_slot;
- unsigned long irq_flags;
- int nentries;
- int entry;
- size_t nbytes;
-
- for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
- nbytes = nentries * ch->entry_size;
- ch_uv->recv_msg_slots = kzalloc(nbytes, GFP_KERNEL);
- if (ch_uv->recv_msg_slots == NULL)
- continue;
-
- for (entry = 0; entry < nentries; entry++) {
- msg_slot = ch_uv->recv_msg_slots +
- entry * ch->entry_size;
-
- msg_slot->hdr.msg_slot_number = entry;
- }
-
- spin_lock_irqsave(&ch->lock, irq_flags);
- if (nentries < ch->remote_nentries)
- ch->remote_nentries = nentries;
- spin_unlock_irqrestore(&ch->lock, irq_flags);
- return xpSuccess;
- }
-
- return xpNoMemory;
-}
-
-/*
- * Allocate msg_slots associated with the channel.
- */
-static enum xp_retval
-xpc_setup_msg_structures_uv(struct xpc_channel *ch)
-{
- static enum xp_retval ret;
- struct xpc_channel_uv *ch_uv = &ch->sn.uv;
-
- DBUG_ON(ch->flags & XPC_C_SETUP);
-
- ch_uv->cached_notify_gru_mq_desc = kmalloc(sizeof(struct
- gru_message_queue_desc),
- GFP_KERNEL);
- if (ch_uv->cached_notify_gru_mq_desc == NULL)
- return xpNoMemory;
-
- ret = xpc_allocate_send_msg_slot_uv(ch);
- if (ret == xpSuccess) {
-
- ret = xpc_allocate_recv_msg_slot_uv(ch);
- if (ret != xpSuccess) {
- kfree(ch_uv->send_msg_slots);
- xpc_init_fifo_uv(&ch_uv->msg_slot_free_list);
- }
- }
- return ret;
-}
-
-/*
- * Free up msg_slots and clear other stuff that were setup for the specified
- * channel.
- */
-static void
-xpc_teardown_msg_structures_uv(struct xpc_channel *ch)
-{
- struct xpc_channel_uv *ch_uv = &ch->sn.uv;
-
- DBUG_ON(!spin_is_locked(&ch->lock));
-
- kfree(ch_uv->cached_notify_gru_mq_desc);
- ch_uv->cached_notify_gru_mq_desc = NULL;
-
- if (ch->flags & XPC_C_SETUP) {
- xpc_init_fifo_uv(&ch_uv->msg_slot_free_list);
- kfree(ch_uv->send_msg_slots);
- xpc_init_fifo_uv(&ch_uv->recv_msg_list);
- kfree(ch_uv->recv_msg_slots);
- }
-}
-
-static void
-xpc_send_chctl_closerequest_uv(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- struct xpc_activate_mq_msg_chctl_closerequest_uv msg;
-
- msg.ch_number = ch->number;
- msg.reason = ch->reason;
- xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV);
-}
-
-static void
-xpc_send_chctl_closereply_uv(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- struct xpc_activate_mq_msg_chctl_closereply_uv msg;
-
- msg.ch_number = ch->number;
- xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV);
-}
-
-static void
-xpc_send_chctl_openrequest_uv(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- struct xpc_activate_mq_msg_chctl_openrequest_uv msg;
-
- msg.ch_number = ch->number;
- msg.entry_size = ch->entry_size;
- msg.local_nentries = ch->local_nentries;
- xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV);
-}
-
-static void
-xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- struct xpc_activate_mq_msg_chctl_openreply_uv msg;
-
- msg.ch_number = ch->number;
- msg.local_nentries = ch->local_nentries;
- msg.remote_nentries = ch->remote_nentries;
- msg.notify_gru_mq_desc_gpa = uv_gpa(xpc_notify_mq_uv->gru_mq_desc);
- xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV);
-}
-
-static void
-xpc_send_chctl_opencomplete_uv(struct xpc_channel *ch, unsigned long *irq_flags)
-{
- struct xpc_activate_mq_msg_chctl_opencomplete_uv msg;
-
- msg.ch_number = ch->number;
- xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV);
-}
-
-static void
-xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number)
-{
- unsigned long irq_flags;
-
- spin_lock_irqsave(&part->chctl_lock, irq_flags);
- part->chctl.flags[ch_number] |= XPC_CHCTL_MSGREQUEST;
- spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
- xpc_wakeup_channel_mgr(part);
-}
-
-static enum xp_retval
-xpc_save_remote_msgqueue_pa_uv(struct xpc_channel *ch,
- unsigned long gru_mq_desc_gpa)
-{
- struct xpc_channel_uv *ch_uv = &ch->sn.uv;
-
- DBUG_ON(ch_uv->cached_notify_gru_mq_desc == NULL);
- return xpc_cache_remote_gru_mq_desc_uv(ch_uv->cached_notify_gru_mq_desc,
- gru_mq_desc_gpa);
-}
-
-static void
-xpc_indicate_partition_engaged_uv(struct xpc_partition *part)
-{
- struct xpc_activate_mq_msg_uv msg;
-
- xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV);
-}
-
-static void
-xpc_indicate_partition_disengaged_uv(struct xpc_partition *part)
-{
- struct xpc_activate_mq_msg_uv msg;
-
- xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
- XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV);
-}
-
-static void
-xpc_assume_partition_disengaged_uv(short partid)
-{
- struct xpc_partition_uv *part_uv = &xpc_partitions[partid].sn.uv;
- unsigned long irq_flags;
-
- spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
- part_uv->flags &= ~XPC_P_ENGAGED_UV;
- spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
-}
-
-static int
-xpc_partition_engaged_uv(short partid)
-{
- return (xpc_partitions[partid].sn.uv.flags & XPC_P_ENGAGED_UV) != 0;
-}
-
-static int
-xpc_any_partition_engaged_uv(void)
-{
- struct xpc_partition_uv *part_uv;
- short partid;
-
- for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
- part_uv = &xpc_partitions[partid].sn.uv;
- if ((part_uv->flags & XPC_P_ENGAGED_UV) != 0)
- return 1;
- }
- return 0;
-}
-
-static enum xp_retval
-xpc_allocate_msg_slot_uv(struct xpc_channel *ch, u32 flags,
- struct xpc_send_msg_slot_uv **address_of_msg_slot)
-{
- enum xp_retval ret;
- struct xpc_send_msg_slot_uv *msg_slot;
- struct xpc_fifo_entry_uv *entry;
-
- while (1) {
- entry = xpc_get_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list);
- if (entry != NULL)
- break;
-
- if (flags & XPC_NOWAIT)
- return xpNoWait;
-
- ret = xpc_allocate_msg_wait(ch);
- if (ret != xpInterrupted && ret != xpTimeout)
- return ret;
- }
-
- msg_slot = container_of(entry, struct xpc_send_msg_slot_uv, next);
- *address_of_msg_slot = msg_slot;
- return xpSuccess;
-}
-
-static void
-xpc_free_msg_slot_uv(struct xpc_channel *ch,
- struct xpc_send_msg_slot_uv *msg_slot)
-{
- xpc_put_fifo_entry_uv(&ch->sn.uv.msg_slot_free_list, &msg_slot->next);
-
- /* wakeup anyone waiting for a free msg slot */
- if (atomic_read(&ch->n_on_msg_allocate_wq) > 0)
- wake_up(&ch->msg_allocate_wq);
-}
-
-static void
-xpc_notify_sender_uv(struct xpc_channel *ch,
- struct xpc_send_msg_slot_uv *msg_slot,
- enum xp_retval reason)
-{
- xpc_notify_func func = msg_slot->func;
-
- if (func != NULL && cmpxchg(&msg_slot->func, func, NULL) == func) {
-
- atomic_dec(&ch->n_to_notify);
-
- dev_dbg(xpc_chan, "msg_slot->func() called, msg_slot=0x%p "
- "msg_slot_number=%d partid=%d channel=%d\n", msg_slot,
- msg_slot->msg_slot_number, ch->partid, ch->number);
-
- func(reason, ch->partid, ch->number, msg_slot->key);
-
- dev_dbg(xpc_chan, "msg_slot->func() returned, msg_slot=0x%p "
- "msg_slot_number=%d partid=%d channel=%d\n", msg_slot,
- msg_slot->msg_slot_number, ch->partid, ch->number);
- }
-}
-
-static void
-xpc_handle_notify_mq_ack_uv(struct xpc_channel *ch,
- struct xpc_notify_mq_msg_uv *msg)
-{
- struct xpc_send_msg_slot_uv *msg_slot;
- int entry = msg->hdr.msg_slot_number % ch->local_nentries;
-
- msg_slot = &ch->sn.uv.send_msg_slots[entry];
-
- BUG_ON(msg_slot->msg_slot_number != msg->hdr.msg_slot_number);
- msg_slot->msg_slot_number += ch->local_nentries;
-
- if (msg_slot->func != NULL)
- xpc_notify_sender_uv(ch, msg_slot, xpMsgDelivered);
-
- xpc_free_msg_slot_uv(ch, msg_slot);
-}
-
-static void
-xpc_handle_notify_mq_msg_uv(struct xpc_partition *part,
- struct xpc_notify_mq_msg_uv *msg)
-{
- struct xpc_partition_uv *part_uv = &part->sn.uv;
- struct xpc_channel *ch;
- struct xpc_channel_uv *ch_uv;
- struct xpc_notify_mq_msg_uv *msg_slot;
- unsigned long irq_flags;
- int ch_number = msg->hdr.ch_number;
-
- if (unlikely(ch_number >= part->nchannels)) {
- dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received invalid "
- "channel number=0x%x in message from partid=%d\n",
- ch_number, XPC_PARTID(part));
-
- /* get hb checker to deactivate from the remote partition */
- spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
- if (part_uv->act_state_req == 0)
- xpc_activate_IRQ_rcvd++;
- part_uv->act_state_req = XPC_P_ASR_DEACTIVATE_UV;
- part_uv->reason = xpBadChannelNumber;
- spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
- wake_up_interruptible(&xpc_activate_IRQ_wq);
- return;
- }
-
- ch = &part->channels[ch_number];
- xpc_msgqueue_ref(ch);
-
- if (!(ch->flags & XPC_C_CONNECTED)) {
- xpc_msgqueue_deref(ch);
- return;
- }
-
- /* see if we're really dealing with an ACK for a previously sent msg */
- if (msg->hdr.size == 0) {
- xpc_handle_notify_mq_ack_uv(ch, msg);
- xpc_msgqueue_deref(ch);
- return;
- }
-
- /* we're dealing with a normal message sent via the notify_mq */
- ch_uv = &ch->sn.uv;
-
- msg_slot = ch_uv->recv_msg_slots +
- (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size;
-
- BUG_ON(msg_slot->hdr.size != 0);
-
- memcpy(msg_slot, msg, msg->hdr.size);
-
- xpc_put_fifo_entry_uv(&ch_uv->recv_msg_list, &msg_slot->hdr.u.next);
-
- if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE) {
- /*
- * If there is an existing idle kthread get it to deliver
- * the payload, otherwise we'll have to get the channel mgr
- * for this partition to create a kthread to do the delivery.
- */
- if (atomic_read(&ch->kthreads_idle) > 0)
- wake_up_nr(&ch->idle_wq, 1);
- else
- xpc_send_chctl_local_msgrequest_uv(part, ch->number);
- }
- xpc_msgqueue_deref(ch);
-}
-
-static irqreturn_t
-xpc_handle_notify_IRQ_uv(int irq, void *dev_id)
-{
- struct xpc_notify_mq_msg_uv *msg;
- short partid;
- struct xpc_partition *part;
-
- while ((msg = gru_get_next_message(xpc_notify_mq_uv->gru_mq_desc)) !=
- NULL) {
-
- partid = msg->hdr.partid;
- if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) {
- dev_err(xpc_part, "xpc_handle_notify_IRQ_uv() received "
- "invalid partid=0x%x in message\n", partid);
- } else {
- part = &xpc_partitions[partid];
-
- if (xpc_part_ref(part)) {
- xpc_handle_notify_mq_msg_uv(part, msg);
- xpc_part_deref(part);
- }
- }
-
- gru_free_message(xpc_notify_mq_uv->gru_mq_desc, msg);
- }
-
- return IRQ_HANDLED;
-}
-
-static int
-xpc_n_of_deliverable_payloads_uv(struct xpc_channel *ch)
-{
- return xpc_n_of_fifo_entries_uv(&ch->sn.uv.recv_msg_list);
-}
-
-static void
-xpc_process_msg_chctl_flags_uv(struct xpc_partition *part, int ch_number)
-{
- struct xpc_channel *ch = &part->channels[ch_number];
- int ndeliverable_payloads;
-
- xpc_msgqueue_ref(ch);
-
- ndeliverable_payloads = xpc_n_of_deliverable_payloads_uv(ch);
-
- if (ndeliverable_payloads > 0 &&
- (ch->flags & XPC_C_CONNECTED) &&
- (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)) {
-
- xpc_activate_kthreads(ch, ndeliverable_payloads);
- }
-
- xpc_msgqueue_deref(ch);
-}
-
-static enum xp_retval
-xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload,
- u16 payload_size, u8 notify_type, xpc_notify_func func,
- void *key)
-{
- enum xp_retval ret = xpSuccess;
- struct xpc_send_msg_slot_uv *msg_slot = NULL;
- struct xpc_notify_mq_msg_uv *msg;
- u8 msg_buffer[XPC_NOTIFY_MSG_SIZE_UV];
- size_t msg_size;
-
- DBUG_ON(notify_type != XPC_N_CALL);
-
- msg_size = sizeof(struct xpc_notify_mq_msghdr_uv) + payload_size;
- if (msg_size > ch->entry_size)
- return xpPayloadTooBig;
-
- xpc_msgqueue_ref(ch);
-
- if (ch->flags & XPC_C_DISCONNECTING) {
- ret = ch->reason;
- goto out_1;
- }
- if (!(ch->flags & XPC_C_CONNECTED)) {
- ret = xpNotConnected;
- goto out_1;
- }
-
- ret = xpc_allocate_msg_slot_uv(ch, flags, &msg_slot);
- if (ret != xpSuccess)
- goto out_1;
-
- if (func != NULL) {
- atomic_inc(&ch->n_to_notify);
-
- msg_slot->key = key;
- smp_wmb(); /* a non-NULL func must hit memory after the key */
- msg_slot->func = func;
-
- if (ch->flags & XPC_C_DISCONNECTING) {
- ret = ch->reason;
- goto out_2;
- }
- }
-
- msg = (struct xpc_notify_mq_msg_uv *)&msg_buffer;
- msg->hdr.partid = xp_partition_id;
- msg->hdr.ch_number = ch->number;
- msg->hdr.size = msg_size;
- msg->hdr.msg_slot_number = msg_slot->msg_slot_number;
- memcpy(&msg->payload, payload, payload_size);
-
- ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
- msg_size);
- if (ret == xpSuccess)
- goto out_1;
-
- XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
-out_2:
- if (func != NULL) {
- /*
- * Try to NULL the msg_slot's func field. If we fail, then
- * xpc_notify_senders_of_disconnect_uv() beat us to it, in which
- * case we need to pretend we succeeded to send the message
- * since the user will get a callout for the disconnect error
- * by xpc_notify_senders_of_disconnect_uv(), and to also get an
- * error returned here will confuse them. Additionally, since
- * in this case the channel is being disconnected we don't need
- * to put the the msg_slot back on the free list.
- */
- if (cmpxchg(&msg_slot->func, func, NULL) != func) {
- ret = xpSuccess;
- goto out_1;
- }
-
- msg_slot->key = NULL;
- atomic_dec(&ch->n_to_notify);
- }
- xpc_free_msg_slot_uv(ch, msg_slot);
-out_1:
- xpc_msgqueue_deref(ch);
- return ret;
-}
-
-/*
- * Tell the callers of xpc_send_notify() that the status of their payloads
- * is unknown because the channel is now disconnecting.
- *
- * We don't worry about putting these msg_slots on the free list since the
- * msg_slots themselves are about to be kfree'd.
- */
-static void
-xpc_notify_senders_of_disconnect_uv(struct xpc_channel *ch)
-{
- struct xpc_send_msg_slot_uv *msg_slot;
- int entry;
-
- DBUG_ON(!(ch->flags & XPC_C_DISCONNECTING));
-
- for (entry = 0; entry < ch->local_nentries; entry++) {
-
- if (atomic_read(&ch->n_to_notify) == 0)
- break;
-
- msg_slot = &ch->sn.uv.send_msg_slots[entry];
- if (msg_slot->func != NULL)
- xpc_notify_sender_uv(ch, msg_slot, ch->reason);
- }
-}
-
-/*
- * Get the next deliverable message's payload.
- */
-static void *
-xpc_get_deliverable_payload_uv(struct xpc_channel *ch)
-{
- struct xpc_fifo_entry_uv *entry;
- struct xpc_notify_mq_msg_uv *msg;
- void *payload = NULL;
-
- if (!(ch->flags & XPC_C_DISCONNECTING)) {
- entry = xpc_get_fifo_entry_uv(&ch->sn.uv.recv_msg_list);
- if (entry != NULL) {
- msg = container_of(entry, struct xpc_notify_mq_msg_uv,
- hdr.u.next);
- payload = &msg->payload;
- }
- }
- return payload;
-}
-
-static void
-xpc_received_payload_uv(struct xpc_channel *ch, void *payload)
-{
- struct xpc_notify_mq_msg_uv *msg;
- enum xp_retval ret;
-
- msg = container_of(payload, struct xpc_notify_mq_msg_uv, payload);
-
- /* return an ACK to the sender of this message */
-
- msg->hdr.partid = xp_partition_id;
- msg->hdr.size = 0; /* size of zero indicates this is an ACK */
-
- ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
- sizeof(struct xpc_notify_mq_msghdr_uv));
- if (ret != xpSuccess)
- XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
-}
-
-static struct xpc_arch_operations xpc_arch_ops_uv = {
- .setup_partitions = xpc_setup_partitions_uv,
- .teardown_partitions = xpc_teardown_partitions_uv,
- .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv,
- .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv,
- .setup_rsvd_page = xpc_setup_rsvd_page_uv,
-
- .allow_hb = xpc_allow_hb_uv,
- .disallow_hb = xpc_disallow_hb_uv,
- .disallow_all_hbs = xpc_disallow_all_hbs_uv,
- .increment_heartbeat = xpc_increment_heartbeat_uv,
- .offline_heartbeat = xpc_offline_heartbeat_uv,
- .online_heartbeat = xpc_online_heartbeat_uv,
- .heartbeat_init = xpc_heartbeat_init_uv,
- .heartbeat_exit = xpc_heartbeat_exit_uv,
- .get_remote_heartbeat = xpc_get_remote_heartbeat_uv,
-
- .request_partition_activation =
- xpc_request_partition_activation_uv,
- .request_partition_reactivation =
- xpc_request_partition_reactivation_uv,
- .request_partition_deactivation =
- xpc_request_partition_deactivation_uv,
- .cancel_partition_deactivation_request =
- xpc_cancel_partition_deactivation_request_uv,
-
- .setup_ch_structures = xpc_setup_ch_structures_uv,
- .teardown_ch_structures = xpc_teardown_ch_structures_uv,
-
- .make_first_contact = xpc_make_first_contact_uv,
-
- .get_chctl_all_flags = xpc_get_chctl_all_flags_uv,
- .send_chctl_closerequest = xpc_send_chctl_closerequest_uv,
- .send_chctl_closereply = xpc_send_chctl_closereply_uv,
- .send_chctl_openrequest = xpc_send_chctl_openrequest_uv,
- .send_chctl_openreply = xpc_send_chctl_openreply_uv,
- .send_chctl_opencomplete = xpc_send_chctl_opencomplete_uv,
- .process_msg_chctl_flags = xpc_process_msg_chctl_flags_uv,
-
- .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv,
-
- .setup_msg_structures = xpc_setup_msg_structures_uv,
- .teardown_msg_structures = xpc_teardown_msg_structures_uv,
-
- .indicate_partition_engaged = xpc_indicate_partition_engaged_uv,
- .indicate_partition_disengaged = xpc_indicate_partition_disengaged_uv,
- .assume_partition_disengaged = xpc_assume_partition_disengaged_uv,
- .partition_engaged = xpc_partition_engaged_uv,
- .any_partition_engaged = xpc_any_partition_engaged_uv,
-
- .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_uv,
- .send_payload = xpc_send_payload_uv,
- .get_deliverable_payload = xpc_get_deliverable_payload_uv,
- .received_payload = xpc_received_payload_uv,
- .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv,
-};
-
-int
-xpc_init_uv(void)
-{
- xpc_arch_ops = xpc_arch_ops_uv;
-
- if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) {
- dev_err(xpc_part, "xpc_notify_mq_msghdr_uv is larger than %d\n",
- XPC_MSG_HDR_MAX_SIZE);
- return -E2BIG;
- }
-
- xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0,
- XPC_ACTIVATE_IRQ_NAME,
- xpc_handle_activate_IRQ_uv);
- if (IS_ERR(xpc_activate_mq_uv))
- return PTR_ERR(xpc_activate_mq_uv);
-
- xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0,
- XPC_NOTIFY_IRQ_NAME,
- xpc_handle_notify_IRQ_uv);
- if (IS_ERR(xpc_notify_mq_uv)) {
- xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
- return PTR_ERR(xpc_notify_mq_uv);
- }
-
- return 0;
-}
-
-void
-xpc_exit_uv(void)
-{
- xpc_destroy_gru_mq_uv(xpc_notify_mq_uv);
- xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
-}
diff --git a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpnet.c b/ANDROID_3.4.5/drivers/misc/sgi-xp/xpnet.c
deleted file mode 100644
index 3fac67a5..00000000
--- a/ANDROID_3.4.5/drivers/misc/sgi-xp/xpnet.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999-2009 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * Cross Partition Network Interface (XPNET) support
- *
- * XPNET provides a virtual network layered on top of the Cross
- * Partition communication layer.
- *
- * XPNET provides direct point-to-point and broadcast-like support
- * for an ethernet-like device. The ethernet broadcast medium is
- * replaced with a point-to-point message structure which passes
- * pointers to a DMA-capable block that a remote partition should
- * retrieve and pass to the upper level networking layer.
- *
- */
-
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include "xp.h"
-
-/*
- * The message payload transferred by XPC.
- *
- * buf_pa is the physical address where the DMA should pull from.
- *
- * NOTE: for performance reasons, buf_pa should _ALWAYS_ begin on a
- * cacheline boundary. To accomplish this, we record the number of
- * bytes from the beginning of the first cacheline to the first useful
- * byte of the skb (leadin_ignore) and the number of bytes from the
- * last useful byte of the skb to the end of the last cacheline
- * (tailout_ignore).
- *
- * size is the number of bytes to transfer which includes the skb->len
- * (useful bytes of the senders skb) plus the leadin and tailout
- */
-struct xpnet_message {
- u16 version; /* Version for this message */
- u16 embedded_bytes; /* #of bytes embedded in XPC message */
- u32 magic; /* Special number indicating this is xpnet */
- unsigned long buf_pa; /* phys address of buffer to retrieve */
- u32 size; /* #of bytes in buffer */
- u8 leadin_ignore; /* #of bytes to ignore at the beginning */
- u8 tailout_ignore; /* #of bytes to ignore at the end */
- unsigned char data; /* body of small packets */
-};
-
-/*
- * Determine the size of our message, the cacheline aligned size,
- * and then the number of message will request from XPC.
- *
- * XPC expects each message to exist in an individual cacheline.
- */
-#define XPNET_MSG_SIZE XPC_MSG_PAYLOAD_MAX_SIZE
-#define XPNET_MSG_DATA_MAX \
- (XPNET_MSG_SIZE - offsetof(struct xpnet_message, data))
-#define XPNET_MSG_NENTRIES (PAGE_SIZE / XPC_MSG_MAX_SIZE)
-
-#define XPNET_MAX_KTHREADS (XPNET_MSG_NENTRIES + 1)
-#define XPNET_MAX_IDLE_KTHREADS (XPNET_MSG_NENTRIES + 1)
-
-/*
- * Version number of XPNET implementation. XPNET can always talk to versions
- * with same major #, and never talk to versions with a different version.
- */
-#define _XPNET_VERSION(_major, _minor) (((_major) << 4) | (_minor))
-#define XPNET_VERSION_MAJOR(_v) ((_v) >> 4)
-#define XPNET_VERSION_MINOR(_v) ((_v) & 0xf)
-
-#define XPNET_VERSION _XPNET_VERSION(1, 0) /* version 1.0 */
-#define XPNET_VERSION_EMBED _XPNET_VERSION(1, 1) /* version 1.1 */
-#define XPNET_MAGIC 0x88786984 /* "XNET" */
-
-#define XPNET_VALID_MSG(_m) \
- ((XPNET_VERSION_MAJOR(_m->version) == XPNET_VERSION_MAJOR(XPNET_VERSION)) \
- && (msg->magic == XPNET_MAGIC))
-
-#define XPNET_DEVICE_NAME "xp0"
-
-/*
- * When messages are queued with xpc_send_notify, a kmalloc'd buffer
- * of the following type is passed as a notification cookie. When the
- * notification function is called, we use the cookie to decide
- * whether all outstanding message sends have completed. The skb can
- * then be released.
- */
-struct xpnet_pending_msg {
- struct sk_buff *skb;
- atomic_t use_count;
-};
-
-struct net_device *xpnet_device;
-
-/*
- * When we are notified of other partitions activating, we add them to
- * our bitmask of partitions to which we broadcast.
- */
-static unsigned long *xpnet_broadcast_partitions;
-/* protect above */
-static DEFINE_SPINLOCK(xpnet_broadcast_lock);
-
-/*
- * Since the Block Transfer Engine (BTE) is being used for the transfer
- * and it relies upon cache-line size transfers, we need to reserve at
- * least one cache-line for head and tail alignment. The BTE is
- * limited to 8MB transfers.
- *
- * Testing has shown that changing MTU to greater than 64KB has no effect
- * on TCP as the two sides negotiate a Max Segment Size that is limited
- * to 64K. Other protocols May use packets greater than this, but for
- * now, the default is 64KB.
- */
-#define XPNET_MAX_MTU (0x800000UL - L1_CACHE_BYTES)
-/* 32KB has been determined to be the ideal */
-#define XPNET_DEF_MTU (0x8000UL)
-
-/*
- * The partid is encapsulated in the MAC address beginning in the following
- * octet and it consists of two octets.
- */
-#define XPNET_PARTID_OCTET 2
-
-/* Define the XPNET debug device structures to be used with dev_dbg() et al */
-
-struct device_driver xpnet_dbg_name = {
- .name = "xpnet"
-};
-
-struct device xpnet_dbg_subname = {
- .init_name = "", /* set to "" */
- .driver = &xpnet_dbg_name
-};
-
-struct device *xpnet = &xpnet_dbg_subname;
-
-/*
- * Packet was recevied by XPC and forwarded to us.
- */
-static void
-xpnet_receive(short partid, int channel, struct xpnet_message *msg)
-{
- struct sk_buff *skb;
- void *dst;
- enum xp_retval ret;
-
- if (!XPNET_VALID_MSG(msg)) {
- /*
- * Packet with a different XPC version. Ignore.
- */
- xpc_received(partid, channel, (void *)msg);
-
- xpnet_device->stats.rx_errors++;
-
- return;
- }
- dev_dbg(xpnet, "received 0x%lx, %d, %d, %d\n", msg->buf_pa, msg->size,
- msg->leadin_ignore, msg->tailout_ignore);
-
- /* reserve an extra cache line */
- skb = dev_alloc_skb(msg->size + L1_CACHE_BYTES);
- if (!skb) {
- dev_err(xpnet, "failed on dev_alloc_skb(%d)\n",
- msg->size + L1_CACHE_BYTES);
-
- xpc_received(partid, channel, (void *)msg);
-
- xpnet_device->stats.rx_errors++;
-
- return;
- }
-
- /*
- * The allocated skb has some reserved space.
- * In order to use xp_remote_memcpy(), we need to get the
- * skb->data pointer moved forward.
- */
- skb_reserve(skb, (L1_CACHE_BYTES - ((u64)skb->data &
- (L1_CACHE_BYTES - 1)) +
- msg->leadin_ignore));
-
- /*
- * Update the tail pointer to indicate data actually
- * transferred.
- */
- skb_put(skb, (msg->size - msg->leadin_ignore - msg->tailout_ignore));
-
- /*
- * Move the data over from the other side.
- */
- if ((XPNET_VERSION_MINOR(msg->version) == 1) &&
- (msg->embedded_bytes != 0)) {
- dev_dbg(xpnet, "copying embedded message. memcpy(0x%p, 0x%p, "
- "%lu)\n", skb->data, &msg->data,
- (size_t)msg->embedded_bytes);
-
- skb_copy_to_linear_data(skb, &msg->data,
- (size_t)msg->embedded_bytes);
- } else {
- dst = (void *)((u64)skb->data & ~(L1_CACHE_BYTES - 1));
- dev_dbg(xpnet, "transferring buffer to the skb->data area;\n\t"
- "xp_remote_memcpy(0x%p, 0x%p, %hu)\n", dst,
- (void *)msg->buf_pa, msg->size);
-
- ret = xp_remote_memcpy(xp_pa(dst), msg->buf_pa, msg->size);
- if (ret != xpSuccess) {
- /*
- * !!! Need better way of cleaning skb. Currently skb
- * !!! appears in_use and we can't just call
- * !!! dev_kfree_skb.
- */
- dev_err(xpnet, "xp_remote_memcpy(0x%p, 0x%p, 0x%hx) "
- "returned error=0x%x\n", dst,
- (void *)msg->buf_pa, msg->size, ret);
-
- xpc_received(partid, channel, (void *)msg);
-
- xpnet_device->stats.rx_errors++;
-
- return;
- }
- }
-
- dev_dbg(xpnet, "<skb->head=0x%p skb->data=0x%p skb->tail=0x%p "
- "skb->end=0x%p skb->len=%d\n", (void *)skb->head,
- (void *)skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
- skb->len);
-
- skb->protocol = eth_type_trans(skb, xpnet_device);
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-
- dev_dbg(xpnet, "passing skb to network layer\n"
- "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p "
- "skb->end=0x%p skb->len=%d\n",
- (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb),
- skb_end_pointer(skb), skb->len);
-
- xpnet_device->stats.rx_packets++;
- xpnet_device->stats.rx_bytes += skb->len + ETH_HLEN;
-
- netif_rx_ni(skb);
- xpc_received(partid, channel, (void *)msg);
-}
-
-/*
- * This is the handler which XPC calls during any sort of change in
- * state or message reception on a connection.
- */
-static void
-xpnet_connection_activity(enum xp_retval reason, short partid, int channel,
- void *data, void *key)
-{
- DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
- DBUG_ON(channel != XPC_NET_CHANNEL);
-
- switch (reason) {
- case xpMsgReceived: /* message received */
- DBUG_ON(data == NULL);
-
- xpnet_receive(partid, channel, (struct xpnet_message *)data);
- break;
-
- case xpConnected: /* connection completed to a partition */
- spin_lock_bh(&xpnet_broadcast_lock);
- __set_bit(partid, xpnet_broadcast_partitions);
- spin_unlock_bh(&xpnet_broadcast_lock);
-
- netif_carrier_on(xpnet_device);
-
- dev_dbg(xpnet, "%s connected to partition %d\n",
- xpnet_device->name, partid);
- break;
-
- default:
- spin_lock_bh(&xpnet_broadcast_lock);
- __clear_bit(partid, xpnet_broadcast_partitions);
- spin_unlock_bh(&xpnet_broadcast_lock);
-
- if (bitmap_empty((unsigned long *)xpnet_broadcast_partitions,
- xp_max_npartitions)) {
- netif_carrier_off(xpnet_device);
- }
-
- dev_dbg(xpnet, "%s disconnected from partition %d\n",
- xpnet_device->name, partid);
- break;
- }
-}
-
-static int
-xpnet_dev_open(struct net_device *dev)
-{
- enum xp_retval ret;
-
- dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, "
- "%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
- (unsigned long)XPNET_MSG_SIZE,
- (unsigned long)XPNET_MSG_NENTRIES,
- (unsigned long)XPNET_MAX_KTHREADS,
- (unsigned long)XPNET_MAX_IDLE_KTHREADS);
-
- ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL,
- XPNET_MSG_SIZE, XPNET_MSG_NENTRIES,
- XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS);
- if (ret != xpSuccess) {
- dev_err(xpnet, "ifconfig up of %s failed on XPC connect, "
- "ret=%d\n", dev->name, ret);
-
- return -ENOMEM;
- }
-
- dev_dbg(xpnet, "ifconfig up of %s; XPC connected\n", dev->name);
-
- return 0;
-}
-
-static int
-xpnet_dev_stop(struct net_device *dev)
-{
- xpc_disconnect(XPC_NET_CHANNEL);
-
- dev_dbg(xpnet, "ifconfig down of %s; XPC disconnected\n", dev->name);
-
- return 0;
-}
-
-static int
-xpnet_dev_change_mtu(struct net_device *dev, int new_mtu)
-{
- /* 68 comes from min TCP+IP+MAC header */
- if ((new_mtu < 68) || (new_mtu > XPNET_MAX_MTU)) {
- dev_err(xpnet, "ifconfig %s mtu %d failed; value must be "
- "between 68 and %ld\n", dev->name, new_mtu,
- XPNET_MAX_MTU);
- return -EINVAL;
- }
-
- dev->mtu = new_mtu;
- dev_dbg(xpnet, "ifconfig %s mtu set to %d\n", dev->name, new_mtu);
- return 0;
-}
-
-/*
- * Notification that the other end has received the message and
- * DMA'd the skb information. At this point, they are done with
- * our side. When all recipients are done processing, we
- * release the skb and then release our pending message structure.
- */
-static void
-xpnet_send_completed(enum xp_retval reason, short partid, int channel,
- void *__qm)
-{
- struct xpnet_pending_msg *queued_msg = (struct xpnet_pending_msg *)__qm;
-
- DBUG_ON(queued_msg == NULL);
-
- dev_dbg(xpnet, "message to %d notified with reason %d\n",
- partid, reason);
-
- if (atomic_dec_return(&queued_msg->use_count) == 0) {
- dev_dbg(xpnet, "all acks for skb->head=-x%p\n",
- (void *)queued_msg->skb->head);
-
- dev_kfree_skb_any(queued_msg->skb);
- kfree(queued_msg);
- }
-}
-
-static void
-xpnet_send(struct sk_buff *skb, struct xpnet_pending_msg *queued_msg,
- u64 start_addr, u64 end_addr, u16 embedded_bytes, int dest_partid)
-{
- u8 msg_buffer[XPNET_MSG_SIZE];
- struct xpnet_message *msg = (struct xpnet_message *)&msg_buffer;
- u16 msg_size = sizeof(struct xpnet_message);
- enum xp_retval ret;
-
- msg->embedded_bytes = embedded_bytes;
- if (unlikely(embedded_bytes != 0)) {
- msg->version = XPNET_VERSION_EMBED;
- dev_dbg(xpnet, "calling memcpy(0x%p, 0x%p, 0x%lx)\n",
- &msg->data, skb->data, (size_t)embedded_bytes);
- skb_copy_from_linear_data(skb, &msg->data,
- (size_t)embedded_bytes);
- msg_size += embedded_bytes - 1;
- } else {
- msg->version = XPNET_VERSION;
- }
- msg->magic = XPNET_MAGIC;
- msg->size = end_addr - start_addr;
- msg->leadin_ignore = (u64)skb->data - start_addr;
- msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb);
- msg->buf_pa = xp_pa((void *)start_addr);
-
- dev_dbg(xpnet, "sending XPC message to %d:%d\n"
- "msg->buf_pa=0x%lx, msg->size=%u, "
- "msg->leadin_ignore=%u, msg->tailout_ignore=%u\n",
- dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size,
- msg->leadin_ignore, msg->tailout_ignore);
-
- atomic_inc(&queued_msg->use_count);
-
- ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, XPC_NOWAIT, msg,
- msg_size, xpnet_send_completed, queued_msg);
- if (unlikely(ret != xpSuccess))
- atomic_dec(&queued_msg->use_count);
-}
-
-/*
- * Network layer has formatted a packet (skb) and is ready to place it
- * "on the wire". Prepare and send an xpnet_message to all partitions
- * which have connected with us and are targets of this packet.
- *
- * MAC-NOTE: For the XPNET driver, the MAC address contains the
- * destination partid. If the destination partid octets are 0xffff,
- * this packet is to be broadcast to all connected partitions.
- */
-static int
-xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct xpnet_pending_msg *queued_msg;
- u64 start_addr, end_addr;
- short dest_partid;
- u16 embedded_bytes = 0;
-
- dev_dbg(xpnet, ">skb->head=0x%p skb->data=0x%p skb->tail=0x%p "
- "skb->end=0x%p skb->len=%d\n", (void *)skb->head,
- (void *)skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
- skb->len);
-
- if (skb->data[0] == 0x33) {
- dev_kfree_skb(skb);
- return NETDEV_TX_OK; /* nothing needed to be done */
- }
-
- /*
- * The xpnet_pending_msg tracks how many outstanding
- * xpc_send_notifies are relying on this skb. When none
- * remain, release the skb.
- */
- queued_msg = kmalloc(sizeof(struct xpnet_pending_msg), GFP_ATOMIC);
- if (queued_msg == NULL) {
- dev_warn(xpnet, "failed to kmalloc %ld bytes; dropping "
- "packet\n", sizeof(struct xpnet_pending_msg));
-
- dev->stats.tx_errors++;
- dev_kfree_skb(skb);
- return NETDEV_TX_OK;
- }
-
- /* get the beginning of the first cacheline and end of last */
- start_addr = ((u64)skb->data & ~(L1_CACHE_BYTES - 1));
- end_addr = L1_CACHE_ALIGN((u64)skb_tail_pointer(skb));
-
- /* calculate how many bytes to embed in the XPC message */
- if (unlikely(skb->len <= XPNET_MSG_DATA_MAX)) {
- /* skb->data does fit so embed */
- embedded_bytes = skb->len;
- }
-
- /*
- * Since the send occurs asynchronously, we set the count to one
- * and begin sending. Any sends that happen to complete before
- * we are done sending will not free the skb. We will be left
- * with that task during exit. This also handles the case of
- * a packet destined for a partition which is no longer up.
- */
- atomic_set(&queued_msg->use_count, 1);
- queued_msg->skb = skb;
-
- if (skb->data[0] == 0xff) {
- /* we are being asked to broadcast to all partitions */
- for_each_set_bit(dest_partid, xpnet_broadcast_partitions,
- xp_max_npartitions) {
-
- xpnet_send(skb, queued_msg, start_addr, end_addr,
- embedded_bytes, dest_partid);
- }
- } else {
- dest_partid = (short)skb->data[XPNET_PARTID_OCTET + 1];
- dest_partid |= (short)skb->data[XPNET_PARTID_OCTET + 0] << 8;
-
- if (dest_partid >= 0 &&
- dest_partid < xp_max_npartitions &&
- test_bit(dest_partid, xpnet_broadcast_partitions) != 0) {
-
- xpnet_send(skb, queued_msg, start_addr, end_addr,
- embedded_bytes, dest_partid);
- }
- }
-
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
-
- if (atomic_dec_return(&queued_msg->use_count) == 0) {
- dev_kfree_skb(skb);
- kfree(queued_msg);
- }
-
- return NETDEV_TX_OK;
-}
-
-/*
- * Deal with transmit timeouts coming from the network layer.
- */
-static void
-xpnet_dev_tx_timeout(struct net_device *dev)
-{
- dev->stats.tx_errors++;
-}
-
-static const struct net_device_ops xpnet_netdev_ops = {
- .ndo_open = xpnet_dev_open,
- .ndo_stop = xpnet_dev_stop,
- .ndo_start_xmit = xpnet_dev_hard_start_xmit,
- .ndo_change_mtu = xpnet_dev_change_mtu,
- .ndo_tx_timeout = xpnet_dev_tx_timeout,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
-};
-
-static int __init
-xpnet_init(void)
-{
- int result;
-
- if (!is_shub() && !is_uv())
- return -ENODEV;
-
- dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
-
- xpnet_broadcast_partitions = kzalloc(BITS_TO_LONGS(xp_max_npartitions) *
- sizeof(long), GFP_KERNEL);
- if (xpnet_broadcast_partitions == NULL)
- return -ENOMEM;
-
- /*
- * use ether_setup() to init the majority of our device
- * structure and then override the necessary pieces.
- */
- xpnet_device = alloc_netdev(0, XPNET_DEVICE_NAME, ether_setup);
- if (xpnet_device == NULL) {
- kfree(xpnet_broadcast_partitions);
- return -ENOMEM;
- }
-
- netif_carrier_off(xpnet_device);
-
- xpnet_device->netdev_ops = &xpnet_netdev_ops;
- xpnet_device->mtu = XPNET_DEF_MTU;
-
- /*
- * Multicast assumes the LSB of the first octet is set for multicast
- * MAC addresses. We chose the first octet of the MAC to be unlikely
- * to collide with any vendor's officially issued MAC.
- */
- xpnet_device->dev_addr[0] = 0x02; /* locally administered, no OUI */
-
- xpnet_device->dev_addr[XPNET_PARTID_OCTET + 1] = xp_partition_id;
- xpnet_device->dev_addr[XPNET_PARTID_OCTET + 0] = (xp_partition_id >> 8);
-
- /*
- * ether_setup() sets this to a multicast device. We are
- * really not supporting multicast at this time.
- */
- xpnet_device->flags &= ~IFF_MULTICAST;
-
- /*
- * No need to checksum as it is a DMA transfer. The BTE will
- * report an error if the data is not retrievable and the
- * packet will be dropped.
- */
- xpnet_device->features = NETIF_F_HW_CSUM;
-
- result = register_netdev(xpnet_device);
- if (result != 0) {
- free_netdev(xpnet_device);
- kfree(xpnet_broadcast_partitions);
- }
-
- return result;
-}
-
-module_init(xpnet_init);
-
-static void __exit
-xpnet_exit(void)
-{
- dev_info(xpnet, "unregistering network device %s\n",
- xpnet_device[0].name);
-
- unregister_netdev(xpnet_device);
- free_netdev(xpnet_device);
- kfree(xpnet_broadcast_partitions);
-}
-
-module_exit(xpnet_exit);
-
-MODULE_AUTHOR("Silicon Graphics, Inc.");
-MODULE_DESCRIPTION("Cross Partition Network adapter (XPNET)");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/spear13xx_pcie_gadget.c b/ANDROID_3.4.5/drivers/misc/spear13xx_pcie_gadget.c
deleted file mode 100644
index 123ed98e..00000000
--- a/ANDROID_3.4.5/drivers/misc/spear13xx_pcie_gadget.c
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
- * drivers/misc/spear13xx_pcie_gadget.c
- *
- * Copyright (C) 2010 ST Microelectronics
- * Pratyush Anand<pratyush.anand@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/clk.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/pci_regs.h>
-#include <linux/configfs.h>
-#include <mach/pcie.h>
-#include <mach/misc_regs.h>
-
-#define IN0_MEM_SIZE (200 * 1024 * 1024 - 1)
-/* In current implementation address translation is done using IN0 only.
- * So IN1 start address and IN0 end address has been kept same
-*/
-#define IN1_MEM_SIZE (0 * 1024 * 1024 - 1)
-#define IN_IO_SIZE (20 * 1024 * 1024 - 1)
-#define IN_CFG0_SIZE (12 * 1024 * 1024 - 1)
-#define IN_CFG1_SIZE (12 * 1024 * 1024 - 1)
-#define IN_MSG_SIZE (12 * 1024 * 1024 - 1)
-/* Keep default BAR size as 4K*/
-/* AORAM would be mapped by default*/
-#define INBOUND_ADDR_MASK (SPEAR13XX_SYSRAM1_SIZE - 1)
-
-#define INT_TYPE_NO_INT 0
-#define INT_TYPE_INTX 1
-#define INT_TYPE_MSI 2
-struct spear_pcie_gadget_config {
- void __iomem *base;
- void __iomem *va_app_base;
- void __iomem *va_dbi_base;
- char int_type[10];
- ulong requested_msi;
- ulong configured_msi;
- ulong bar0_size;
- ulong bar0_rw_offset;
- void __iomem *va_bar0_address;
-};
-
-struct pcie_gadget_target {
- struct configfs_subsystem subsys;
- struct spear_pcie_gadget_config config;
-};
-
-struct pcie_gadget_target_attr {
- struct configfs_attribute attr;
- ssize_t (*show)(struct spear_pcie_gadget_config *config,
- char *buf);
- ssize_t (*store)(struct spear_pcie_gadget_config *config,
- const char *buf,
- size_t count);
-};
-
-static void enable_dbi_access(struct pcie_app_reg __iomem *app_reg)
-{
- /* Enable DBI access */
- writel(readl(&app_reg->slv_armisc) | (1 << AXI_OP_DBI_ACCESS_ID),
- &app_reg->slv_armisc);
- writel(readl(&app_reg->slv_awmisc) | (1 << AXI_OP_DBI_ACCESS_ID),
- &app_reg->slv_awmisc);
-
-}
-
-static void disable_dbi_access(struct pcie_app_reg __iomem *app_reg)
-{
- /* disable DBI access */
- writel(readl(&app_reg->slv_armisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
- &app_reg->slv_armisc);
- writel(readl(&app_reg->slv_awmisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
- &app_reg->slv_awmisc);
-
-}
-
-static void spear_dbi_read_reg(struct spear_pcie_gadget_config *config,
- int where, int size, u32 *val)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
- ulong va_address;
-
- /* Enable DBI access */
- enable_dbi_access(app_reg);
-
- va_address = (ulong)config->va_dbi_base + (where & ~0x3);
-
- *val = readl(va_address);
-
- if (size == 1)
- *val = (*val >> (8 * (where & 3))) & 0xff;
- else if (size == 2)
- *val = (*val >> (8 * (where & 3))) & 0xffff;
-
- /* Disable DBI access */
- disable_dbi_access(app_reg);
-}
-
-static void spear_dbi_write_reg(struct spear_pcie_gadget_config *config,
- int where, int size, u32 val)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
- ulong va_address;
-
- /* Enable DBI access */
- enable_dbi_access(app_reg);
-
- va_address = (ulong)config->va_dbi_base + (where & ~0x3);
-
- if (size == 4)
- writel(val, va_address);
- else if (size == 2)
- writew(val, va_address + (where & 2));
- else if (size == 1)
- writeb(val, va_address + (where & 3));
-
- /* Disable DBI access */
- disable_dbi_access(app_reg);
-}
-
-#define PCI_FIND_CAP_TTL 48
-
-static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config *config,
- u32 pos, int cap, int *ttl)
-{
- u32 id;
-
- while ((*ttl)--) {
- spear_dbi_read_reg(config, pos, 1, &pos);
- if (pos < 0x40)
- break;
- pos &= ~3;
- spear_dbi_read_reg(config, pos + PCI_CAP_LIST_ID, 1, &id);
- if (id == 0xff)
- break;
- if (id == cap)
- return pos;
- pos += PCI_CAP_LIST_NEXT;
- }
- return 0;
-}
-
-static int pci_find_own_next_cap(struct spear_pcie_gadget_config *config,
- u32 pos, int cap)
-{
- int ttl = PCI_FIND_CAP_TTL;
-
- return pci_find_own_next_cap_ttl(config, pos, cap, &ttl);
-}
-
-static int pci_find_own_cap_start(struct spear_pcie_gadget_config *config,
- u8 hdr_type)
-{
- u32 status;
-
- spear_dbi_read_reg(config, PCI_STATUS, 2, &status);
- if (!(status & PCI_STATUS_CAP_LIST))
- return 0;
-
- switch (hdr_type) {
- case PCI_HEADER_TYPE_NORMAL:
- case PCI_HEADER_TYPE_BRIDGE:
- return PCI_CAPABILITY_LIST;
- case PCI_HEADER_TYPE_CARDBUS:
- return PCI_CB_CAPABILITY_LIST;
- default:
- return 0;
- }
-
- return 0;
-}
-
-/*
- * Tell if a device supports a given PCI capability.
- * Returns the address of the requested capability structure within the
- * device's PCI configuration space or 0 in case the device does not
- * support it. Possible values for @cap:
- *
- * %PCI_CAP_ID_PM Power Management
- * %PCI_CAP_ID_AGP Accelerated Graphics Port
- * %PCI_CAP_ID_VPD Vital Product Data
- * %PCI_CAP_ID_SLOTID Slot Identification
- * %PCI_CAP_ID_MSI Message Signalled Interrupts
- * %PCI_CAP_ID_CHSWP CompactPCI HotSwap
- * %PCI_CAP_ID_PCIX PCI-X
- * %PCI_CAP_ID_EXP PCI Express
- */
-static int pci_find_own_capability(struct spear_pcie_gadget_config *config,
- int cap)
-{
- u32 pos;
- u32 hdr_type;
-
- spear_dbi_read_reg(config, PCI_HEADER_TYPE, 1, &hdr_type);
-
- pos = pci_find_own_cap_start(config, hdr_type);
- if (pos)
- pos = pci_find_own_next_cap(config, pos, cap);
-
- return pos;
-}
-
-static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id)
-{
- return 0;
-}
-
-/*
- * configfs interfaces show/store functions
- */
-static ssize_t pcie_gadget_show_link(
- struct spear_pcie_gadget_config *config,
- char *buf)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
-
- if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID))
- return sprintf(buf, "UP");
- else
- return sprintf(buf, "DOWN");
-}
-
-static ssize_t pcie_gadget_store_link(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
-
- if (sysfs_streq(buf, "UP"))
- writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID),
- &app_reg->app_ctrl_0);
- else if (sysfs_streq(buf, "DOWN"))
- writel(readl(&app_reg->app_ctrl_0)
- & ~(1 << APP_LTSSM_ENABLE_ID),
- &app_reg->app_ctrl_0);
- else
- return -EINVAL;
- return count;
-}
-
-static ssize_t pcie_gadget_show_int_type(
- struct spear_pcie_gadget_config *config,
- char *buf)
-{
- return sprintf(buf, "%s", config->int_type);
-}
-
-static ssize_t pcie_gadget_store_int_type(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- u32 cap, vec, flags;
- ulong vector;
-
- if (sysfs_streq(buf, "INTA"))
- spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
-
- else if (sysfs_streq(buf, "MSI")) {
- vector = config->requested_msi;
- vec = 0;
- while (vector > 1) {
- vector /= 2;
- vec++;
- }
- spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 0);
- cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
- spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
- flags &= ~PCI_MSI_FLAGS_QMASK;
- flags |= vec << 1;
- spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags);
- } else
- return -EINVAL;
-
- strcpy(config->int_type, buf);
-
- return count;
-}
-
-static ssize_t pcie_gadget_show_no_of_msi(
- struct spear_pcie_gadget_config *config,
- char *buf)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
- u32 cap, vec, flags;
- ulong vector;
-
- if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID))
- != (1 << CFG_MSI_EN_ID))
- vector = 0;
- else {
- cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
- spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
- flags &= ~PCI_MSI_FLAGS_QSIZE;
- vec = flags >> 4;
- vector = 1;
- while (vec--)
- vector *= 2;
- }
- config->configured_msi = vector;
-
- return sprintf(buf, "%lu", vector);
-}
-
-static ssize_t pcie_gadget_store_no_of_msi(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- if (strict_strtoul(buf, 0, &config->requested_msi))
- return -EINVAL;
- if (config->requested_msi > 32)
- config->requested_msi = 32;
-
- return count;
-}
-
-static ssize_t pcie_gadget_store_inta(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
- ulong en;
-
- if (strict_strtoul(buf, 0, &en))
- return -EINVAL;
-
- if (en)
- writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID),
- &app_reg->app_ctrl_0);
- else
- writel(readl(&app_reg->app_ctrl_0) & ~(1 << SYS_INT_ID),
- &app_reg->app_ctrl_0);
-
- return count;
-}
-
-static ssize_t pcie_gadget_store_send_msi(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
- ulong vector;
- u32 ven_msi;
-
- if (strict_strtoul(buf, 0, &vector))
- return -EINVAL;
-
- if (!config->configured_msi)
- return -EINVAL;
-
- if (vector >= config->configured_msi)
- return -EINVAL;
-
- ven_msi = readl(&app_reg->ven_msi_1);
- ven_msi &= ~VEN_MSI_FUN_NUM_MASK;
- ven_msi |= 0 << VEN_MSI_FUN_NUM_ID;
- ven_msi &= ~VEN_MSI_TC_MASK;
- ven_msi |= 0 << VEN_MSI_TC_ID;
- ven_msi &= ~VEN_MSI_VECTOR_MASK;
- ven_msi |= vector << VEN_MSI_VECTOR_ID;
-
- /* generating interrupt for msi vector */
- ven_msi |= VEN_MSI_REQ_EN;
- writel(ven_msi, &app_reg->ven_msi_1);
- udelay(1);
- ven_msi &= ~VEN_MSI_REQ_EN;
- writel(ven_msi, &app_reg->ven_msi_1);
-
- return count;
-}
-
-static ssize_t pcie_gadget_show_vendor_id(
- struct spear_pcie_gadget_config *config,
- char *buf)
-{
- u32 id;
-
- spear_dbi_read_reg(config, PCI_VENDOR_ID, 2, &id);
-
- return sprintf(buf, "%x", id);
-}
-
-static ssize_t pcie_gadget_store_vendor_id(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- ulong id;
-
- if (strict_strtoul(buf, 0, &id))
- return -EINVAL;
-
- spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id);
-
- return count;
-}
-
-static ssize_t pcie_gadget_show_device_id(
- struct spear_pcie_gadget_config *config,
- char *buf)
-{
- u32 id;
-
- spear_dbi_read_reg(config, PCI_DEVICE_ID, 2, &id);
-
- return sprintf(buf, "%x", id);
-}
-
-static ssize_t pcie_gadget_store_device_id(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- ulong id;
-
- if (strict_strtoul(buf, 0, &id))
- return -EINVAL;
-
- spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id);
-
- return count;
-}
-
-static ssize_t pcie_gadget_show_bar0_size(
- struct spear_pcie_gadget_config *config,
- char *buf)
-{
- return sprintf(buf, "%lx", config->bar0_size);
-}
-
-static ssize_t pcie_gadget_store_bar0_size(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- ulong size;
- u32 pos, pos1;
- u32 no_of_bit = 0;
-
- if (strict_strtoul(buf, 0, &size))
- return -EINVAL;
- /* min bar size is 256 */
- if (size <= 0x100)
- size = 0x100;
- /* max bar size is 1MB*/
- else if (size >= 0x100000)
- size = 0x100000;
- else {
- pos = 0;
- pos1 = 0;
- while (pos < 21) {
- pos = find_next_bit((ulong *)&size, 21, pos);
- if (pos != 21)
- pos1 = pos + 1;
- pos++;
- no_of_bit++;
- }
- if (no_of_bit == 2)
- pos1--;
-
- size = 1 << pos1;
- }
- config->bar0_size = size;
- spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, size - 1);
-
- return count;
-}
-
-static ssize_t pcie_gadget_show_bar0_address(
- struct spear_pcie_gadget_config *config,
- char *buf)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
-
- u32 address = readl(&app_reg->pim0_mem_addr_start);
-
- return sprintf(buf, "%x", address);
-}
-
-static ssize_t pcie_gadget_store_bar0_address(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
- ulong address;
-
- if (strict_strtoul(buf, 0, &address))
- return -EINVAL;
-
- address &= ~(config->bar0_size - 1);
- if (config->va_bar0_address)
- iounmap(config->va_bar0_address);
- config->va_bar0_address = ioremap(address, config->bar0_size);
- if (!config->va_bar0_address)
- return -ENOMEM;
-
- writel(address, &app_reg->pim0_mem_addr_start);
-
- return count;
-}
-
-static ssize_t pcie_gadget_show_bar0_rw_offset(
- struct spear_pcie_gadget_config *config,
- char *buf)
-{
- return sprintf(buf, "%lx", config->bar0_rw_offset);
-}
-
-static ssize_t pcie_gadget_store_bar0_rw_offset(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- ulong offset;
-
- if (strict_strtoul(buf, 0, &offset))
- return -EINVAL;
-
- if (offset % 4)
- return -EINVAL;
-
- config->bar0_rw_offset = offset;
-
- return count;
-}
-
-static ssize_t pcie_gadget_show_bar0_data(
- struct spear_pcie_gadget_config *config,
- char *buf)
-{
- ulong data;
-
- if (!config->va_bar0_address)
- return -ENOMEM;
-
- data = readl((ulong)config->va_bar0_address + config->bar0_rw_offset);
-
- return sprintf(buf, "%lx", data);
-}
-
-static ssize_t pcie_gadget_store_bar0_data(
- struct spear_pcie_gadget_config *config,
- const char *buf, size_t count)
-{
- ulong data;
-
- if (strict_strtoul(buf, 0, &data))
- return -EINVAL;
-
- if (!config->va_bar0_address)
- return -ENOMEM;
-
- writel(data, (ulong)config->va_bar0_address + config->bar0_rw_offset);
-
- return count;
-}
-
-/*
- * Attribute definitions.
- */
-
-#define PCIE_GADGET_TARGET_ATTR_RO(_name) \
-static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \
- __CONFIGFS_ATTR(_name, S_IRUGO, pcie_gadget_show_##_name, NULL)
-
-#define PCIE_GADGET_TARGET_ATTR_WO(_name) \
-static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \
- __CONFIGFS_ATTR(_name, S_IWUSR, NULL, pcie_gadget_store_##_name)
-
-#define PCIE_GADGET_TARGET_ATTR_RW(_name) \
-static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \
- __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, pcie_gadget_show_##_name, \
- pcie_gadget_store_##_name)
-PCIE_GADGET_TARGET_ATTR_RW(link);
-PCIE_GADGET_TARGET_ATTR_RW(int_type);
-PCIE_GADGET_TARGET_ATTR_RW(no_of_msi);
-PCIE_GADGET_TARGET_ATTR_WO(inta);
-PCIE_GADGET_TARGET_ATTR_WO(send_msi);
-PCIE_GADGET_TARGET_ATTR_RW(vendor_id);
-PCIE_GADGET_TARGET_ATTR_RW(device_id);
-PCIE_GADGET_TARGET_ATTR_RW(bar0_size);
-PCIE_GADGET_TARGET_ATTR_RW(bar0_address);
-PCIE_GADGET_TARGET_ATTR_RW(bar0_rw_offset);
-PCIE_GADGET_TARGET_ATTR_RW(bar0_data);
-
-static struct configfs_attribute *pcie_gadget_target_attrs[] = {
- &pcie_gadget_target_link.attr,
- &pcie_gadget_target_int_type.attr,
- &pcie_gadget_target_no_of_msi.attr,
- &pcie_gadget_target_inta.attr,
- &pcie_gadget_target_send_msi.attr,
- &pcie_gadget_target_vendor_id.attr,
- &pcie_gadget_target_device_id.attr,
- &pcie_gadget_target_bar0_size.attr,
- &pcie_gadget_target_bar0_address.attr,
- &pcie_gadget_target_bar0_rw_offset.attr,
- &pcie_gadget_target_bar0_data.attr,
- NULL,
-};
-
-static struct pcie_gadget_target *to_target(struct config_item *item)
-{
- return item ?
- container_of(to_configfs_subsystem(to_config_group(item)),
- struct pcie_gadget_target, subsys) : NULL;
-}
-
-/*
- * Item operations and type for pcie_gadget_target.
- */
-
-static ssize_t pcie_gadget_target_attr_show(struct config_item *item,
- struct configfs_attribute *attr,
- char *buf)
-{
- ssize_t ret = -EINVAL;
- struct pcie_gadget_target *target = to_target(item);
- struct pcie_gadget_target_attr *t_attr =
- container_of(attr, struct pcie_gadget_target_attr, attr);
-
- if (t_attr->show)
- ret = t_attr->show(&target->config, buf);
- return ret;
-}
-
-static ssize_t pcie_gadget_target_attr_store(struct config_item *item,
- struct configfs_attribute *attr,
- const char *buf,
- size_t count)
-{
- ssize_t ret = -EINVAL;
- struct pcie_gadget_target *target = to_target(item);
- struct pcie_gadget_target_attr *t_attr =
- container_of(attr, struct pcie_gadget_target_attr, attr);
-
- if (t_attr->store)
- ret = t_attr->store(&target->config, buf, count);
- return ret;
-}
-
-static struct configfs_item_operations pcie_gadget_target_item_ops = {
- .show_attribute = pcie_gadget_target_attr_show,
- .store_attribute = pcie_gadget_target_attr_store,
-};
-
-static struct config_item_type pcie_gadget_target_type = {
- .ct_attrs = pcie_gadget_target_attrs,
- .ct_item_ops = &pcie_gadget_target_item_ops,
- .ct_owner = THIS_MODULE,
-};
-
-static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config)
-{
- struct pcie_app_reg __iomem *app_reg = config->va_app_base;
-
- /*setup registers for outbound translation */
-
- writel(config->base, &app_reg->in0_mem_addr_start);
- writel(app_reg->in0_mem_addr_start + IN0_MEM_SIZE,
- &app_reg->in0_mem_addr_limit);
- writel(app_reg->in0_mem_addr_limit + 1, &app_reg->in1_mem_addr_start);
- writel(app_reg->in1_mem_addr_start + IN1_MEM_SIZE,
- &app_reg->in1_mem_addr_limit);
- writel(app_reg->in1_mem_addr_limit + 1, &app_reg->in_io_addr_start);
- writel(app_reg->in_io_addr_start + IN_IO_SIZE,
- &app_reg->in_io_addr_limit);
- writel(app_reg->in_io_addr_limit + 1, &app_reg->in_cfg0_addr_start);
- writel(app_reg->in_cfg0_addr_start + IN_CFG0_SIZE,
- &app_reg->in_cfg0_addr_limit);
- writel(app_reg->in_cfg0_addr_limit + 1, &app_reg->in_cfg1_addr_start);
- writel(app_reg->in_cfg1_addr_start + IN_CFG1_SIZE,
- &app_reg->in_cfg1_addr_limit);
- writel(app_reg->in_cfg1_addr_limit + 1, &app_reg->in_msg_addr_start);
- writel(app_reg->in_msg_addr_start + IN_MSG_SIZE,
- &app_reg->in_msg_addr_limit);
-
- writel(app_reg->in0_mem_addr_start, &app_reg->pom0_mem_addr_start);
- writel(app_reg->in1_mem_addr_start, &app_reg->pom1_mem_addr_start);
- writel(app_reg->in_io_addr_start, &app_reg->pom_io_addr_start);
-
- /*setup registers for inbound translation */
-
- /* Keep AORAM mapped at BAR0 as default */
- config->bar0_size = INBOUND_ADDR_MASK + 1;
- spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK);
- spear_dbi_write_reg(config, PCI_BASE_ADDRESS_0, 4, 0xC);
- config->va_bar0_address = ioremap(SPEAR13XX_SYSRAM1_BASE,
- config->bar0_size);
-
- writel(SPEAR13XX_SYSRAM1_BASE, &app_reg->pim0_mem_addr_start);
- writel(0, &app_reg->pim1_mem_addr_start);
- writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit);
-
- writel(0x0, &app_reg->pim_io_addr_start);
- writel(0x0, &app_reg->pim_io_addr_start);
- writel(0x0, &app_reg->pim_rom_addr_start);
-
- writel(DEVICE_TYPE_EP | (1 << MISCTRL_EN_ID)
- | ((u32)1 << REG_TRANSLATION_ENABLE),
- &app_reg->app_ctrl_0);
- /* disable all rx interrupts */
- writel(0, &app_reg->int_mask);
-
- /* Select INTA as default*/
- spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
-}
-
-static int __devinit spear_pcie_gadget_probe(struct platform_device *pdev)
-{
- struct resource *res0, *res1;
- unsigned int status = 0;
- int irq;
- struct clk *clk;
- static struct pcie_gadget_target *target;
- struct spear_pcie_gadget_config *config;
- struct config_item *cg_item;
- struct configfs_subsystem *subsys;
-
- /* get resource for application registers*/
-
- res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res0) {
- dev_err(&pdev->dev, "no resource defined\n");
- return -EBUSY;
- }
- if (!request_mem_region(res0->start, resource_size(res0),
- pdev->name)) {
- dev_err(&pdev->dev, "pcie gadget region already claimed\n");
- return -EBUSY;
- }
- /* get resource for dbi registers*/
-
- res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (!res1) {
- dev_err(&pdev->dev, "no resource defined\n");
- goto err_rel_res0;
- }
- if (!request_mem_region(res1->start, resource_size(res1),
- pdev->name)) {
- dev_err(&pdev->dev, "pcie gadget region already claimed\n");
- goto err_rel_res0;
- }
-
- target = kzalloc(sizeof(*target), GFP_KERNEL);
- if (!target) {
- dev_err(&pdev->dev, "out of memory\n");
- status = -ENOMEM;
- goto err_rel_res;
- }
-
- cg_item = &target->subsys.su_group.cg_item;
- sprintf(cg_item->ci_namebuf, "pcie_gadget.%d", pdev->id);
- cg_item->ci_type = &pcie_gadget_target_type;
- config = &target->config;
- config->va_app_base = (void __iomem *)ioremap(res0->start,
- resource_size(res0));
- if (!config->va_app_base) {
- dev_err(&pdev->dev, "ioremap fail\n");
- status = -ENOMEM;
- goto err_kzalloc;
- }
-
- config->base = (void __iomem *)res1->start;
-
- config->va_dbi_base = (void __iomem *)ioremap(res1->start,
- resource_size(res1));
- if (!config->va_dbi_base) {
- dev_err(&pdev->dev, "ioremap fail\n");
- status = -ENOMEM;
- goto err_iounmap_app;
- }
-
- dev_set_drvdata(&pdev->dev, target);
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- dev_err(&pdev->dev, "no update irq?\n");
- status = irq;
- goto err_iounmap;
- }
-
- status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL);
- if (status) {
- dev_err(&pdev->dev,
- "pcie gadget interrupt IRQ%d already claimed\n", irq);
- goto err_iounmap;
- }
-
- /* Register configfs hooks */
- subsys = &target->subsys;
- config_group_init(&subsys->su_group);
- mutex_init(&subsys->su_mutex);
- status = configfs_register_subsystem(subsys);
- if (status)
- goto err_irq;
-
- /*
- * init basic pcie application registers
- * do not enable clock if it is PCIE0.Ideally , all controller should
- * have been independent from others with respect to clock. But PCIE1
- * and 2 depends on PCIE0.So PCIE0 clk is provided during board init.
- */
- if (pdev->id == 1) {
- /*
- * Ideally CFG Clock should have been also enabled here. But
- * it is done currently during board init routne
- */
- clk = clk_get_sys("pcie1", NULL);
- if (IS_ERR(clk)) {
- pr_err("%s:couldn't get clk for pcie1\n", __func__);
- goto err_irq;
- }
- if (clk_enable(clk)) {
- pr_err("%s:couldn't enable clk for pcie1\n", __func__);
- goto err_irq;
- }
- } else if (pdev->id == 2) {
- /*
- * Ideally CFG Clock should have been also enabled here. But
- * it is done currently during board init routne
- */
- clk = clk_get_sys("pcie2", NULL);
- if (IS_ERR(clk)) {
- pr_err("%s:couldn't get clk for pcie2\n", __func__);
- goto err_irq;
- }
- if (clk_enable(clk)) {
- pr_err("%s:couldn't enable clk for pcie2\n", __func__);
- goto err_irq;
- }
- }
- spear13xx_pcie_device_init(config);
-
- return 0;
-err_irq:
- free_irq(irq, NULL);
-err_iounmap:
- iounmap(config->va_dbi_base);
-err_iounmap_app:
- iounmap(config->va_app_base);
-err_kzalloc:
- kfree(target);
-err_rel_res:
- release_mem_region(res1->start, resource_size(res1));
-err_rel_res0:
- release_mem_region(res0->start, resource_size(res0));
- return status;
-}
-
-static int __devexit spear_pcie_gadget_remove(struct platform_device *pdev)
-{
- struct resource *res0, *res1;
- static struct pcie_gadget_target *target;
- struct spear_pcie_gadget_config *config;
- int irq;
-
- res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- irq = platform_get_irq(pdev, 0);
- target = dev_get_drvdata(&pdev->dev);
- config = &target->config;
-
- free_irq(irq, NULL);
- iounmap(config->va_dbi_base);
- iounmap(config->va_app_base);
- release_mem_region(res1->start, resource_size(res1));
- release_mem_region(res0->start, resource_size(res0));
- configfs_unregister_subsystem(&target->subsys);
- kfree(target);
-
- return 0;
-}
-
-static void spear_pcie_gadget_shutdown(struct platform_device *pdev)
-{
-}
-
-static struct platform_driver spear_pcie_gadget_driver = {
- .probe = spear_pcie_gadget_probe,
- .remove = spear_pcie_gadget_remove,
- .shutdown = spear_pcie_gadget_shutdown,
- .driver = {
- .name = "pcie-gadget-spear",
- .bus = &platform_bus_type
- },
-};
-
-module_platform_driver(spear_pcie_gadget_driver);
-
-MODULE_ALIAS("platform:pcie-gadget-spear");
-MODULE_AUTHOR("Pratyush Anand");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/ti-st/Kconfig b/ANDROID_3.4.5/drivers/misc/ti-st/Kconfig
deleted file mode 100644
index abb5de1a..00000000
--- a/ANDROID_3.4.5/drivers/misc/ti-st/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# TI's shared transport line discipline and the protocol
-# drivers (BT, FM and GPS)
-#
-menu "Texas Instruments shared transport line discipline"
-config TI_ST
- tristate "Shared transport core driver"
- depends on NET && GPIOLIB
- select FW_LOADER
- help
- This enables the shared transport core driver for TI
- BT / FM and GPS combo chips. This enables protocol drivers
- to register themselves with core and send data, the responses
- are returned to relevant protocol drivers based on their
- packet types.
-
-endmenu
diff --git a/ANDROID_3.4.5/drivers/misc/ti-st/Makefile b/ANDROID_3.4.5/drivers/misc/ti-st/Makefile
deleted file mode 100644
index 78d7ebb1..00000000
--- a/ANDROID_3.4.5/drivers/misc/ti-st/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# Makefile for TI's shared transport line discipline
-# and its protocol drivers (BT, FM, GPS)
-#
-obj-$(CONFIG_TI_ST) += st_drv.o
-st_drv-objs := st_core.o st_kim.o st_ll.o
diff --git a/ANDROID_3.4.5/drivers/misc/ti-st/st_core.c b/ANDROID_3.4.5/drivers/misc/ti-st/st_core.c
deleted file mode 100644
index 2b62232c..00000000
--- a/ANDROID_3.4.5/drivers/misc/ti-st/st_core.c
+++ /dev/null
@@ -1,890 +0,0 @@
-/*
- * Shared Transport Line discipline driver Core
- * This hooks up ST KIM driver and ST LL driver
- * Copyright (C) 2009-2010 Texas Instruments
- * Author: Pavan Savoy <pavan_savoy@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) "(stc): " fmt
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-
-#include <linux/seq_file.h>
-#include <linux/skbuff.h>
-
-#include <linux/ti_wilink_st.h>
-
-/* function pointer pointing to either,
- * st_kim_recv during registration to receive fw download responses
- * st_int_recv after registration to receive proto stack responses
- */
-void (*st_recv) (void*, const unsigned char*, long);
-
-/********************************************************************/
-static void add_channel_to_table(struct st_data_s *st_gdata,
- struct st_proto_s *new_proto)
-{
- pr_info("%s: id %d\n", __func__, new_proto->chnl_id);
- /* list now has the channel id as index itself */
- st_gdata->list[new_proto->chnl_id] = new_proto;
- st_gdata->is_registered[new_proto->chnl_id] = true;
-}
-
-static void remove_channel_from_table(struct st_data_s *st_gdata,
- struct st_proto_s *proto)
-{
- pr_info("%s: id %d\n", __func__, proto->chnl_id);
-/* st_gdata->list[proto->chnl_id] = NULL; */
- st_gdata->is_registered[proto->chnl_id] = false;
-}
-
-/*
- * called from KIM during firmware download.
- *
- * This is a wrapper function to tty->ops->write_room.
- * It returns number of free space available in
- * uart tx buffer.
- */
-int st_get_uart_wr_room(struct st_data_s *st_gdata)
-{
- struct tty_struct *tty;
- if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) {
- pr_err("tty unavailable to perform write");
- return -1;
- }
- tty = st_gdata->tty;
- return tty->ops->write_room(tty);
-}
-
-/* can be called in from
- * -- KIM (during fw download)
- * -- ST Core (during st_write)
- *
- * This is the internal write function - a wrapper
- * to tty->ops->write
- */
-int st_int_write(struct st_data_s *st_gdata,
- const unsigned char *data, int count)
-{
- struct tty_struct *tty;
- if (unlikely(st_gdata == NULL || st_gdata->tty == NULL)) {
- pr_err("tty unavailable to perform write");
- return -EINVAL;
- }
- tty = st_gdata->tty;
-#ifdef VERBOSE
- print_hex_dump(KERN_DEBUG, "<out<", DUMP_PREFIX_NONE,
- 16, 1, data, count, 0);
-#endif
- return tty->ops->write(tty, data, count);
-
-}
-
-/*
- * push the skb received to relevant
- * protocol stacks
- */
-void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata)
-{
- pr_debug(" %s(prot:%d) ", __func__, chnl_id);
-
- if (unlikely
- (st_gdata == NULL || st_gdata->rx_skb == NULL
- || st_gdata->is_registered[chnl_id] == false)) {
- pr_err("chnl_id %d not registered, no data to send?",
- chnl_id);
- kfree_skb(st_gdata->rx_skb);
- return;
- }
- /* this cannot fail
- * this shouldn't take long
- * - should be just skb_queue_tail for the
- * protocol stack driver
- */
- if (likely(st_gdata->list[chnl_id]->recv != NULL)) {
- if (unlikely
- (st_gdata->list[chnl_id]->recv
- (st_gdata->list[chnl_id]->priv_data, st_gdata->rx_skb)
- != 0)) {
- pr_err(" proto stack %d's ->recv failed", chnl_id);
- kfree_skb(st_gdata->rx_skb);
- return;
- }
- } else {
- pr_err(" proto stack %d's ->recv null", chnl_id);
- kfree_skb(st_gdata->rx_skb);
- }
- return;
-}
-
-/**
- * st_reg_complete -
- * to call registration complete callbacks
- * of all protocol stack drivers
- * This function is being called with spin lock held, protocol drivers are
- * only expected to complete their waits and do nothing more than that.
- */
-void st_reg_complete(struct st_data_s *st_gdata, char err)
-{
- unsigned char i = 0;
- pr_info(" %s ", __func__);
- for (i = 0; i < ST_MAX_CHANNELS; i++) {
- if (likely(st_gdata != NULL &&
- st_gdata->is_registered[i] == true &&
- st_gdata->list[i]->reg_complete_cb != NULL)) {
- st_gdata->list[i]->reg_complete_cb
- (st_gdata->list[i]->priv_data, err);
- pr_info("protocol %d's cb sent %d\n", i, err);
- if (err) { /* cleanup registered protocol */
- st_gdata->protos_registered--;
- st_gdata->is_registered[i] = false;
- }
- }
- }
-}
-
-static inline int st_check_data_len(struct st_data_s *st_gdata,
- unsigned char chnl_id, int len)
-{
- int room = skb_tailroom(st_gdata->rx_skb);
-
- pr_debug("len %d room %d", len, room);
-
- if (!len) {
- /* Received packet has only packet header and
- * has zero length payload. So, ask ST CORE to
- * forward the packet to protocol driver (BT/FM/GPS)
- */
- st_send_frame(chnl_id, st_gdata);
-
- } else if (len > room) {
- /* Received packet's payload length is larger.
- * We can't accommodate it in created skb.
- */
- pr_err("Data length is too large len %d room %d", len,
- room);
- kfree_skb(st_gdata->rx_skb);
- } else {
- /* Packet header has non-zero payload length and
- * we have enough space in created skb. Lets read
- * payload data */
- st_gdata->rx_state = ST_W4_DATA;
- st_gdata->rx_count = len;
- return len;
- }
-
- /* Change ST state to continue to process next
- * packet */
- st_gdata->rx_state = ST_W4_PACKET_TYPE;
- st_gdata->rx_skb = NULL;
- st_gdata->rx_count = 0;
- st_gdata->rx_chnl = 0;
-
- return 0;
-}
-
-/**
- * st_wakeup_ack - internal function for action when wake-up ack
- * received
- */
-static inline void st_wakeup_ack(struct st_data_s *st_gdata,
- unsigned char cmd)
-{
- struct sk_buff *waiting_skb;
- unsigned long flags = 0;
-
- spin_lock_irqsave(&st_gdata->lock, flags);
- /* de-Q from waitQ and Q in txQ now that the
- * chip is awake
- */
- while ((waiting_skb = skb_dequeue(&st_gdata->tx_waitq)))
- skb_queue_tail(&st_gdata->txq, waiting_skb);
-
- /* state forwarded to ST LL */
- st_ll_sleep_state(st_gdata, (unsigned long)cmd);
- spin_unlock_irqrestore(&st_gdata->lock, flags);
-
- /* wake up to send the recently copied skbs from waitQ */
- st_tx_wakeup(st_gdata);
-}
-
-/**
- * st_int_recv - ST's internal receive function.
- * Decodes received RAW data and forwards to corresponding
- * client drivers (Bluetooth,FM,GPS..etc).
- * This can receive various types of packets,
- * HCI-Events, ACL, SCO, 4 types of HCI-LL PM packets
- * CH-8 packets from FM, CH-9 packets from GPS cores.
- */
-void st_int_recv(void *disc_data,
- const unsigned char *data, long count)
-{
- char *ptr;
- struct st_proto_s *proto;
- unsigned short payload_len = 0;
- int len = 0, type = 0;
- unsigned char *plen;
- struct st_data_s *st_gdata = (struct st_data_s *)disc_data;
- unsigned long flags;
-
- ptr = (char *)data;
- /* tty_receive sent null ? */
- if (unlikely(ptr == NULL) || (st_gdata == NULL)) {
- pr_err(" received null from TTY ");
- return;
- }
-
- pr_debug("count %ld rx_state %ld"
- "rx_count %ld", count, st_gdata->rx_state,
- st_gdata->rx_count);
-
- spin_lock_irqsave(&st_gdata->lock, flags);
- /* Decode received bytes here */
- while (count) {
- if (st_gdata->rx_count) {
- len = min_t(unsigned int, st_gdata->rx_count, count);
- memcpy(skb_put(st_gdata->rx_skb, len), ptr, len);
- st_gdata->rx_count -= len;
- count -= len;
- ptr += len;
-
- if (st_gdata->rx_count)
- continue;
-
- /* Check ST RX state machine , where are we? */
- switch (st_gdata->rx_state) {
- /* Waiting for complete packet ? */
- case ST_W4_DATA:
- pr_debug("Complete pkt received");
- /* Ask ST CORE to forward
- * the packet to protocol driver */
- st_send_frame(st_gdata->rx_chnl, st_gdata);
-
- st_gdata->rx_state = ST_W4_PACKET_TYPE;
- st_gdata->rx_skb = NULL;
- continue;
- /* parse the header to know details */
- case ST_W4_HEADER:
- proto = st_gdata->list[st_gdata->rx_chnl];
- plen =
- &st_gdata->rx_skb->data
- [proto->offset_len_in_hdr];
- pr_debug("plen pointing to %x\n", *plen);
- if (proto->len_size == 1)/* 1 byte len field */
- payload_len = *(unsigned char *)plen;
- else if (proto->len_size == 2)
- payload_len =
- __le16_to_cpu(*(unsigned short *)plen);
- else
- pr_info("%s: invalid length "
- "for id %d\n",
- __func__, proto->chnl_id);
- st_check_data_len(st_gdata, proto->chnl_id,
- payload_len);
- pr_debug("off %d, pay len %d\n",
- proto->offset_len_in_hdr, payload_len);
- continue;
- } /* end of switch rx_state */
- }
-
- /* end of if rx_count */
- /* Check first byte of packet and identify module
- * owner (BT/FM/GPS) */
- switch (*ptr) {
- case LL_SLEEP_IND:
- case LL_SLEEP_ACK:
- case LL_WAKE_UP_IND:
- pr_debug("PM packet");
- /* this takes appropriate action based on
- * sleep state received --
- */
- st_ll_sleep_state(st_gdata, *ptr);
- /* if WAKEUP_IND collides copy from waitq to txq
- * and assume chip awake
- */
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- if (st_ll_getstate(st_gdata) == ST_LL_AWAKE)
- st_wakeup_ack(st_gdata, LL_WAKE_UP_ACK);
- spin_lock_irqsave(&st_gdata->lock, flags);
-
- ptr++;
- count--;
- continue;
- case LL_WAKE_UP_ACK:
- pr_debug("PM packet");
-
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- /* wake up ack received */
- st_wakeup_ack(st_gdata, *ptr);
- spin_lock_irqsave(&st_gdata->lock, flags);
-
- ptr++;
- count--;
- continue;
- /* Unknow packet? */
- default:
- type = *ptr;
- if (st_gdata->list[type] == NULL) {
- pr_err("chip/interface misbehavior dropping"
- " frame starting with 0x%02x", type);
- goto done;
-
- }
- st_gdata->rx_skb = alloc_skb(
- st_gdata->list[type]->max_frame_size,
- GFP_ATOMIC);
- skb_reserve(st_gdata->rx_skb,
- st_gdata->list[type]->reserve);
- /* next 2 required for BT only */
- st_gdata->rx_skb->cb[0] = type; /*pkt_type*/
- st_gdata->rx_skb->cb[1] = 0; /*incoming*/
- st_gdata->rx_chnl = *ptr;
- st_gdata->rx_state = ST_W4_HEADER;
- st_gdata->rx_count = st_gdata->list[type]->hdr_len;
- pr_debug("rx_count %ld\n", st_gdata->rx_count);
- };
- ptr++;
- count--;
- }
-done:
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- pr_debug("done %s", __func__);
- return;
-}
-
-/**
- * st_int_dequeue - internal de-Q function.
- * If the previous data set was not written
- * completely, return that skb which has the pending data.
- * In normal cases, return top of txq.
- */
-struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata)
-{
- struct sk_buff *returning_skb;
-
- pr_debug("%s", __func__);
- if (st_gdata->tx_skb != NULL) {
- returning_skb = st_gdata->tx_skb;
- st_gdata->tx_skb = NULL;
- return returning_skb;
- }
- return skb_dequeue(&st_gdata->txq);
-}
-
-/**
- * st_int_enqueue - internal Q-ing function.
- * Will either Q the skb to txq or the tx_waitq
- * depending on the ST LL state.
- * If the chip is asleep, then Q it onto waitq and
- * wakeup the chip.
- * txq and waitq needs protection since the other contexts
- * may be sending data, waking up chip.
- */
-void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
-{
- unsigned long flags = 0;
-
- pr_debug("%s", __func__);
- spin_lock_irqsave(&st_gdata->lock, flags);
-
- switch (st_ll_getstate(st_gdata)) {
- case ST_LL_AWAKE:
- pr_debug("ST LL is AWAKE, sending normally");
- skb_queue_tail(&st_gdata->txq, skb);
- break;
- case ST_LL_ASLEEP_TO_AWAKE:
- skb_queue_tail(&st_gdata->tx_waitq, skb);
- break;
- case ST_LL_AWAKE_TO_ASLEEP:
- pr_err("ST LL is illegal state(%ld),"
- "purging received skb.", st_ll_getstate(st_gdata));
- kfree_skb(skb);
- break;
- case ST_LL_ASLEEP:
- skb_queue_tail(&st_gdata->tx_waitq, skb);
- st_ll_wakeup(st_gdata);
- break;
- default:
- pr_err("ST LL is illegal state(%ld),"
- "purging received skb.", st_ll_getstate(st_gdata));
- kfree_skb(skb);
- break;
- }
-
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- pr_debug("done %s", __func__);
- return;
-}
-
-/*
- * internal wakeup function
- * called from either
- * - TTY layer when write's finished
- * - st_write (in context of the protocol stack)
- */
-void st_tx_wakeup(struct st_data_s *st_data)
-{
- struct sk_buff *skb;
- unsigned long flags; /* for irq save flags */
- pr_debug("%s", __func__);
- /* check for sending & set flag sending here */
- if (test_and_set_bit(ST_TX_SENDING, &st_data->tx_state)) {
- pr_debug("ST already sending");
- /* keep sending */
- set_bit(ST_TX_WAKEUP, &st_data->tx_state);
- return;
- /* TX_WAKEUP will be checked in another
- * context
- */
- }
- do { /* come back if st_tx_wakeup is set */
- /* woke-up to write */
- clear_bit(ST_TX_WAKEUP, &st_data->tx_state);
- while ((skb = st_int_dequeue(st_data))) {
- int len;
- spin_lock_irqsave(&st_data->lock, flags);
- /* enable wake-up from TTY */
- set_bit(TTY_DO_WRITE_WAKEUP, &st_data->tty->flags);
- len = st_int_write(st_data, skb->data, skb->len);
- skb_pull(skb, len);
- /* if skb->len = len as expected, skb->len=0 */
- if (skb->len) {
- /* would be the next skb to be sent */
- st_data->tx_skb = skb;
- spin_unlock_irqrestore(&st_data->lock, flags);
- break;
- }
- kfree_skb(skb);
- spin_unlock_irqrestore(&st_data->lock, flags);
- }
- /* if wake-up is set in another context- restart sending */
- } while (test_bit(ST_TX_WAKEUP, &st_data->tx_state));
-
- /* clear flag sending */
- clear_bit(ST_TX_SENDING, &st_data->tx_state);
-}
-
-/********************************************************************/
-/* functions called from ST KIM
-*/
-void kim_st_list_protocols(struct st_data_s *st_gdata, void *buf)
-{
- seq_printf(buf, "[%d]\nBT=%c\nFM=%c\nGPS=%c\n",
- st_gdata->protos_registered,
- st_gdata->is_registered[0x04] == true ? 'R' : 'U',
- st_gdata->is_registered[0x08] == true ? 'R' : 'U',
- st_gdata->is_registered[0x09] == true ? 'R' : 'U');
-}
-
-/********************************************************************/
-/*
- * functions called from protocol stack drivers
- * to be EXPORT-ed
- */
-long st_register(struct st_proto_s *new_proto)
-{
- struct st_data_s *st_gdata;
- long err = 0;
- unsigned long flags = 0;
-
- st_kim_ref(&st_gdata, 0);
- pr_info("%s(%d) ", __func__, new_proto->chnl_id);
- if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL
- || new_proto->reg_complete_cb == NULL) {
- pr_err("gdata/new_proto/recv or reg_complete_cb not ready");
- return -EINVAL;
- }
-
- if (new_proto->chnl_id >= ST_MAX_CHANNELS) {
- pr_err("chnl_id %d not supported", new_proto->chnl_id);
- return -EPROTONOSUPPORT;
- }
-
- if (st_gdata->is_registered[new_proto->chnl_id] == true) {
- pr_err("chnl_id %d already registered", new_proto->chnl_id);
- return -EALREADY;
- }
-
- /* can be from process context only */
- spin_lock_irqsave(&st_gdata->lock, flags);
-
- if (test_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state)) {
- pr_info(" ST_REG_IN_PROGRESS:%d ", new_proto->chnl_id);
- /* fw download in progress */
-
- add_channel_to_table(st_gdata, new_proto);
- st_gdata->protos_registered++;
- new_proto->write = st_write;
-
- set_bit(ST_REG_PENDING, &st_gdata->st_state);
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- return -EINPROGRESS;
- } else if (st_gdata->protos_registered == ST_EMPTY) {
- pr_info(" chnl_id list empty :%d ", new_proto->chnl_id);
- set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
- st_recv = st_kim_recv;
-
- /* enable the ST LL - to set default chip state */
- st_ll_enable(st_gdata);
-
- /* release lock previously held - re-locked below */
- spin_unlock_irqrestore(&st_gdata->lock, flags);
-
- /* this may take a while to complete
- * since it involves BT fw download
- */
- err = st_kim_start(st_gdata->kim_data);
- if (err != 0) {
- clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
- if ((st_gdata->protos_registered != ST_EMPTY) &&
- (test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
- pr_err(" KIM failure complete callback ");
- st_reg_complete(st_gdata, err);
- clear_bit(ST_REG_PENDING, &st_gdata->st_state);
- }
- return -EINVAL;
- }
-
- spin_lock_irqsave(&st_gdata->lock, flags);
-
- clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state);
- st_recv = st_int_recv;
-
- /* this is where all pending registration
- * are signalled to be complete by calling callback functions
- */
- if ((st_gdata->protos_registered != ST_EMPTY) &&
- (test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
- pr_debug(" call reg complete callback ");
- st_reg_complete(st_gdata, 0);
- }
- clear_bit(ST_REG_PENDING, &st_gdata->st_state);
-
- /* check for already registered once more,
- * since the above check is old
- */
- if (st_gdata->is_registered[new_proto->chnl_id] == true) {
- pr_err(" proto %d already registered ",
- new_proto->chnl_id);
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- return -EALREADY;
- }
-
- add_channel_to_table(st_gdata, new_proto);
- st_gdata->protos_registered++;
- new_proto->write = st_write;
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- return err;
- }
- /* if fw is already downloaded & new stack registers protocol */
- else {
- add_channel_to_table(st_gdata, new_proto);
- st_gdata->protos_registered++;
- new_proto->write = st_write;
-
- /* lock already held before entering else */
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- return err;
- }
- pr_debug("done %s(%d) ", __func__, new_proto->chnl_id);
-}
-EXPORT_SYMBOL_GPL(st_register);
-
-/* to unregister a protocol -
- * to be called from protocol stack driver
- */
-long st_unregister(struct st_proto_s *proto)
-{
- long err = 0;
- unsigned long flags = 0;
- struct st_data_s *st_gdata;
-
- pr_debug("%s: %d ", __func__, proto->chnl_id);
-
- st_kim_ref(&st_gdata, 0);
- if (!st_gdata || proto->chnl_id >= ST_MAX_CHANNELS) {
- pr_err(" chnl_id %d not supported", proto->chnl_id);
- return -EPROTONOSUPPORT;
- }
-
- spin_lock_irqsave(&st_gdata->lock, flags);
-
- if (st_gdata->is_registered[proto->chnl_id] == false) {
- pr_err(" chnl_id %d not registered", proto->chnl_id);
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- return -EPROTONOSUPPORT;
- }
-
- st_gdata->protos_registered--;
- remove_channel_from_table(st_gdata, proto);
- spin_unlock_irqrestore(&st_gdata->lock, flags);
-
- /* paranoid check */
- if (st_gdata->protos_registered < ST_EMPTY)
- st_gdata->protos_registered = ST_EMPTY;
-
- if ((st_gdata->protos_registered == ST_EMPTY) &&
- (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) {
- pr_info(" all chnl_ids unregistered ");
-
- /* stop traffic on tty */
- if (st_gdata->tty) {
- tty_ldisc_flush(st_gdata->tty);
- stop_tty(st_gdata->tty);
- }
-
- /* all chnl_ids now unregistered */
- st_kim_stop(st_gdata->kim_data);
- /* disable ST LL */
- st_ll_disable(st_gdata);
- }
- return err;
-}
-
-/*
- * called in protocol stack drivers
- * via the write function pointer
- */
-long st_write(struct sk_buff *skb)
-{
- struct st_data_s *st_gdata;
- long len;
-
- st_kim_ref(&st_gdata, 0);
- if (unlikely(skb == NULL || st_gdata == NULL
- || st_gdata->tty == NULL)) {
- pr_err("data/tty unavailable to perform write");
- return -EINVAL;
- }
-
- pr_debug("%d to be written", skb->len);
- len = skb->len;
-
- /* st_ll to decide where to enqueue the skb */
- st_int_enqueue(st_gdata, skb);
- /* wake up */
- st_tx_wakeup(st_gdata);
-
- /* return number of bytes written */
- return len;
-}
-
-/* for protocols making use of shared transport */
-EXPORT_SYMBOL_GPL(st_unregister);
-
-/********************************************************************/
-/*
- * functions called from TTY layer
- */
-static int st_tty_open(struct tty_struct *tty)
-{
- int err = 0;
- struct st_data_s *st_gdata;
- pr_info("%s ", __func__);
-
- st_kim_ref(&st_gdata, 0);
- st_gdata->tty = tty;
- tty->disc_data = st_gdata;
-
- /* don't do an wakeup for now */
- clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-
- /* mem already allocated
- */
- tty->receive_room = 65536;
- /* Flush any pending characters in the driver and discipline. */
- tty_ldisc_flush(tty);
- tty_driver_flush_buffer(tty);
- /*
- * signal to UIM via KIM that -
- * installation of N_TI_WL ldisc is complete
- */
- st_kim_complete(st_gdata->kim_data);
- pr_debug("done %s", __func__);
- return err;
-}
-
-static void st_tty_close(struct tty_struct *tty)
-{
- unsigned char i = ST_MAX_CHANNELS;
- unsigned long flags = 0;
- struct st_data_s *st_gdata = tty->disc_data;
-
- pr_info("%s ", __func__);
-
- /* TODO:
- * if a protocol has been registered & line discipline
- * un-installed for some reason - what should be done ?
- */
- spin_lock_irqsave(&st_gdata->lock, flags);
- for (i = ST_BT; i < ST_MAX_CHANNELS; i++) {
- if (st_gdata->is_registered[i] == true)
- pr_err("%d not un-registered", i);
- st_gdata->list[i] = NULL;
- st_gdata->is_registered[i] = false;
- }
- st_gdata->protos_registered = 0;
- spin_unlock_irqrestore(&st_gdata->lock, flags);
- /*
- * signal to UIM via KIM that -
- * N_TI_WL ldisc is un-installed
- */
- st_kim_complete(st_gdata->kim_data);
- st_gdata->tty = NULL;
- /* Flush any pending characters in the driver and discipline. */
- tty_ldisc_flush(tty);
- tty_driver_flush_buffer(tty);
-
- spin_lock_irqsave(&st_gdata->lock, flags);
- /* empty out txq and tx_waitq */
- skb_queue_purge(&st_gdata->txq);
- skb_queue_purge(&st_gdata->tx_waitq);
- /* reset the TTY Rx states of ST */
- st_gdata->rx_count = 0;
- st_gdata->rx_state = ST_W4_PACKET_TYPE;
- kfree_skb(st_gdata->rx_skb);
- st_gdata->rx_skb = NULL;
- spin_unlock_irqrestore(&st_gdata->lock, flags);
-
- pr_debug("%s: done ", __func__);
-}
-
-static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
- char *tty_flags, int count)
-{
-#ifdef VERBOSE
- print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE,
- 16, 1, data, count, 0);
-#endif
-
- /*
- * if fw download is in progress then route incoming data
- * to KIM for validation
- */
- st_recv(tty->disc_data, data, count);
- pr_debug("done %s", __func__);
-}
-
-/* wake-up function called in from the TTY layer
- * inside the internal wakeup function will be called
- */
-static void st_tty_wakeup(struct tty_struct *tty)
-{
- struct st_data_s *st_gdata = tty->disc_data;
- pr_debug("%s ", __func__);
- /* don't do an wakeup for now */
- clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-
- /* call our internal wakeup */
- st_tx_wakeup((void *)st_gdata);
-}
-
-static void st_tty_flush_buffer(struct tty_struct *tty)
-{
- struct st_data_s *st_gdata = tty->disc_data;
- pr_debug("%s ", __func__);
-
- kfree_skb(st_gdata->tx_skb);
- st_gdata->tx_skb = NULL;
-
- tty->ops->flush_buffer(tty);
- return;
-}
-
-static struct tty_ldisc_ops st_ldisc_ops = {
- .magic = TTY_LDISC_MAGIC,
- .name = "n_st",
- .open = st_tty_open,
- .close = st_tty_close,
- .receive_buf = st_tty_receive,
- .write_wakeup = st_tty_wakeup,
- .flush_buffer = st_tty_flush_buffer,
- .owner = THIS_MODULE
-};
-
-/********************************************************************/
-int st_core_init(struct st_data_s **core_data)
-{
- struct st_data_s *st_gdata;
- long err;
-
- err = tty_register_ldisc(N_TI_WL, &st_ldisc_ops);
- if (err) {
- pr_err("error registering %d line discipline %ld",
- N_TI_WL, err);
- return err;
- }
- pr_debug("registered n_shared line discipline");
-
- st_gdata = kzalloc(sizeof(struct st_data_s), GFP_KERNEL);
- if (!st_gdata) {
- pr_err("memory allocation failed");
- err = tty_unregister_ldisc(N_TI_WL);
- if (err)
- pr_err("unable to un-register ldisc %ld", err);
- err = -ENOMEM;
- return err;
- }
-
- /* Initialize ST TxQ and Tx waitQ queue head. All BT/FM/GPS module skb's
- * will be pushed in this queue for actual transmission.
- */
- skb_queue_head_init(&st_gdata->txq);
- skb_queue_head_init(&st_gdata->tx_waitq);
-
- /* Locking used in st_int_enqueue() to avoid multiple execution */
- spin_lock_init(&st_gdata->lock);
-
- err = st_ll_init(st_gdata);
- if (err) {
- pr_err("error during st_ll initialization(%ld)", err);
- kfree(st_gdata);
- err = tty_unregister_ldisc(N_TI_WL);
- if (err)
- pr_err("unable to un-register ldisc");
- return err;
- }
- *core_data = st_gdata;
- return 0;
-}
-
-void st_core_exit(struct st_data_s *st_gdata)
-{
- long err;
- /* internal module cleanup */
- err = st_ll_deinit(st_gdata);
- if (err)
- pr_err("error during deinit of ST LL %ld", err);
-
- if (st_gdata != NULL) {
- /* Free ST Tx Qs and skbs */
- skb_queue_purge(&st_gdata->txq);
- skb_queue_purge(&st_gdata->tx_waitq);
- kfree_skb(st_gdata->rx_skb);
- kfree_skb(st_gdata->tx_skb);
- /* TTY ldisc cleanup */
- err = tty_unregister_ldisc(N_TI_WL);
- if (err)
- pr_err("unable to un-register ldisc %ld", err);
- /* free the global data pointer */
- kfree(st_gdata);
- }
-}
-
-
diff --git a/ANDROID_3.4.5/drivers/misc/ti-st/st_kim.c b/ANDROID_3.4.5/drivers/misc/ti-st/st_kim.c
deleted file mode 100644
index 7c14f8fd..00000000
--- a/ANDROID_3.4.5/drivers/misc/ti-st/st_kim.c
+++ /dev/null
@@ -1,844 +0,0 @@
-/*
- * Shared Transport Line discipline driver Core
- * Init Manager module responsible for GPIO control
- * and firmware download
- * Copyright (C) 2009-2010 Texas Instruments
- * Author: Pavan Savoy <pavan_savoy@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) "(stk) :" fmt
-#include <linux/platform_device.h>
-#include <linux/jiffies.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/gpio.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/sched.h>
-#include <linux/sysfs.h>
-#include <linux/tty.h>
-
-#include <linux/skbuff.h>
-#include <linux/ti_wilink_st.h>
-#include <linux/module.h>
-
-
-#define MAX_ST_DEVICES 3 /* Imagine 1 on each UART for now */
-static struct platform_device *st_kim_devices[MAX_ST_DEVICES];
-
-/**********************************************************************/
-/* internal functions */
-
-/**
- * st_get_plat_device -
- * function which returns the reference to the platform device
- * requested by id. As of now only 1 such device exists (id=0)
- * the context requesting for reference can get the id to be
- * requested by a. The protocol driver which is registering or
- * b. the tty device which is opened.
- */
-static struct platform_device *st_get_plat_device(int id)
-{
- return st_kim_devices[id];
-}
-
-/**
- * validate_firmware_response -
- * function to return whether the firmware response was proper
- * in case of error don't complete so that waiting for proper
- * response times out
- */
-void validate_firmware_response(struct kim_data_s *kim_gdata)
-{
- struct sk_buff *skb = kim_gdata->rx_skb;
- if (unlikely(skb->data[5] != 0)) {
- pr_err("no proper response during fw download");
- pr_err("data6 %x", skb->data[5]);
- kfree_skb(skb);
- return; /* keep waiting for the proper response */
- }
- /* becos of all the script being downloaded */
- complete_all(&kim_gdata->kim_rcvd);
- kfree_skb(skb);
-}
-
-/* check for data len received inside kim_int_recv
- * most often hit the last case to update state to waiting for data
- */
-static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len)
-{
- register int room = skb_tailroom(kim_gdata->rx_skb);
-
- pr_debug("len %d room %d", len, room);
-
- if (!len) {
- validate_firmware_response(kim_gdata);
- } else if (len > room) {
- /* Received packet's payload length is larger.
- * We can't accommodate it in created skb.
- */
- pr_err("Data length is too large len %d room %d", len,
- room);
- kfree_skb(kim_gdata->rx_skb);
- } else {
- /* Packet header has non-zero payload length and
- * we have enough space in created skb. Lets read
- * payload data */
- kim_gdata->rx_state = ST_W4_DATA;
- kim_gdata->rx_count = len;
- return len;
- }
-
- /* Change ST LL state to continue to process next
- * packet */
- kim_gdata->rx_state = ST_W4_PACKET_TYPE;
- kim_gdata->rx_skb = NULL;
- kim_gdata->rx_count = 0;
-
- return 0;
-}
-
-/**
- * kim_int_recv - receive function called during firmware download
- * firmware download responses on different UART drivers
- * have been observed to come in bursts of different
- * tty_receive and hence the logic
- */
-void kim_int_recv(struct kim_data_s *kim_gdata,
- const unsigned char *data, long count)
-{
- const unsigned char *ptr;
- int len = 0, type = 0;
- unsigned char *plen;
-
- pr_debug("%s", __func__);
- /* Decode received bytes here */
- ptr = data;
- if (unlikely(ptr == NULL)) {
- pr_err(" received null from TTY ");
- return;
- }
-
- while (count) {
- if (kim_gdata->rx_count) {
- len = min_t(unsigned int, kim_gdata->rx_count, count);
- memcpy(skb_put(kim_gdata->rx_skb, len), ptr, len);
- kim_gdata->rx_count -= len;
- count -= len;
- ptr += len;
-
- if (kim_gdata->rx_count)
- continue;
-
- /* Check ST RX state machine , where are we? */
- switch (kim_gdata->rx_state) {
- /* Waiting for complete packet ? */
- case ST_W4_DATA:
- pr_debug("Complete pkt received");
- validate_firmware_response(kim_gdata);
- kim_gdata->rx_state = ST_W4_PACKET_TYPE;
- kim_gdata->rx_skb = NULL;
- continue;
- /* Waiting for Bluetooth event header ? */
- case ST_W4_HEADER:
- plen =
- (unsigned char *)&kim_gdata->rx_skb->data[1];
- pr_debug("event hdr: plen 0x%02x\n", *plen);
- kim_check_data_len(kim_gdata, *plen);
- continue;
- } /* end of switch */
- } /* end of if rx_state */
- switch (*ptr) {
- /* Bluetooth event packet? */
- case 0x04:
- kim_gdata->rx_state = ST_W4_HEADER;
- kim_gdata->rx_count = 2;
- type = *ptr;
- break;
- default:
- pr_info("unknown packet");
- ptr++;
- count--;
- continue;
- }
- ptr++;
- count--;
- kim_gdata->rx_skb =
- alloc_skb(1024+8, GFP_ATOMIC);
- if (!kim_gdata->rx_skb) {
- pr_err("can't allocate mem for new packet");
- kim_gdata->rx_state = ST_W4_PACKET_TYPE;
- kim_gdata->rx_count = 0;
- return;
- }
- skb_reserve(kim_gdata->rx_skb, 8);
- kim_gdata->rx_skb->cb[0] = 4;
- kim_gdata->rx_skb->cb[1] = 0;
-
- }
- return;
-}
-
-static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
-{
- unsigned short version = 0, chip = 0, min_ver = 0, maj_ver = 0;
- const char read_ver_cmd[] = { 0x01, 0x01, 0x10, 0x00 };
-
- pr_debug("%s", __func__);
-
- INIT_COMPLETION(kim_gdata->kim_rcvd);
- if (4 != st_int_write(kim_gdata->core_data, read_ver_cmd, 4)) {
- pr_err("kim: couldn't write 4 bytes");
- return -EIO;
- }
-
- if (!wait_for_completion_timeout
- (&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) {
- pr_err(" waiting for ver info- timed out ");
- return -ETIMEDOUT;
- }
- INIT_COMPLETION(kim_gdata->kim_rcvd);
-
- version =
- MAKEWORD(kim_gdata->resp_buffer[13],
- kim_gdata->resp_buffer[14]);
- chip = (version & 0x7C00) >> 10;
- min_ver = (version & 0x007F);
- maj_ver = (version & 0x0380) >> 7;
-
- if (version & 0x8000)
- maj_ver |= 0x0008;
-
- sprintf(bts_scr_name, "TIInit_%d.%d.%d.bts", chip, maj_ver, min_ver);
-
- /* to be accessed later via sysfs entry */
- kim_gdata->version.full = version;
- kim_gdata->version.chip = chip;
- kim_gdata->version.maj_ver = maj_ver;
- kim_gdata->version.min_ver = min_ver;
-
- pr_info("%s", bts_scr_name);
- return 0;
-}
-
-void skip_change_remote_baud(unsigned char **ptr, long *len)
-{
- unsigned char *nxt_action, *cur_action;
- cur_action = *ptr;
-
- nxt_action = cur_action + sizeof(struct bts_action) +
- ((struct bts_action *) cur_action)->size;
-
- if (((struct bts_action *) nxt_action)->type != ACTION_WAIT_EVENT) {
- pr_err("invalid action after change remote baud command");
- } else {
- *ptr = *ptr + sizeof(struct bts_action) +
- ((struct bts_action *)cur_action)->size;
- *len = *len - (sizeof(struct bts_action) +
- ((struct bts_action *)cur_action)->size);
- /* warn user on not commenting these in firmware */
- pr_warn("skipping the wait event of change remote baud");
- }
-}
-
-/**
- * download_firmware -
- * internal function which parses through the .bts firmware
- * script file intreprets SEND, DELAY actions only as of now
- */
-static long download_firmware(struct kim_data_s *kim_gdata)
-{
- long err = 0;
- long len = 0;
- unsigned char *ptr = NULL;
- unsigned char *action_ptr = NULL;
- unsigned char bts_scr_name[30] = { 0 }; /* 30 char long bts scr name? */
- int wr_room_space;
- int cmd_size;
- unsigned long timeout;
-
- err = read_local_version(kim_gdata, bts_scr_name);
- if (err != 0) {
- pr_err("kim: failed to read local ver");
- return err;
- }
- err =
- request_firmware(&kim_gdata->fw_entry, bts_scr_name,
- &kim_gdata->kim_pdev->dev);
- if (unlikely((err != 0) || (kim_gdata->fw_entry->data == NULL) ||
- (kim_gdata->fw_entry->size == 0))) {
- pr_err(" request_firmware failed(errno %ld) for %s", err,
- bts_scr_name);
- return -EINVAL;
- }
- ptr = (void *)kim_gdata->fw_entry->data;
- len = kim_gdata->fw_entry->size;
- /* bts_header to remove out magic number and
- * version
- */
- ptr += sizeof(struct bts_header);
- len -= sizeof(struct bts_header);
-
- while (len > 0 && ptr) {
- pr_debug(" action size %d, type %d ",
- ((struct bts_action *)ptr)->size,
- ((struct bts_action *)ptr)->type);
-
- switch (((struct bts_action *)ptr)->type) {
- case ACTION_SEND_COMMAND: /* action send */
- pr_debug("S");
- action_ptr = &(((struct bts_action *)ptr)->data[0]);
- if (unlikely
- (((struct hci_command *)action_ptr)->opcode ==
- 0xFF36)) {
- /* ignore remote change
- * baud rate HCI VS command */
- pr_warn("change remote baud"
- " rate command in firmware");
- skip_change_remote_baud(&ptr, &len);
- break;
- }
- /*
- * Make sure we have enough free space in uart
- * tx buffer to write current firmware command
- */
- cmd_size = ((struct bts_action *)ptr)->size;
- timeout = jiffies + msecs_to_jiffies(CMD_WR_TIME);
- do {
- wr_room_space =
- st_get_uart_wr_room(kim_gdata->core_data);
- if (wr_room_space < 0) {
- pr_err("Unable to get free "
- "space info from uart tx buffer");
- release_firmware(kim_gdata->fw_entry);
- return wr_room_space;
- }
- mdelay(1); /* wait 1ms before checking room */
- } while ((wr_room_space < cmd_size) &&
- time_before(jiffies, timeout));
-
- /* Timeout happened ? */
- if (time_after_eq(jiffies, timeout)) {
- pr_err("Timeout while waiting for free "
- "free space in uart tx buffer");
- release_firmware(kim_gdata->fw_entry);
- return -ETIMEDOUT;
- }
- /* reinit completion before sending for the
- * relevant wait
- */
- INIT_COMPLETION(kim_gdata->kim_rcvd);
-
- /*
- * Free space found in uart buffer, call st_int_write
- * to send current firmware command to the uart tx
- * buffer.
- */
- err = st_int_write(kim_gdata->core_data,
- ((struct bts_action_send *)action_ptr)->data,
- ((struct bts_action *)ptr)->size);
- if (unlikely(err < 0)) {
- release_firmware(kim_gdata->fw_entry);
- return err;
- }
- /*
- * Check number of bytes written to the uart tx buffer
- * and requested command write size
- */
- if (err != cmd_size) {
- pr_err("Number of bytes written to uart "
- "tx buffer are not matching with "
- "requested cmd write size");
- release_firmware(kim_gdata->fw_entry);
- return -EIO;
- }
- break;
- case ACTION_WAIT_EVENT: /* wait */
- pr_debug("W");
- if (!wait_for_completion_timeout
- (&kim_gdata->kim_rcvd,
- msecs_to_jiffies(CMD_RESP_TIME))) {
- pr_err("response timeout during fw download ");
- /* timed out */
- release_firmware(kim_gdata->fw_entry);
- return -ETIMEDOUT;
- }
- INIT_COMPLETION(kim_gdata->kim_rcvd);
- break;
- case ACTION_DELAY: /* sleep */
- pr_info("sleep command in scr");
- action_ptr = &(((struct bts_action *)ptr)->data[0]);
- mdelay(((struct bts_action_delay *)action_ptr)->msec);
- break;
- }
- len =
- len - (sizeof(struct bts_action) +
- ((struct bts_action *)ptr)->size);
- ptr =
- ptr + sizeof(struct bts_action) +
- ((struct bts_action *)ptr)->size;
- }
- /* fw download complete */
- release_firmware(kim_gdata->fw_entry);
- return 0;
-}
-
-/**********************************************************************/
-/* functions called from ST core */
-/* called from ST Core, when REG_IN_PROGRESS (registration in progress)
- * can be because of
- * 1. response to read local version
- * 2. during send/recv's of firmware download
- */
-void st_kim_recv(void *disc_data, const unsigned char *data, long count)
-{
- struct st_data_s *st_gdata = (struct st_data_s *)disc_data;
- struct kim_data_s *kim_gdata = st_gdata->kim_data;
-
- /* copy to local buffer */
- if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) {
- /* must be the read_ver_cmd */
- memcpy(kim_gdata->resp_buffer, data, count);
- complete_all(&kim_gdata->kim_rcvd);
- return;
- } else {
- kim_int_recv(kim_gdata, data, count);
- /* either completes or times out */
- }
- return;
-}
-
-/* to signal completion of line discipline installation
- * called from ST Core, upon tty_open
- */
-void st_kim_complete(void *kim_data)
-{
- struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
- complete(&kim_gdata->ldisc_installed);
-}
-
-/**
- * st_kim_start - called from ST Core upon 1st registration
- * This involves toggling the chip enable gpio, reading
- * the firmware version from chip, forming the fw file name
- * based on the chip version, requesting the fw, parsing it
- * and perform download(send/recv).
- */
-long st_kim_start(void *kim_data)
-{
- long err = 0;
- long retry = POR_RETRY_COUNT;
- struct ti_st_plat_data *pdata;
- struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
-
- pr_info(" %s", __func__);
- pdata = kim_gdata->kim_pdev->dev.platform_data;
-
- do {
- /* platform specific enabling code here */
- if (pdata->chip_enable)
- pdata->chip_enable(kim_gdata);
-
- /* Configure BT nShutdown to HIGH state */
- gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
- mdelay(5); /* FIXME: a proper toggle */
- gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);
- mdelay(100);
- /* re-initialize the completion */
- INIT_COMPLETION(kim_gdata->ldisc_installed);
- /* send notification to UIM */
- kim_gdata->ldisc_install = 1;
- pr_info("ldisc_install = 1");
- sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
- NULL, "install");
- /* wait for ldisc to be installed */
- err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
- msecs_to_jiffies(LDISC_TIME));
- if (!err) {
- /* ldisc installation timeout,
- * flush uart, power cycle BT_EN */
- pr_err("ldisc installation timeout");
- err = st_kim_stop(kim_gdata);
- continue;
- } else {
- /* ldisc installed now */
- pr_info("line discipline installed");
- err = download_firmware(kim_gdata);
- if (err != 0) {
- /* ldisc installed but fw download failed,
- * flush uart & power cycle BT_EN */
- pr_err("download firmware failed");
- err = st_kim_stop(kim_gdata);
- continue;
- } else { /* on success don't retry */
- break;
- }
- }
- } while (retry--);
- return err;
-}
-
-/**
- * st_kim_stop - stop communication with chip.
- * This can be called from ST Core/KIM, on the-
- * (a) last un-register when chip need not be powered there-after,
- * (b) upon failure to either install ldisc or download firmware.
- * The function is responsible to (a) notify UIM about un-installation,
- * (b) flush UART if the ldisc was installed.
- * (c) reset BT_EN - pull down nshutdown at the end.
- * (d) invoke platform's chip disabling routine.
- */
-long st_kim_stop(void *kim_data)
-{
- long err = 0;
- struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data;
- struct ti_st_plat_data *pdata =
- kim_gdata->kim_pdev->dev.platform_data;
- struct tty_struct *tty = kim_gdata->core_data->tty;
-
- INIT_COMPLETION(kim_gdata->ldisc_installed);
-
- if (tty) { /* can be called before ldisc is installed */
- /* Flush any pending characters in the driver and discipline. */
- tty_ldisc_flush(tty);
- tty_driver_flush_buffer(tty);
- tty->ops->flush_buffer(tty);
- }
-
- /* send uninstall notification to UIM */
- pr_info("ldisc_install = 0");
- kim_gdata->ldisc_install = 0;
- sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, NULL, "install");
-
- /* wait for ldisc to be un-installed */
- err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
- msecs_to_jiffies(LDISC_TIME));
- if (!err) { /* timeout */
- pr_err(" timed out waiting for ldisc to be un-installed");
- return -ETIMEDOUT;
- }
-
- /* By default configure BT nShutdown to LOW state */
- gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
- mdelay(1);
- gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);
- mdelay(1);
- gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
-
- /* platform specific disable */
- if (pdata->chip_disable)
- pdata->chip_disable(kim_gdata);
- return err;
-}
-
-/**********************************************************************/
-/* functions called from subsystems */
-/* called when debugfs entry is read from */
-
-static int show_version(struct seq_file *s, void *unused)
-{
- struct kim_data_s *kim_gdata = (struct kim_data_s *)s->private;
- seq_printf(s, "%04X %d.%d.%d\n", kim_gdata->version.full,
- kim_gdata->version.chip, kim_gdata->version.maj_ver,
- kim_gdata->version.min_ver);
- return 0;
-}
-
-static int show_list(struct seq_file *s, void *unused)
-{
- struct kim_data_s *kim_gdata = (struct kim_data_s *)s->private;
- kim_st_list_protocols(kim_gdata->core_data, s);
- return 0;
-}
-
-static ssize_t show_install(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kim_data_s *kim_data = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", kim_data->ldisc_install);
-}
-
-#ifdef DEBUG
-static ssize_t store_dev_name(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct kim_data_s *kim_data = dev_get_drvdata(dev);
- pr_debug("storing dev name >%s<", buf);
- strncpy(kim_data->dev_name, buf, count);
- pr_debug("stored dev name >%s<", kim_data->dev_name);
- return count;
-}
-
-static ssize_t store_baud_rate(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct kim_data_s *kim_data = dev_get_drvdata(dev);
- pr_debug("storing baud rate >%s<", buf);
- sscanf(buf, "%ld", &kim_data->baud_rate);
- pr_debug("stored baud rate >%ld<", kim_data->baud_rate);
- return count;
-}
-#endif /* if DEBUG */
-
-static ssize_t show_dev_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kim_data_s *kim_data = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", kim_data->dev_name);
-}
-
-static ssize_t show_baud_rate(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kim_data_s *kim_data = dev_get_drvdata(dev);
- return sprintf(buf, "%ld\n", kim_data->baud_rate);
-}
-
-static ssize_t show_flow_cntrl(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct kim_data_s *kim_data = dev_get_drvdata(dev);
- return sprintf(buf, "%d\n", kim_data->flow_cntrl);
-}
-
-/* structures specific for sysfs entries */
-static struct kobj_attribute ldisc_install =
-__ATTR(install, 0444, (void *)show_install, NULL);
-
-static struct kobj_attribute uart_dev_name =
-#ifdef DEBUG /* TODO: move this to debug-fs if possible */
-__ATTR(dev_name, 0644, (void *)show_dev_name, (void *)store_dev_name);
-#else
-__ATTR(dev_name, 0444, (void *)show_dev_name, NULL);
-#endif
-
-static struct kobj_attribute uart_baud_rate =
-#ifdef DEBUG /* TODO: move to debugfs */
-__ATTR(baud_rate, 0644, (void *)show_baud_rate, (void *)store_baud_rate);
-#else
-__ATTR(baud_rate, 0444, (void *)show_baud_rate, NULL);
-#endif
-
-static struct kobj_attribute uart_flow_cntrl =
-__ATTR(flow_cntrl, 0444, (void *)show_flow_cntrl, NULL);
-
-static struct attribute *uim_attrs[] = {
- &ldisc_install.attr,
- &uart_dev_name.attr,
- &uart_baud_rate.attr,
- &uart_flow_cntrl.attr,
- NULL,
-};
-
-static struct attribute_group uim_attr_grp = {
- .attrs = uim_attrs,
-};
-
-/**
- * st_kim_ref - reference the core's data
- * This references the per-ST platform device in the arch/xx/
- * board-xx.c file.
- * This would enable multiple such platform devices to exist
- * on a given platform
- */
-void st_kim_ref(struct st_data_s **core_data, int id)
-{
- struct platform_device *pdev;
- struct kim_data_s *kim_gdata;
- /* get kim_gdata reference from platform device */
- pdev = st_get_plat_device(id);
- if (!pdev) {
- *core_data = NULL;
- return;
- }
- kim_gdata = dev_get_drvdata(&pdev->dev);
- *core_data = kim_gdata->core_data;
-}
-
-static int kim_version_open(struct inode *i, struct file *f)
-{
- return single_open(f, show_version, i->i_private);
-}
-
-static int kim_list_open(struct inode *i, struct file *f)
-{
- return single_open(f, show_list, i->i_private);
-}
-
-static const struct file_operations version_debugfs_fops = {
- /* version info */
- .open = kim_version_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-static const struct file_operations list_debugfs_fops = {
- /* protocols info */
- .open = kim_list_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-/**********************************************************************/
-/* functions called from platform device driver subsystem
- * need to have a relevant platform device entry in the platform's
- * board-*.c file
- */
-
-struct dentry *kim_debugfs_dir;
-static int kim_probe(struct platform_device *pdev)
-{
- long status;
- struct kim_data_s *kim_gdata;
- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
-
- if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) {
- /* multiple devices could exist */
- st_kim_devices[pdev->id] = pdev;
- } else {
- /* platform's sure about existence of 1 device */
- st_kim_devices[0] = pdev;
- }
-
- kim_gdata = kzalloc(sizeof(struct kim_data_s), GFP_ATOMIC);
- if (!kim_gdata) {
- pr_err("no mem to allocate");
- return -ENOMEM;
- }
- dev_set_drvdata(&pdev->dev, kim_gdata);
-
- status = st_core_init(&kim_gdata->core_data);
- if (status != 0) {
- pr_err(" ST core init failed");
- return -EIO;
- }
- /* refer to itself */
- kim_gdata->core_data->kim_data = kim_gdata;
-
- /* Claim the chip enable nShutdown gpio from the system */
- kim_gdata->nshutdown = pdata->nshutdown_gpio;
- status = gpio_request(kim_gdata->nshutdown, "kim");
- if (unlikely(status)) {
- pr_err(" gpio %ld request failed ", kim_gdata->nshutdown);
- return status;
- }
-
- /* Configure nShutdown GPIO as output=0 */
- status = gpio_direction_output(kim_gdata->nshutdown, 0);
- if (unlikely(status)) {
- pr_err(" unable to configure gpio %ld", kim_gdata->nshutdown);
- return status;
- }
- /* get reference of pdev for request_firmware
- */
- kim_gdata->kim_pdev = pdev;
- init_completion(&kim_gdata->kim_rcvd);
- init_completion(&kim_gdata->ldisc_installed);
-
- status = sysfs_create_group(&pdev->dev.kobj, &uim_attr_grp);
- if (status) {
- pr_err("failed to create sysfs entries");
- return status;
- }
-
- /* copying platform data */
- strncpy(kim_gdata->dev_name, pdata->dev_name, UART_DEV_NAME_LEN);
- kim_gdata->flow_cntrl = pdata->flow_cntrl;
- kim_gdata->baud_rate = pdata->baud_rate;
- pr_info("sysfs entries created\n");
-
- kim_debugfs_dir = debugfs_create_dir("ti-st", NULL);
- if (IS_ERR(kim_debugfs_dir)) {
- pr_err(" debugfs entries creation failed ");
- kim_debugfs_dir = NULL;
- return -EIO;
- }
-
- debugfs_create_file("version", S_IRUGO, kim_debugfs_dir,
- kim_gdata, &version_debugfs_fops);
- debugfs_create_file("protocols", S_IRUGO, kim_debugfs_dir,
- kim_gdata, &list_debugfs_fops);
- pr_info(" debugfs entries created ");
- return 0;
-}
-
-static int kim_remove(struct platform_device *pdev)
-{
- /* free the GPIOs requested */
- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
- struct kim_data_s *kim_gdata;
-
- kim_gdata = dev_get_drvdata(&pdev->dev);
-
- /* Free the Bluetooth/FM/GPIO
- * nShutdown gpio from the system
- */
- gpio_free(pdata->nshutdown_gpio);
- pr_info("nshutdown GPIO Freed");
-
- debugfs_remove_recursive(kim_debugfs_dir);
- sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp);
- pr_info("sysfs entries removed");
-
- kim_gdata->kim_pdev = NULL;
- st_core_exit(kim_gdata->core_data);
-
- kfree(kim_gdata);
- kim_gdata = NULL;
- return 0;
-}
-
-int kim_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
-
- if (pdata->suspend)
- return pdata->suspend(pdev, state);
-
- return -EOPNOTSUPP;
-}
-
-int kim_resume(struct platform_device *pdev)
-{
- struct ti_st_plat_data *pdata = pdev->dev.platform_data;
-
- if (pdata->resume)
- return pdata->resume(pdev);
-
- return -EOPNOTSUPP;
-}
-
-/**********************************************************************/
-/* entry point for ST KIM module, called in from ST Core */
-static struct platform_driver kim_platform_driver = {
- .probe = kim_probe,
- .remove = kim_remove,
- .suspend = kim_suspend,
- .resume = kim_resume,
- .driver = {
- .name = "kim",
- .owner = THIS_MODULE,
- },
-};
-
-module_platform_driver(kim_platform_driver);
-
-MODULE_AUTHOR("Pavan Savoy <pavan_savoy@ti.com>");
-MODULE_DESCRIPTION("Shared Transport Driver for TI BT/FM/GPS combo chips ");
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/misc/ti-st/st_ll.c b/ANDROID_3.4.5/drivers/misc/ti-st/st_ll.c
deleted file mode 100644
index 1ff460a8..00000000
--- a/ANDROID_3.4.5/drivers/misc/ti-st/st_ll.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Shared Transport driver
- * HCI-LL module responsible for TI proprietary HCI_LL protocol
- * Copyright (C) 2009-2010 Texas Instruments
- * Author: Pavan Savoy <pavan_savoy@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#define pr_fmt(fmt) "(stll) :" fmt
-#include <linux/skbuff.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/ti_wilink_st.h>
-
-/**********************************************************************/
-/* internal functions */
-static void send_ll_cmd(struct st_data_s *st_data,
- unsigned char cmd)
-{
-
- pr_debug("%s: writing %x", __func__, cmd);
- st_int_write(st_data, &cmd, 1);
- return;
-}
-
-static void ll_device_want_to_sleep(struct st_data_s *st_data)
-{
- struct kim_data_s *kim_data;
- struct ti_st_plat_data *pdata;
-
- pr_debug("%s", __func__);
- /* sanity check */
- if (st_data->ll_state != ST_LL_AWAKE)
- pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND"
- "in state %ld", st_data->ll_state);
-
- send_ll_cmd(st_data, LL_SLEEP_ACK);
- /* update state */
- st_data->ll_state = ST_LL_ASLEEP;
-
- /* communicate to platform about chip asleep */
- kim_data = st_data->kim_data;
- pdata = kim_data->kim_pdev->dev.platform_data;
- if (pdata->chip_asleep)
- pdata->chip_asleep(NULL);
-}
-
-static void ll_device_want_to_wakeup(struct st_data_s *st_data)
-{
- struct kim_data_s *kim_data;
- struct ti_st_plat_data *pdata;
-
- /* diff actions in diff states */
- switch (st_data->ll_state) {
- case ST_LL_ASLEEP:
- send_ll_cmd(st_data, LL_WAKE_UP_ACK); /* send wake_ack */
- break;
- case ST_LL_ASLEEP_TO_AWAKE:
- /* duplicate wake_ind */
- pr_err("duplicate wake_ind while waiting for Wake ack");
- break;
- case ST_LL_AWAKE:
- /* duplicate wake_ind */
- pr_err("duplicate wake_ind already AWAKE");
- break;
- case ST_LL_AWAKE_TO_ASLEEP:
- /* duplicate wake_ind */
- pr_err("duplicate wake_ind");
- break;
- }
- /* update state */
- st_data->ll_state = ST_LL_AWAKE;
-
- /* communicate to platform about chip wakeup */
- kim_data = st_data->kim_data;
- pdata = kim_data->kim_pdev->dev.platform_data;
- if (pdata->chip_asleep)
- pdata->chip_awake(NULL);
-}
-
-/**********************************************************************/
-/* functions invoked by ST Core */
-
-/* called when ST Core wants to
- * enable ST LL */
-void st_ll_enable(struct st_data_s *ll)
-{
- ll->ll_state = ST_LL_AWAKE;
-}
-
-/* called when ST Core /local module wants to
- * disable ST LL */
-void st_ll_disable(struct st_data_s *ll)
-{
- ll->ll_state = ST_LL_INVALID;
-}
-
-/* called when ST Core wants to update the state */
-void st_ll_wakeup(struct st_data_s *ll)
-{
- if (likely(ll->ll_state != ST_LL_AWAKE)) {
- send_ll_cmd(ll, LL_WAKE_UP_IND); /* WAKE_IND */
- ll->ll_state = ST_LL_ASLEEP_TO_AWAKE;
- } else {
- /* don't send the duplicate wake_indication */
- pr_err(" Chip already AWAKE ");
- }
-}
-
-/* called when ST Core wants the state */
-unsigned long st_ll_getstate(struct st_data_s *ll)
-{
- pr_debug(" returning state %ld", ll->ll_state);
- return ll->ll_state;
-}
-
-/* called from ST Core, when a PM related packet arrives */
-unsigned long st_ll_sleep_state(struct st_data_s *st_data,
- unsigned char cmd)
-{
- switch (cmd) {
- case LL_SLEEP_IND: /* sleep ind */
- pr_debug("sleep indication recvd");
- ll_device_want_to_sleep(st_data);
- break;
- case LL_SLEEP_ACK: /* sleep ack */
- pr_err("sleep ack rcvd: host shouldn't");
- break;
- case LL_WAKE_UP_IND: /* wake ind */
- pr_debug("wake indication recvd");
- ll_device_want_to_wakeup(st_data);
- break;
- case LL_WAKE_UP_ACK: /* wake ack */
- pr_debug("wake ack rcvd");
- st_data->ll_state = ST_LL_AWAKE;
- break;
- default:
- pr_err(" unknown input/state ");
- return -EINVAL;
- }
- return 0;
-}
-
-/* Called from ST CORE to initialize ST LL */
-long st_ll_init(struct st_data_s *ll)
-{
- /* set state to invalid */
- ll->ll_state = ST_LL_INVALID;
- return 0;
-}
-
-/* Called from ST CORE to de-initialize ST LL */
-long st_ll_deinit(struct st_data_s *ll)
-{
- return 0;
-}
diff --git a/ANDROID_3.4.5/drivers/misc/ti_dac7512.c b/ANDROID_3.4.5/drivers/misc/ti_dac7512.c
deleted file mode 100644
index 5acbba12..00000000
--- a/ANDROID_3.4.5/drivers/misc/ti_dac7512.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * dac7512.c - Linux kernel module for
- * Texas Instruments DAC7512
- *
- * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/spi/spi.h>
-
-#define DAC7512_DRV_NAME "dac7512"
-#define DRIVER_VERSION "1.0"
-
-static ssize_t dac7512_store_val(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct spi_device *spi = to_spi_device(dev);
- unsigned char tmp[2];
- unsigned long val;
-
- if (strict_strtoul(buf, 10, &val) < 0)
- return -EINVAL;
-
- tmp[0] = val >> 8;
- tmp[1] = val & 0xff;
- spi_write(spi, tmp, sizeof(tmp));
- return count;
-}
-
-static DEVICE_ATTR(value, S_IWUSR, NULL, dac7512_store_val);
-
-static struct attribute *dac7512_attributes[] = {
- &dev_attr_value.attr,
- NULL
-};
-
-static const struct attribute_group dac7512_attr_group = {
- .attrs = dac7512_attributes,
-};
-
-static int __devinit dac7512_probe(struct spi_device *spi)
-{
- int ret;
-
- spi->bits_per_word = 8;
- spi->mode = SPI_MODE_0;
- ret = spi_setup(spi);
- if (ret < 0)
- return ret;
-
- return sysfs_create_group(&spi->dev.kobj, &dac7512_attr_group);
-}
-
-static int __devexit dac7512_remove(struct spi_device *spi)
-{
- sysfs_remove_group(&spi->dev.kobj, &dac7512_attr_group);
- return 0;
-}
-
-static struct spi_driver dac7512_driver = {
- .driver = {
- .name = DAC7512_DRV_NAME,
- .owner = THIS_MODULE,
- },
- .probe = dac7512_probe,
- .remove = __devexit_p(dac7512_remove),
-};
-
-module_spi_driver(dac7512_driver);
-
-MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("DAC7512 16-bit DAC");
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION(DRIVER_VERSION);
diff --git a/ANDROID_3.4.5/drivers/misc/tifm_7xx1.c b/ANDROID_3.4.5/drivers/misc/tifm_7xx1.c
deleted file mode 100644
index ba247902..00000000
--- a/ANDROID_3.4.5/drivers/misc/tifm_7xx1.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * tifm_7xx1.c - TI FlashMedia driver
- *
- * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/tifm.h>
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-
-#define DRIVER_NAME "tifm_7xx1"
-#define DRIVER_VERSION "0.8"
-
-#define TIFM_IRQ_ENABLE 0x80000000
-#define TIFM_IRQ_SOCKMASK(x) (x)
-#define TIFM_IRQ_CARDMASK(x) ((x) << 8)
-#define TIFM_IRQ_FIFOMASK(x) ((x) << 16)
-#define TIFM_IRQ_SETALL 0xffffffff
-
-static void tifm_7xx1_dummy_eject(struct tifm_adapter *fm,
- struct tifm_dev *sock)
-{
-}
-
-static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&fm->lock, flags);
- fm->socket_change_set |= 1 << sock->socket_id;
- tifm_queue_work(&fm->media_switcher);
- spin_unlock_irqrestore(&fm->lock, flags);
-}
-
-static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id)
-{
- struct tifm_adapter *fm = dev_id;
- struct tifm_dev *sock;
- unsigned int irq_status, cnt;
-
- spin_lock(&fm->lock);
- irq_status = readl(fm->addr + FM_INTERRUPT_STATUS);
- if (irq_status == 0 || irq_status == (~0)) {
- spin_unlock(&fm->lock);
- return IRQ_NONE;
- }
-
- if (irq_status & TIFM_IRQ_ENABLE) {
- writel(TIFM_IRQ_ENABLE, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
-
- for (cnt = 0; cnt < fm->num_sockets; cnt++) {
- sock = fm->sockets[cnt];
- if (sock) {
- if ((irq_status >> cnt) & TIFM_IRQ_FIFOMASK(1))
- sock->data_event(sock);
- if ((irq_status >> cnt) & TIFM_IRQ_CARDMASK(1))
- sock->card_event(sock);
- }
- }
-
- fm->socket_change_set |= irq_status
- & ((1 << fm->num_sockets) - 1);
- }
- writel(irq_status, fm->addr + FM_INTERRUPT_STATUS);
-
- if (fm->finish_me)
- complete_all(fm->finish_me);
- else if (!fm->socket_change_set)
- writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE);
- else
- tifm_queue_work(&fm->media_switcher);
-
- spin_unlock(&fm->lock);
- return IRQ_HANDLED;
-}
-
-static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr)
-{
- unsigned int s_state;
- int cnt;
-
- writel(0x0e00, sock_addr + SOCK_CONTROL);
-
- for (cnt = 16; cnt <= 256; cnt <<= 1) {
- if (!(TIFM_SOCK_STATE_POWERED
- & readl(sock_addr + SOCK_PRESENT_STATE)))
- break;
-
- msleep(cnt);
- }
-
- s_state = readl(sock_addr + SOCK_PRESENT_STATE);
- if (!(TIFM_SOCK_STATE_OCCUPIED & s_state))
- return 0;
-
- writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED,
- sock_addr + SOCK_CONTROL);
-
- /* xd needs some extra time before power on */
- if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7)
- == TIFM_TYPE_XD)
- msleep(40);
-
- writel((s_state & TIFM_CTRL_POWER_MASK) | 0x0c00,
- sock_addr + SOCK_CONTROL);
- /* wait for power to stabilize */
- msleep(20);
- for (cnt = 16; cnt <= 256; cnt <<= 1) {
- if ((TIFM_SOCK_STATE_POWERED
- & readl(sock_addr + SOCK_PRESENT_STATE)))
- break;
-
- msleep(cnt);
- }
-
- writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED),
- sock_addr + SOCK_CONTROL);
-
- return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7;
-}
-
-inline static void tifm_7xx1_sock_power_off(char __iomem *sock_addr)
-{
- writel((~TIFM_CTRL_POWER_MASK) & readl(sock_addr + SOCK_CONTROL),
- sock_addr + SOCK_CONTROL);
-}
-
-inline static char __iomem *
-tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num)
-{
- return base_addr + ((sock_num + 1) << 10);
-}
-
-static void tifm_7xx1_switch_media(struct work_struct *work)
-{
- struct tifm_adapter *fm = container_of(work, struct tifm_adapter,
- media_switcher);
- struct tifm_dev *sock;
- char __iomem *sock_addr;
- unsigned long flags;
- unsigned char media_id;
- unsigned int socket_change_set, cnt;
-
- spin_lock_irqsave(&fm->lock, flags);
- socket_change_set = fm->socket_change_set;
- fm->socket_change_set = 0;
-
- dev_dbg(fm->dev.parent, "checking media set %x\n",
- socket_change_set);
-
- if (!socket_change_set) {
- spin_unlock_irqrestore(&fm->lock, flags);
- return;
- }
-
- for (cnt = 0; cnt < fm->num_sockets; cnt++) {
- if (!(socket_change_set & (1 << cnt)))
- continue;
- sock = fm->sockets[cnt];
- if (sock) {
- printk(KERN_INFO
- "%s : demand removing card from socket %u:%u\n",
- dev_name(&fm->dev), fm->id, cnt);
- fm->sockets[cnt] = NULL;
- sock_addr = sock->addr;
- spin_unlock_irqrestore(&fm->lock, flags);
- device_unregister(&sock->dev);
- spin_lock_irqsave(&fm->lock, flags);
- tifm_7xx1_sock_power_off(sock_addr);
- writel(0x0e00, sock_addr + SOCK_CONTROL);
- }
-
- spin_unlock_irqrestore(&fm->lock, flags);
-
- media_id = tifm_7xx1_toggle_sock_power(
- tifm_7xx1_sock_addr(fm->addr, cnt));
-
- // tifm_alloc_device will check if media_id is valid
- sock = tifm_alloc_device(fm, cnt, media_id);
- if (sock) {
- sock->addr = tifm_7xx1_sock_addr(fm->addr, cnt);
-
- if (!device_register(&sock->dev)) {
- spin_lock_irqsave(&fm->lock, flags);
- if (!fm->sockets[cnt]) {
- fm->sockets[cnt] = sock;
- sock = NULL;
- }
- spin_unlock_irqrestore(&fm->lock, flags);
- }
- if (sock)
- tifm_free_device(&sock->dev);
- }
- spin_lock_irqsave(&fm->lock, flags);
- }
-
- writel(TIFM_IRQ_FIFOMASK(socket_change_set)
- | TIFM_IRQ_CARDMASK(socket_change_set),
- fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
-
- writel(TIFM_IRQ_FIFOMASK(socket_change_set)
- | TIFM_IRQ_CARDMASK(socket_change_set),
- fm->addr + FM_SET_INTERRUPT_ENABLE);
-
- writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE);
- spin_unlock_irqrestore(&fm->lock, flags);
-}
-
-#ifdef CONFIG_PM
-
-static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state)
-{
- struct tifm_adapter *fm = pci_get_drvdata(dev);
- int cnt;
-
- dev_dbg(&dev->dev, "suspending host\n");
-
- for (cnt = 0; cnt < fm->num_sockets; cnt++) {
- if (fm->sockets[cnt])
- tifm_7xx1_sock_power_off(fm->sockets[cnt]->addr);
- }
-
- pci_save_state(dev);
- pci_enable_wake(dev, pci_choose_state(dev, state), 0);
- pci_disable_device(dev);
- pci_set_power_state(dev, pci_choose_state(dev, state));
- return 0;
-}
-
-static int tifm_7xx1_resume(struct pci_dev *dev)
-{
- struct tifm_adapter *fm = pci_get_drvdata(dev);
- int rc;
- unsigned int good_sockets = 0, bad_sockets = 0;
- unsigned long flags;
- unsigned char new_ids[fm->num_sockets];
- DECLARE_COMPLETION_ONSTACK(finish_resume);
-
- pci_set_power_state(dev, PCI_D0);
- pci_restore_state(dev);
- rc = pci_enable_device(dev);
- if (rc)
- return rc;
- pci_set_master(dev);
-
- dev_dbg(&dev->dev, "resuming host\n");
-
- for (rc = 0; rc < fm->num_sockets; rc++)
- new_ids[rc] = tifm_7xx1_toggle_sock_power(
- tifm_7xx1_sock_addr(fm->addr, rc));
- spin_lock_irqsave(&fm->lock, flags);
- for (rc = 0; rc < fm->num_sockets; rc++) {
- if (fm->sockets[rc]) {
- if (fm->sockets[rc]->type == new_ids[rc])
- good_sockets |= 1 << rc;
- else
- bad_sockets |= 1 << rc;
- }
- }
-
- writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1),
- fm->addr + FM_SET_INTERRUPT_ENABLE);
- dev_dbg(&dev->dev, "change sets on resume: good %x, bad %x\n",
- good_sockets, bad_sockets);
-
- fm->socket_change_set = 0;
- if (good_sockets) {
- fm->finish_me = &finish_resume;
- spin_unlock_irqrestore(&fm->lock, flags);
- rc = wait_for_completion_timeout(&finish_resume, HZ);
- dev_dbg(&dev->dev, "wait returned %d\n", rc);
- writel(TIFM_IRQ_FIFOMASK(good_sockets)
- | TIFM_IRQ_CARDMASK(good_sockets),
- fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
- writel(TIFM_IRQ_FIFOMASK(good_sockets)
- | TIFM_IRQ_CARDMASK(good_sockets),
- fm->addr + FM_SET_INTERRUPT_ENABLE);
- spin_lock_irqsave(&fm->lock, flags);
- fm->finish_me = NULL;
- fm->socket_change_set ^= good_sockets & fm->socket_change_set;
- }
-
- fm->socket_change_set |= bad_sockets;
- if (fm->socket_change_set)
- tifm_queue_work(&fm->media_switcher);
-
- spin_unlock_irqrestore(&fm->lock, flags);
- writel(TIFM_IRQ_ENABLE,
- fm->addr + FM_SET_INTERRUPT_ENABLE);
-
- return 0;
-}
-
-#else
-
-#define tifm_7xx1_suspend NULL
-#define tifm_7xx1_resume NULL
-
-#endif /* CONFIG_PM */
-
-static int tifm_7xx1_dummy_has_ms_pif(struct tifm_adapter *fm,
- struct tifm_dev *sock)
-{
- return 0;
-}
-
-static int tifm_7xx1_has_ms_pif(struct tifm_adapter *fm, struct tifm_dev *sock)
-{
- if (((fm->num_sockets == 4) && (sock->socket_id == 2))
- || ((fm->num_sockets == 2) && (sock->socket_id == 0)))
- return 1;
-
- return 0;
-}
-
-static int tifm_7xx1_probe(struct pci_dev *dev,
- const struct pci_device_id *dev_id)
-{
- struct tifm_adapter *fm;
- int pci_dev_busy = 0;
- int rc;
-
- rc = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
- if (rc)
- return rc;
-
- rc = pci_enable_device(dev);
- if (rc)
- return rc;
-
- pci_set_master(dev);
-
- rc = pci_request_regions(dev, DRIVER_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
-
- pci_intx(dev, 1);
-
- fm = tifm_alloc_adapter(dev->device == PCI_DEVICE_ID_TI_XX21_XX11_FM
- ? 4 : 2, &dev->dev);
- if (!fm) {
- rc = -ENOMEM;
- goto err_out_int;
- }
-
- INIT_WORK(&fm->media_switcher, tifm_7xx1_switch_media);
- fm->eject = tifm_7xx1_eject;
- fm->has_ms_pif = tifm_7xx1_has_ms_pif;
- pci_set_drvdata(dev, fm);
-
- fm->addr = pci_ioremap_bar(dev, 0);
- if (!fm->addr)
- goto err_out_free;
-
- rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm);
- if (rc)
- goto err_out_unmap;
-
- rc = tifm_add_adapter(fm);
- if (rc)
- goto err_out_irq;
-
- writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1),
- fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
- writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1),
- fm->addr + FM_SET_INTERRUPT_ENABLE);
- return 0;
-
-err_out_irq:
- free_irq(dev->irq, fm);
-err_out_unmap:
- iounmap(fm->addr);
-err_out_free:
- pci_set_drvdata(dev, NULL);
- tifm_free_adapter(fm);
-err_out_int:
- pci_intx(dev, 0);
- pci_release_regions(dev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(dev);
- return rc;
-}
-
-static void tifm_7xx1_remove(struct pci_dev *dev)
-{
- struct tifm_adapter *fm = pci_get_drvdata(dev);
- int cnt;
-
- fm->eject = tifm_7xx1_dummy_eject;
- fm->has_ms_pif = tifm_7xx1_dummy_has_ms_pif;
- writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE);
- mmiowb();
- free_irq(dev->irq, fm);
-
- tifm_remove_adapter(fm);
-
- for (cnt = 0; cnt < fm->num_sockets; cnt++)
- tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt));
-
- pci_set_drvdata(dev, NULL);
-
- iounmap(fm->addr);
- pci_intx(dev, 0);
- pci_release_regions(dev);
-
- pci_disable_device(dev);
- tifm_free_adapter(fm);
-}
-
-static struct pci_device_id tifm_7xx1_pci_tbl [] = {
- { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX21_XX11_FM, PCI_ANY_ID,
- PCI_ANY_ID, 0, 0, 0 }, /* xx21 - the one I have */
- { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX12_FM, PCI_ANY_ID,
- PCI_ANY_ID, 0, 0, 0 },
- { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XX20_FM, PCI_ANY_ID,
- PCI_ANY_ID, 0, 0, 0 },
- { }
-};
-
-static struct pci_driver tifm_7xx1_driver = {
- .name = DRIVER_NAME,
- .id_table = tifm_7xx1_pci_tbl,
- .probe = tifm_7xx1_probe,
- .remove = tifm_7xx1_remove,
- .suspend = tifm_7xx1_suspend,
- .resume = tifm_7xx1_resume,
-};
-
-static int __init tifm_7xx1_init(void)
-{
- return pci_register_driver(&tifm_7xx1_driver);
-}
-
-static void __exit tifm_7xx1_exit(void)
-{
- pci_unregister_driver(&tifm_7xx1_driver);
-}
-
-MODULE_AUTHOR("Alex Dubov");
-MODULE_DESCRIPTION("TI FlashMedia host driver");
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, tifm_7xx1_pci_tbl);
-MODULE_VERSION(DRIVER_VERSION);
-
-module_init(tifm_7xx1_init);
-module_exit(tifm_7xx1_exit);
diff --git a/ANDROID_3.4.5/drivers/misc/tifm_core.c b/ANDROID_3.4.5/drivers/misc/tifm_core.c
deleted file mode 100644
index 0bd5349b..00000000
--- a/ANDROID_3.4.5/drivers/misc/tifm_core.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * tifm_core.c - TI FlashMedia driver
- *
- * Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/tifm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/idr.h>
-#include <linux/module.h>
-
-#define DRIVER_NAME "tifm_core"
-#define DRIVER_VERSION "0.8"
-
-static struct workqueue_struct *workqueue;
-static DEFINE_IDR(tifm_adapter_idr);
-static DEFINE_SPINLOCK(tifm_adapter_lock);
-
-static const char *tifm_media_type_name(unsigned char type, unsigned char nt)
-{
- const char *card_type_name[3][3] = {
- { "SmartMedia/xD", "MemoryStick", "MMC/SD" },
- { "XD", "MS", "SD"},
- { "xd", "ms", "sd"}
- };
-
- if (nt > 2 || type < 1 || type > 3)
- return NULL;
- return card_type_name[nt][type - 1];
-}
-
-static int tifm_dev_match(struct tifm_dev *sock, struct tifm_device_id *id)
-{
- if (sock->type == id->type)
- return 1;
- return 0;
-}
-
-static int tifm_bus_match(struct device *dev, struct device_driver *drv)
-{
- struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
- struct tifm_driver *fm_drv = container_of(drv, struct tifm_driver,
- driver);
- struct tifm_device_id *ids = fm_drv->id_table;
-
- if (ids) {
- while (ids->type) {
- if (tifm_dev_match(sock, ids))
- return 1;
- ++ids;
- }
- }
- return 0;
-}
-
-static int tifm_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
- struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
-
- if (add_uevent_var(env, "TIFM_CARD_TYPE=%s", tifm_media_type_name(sock->type, 1)))
- return -ENOMEM;
-
- return 0;
-}
-
-static int tifm_device_probe(struct device *dev)
-{
- struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
- struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
- driver);
- int rc = -ENODEV;
-
- get_device(dev);
- if (dev->driver && drv->probe) {
- rc = drv->probe(sock);
- if (!rc)
- return 0;
- }
- put_device(dev);
- return rc;
-}
-
-static void tifm_dummy_event(struct tifm_dev *sock)
-{
- return;
-}
-
-static int tifm_device_remove(struct device *dev)
-{
- struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
- struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
- driver);
-
- if (dev->driver && drv->remove) {
- sock->card_event = tifm_dummy_event;
- sock->data_event = tifm_dummy_event;
- drv->remove(sock);
- sock->dev.driver = NULL;
- }
-
- put_device(dev);
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int tifm_device_suspend(struct device *dev, pm_message_t state)
-{
- struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
- struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
- driver);
-
- if (dev->driver && drv->suspend)
- return drv->suspend(sock, state);
- return 0;
-}
-
-static int tifm_device_resume(struct device *dev)
-{
- struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
- struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver,
- driver);
-
- if (dev->driver && drv->resume)
- return drv->resume(sock);
- return 0;
-}
-
-#else
-
-#define tifm_device_suspend NULL
-#define tifm_device_resume NULL
-
-#endif /* CONFIG_PM */
-
-static ssize_t type_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
- return sprintf(buf, "%x", sock->type);
-}
-
-static struct device_attribute tifm_dev_attrs[] = {
- __ATTR(type, S_IRUGO, type_show, NULL),
- __ATTR_NULL
-};
-
-static struct bus_type tifm_bus_type = {
- .name = "tifm",
- .dev_attrs = tifm_dev_attrs,
- .match = tifm_bus_match,
- .uevent = tifm_uevent,
- .probe = tifm_device_probe,
- .remove = tifm_device_remove,
- .suspend = tifm_device_suspend,
- .resume = tifm_device_resume
-};
-
-static void tifm_free(struct device *dev)
-{
- struct tifm_adapter *fm = container_of(dev, struct tifm_adapter, dev);
-
- kfree(fm);
-}
-
-static struct class tifm_adapter_class = {
- .name = "tifm_adapter",
- .dev_release = tifm_free
-};
-
-struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets,
- struct device *dev)
-{
- struct tifm_adapter *fm;
-
- fm = kzalloc(sizeof(struct tifm_adapter)
- + sizeof(struct tifm_dev*) * num_sockets, GFP_KERNEL);
- if (fm) {
- fm->dev.class = &tifm_adapter_class;
- fm->dev.parent = dev;
- device_initialize(&fm->dev);
- spin_lock_init(&fm->lock);
- fm->num_sockets = num_sockets;
- }
- return fm;
-}
-EXPORT_SYMBOL(tifm_alloc_adapter);
-
-int tifm_add_adapter(struct tifm_adapter *fm)
-{
- int rc;
-
- if (!idr_pre_get(&tifm_adapter_idr, GFP_KERNEL))
- return -ENOMEM;
-
- spin_lock(&tifm_adapter_lock);
- rc = idr_get_new(&tifm_adapter_idr, fm, &fm->id);
- spin_unlock(&tifm_adapter_lock);
- if (rc)
- return rc;
-
- dev_set_name(&fm->dev, "tifm%u", fm->id);
- rc = device_add(&fm->dev);
- if (rc) {
- spin_lock(&tifm_adapter_lock);
- idr_remove(&tifm_adapter_idr, fm->id);
- spin_unlock(&tifm_adapter_lock);
- }
-
- return rc;
-}
-EXPORT_SYMBOL(tifm_add_adapter);
-
-void tifm_remove_adapter(struct tifm_adapter *fm)
-{
- unsigned int cnt;
-
- flush_workqueue(workqueue);
- for (cnt = 0; cnt < fm->num_sockets; ++cnt) {
- if (fm->sockets[cnt])
- device_unregister(&fm->sockets[cnt]->dev);
- }
-
- spin_lock(&tifm_adapter_lock);
- idr_remove(&tifm_adapter_idr, fm->id);
- spin_unlock(&tifm_adapter_lock);
- device_del(&fm->dev);
-}
-EXPORT_SYMBOL(tifm_remove_adapter);
-
-void tifm_free_adapter(struct tifm_adapter *fm)
-{
- put_device(&fm->dev);
-}
-EXPORT_SYMBOL(tifm_free_adapter);
-
-void tifm_free_device(struct device *dev)
-{
- struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
- kfree(sock);
-}
-EXPORT_SYMBOL(tifm_free_device);
-
-struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id,
- unsigned char type)
-{
- struct tifm_dev *sock = NULL;
-
- if (!tifm_media_type_name(type, 0))
- return sock;
-
- sock = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL);
- if (sock) {
- spin_lock_init(&sock->lock);
- sock->type = type;
- sock->socket_id = id;
- sock->card_event = tifm_dummy_event;
- sock->data_event = tifm_dummy_event;
-
- sock->dev.parent = fm->dev.parent;
- sock->dev.bus = &tifm_bus_type;
- sock->dev.dma_mask = fm->dev.parent->dma_mask;
- sock->dev.release = tifm_free_device;
-
- dev_set_name(&sock->dev, "tifm_%s%u:%u",
- tifm_media_type_name(type, 2), fm->id, id);
- printk(KERN_INFO DRIVER_NAME
- ": %s card detected in socket %u:%u\n",
- tifm_media_type_name(type, 0), fm->id, id);
- }
- return sock;
-}
-EXPORT_SYMBOL(tifm_alloc_device);
-
-void tifm_eject(struct tifm_dev *sock)
-{
- struct tifm_adapter *fm = dev_get_drvdata(sock->dev.parent);
- fm->eject(fm, sock);
-}
-EXPORT_SYMBOL(tifm_eject);
-
-int tifm_has_ms_pif(struct tifm_dev *sock)
-{
- struct tifm_adapter *fm = dev_get_drvdata(sock->dev.parent);
- return fm->has_ms_pif(fm, sock);
-}
-EXPORT_SYMBOL(tifm_has_ms_pif);
-
-int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
- int direction)
-{
- return pci_map_sg(to_pci_dev(sock->dev.parent), sg, nents, direction);
-}
-EXPORT_SYMBOL(tifm_map_sg);
-
-void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents,
- int direction)
-{
- pci_unmap_sg(to_pci_dev(sock->dev.parent), sg, nents, direction);
-}
-EXPORT_SYMBOL(tifm_unmap_sg);
-
-void tifm_queue_work(struct work_struct *work)
-{
- queue_work(workqueue, work);
-}
-EXPORT_SYMBOL(tifm_queue_work);
-
-int tifm_register_driver(struct tifm_driver *drv)
-{
- drv->driver.bus = &tifm_bus_type;
-
- return driver_register(&drv->driver);
-}
-EXPORT_SYMBOL(tifm_register_driver);
-
-void tifm_unregister_driver(struct tifm_driver *drv)
-{
- driver_unregister(&drv->driver);
-}
-EXPORT_SYMBOL(tifm_unregister_driver);
-
-static int __init tifm_init(void)
-{
- int rc;
-
- workqueue = create_freezable_workqueue("tifm");
- if (!workqueue)
- return -ENOMEM;
-
- rc = bus_register(&tifm_bus_type);
-
- if (rc)
- goto err_out_wq;
-
- rc = class_register(&tifm_adapter_class);
- if (!rc)
- return 0;
-
- bus_unregister(&tifm_bus_type);
-
-err_out_wq:
- destroy_workqueue(workqueue);
-
- return rc;
-}
-
-static void __exit tifm_exit(void)
-{
- class_unregister(&tifm_adapter_class);
- bus_unregister(&tifm_bus_type);
- destroy_workqueue(workqueue);
-}
-
-subsys_initcall(tifm_init);
-module_exit(tifm_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Alex Dubov");
-MODULE_DESCRIPTION("TI FlashMedia core driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
diff --git a/ANDROID_3.4.5/drivers/misc/tsl2550.c b/ANDROID_3.4.5/drivers/misc/tsl2550.c
deleted file mode 100644
index 0beb298a..00000000
--- a/ANDROID_3.4.5/drivers/misc/tsl2550.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * tsl2550.c - Linux kernel modules for ambient light sensor
- *
- * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
- * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
- *
- * This program is free software; you can redistribute 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/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-#define TSL2550_DRV_NAME "tsl2550"
-#define DRIVER_VERSION "1.2"
-
-/*
- * Defines
- */
-
-#define TSL2550_POWER_DOWN 0x00
-#define TSL2550_POWER_UP 0x03
-#define TSL2550_STANDARD_RANGE 0x18
-#define TSL2550_EXTENDED_RANGE 0x1d
-#define TSL2550_READ_ADC0 0x43
-#define TSL2550_READ_ADC1 0x83
-
-/*
- * Structs
- */
-
-struct tsl2550_data {
- struct i2c_client *client;
- struct mutex update_lock;
-
- unsigned int power_state:1;
- unsigned int operating_mode:1;
-};
-
-/*
- * Global data
- */
-
-static const u8 TSL2550_MODE_RANGE[2] = {
- TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
-};
-
-/*
- * Management functions
- */
-
-static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
-
- int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
-
- data->operating_mode = mode;
-
- return ret;
-}
-
-static int tsl2550_set_power_state(struct i2c_client *client, int state)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
- int ret;
-
- if (state == 0)
- ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
- else {
- ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
-
- /* On power up we should reset operating mode also... */
- tsl2550_set_operating_mode(client, data->operating_mode);
- }
-
- data->power_state = state;
-
- return ret;
-}
-
-static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
-{
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, cmd);
- if (ret < 0)
- return ret;
- if (!(ret & 0x80))
- return -EAGAIN;
- return ret & 0x7f; /* remove the "valid" bit */
-}
-
-/*
- * LUX calculation
- */
-
-#define TSL2550_MAX_LUX 1846
-
-static const u8 ratio_lut[] = {
- 100, 100, 100, 100, 100, 100, 100, 100,
- 100, 100, 100, 100, 100, 100, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 98, 98, 98, 98, 98,
- 98, 98, 97, 97, 97, 97, 97, 96,
- 96, 96, 96, 95, 95, 95, 94, 94,
- 93, 93, 93, 92, 92, 91, 91, 90,
- 89, 89, 88, 87, 87, 86, 85, 84,
- 83, 82, 81, 80, 79, 78, 77, 75,
- 74, 73, 71, 69, 68, 66, 64, 62,
- 60, 58, 56, 54, 52, 49, 47, 44,
- 42, 41, 40, 40, 39, 39, 38, 38,
- 37, 37, 37, 36, 36, 36, 35, 35,
- 35, 35, 34, 34, 34, 34, 33, 33,
- 33, 33, 32, 32, 32, 32, 32, 31,
- 31, 31, 31, 31, 30, 30, 30, 30,
- 30,
-};
-
-static const u16 count_lut[] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 49, 53, 57, 61, 65, 69, 73, 77,
- 81, 85, 89, 93, 97, 101, 105, 109,
- 115, 123, 131, 139, 147, 155, 163, 171,
- 179, 187, 195, 203, 211, 219, 227, 235,
- 247, 263, 279, 295, 311, 327, 343, 359,
- 375, 391, 407, 423, 439, 455, 471, 487,
- 511, 543, 575, 607, 639, 671, 703, 735,
- 767, 799, 831, 863, 895, 927, 959, 991,
- 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
- 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
- 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
- 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
-};
-
-/*
- * This function is described into Taos TSL2550 Designer's Notebook
- * pages 2, 3.
- */
-static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
-{
- unsigned int lux;
-
- /* Look up count from channel values */
- u16 c0 = count_lut[ch0];
- u16 c1 = count_lut[ch1];
-
- /*
- * Calculate ratio.
- * Note: the "128" is a scaling factor
- */
- u8 r = 128;
-
- /* Avoid division by 0 and count 1 cannot be greater than count 0 */
- if (c1 <= c0)
- if (c0) {
- r = c1 * 128 / c0;
-
- /* Calculate LUX */
- lux = ((c0 - c1) * ratio_lut[r]) / 256;
- } else
- lux = 0;
- else
- return -EAGAIN;
-
- /* LUX range check */
- return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
-}
-
-/*
- * SysFS support
- */
-
-static ssize_t tsl2550_show_power_state(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
-
- return sprintf(buf, "%u\n", data->power_state);
-}
-
-static ssize_t tsl2550_store_power_state(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct tsl2550_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10);
- int ret;
-
- if (val < 0 || val > 1)
- return -EINVAL;
-
- mutex_lock(&data->update_lock);
- ret = tsl2550_set_power_state(client, val);
- mutex_unlock(&data->update_lock);
-
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
- tsl2550_show_power_state, tsl2550_store_power_state);
-
-static ssize_t tsl2550_show_operating_mode(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
-
- return sprintf(buf, "%u\n", data->operating_mode);
-}
-
-static ssize_t tsl2550_store_operating_mode(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct tsl2550_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10);
- int ret;
-
- if (val < 0 || val > 1)
- return -EINVAL;
-
- if (data->power_state == 0)
- return -EBUSY;
-
- mutex_lock(&data->update_lock);
- ret = tsl2550_set_operating_mode(client, val);
- mutex_unlock(&data->update_lock);
-
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
- tsl2550_show_operating_mode, tsl2550_store_operating_mode);
-
-static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
- u8 ch0, ch1;
- int ret;
-
- ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
- if (ret < 0)
- return ret;
- ch0 = ret;
-
- ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
- if (ret < 0)
- return ret;
- ch1 = ret;
-
- /* Do the job */
- ret = tsl2550_calculate_lux(ch0, ch1);
- if (ret < 0)
- return ret;
- if (data->operating_mode == 1)
- ret *= 5;
-
- return sprintf(buf, "%d\n", ret);
-}
-
-static ssize_t tsl2550_show_lux1_input(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct tsl2550_data *data = i2c_get_clientdata(client);
- int ret;
-
- /* No LUX data if not operational */
- if (!data->power_state)
- return -EBUSY;
-
- mutex_lock(&data->update_lock);
- ret = __tsl2550_show_lux(client, buf);
- mutex_unlock(&data->update_lock);
-
- return ret;
-}
-
-static DEVICE_ATTR(lux1_input, S_IRUGO,
- tsl2550_show_lux1_input, NULL);
-
-static struct attribute *tsl2550_attributes[] = {
- &dev_attr_power_state.attr,
- &dev_attr_operating_mode.attr,
- &dev_attr_lux1_input.attr,
- NULL
-};
-
-static const struct attribute_group tsl2550_attr_group = {
- .attrs = tsl2550_attributes,
-};
-
-/*
- * Initialization function
- */
-
-static int tsl2550_init_client(struct i2c_client *client)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
- int err;
-
- /*
- * Probe the chip. To do so we try to power up the device and then to
- * read back the 0x03 code
- */
- err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
- if (err < 0)
- return err;
- if (err != TSL2550_POWER_UP)
- return -ENODEV;
- data->power_state = 1;
-
- /* Set the default operating mode */
- err = i2c_smbus_write_byte(client,
- TSL2550_MODE_RANGE[data->operating_mode]);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-/*
- * I2C init/probing/exit functions
- */
-
-static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct tsl2550_data *data;
- int *opmode, err = 0;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
- | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
- err = -EIO;
- goto exit;
- }
-
- data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
- data->client = client;
- i2c_set_clientdata(client, data);
-
- /* Check platform data */
- opmode = client->dev.platform_data;
- if (opmode) {
- if (*opmode < 0 || *opmode > 1) {
- dev_err(&client->dev, "invalid operating_mode (%d)\n",
- *opmode);
- err = -EINVAL;
- goto exit_kfree;
- }
- data->operating_mode = *opmode;
- } else
- data->operating_mode = 0; /* default mode is standard */
- dev_info(&client->dev, "%s operating mode\n",
- data->operating_mode ? "extended" : "standard");
-
- mutex_init(&data->update_lock);
-
- /* Initialize the TSL2550 chip */
- err = tsl2550_init_client(client);
- if (err)
- goto exit_kfree;
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
- if (err)
- goto exit_kfree;
-
- dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
-
- return 0;
-
-exit_kfree:
- kfree(data);
-exit:
- return err;
-}
-
-static int __devexit tsl2550_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
-
- /* Power down the device */
- tsl2550_set_power_state(client, 0);
-
- kfree(i2c_get_clientdata(client));
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg)
-{
- return tsl2550_set_power_state(client, 0);
-}
-
-static int tsl2550_resume(struct i2c_client *client)
-{
- return tsl2550_set_power_state(client, 1);
-}
-
-#else
-
-#define tsl2550_suspend NULL
-#define tsl2550_resume NULL
-
-#endif /* CONFIG_PM */
-
-static const struct i2c_device_id tsl2550_id[] = {
- { "tsl2550", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tsl2550_id);
-
-static struct i2c_driver tsl2550_driver = {
- .driver = {
- .name = TSL2550_DRV_NAME,
- .owner = THIS_MODULE,
- },
- .suspend = tsl2550_suspend,
- .resume = tsl2550_resume,
- .probe = tsl2550_probe,
- .remove = __devexit_p(tsl2550_remove),
- .id_table = tsl2550_id,
-};
-
-module_i2c_driver(tsl2550_driver);
-
-MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
diff --git a/ANDROID_3.4.5/drivers/misc/uid_stat.c b/ANDROID_3.4.5/drivers/misc/uid_stat.c
deleted file mode 100644
index 2141124a..00000000
--- a/ANDROID_3.4.5/drivers/misc/uid_stat.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* drivers/misc/uid_stat.c
- *
- * Copyright (C) 2008 - 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 <asm/atomic.h>
-
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/stat.h>
-#include <linux/uid_stat.h>
-#include <net/activity_stats.h>
-
-static DEFINE_SPINLOCK(uid_lock);
-static LIST_HEAD(uid_list);
-static struct proc_dir_entry *parent;
-
-struct uid_stat {
- struct list_head link;
- uid_t uid;
- atomic_t tcp_rcv;
- atomic_t tcp_snd;
-};
-
-static struct uid_stat *find_uid_stat(uid_t uid) {
- unsigned long flags;
- struct uid_stat *entry;
-
- spin_lock_irqsave(&uid_lock, flags);
- list_for_each_entry(entry, &uid_list, link) {
- if (entry->uid == uid) {
- spin_unlock_irqrestore(&uid_lock, flags);
- return entry;
- }
- }
- spin_unlock_irqrestore(&uid_lock, flags);
- return NULL;
-}
-
-static int tcp_snd_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len;
- unsigned int bytes;
- char *p = page;
- struct uid_stat *uid_entry = (struct uid_stat *) data;
- if (!data)
- return 0;
-
- bytes = (unsigned int) (atomic_read(&uid_entry->tcp_snd) + INT_MIN);
- p += sprintf(p, "%u\n", bytes);
- len = (p - page) - off;
- *eof = (len <= count) ? 1 : 0;
- *start = page + off;
- return len;
-}
-
-static int tcp_rcv_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len;
- unsigned int bytes;
- char *p = page;
- struct uid_stat *uid_entry = (struct uid_stat *) data;
- if (!data)
- return 0;
-
- bytes = (unsigned int) (atomic_read(&uid_entry->tcp_rcv) + INT_MIN);
- p += sprintf(p, "%u\n", bytes);
- len = (p - page) - off;
- *eof = (len <= count) ? 1 : 0;
- *start = page + off;
- return len;
-}
-
-/* Create a new entry for tracking the specified uid. */
-static struct uid_stat *create_stat(uid_t uid) {
- unsigned long flags;
- char uid_s[32];
- struct uid_stat *new_uid;
- struct proc_dir_entry *entry;
-
- /* Create the uid stat struct and append it to the list. */
- if ((new_uid = kmalloc(sizeof(struct uid_stat), GFP_KERNEL)) == NULL)
- return NULL;
-
- new_uid->uid = uid;
- /* Counters start at INT_MIN, so we can track 4GB of network traffic. */
- atomic_set(&new_uid->tcp_rcv, INT_MIN);
- atomic_set(&new_uid->tcp_snd, INT_MIN);
-
- spin_lock_irqsave(&uid_lock, flags);
- list_add_tail(&new_uid->link, &uid_list);
- spin_unlock_irqrestore(&uid_lock, flags);
-
- sprintf(uid_s, "%d", uid);
- entry = proc_mkdir(uid_s, parent);
-
- /* Keep reference to uid_stat so we know what uid to read stats from. */
- create_proc_read_entry("tcp_snd", S_IRUGO, entry , tcp_snd_read_proc,
- (void *) new_uid);
-
- create_proc_read_entry("tcp_rcv", S_IRUGO, entry, tcp_rcv_read_proc,
- (void *) new_uid);
-
- return new_uid;
-}
-
-int uid_stat_tcp_snd(uid_t uid, int size) {
- struct uid_stat *entry;
- activity_stats_update();
- if ((entry = find_uid_stat(uid)) == NULL &&
- ((entry = create_stat(uid)) == NULL)) {
- return -1;
- }
- atomic_add(size, &entry->tcp_snd);
- return 0;
-}
-
-int uid_stat_tcp_rcv(uid_t uid, int size) {
- struct uid_stat *entry;
- activity_stats_update();
- if ((entry = find_uid_stat(uid)) == NULL &&
- ((entry = create_stat(uid)) == NULL)) {
- return -1;
- }
- atomic_add(size, &entry->tcp_rcv);
- return 0;
-}
-
-static int __init uid_stat_init(void)
-{
- parent = proc_mkdir("uid_stat", NULL);
- if (!parent) {
- pr_err("uid_stat: failed to create proc entry\n");
- return -1;
- }
- return 0;
-}
-
-__initcall(uid_stat_init);
diff --git a/ANDROID_3.4.5/drivers/misc/viatel/Kconfig b/ANDROID_3.4.5/drivers/misc/viatel/Kconfig
deleted file mode 100755
index a341da3f..00000000
--- a/ANDROID_3.4.5/drivers/misc/viatel/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-menu "Viatelecom OEM funtion support"
-
-config VIATELECOM_SYNC_CBP
- bool "Ap Sync Cbp"
- help
- The synchronous mechanism for the data exchage between Ap and Cbp.
-
-config VIATELECOM_POWER_CBP
- bool "AP Power Cbp"
- help
- Enable this driver to support to control funtion such as reset, power
- between AP and Cbp.
-
-endmenu
diff --git a/ANDROID_3.4.5/drivers/misc/viatel/Makefile b/ANDROID_3.4.5/drivers/misc/viatel/Makefile
deleted file mode 100755
index fe30dd44..00000000
--- a/ANDROID_3.4.5/drivers/misc/viatel/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-y += core.o oem.o sync.o # cp_reset.o
-obj-$(CONFIG_VIATELECOM_SYNC_CBP) += sync.o
-obj-$(CONFIG_VIATELECOM_POWER_CBP) += power.o
diff --git a/ANDROID_3.4.5/drivers/misc/viatel/core.c b/ANDROID_3.4.5/drivers/misc/viatel/core.c
deleted file mode 100755
index d06d7a48..00000000
--- a/ANDROID_3.4.5/drivers/misc/viatel/core.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * core.c
- *
- * VIA CBP driver for Linux
- *
- * Copyright (C) 2011 VIA TELECOM Corporation, Inc.
- * Author: VIA TELECOM Corporation, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/platform_device.h>
-
-static struct kobject *viatel_kobj;
-
-struct kobject *viatel_kobject_add(const char *name)
-{
- struct kobject *kobj = NULL;
- if(viatel_kobj){
- kobj = kobject_create_and_add(name, viatel_kobj);
- }
-
- return kobj;
-}
-
-static int __init viatel_core_init(void)
-{
- int ret = 0;
- viatel_kobj = kobject_create_and_add("viatel", NULL);
- if (!viatel_kobj){
- ret = -ENOMEM;
- goto err_create_kobj;
- }
-err_create_kobj:
- return ret;
-}
-
-arch_initcall(viatel_core_init);
diff --git a/ANDROID_3.4.5/drivers/misc/viatel/core.h b/ANDROID_3.4.5/drivers/misc/viatel/core.h
deleted file mode 100755
index d6d323cc..00000000
--- a/ANDROID_3.4.5/drivers/misc/viatel/core.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * core.h
- *
- * VIA CBP driver for Linux
- *
- * Copyright (C) 2011 VIA TELECOM Corporation, Inc.
- * Author: VIA TELECOM Corporation, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#ifndef VIATEL_CORE_H
-#define VIATEL_CORE_H
-
-extern struct kobject *viatel_kobject_add(const char *name);
-#endif
diff --git a/ANDROID_3.4.5/drivers/misc/viatel/oem.c b/ANDROID_3.4.5/drivers/misc/viatel/oem.c
deleted file mode 100755
index 105c4d7d..00000000
--- a/ANDROID_3.4.5/drivers/misc/viatel/oem.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- * viatel_cbp_oem.c
- *
- * VIA CBP driver for Linux
- *
- * Copyright (C) 2011 VIA TELECOM Corporation, Inc.
- * Author: VIA TELECOM Corporation, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/interrupt.h>
-#include <mach/viatel.h>
-#include <linux/gpio.h>
-#include <mach/wmt_iomux.h>
-#include <mach/hardware.h>
-#include "linux/delay.h"
-
-#if 1
-
-//#define VIATEL_DEBUG
-#ifdef VIATEL_DEBUG
-#define wmt_dbg(fmt, arg...) printk(fmt, ##arg)
-#else
-#define wmt_dbg(fmt, arg...)
-#endif
-
-int isviatelcom = 0;
-int wk1_high_active = 0;
-int gpio_viatel_4wire[4];
-int ap_ready_always = 0;
-unsigned int wakeup_reg_val;
-unsigned int wakeup_shift_bit;
-int wakeup_type_mask;
-
-extern int wmt_getsyspara(char *varname, char *varval, int *varlen);
-
-int oem_gpio_convert_init(void){
- char buf[256];
- int varlen = 256;
- if( wmt_getsyspara("wmt.modem.viatel.4wire",buf,&varlen) == 0)
- {
- sscanf(buf,"%d:%d:%d:%d",&gpio_viatel_4wire[GPIO_VIATEL_USB_AP_RDY],
- &gpio_viatel_4wire[GPIO_VIATEL_USB_MDM_RDY],
- &gpio_viatel_4wire[GPIO_VIATEL_USB_AP_WAKE_MDM],
- &gpio_viatel_4wire[GPIO_VIATEL_USB_MDM_WAKE_AP]);
-
- printk("4wire %d:%d:%d:%d\n",gpio_viatel_4wire[GPIO_VIATEL_USB_AP_RDY],
- gpio_viatel_4wire[GPIO_VIATEL_USB_MDM_RDY],
- gpio_viatel_4wire[GPIO_VIATEL_USB_AP_WAKE_MDM],
- gpio_viatel_4wire[GPIO_VIATEL_USB_MDM_WAKE_AP]);
-
- isviatelcom = 1;
- printk("disable wakeup1 %s %d\n",__FUNCTION__,__LINE__);
-
-
- if(gpio_viatel_4wire[GPIO_VIATEL_USB_MDM_WAKE_AP]==149){
- wakeup_reg_val=0x1L;
- wakeup_shift_bit = 0;
- wakeup_type_mask = 0xfffffff8;
- }else{
- wakeup_reg_val=0x4L;
- wakeup_shift_bit = 8;
- wakeup_type_mask = 0xfffff8ff;
- }
-
-
- PMCIE_VAL &=(~wakeup_reg_val);
- INT_TRG_EN_VAL&=(~wakeup_reg_val);
-
- if(wmt_getsyspara("wmt.modem.viatel.aprdy",buf,&varlen) == 0){
- sscanf(buf,"%d",&ap_ready_always);
- }else{
- ap_ready_always = 0;/* default value */
- }
-
- return 0;
- }
-
- return -1;
-}
-
-int oem_gpio_request(int gpio, const char *label)
-{
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
- gpio_request(gpio_viatel_4wire[gpio], label);
- return 0;
-}
-
-void oem_gpio_free(int gpio)
-{
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
- gpio_free(gpio_viatel_4wire[gpio]);
- return ;
-}
-
-/*config the gpio to be input for irq if the SOC need*/
-int oem_gpio_direction_input_for_irq(int gpio)
-{
- if(!isviatelcom)
- return 0;
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
-
- wmt_gpio_setpull(gpio_viatel_4wire[gpio], WMT_GPIO_PULL_DOWN);
- gpio_direction_input(gpio_viatel_4wire[gpio]);
- gpio_re_enabled(gpio_viatel_4wire[gpio]);
-
- return 0;
-}
-
-int oem_gpio_direction_output(int gpio, int value)
-{
- if(!isviatelcom)
- return 0;
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
- if(ap_ready_always&&(gpio == GPIO_VIATEL_USB_AP_RDY))
- return 0;
-
-
- gpio_re_enabled(gpio_viatel_4wire[gpio]);
- gpio_direction_output(gpio_viatel_4wire[gpio], value);
-
- return 0;
-}
-
-int oem_gpio_output(int gpio, int value)
-{
- if(!isviatelcom)
- return 0;
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
-
- gpio_re_enabled(gpio_viatel_4wire[gpio]);
- gpio_direction_output(gpio_viatel_4wire[gpio], value);
-
- return 0;
-}
-
-int oem_gpio_is_wakeup(int gpio)
-{
- if(gpio==149||gpio==152) //wekup0 gpio index WMT_PIN_GP62_WAKEUP0
- return 1;
- else
- return 0;
-}
-
-
-/*
- * Get the output level if the gpio is output type;
- * Get the input level if the gpio is input type
- */
-int oem_gpio_get_value(int gpio)
-{
- int rtn;
- if(!isviatelcom)
- return 0;
- wmt_gpio_setpull(gpio_viatel_4wire[gpio], WMT_GPIO_PULL_DOWN);
- gpio_direction_input(gpio_viatel_4wire[gpio]);
- gpio_re_enabled(gpio_viatel_4wire[gpio]);
- rtn = __gpio_get_value(gpio_viatel_4wire[gpio]);
- wmt_dbg("%s index=%d gpio=%d,rtn=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio],rtn);
- if(oem_gpio_is_wakeup(gpio_viatel_4wire[gpio])&&(!wk1_high_active))
- return !rtn;
- else
- return rtn;
-}
-
-
-
-
-int oem_gpio_to_irq(int gpio)
-{
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
- return IRQ_GPIO;
-}
-
-/*
- * Set the irq type of the pin.
- * Get the pin level and set the correct edge if the type is both edge and
- * the SOC do not support both edge detection at one time
- */
-int oem_gpio_set_irq_type(int gpio, unsigned int type)
-{
- if(!isviatelcom)
- return 0;
-
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
- if(oem_gpio_is_wakeup(gpio_viatel_4wire[gpio])){
- int wakeup_type;
- if(type==IRQF_TRIGGER_RISING){
- if(wk1_high_active)
- wakeup_type=(0x3<<wakeup_shift_bit);
- else
- wakeup_type=(0x2<<wakeup_shift_bit);
- }
- else if(type==(IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
- wakeup_type=(0x4<<wakeup_shift_bit);
- else{
- printk("\n\n\n\n\n=======oem_gpio_set_irq_type error\n\n\n\n\n\n");
- return 0;
- }
-
- INT_TYPE0_VAL = (INT_TYPE0_VAL&wakeup_type_mask)|wakeup_type;
- return 0;
- }
-
- if(type < IRQF_TRIGGER_NONE ||type >=IRQF_TRIGGER_HIGH)
- printk("error %s %d gpio %d type 0x%x\n",__FUNCTION__,__LINE__,gpio_viatel_4wire[gpio],type);
- return wmt_gpio_set_irq_type(gpio_viatel_4wire[gpio], type);
-}
-
-
-int oem_gpio_request_irq(int gpio, irq_handler_t handler, unsigned long flags,
- const char *name, void *dev)
-{
- if(!isviatelcom)
- return 0;
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
- if(oem_gpio_is_wakeup(gpio_viatel_4wire[gpio]))
- return 0;
-
- return request_irq(oem_gpio_to_irq(gpio), handler, flags, name, dev);
-}
-
-void oem_gpio_irq_mask(int gpio)
-{
- if(!isviatelcom)
- return ;
-
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
- if(oem_gpio_is_wakeup(gpio_viatel_4wire[gpio])){
- PMCIE_VAL &=(~wakeup_reg_val);
- INT_TRG_EN_VAL&=(~wakeup_reg_val);
- return ;
- }
-
- wmt_gpio_mask_irq(gpio_viatel_4wire[gpio]);
-
- return ;
-}
-void oem_gpio_irq_unmask(int gpio)
-{
- if(!isviatelcom)
- return;
-
- wmt_dbg("%s index=%d gpio=%d\n",__FUNCTION__,gpio,gpio_viatel_4wire[gpio]);
- if(oem_gpio_is_wakeup(gpio_viatel_4wire[gpio])){
- int i;
- for(i=0;i<100;i++){
- PMCIE_VAL |=wakeup_reg_val;
- INT_TRG_EN_VAL|=wakeup_reg_val;
- if(PMCIE_VAL&wakeup_reg_val){
- break;
- }
- printk("PMCIE_VAL set error %x,retry %d\n", PMCIE_VAL,i);
- mdelay(10);
- }
- return ;
- }
-
- wmt_gpio_unmask_irq(gpio_viatel_4wire[gpio]);
-
- return ;
-}
-
-int oem_gpio_irq_isenable(int gpio){
- if(!isviatelcom)
- return 0;
-
- if(oem_gpio_is_wakeup(gpio_viatel_4wire[gpio]))
- return 1;
-
- return is_gpio_irqenable(gpio_viatel_4wire[gpio]);
-}
-
-int oem_gpio_irq_isint(int gpio){
- if(!isviatelcom)
- return 0;
-
- if(oem_gpio_is_wakeup(gpio_viatel_4wire[gpio]))
- return 1;
-
- return gpio_irqstatus(gpio_viatel_4wire[gpio]);
-
-}
-int oem_gpio_irq_clear(int gpio){
- if(!isviatelcom)
- return 1;
-
- if(oem_gpio_is_wakeup(gpio_viatel_4wire[gpio]))
- return 0;
-
- wmt_gpio_ack_irq(gpio_viatel_4wire[gpio]);
-
- return 0;
-}
-
-#endif
-#if 0
-
-#if defined(CONFIG_MACH_OMAP_KUNLUN)
-int oem_gpio_request(int gpio, const char *label)
-{
- return gpio_request(gpio, label);
-}
-
-void oem_gpio_free(int gpio)
-{
- gpio_free(gpio);
-}
-
-/*config the gpio to be input for irq if the SOC need*/
-int oem_gpio_direction_input_for_irq(int gpio)
-{
- return gpio_direction_input(gpio);
-}
-
-int oem_gpio_direction_output(int gpio, int value)
-{
- return gpio_direction_output(gpio, value);
-}
-
-/*
- * Get the output level if the gpio is output type;
- * Get the input level if the gpio is input type
- */
-int oem_gpio_get_value(int gpio)
-{
- return gpio_get_value(gpio);
-}
-
-int oem_gpio_to_irq(int gpio)
-{
- return gpio_to_irq(gpio);
-}
-
-/*
- * Set the irq type of the pin.
- * Get the pin level and set the correct edge if the type is both edge and
- * the SOC do not support both edge detection at one time
- */
-int oem_gpio_set_irq_type(unsigned gpio, unsigned int type)
-{
- return set_irq_type(oem_gpio_to_irq(gpio), type);
-}
-
-
-int oem_gpio_request_irq(int gpio, irq_handler_t handler, unsigned long flags,
- const char *name, void *dev)
-{
- return request_irq(oem_gpio_to_irq(gpio), handler, flags, name, dev);
-}
-
-void oem_gpio_irq_mask(int gpio)
-{
- return ;
-}
-
-void oem_gpio_irq_unmask(int gpio)
-{
- return ;
-}
-
-
-
-#endif
-
-#if defined(CONFIG_SOC_JZ4770)
-int oem_gpio_request(int gpio, const char *label)
-{
- return gpio_request(gpio, label);
-}
-
-void oem_gpio_free(int gpio)
-{
- gpio_free(gpio);
-}
-
-/*config the gpio to be input for irq if the SOC need*/
-int oem_gpio_direction_input_for_irq(int gpio)
-{
- return 0;
-}
-
-int oem_gpio_direction_output(int gpio, int value)
-{
- return gpio_direction_output(gpio, value);
-}
-
-/*
- * Get the output level if the gpio is output type;
- * Get the input level if the gpio is input type
- */
-int oem_gpio_get_value(int gpio)
-{
- return gpio_get_value(gpio);
-}
-
-int oem_gpio_to_irq(int gpio)
-{
- return gpio_to_irq(gpio);
-}
-
-#define GPIO_DEBOUNCE (3)
-int read_gpio_pin(int pin)
-{
- int t, v;
- int i;
-
- i = GPIO_DEBOUNCE;
-
- v = t = 0;
-
- while (i--) {
- t = __gpio_get_pin(pin);
- if (v != t)
- i = GPIO_DEBOUNCE;
-
- v = t;
- ndelay(100);
- }
-
- return v;
-}
-
-int oem_gpio_set_irq_type(int gpio, unsigned int type)
-{
- if(type == IRQ_TYPE_EDGE_BOTH){
- if(read_gpio_pin(gpio)){
- type = IRQ_TYPE_EDGE_FALLING;
- }else{
- type = IRQ_TYPE_EDGE_RISING;
- }
- }
-
- if(type == IRQ_TYPE_LEVEL_MASK){
- if(read_gpio_pin(gpio)){
- type = IRQ_TYPE_LEVEL_LOW;
- }else{
- type = IRQ_TYPE_LEVEL_HIGH;
- }
- }
-
- switch(type){
- case IRQ_TYPE_EDGE_RISING:
- __gpio_as_irq_rise_edge(gpio);
- break;
- case IRQ_TYPE_EDGE_FALLING:
- __gpio_as_irq_fall_edge(gpio);
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- __gpio_as_irq_high_level(gpio);
- break;
- case IRQ_TYPE_LEVEL_LOW:
- __gpio_as_irq_low_level(gpio);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-int oem_gpio_request_irq(int gpio, irq_handler_t handler, unsigned long flags,
- const char *name, void *dev)
-{
- int ret = request_irq(oem_gpio_to_irq(gpio), handler, flags, name, dev);
- enable_irq_wake(oem_gpio_to_irq(gpio));
- return ret;
-}
-
-void oem_gpio_irq_mask(int gpio)
-{
- return ;
-}
-
-void oem_gpio_irq_unmask(int gpio)
-{
- return ;
-}
-#endif
-
-#if defined(EVDO_DT_SUPPORT)
-#include <linux/interrupt.h>
-int oem_gpio_request(int gpio, const char *label)
-{
- return 0;
-}
-
-void oem_gpio_free(int gpio)
-{
- return ;
-}
-
-/*config the gpio to be input for irq if the SOC need*/
-int oem_gpio_direction_input_for_irq(int gpio)
-{
- mt_set_gpio_mode(gpio, GPIO_MODE_02);
- mt_set_gpio_dir(gpio, GPIO_DIR_IN);
- return 0;
-}
-
-int oem_gpio_direction_output(int gpio, int value)
-{
- mt_set_gpio_mode(gpio, GPIO_MODE_GPIO);
- mt_set_gpio_dir(gpio, GPIO_DIR_OUT);
- mt_set_gpio_out(gpio, !!value);
- return 0;
-}
-
-int oem_gpio_get_value(int gpio)
-{
- if(GPIO_DIR_IN == mt_get_gpio_dir(gpio)){
- return mt_get_gpio_in(gpio);
- }else{
- return mt_get_gpio_out(gpio);
- }
-}
-
-typedef struct mtk_oem_gpio_des{
- int gpio;
- int irq;
- void (*redirect)(void);
- irq_handler_t handle;
- void *data;
-}mtk_oem_gpio_des;
-
-static void gpio_irq_handle_usb_mdm_rdy(void);
-static void gpio_irq_handle_usb_mdm_wake_ap(void);
-static void gpio_irq_handle_uart_mdm_wake_ap(void);
-static void gpio_irq_handle_rst_ind(void);
-static void gpio_irq_handle_pwr_ind(void);
-
-mtk_oem_gpio_des oem_gpio_list[] = {
- {GPIO_VIATEL_USB_MDM_RDY, 4, gpio_irq_handle_usb_mdm_rdy, NULL, NULL},
- {GPIO_VIATEL_USB_MDM_WAKE_AP, 29, gpio_irq_handle_usb_mdm_wake_ap, NULL, NULL},
- {GPIO_VIATEL_MDM_RST_IND, 28, gpio_irq_handle_rst_ind, NULL, NULL},
- {GPIO_VIATEL_UART_MDM_WAKE_AP, 27, gpio_irq_handle_uart_mdm_wake_ap, NULL, NULL},
- {GPIO_VIATEL_MDM_PWR_IND, 27, gpio_irq_handle_pwr_ind, NULL, NULL},
-};
-
-static mtk_oem_gpio_des* gpio_des_find_by_gpio(int gpio)
-{
- int i = 0;
- mtk_oem_gpio_des *des = NULL;
-
- if(gpio < 0){
- return NULL;
- }
-
- for(i=0; i < sizeof(oem_gpio_list) / sizeof(mtk_oem_gpio_des); i++){
- des = oem_gpio_list + i;
- if(des->gpio == gpio){
- return des;
- }
- }
-
- return NULL;
-}
-
-static mtk_oem_gpio_des* gpio_des_find_by_irq(int irq)
-{
- int i = 0;
- mtk_oem_gpio_des *des = NULL;
-
- for(i=0; i < sizeof(oem_gpio_list) / sizeof(mtk_oem_gpio_des); i++){
- des = oem_gpio_list + i;
- if(des->irq == irq){
- return des;
- }
- }
-
- return NULL;
-}
-static void gpio_irq_handle_usb_mdm_rdy(void)
-{
- int irq = 0;
- mtk_oem_gpio_des *des = NULL;
-
- des = gpio_des_find_by_gpio(GPIO_VIATEL_USB_MDM_RDY);
- if(des && des->handle){
- des->handle(des->irq, des->data);
- }
-}
-static void gpio_irq_handle_usb_mdm_wake_ap(void)
-{
- int irq = 0;
- mtk_oem_gpio_des *des = NULL;
-
- des = gpio_des_find_by_gpio(GPIO_VIATEL_USB_MDM_WAKE_AP);
- if(des && des->handle){
- des->handle(des->irq, des->data);
- }
-}
-
-static void gpio_irq_handle_uart_mdm_wake_ap(void)
-{
- int irq = 0;
- mtk_oem_gpio_des *des = NULL;
-
- des = gpio_des_find_by_gpio(GPIO_VIATEL_UART_MDM_WAKE_AP);
- if(des && des->handle){
- des->handle(des->irq, des->data);
- }
-}
-
-static void gpio_irq_handle_rst_ind(void)
-{
- int irq = 0;
- mtk_oem_gpio_des *des = NULL;
-
- des = gpio_des_find_by_gpio(GPIO_VIATEL_MDM_RST_IND);
- if(des && des->handle){
- des->handle(des->irq, des->data);
- }
-}
-static void gpio_irq_handle_pwr_ind(void)
-{
- int irq = 0;
- mtk_oem_gpio_des *des = NULL;
-
- des = gpio_des_find_by_gpio(GPIO_VIATEL_MDM_PWR_IND);
- if(des && des->handle){
- des->handle(des->irq, des->data);
- }
-}
-
-int oem_gpio_to_irq(int gpio)
-{
- mtk_oem_gpio_des *des = NULL;
-
- des = gpio_des_find_by_gpio(gpio);
- if(NULL == des){
- printk("%s: no irq for gpio %d\n", __FUNCTION__, gpio);
- return -1;
- }else{
- return des->irq;
- }
-}
-
-int oem_irq_to_gpio(int irq)
-{
- mtk_oem_gpio_des *des = NULL;
-
- des = gpio_des_find_by_irq(irq);
- if(NULL == des){
- printk("%s: no gpio for irq %d\n", __FUNCTION__, irq);
- return -1;
- }else{
- return des->gpio;
- }
-}
-
-int oem_gpio_set_irq_type(int gpio, unsigned int type)
-{
- int irq, level;
-
- irq = oem_gpio_to_irq(gpio);
- if(irq < 0){
- return irq;
- }
-
- level = oem_gpio_get_value(gpio);
-
- if(type == IRQ_TYPE_EDGE_BOTH){
- if(level){
- type = IRQ_TYPE_EDGE_FALLING;
- }else{
- type = IRQ_TYPE_EDGE_RISING;
- }
- }
-
- if(type == IRQ_TYPE_LEVEL_MASK){
- if(level){
- type = IRQ_TYPE_LEVEL_LOW;
- }else{
- type = IRQ_TYPE_LEVEL_HIGH;
- }
- }
-
- mt65xx_eint_set_hw_debounce(irq, 3);
- switch(type){
- case IRQ_TYPE_EDGE_RISING:
- mt65xx_eint_set_sens(irq, MT65xx_EDGE_SENSITIVE);
- mt65xx_eint_set_polarity(irq, MT65xx_POLARITY_HIGH);
- break;
- case IRQ_TYPE_EDGE_FALLING:
- mt65xx_eint_set_sens(irq, MT65xx_EDGE_SENSITIVE);
- mt65xx_eint_set_polarity(irq, MT65xx_POLARITY_LOW);
- break;
- case IRQ_TYPE_LEVEL_HIGH:
- mt65xx_eint_set_sens(irq, MT65xx_LEVEL_SENSITIVE);
- mt65xx_eint_set_polarity(irq, MT65xx_POLARITY_HIGH);
- break;
- case IRQ_TYPE_LEVEL_LOW:
- mt65xx_eint_set_sens(irq, MT65xx_LEVEL_SENSITIVE);
- mt65xx_eint_set_polarity(irq, MT65xx_POLARITY_LOW);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-int oem_gpio_request_irq(int gpio, irq_handler_t handler, unsigned long flags,
- const char *name, void *dev)
-{
- mtk_oem_gpio_des *des = NULL;
-
- des = gpio_des_find_by_gpio(gpio);
- if(des == NULL){
- return -1;
- }
- des->data = dev;
- des->handle = handler;
-
- mt65xx_eint_registration(des->irq, 1, 1, des->redirect, 0);
-
- return 0;
-}
-
-void oem_gpio_irq_mask(int gpio)
-{
- int irq;
-
- irq = oem_gpio_to_irq(gpio);
- if(irq < 0){
- return ;
- }
-
- mt65xx_eint_mask(irq);
-}
-
-void oem_gpio_irq_unmask(int gpio)
-{
- int irq;
-
- irq = oem_gpio_to_irq(gpio);
- if(irq < 0){
- return ;
- }
-
- mt65xx_eint_unmask(irq);
-}
-#endif
-#endif
diff --git a/ANDROID_3.4.5/drivers/misc/viatel/power.c b/ANDROID_3.4.5/drivers/misc/viatel/power.c
deleted file mode 100755
index 0fc22cb3..00000000
--- a/ANDROID_3.4.5/drivers/misc/viatel/power.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * viatel_cbp_power.c
- *
- * VIA CBP driver for Linux
- *
- * Copyright (C) 2009 VIA TELECOM Corporation, Inc.
- * Author: VIA TELECOM Corporation, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/wakelock.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <mach/viatel.h>
-#include "core.h"
-
-#define MDM_RST_LOCK_TIME (120)
-#define MDM_RST_HOLD_DELAY (100) //ms
-#define MDM_PWR_HOLD_DELAY (500) //ms
-
-//#define VIA_AP_MODEM_DEBU
-#ifdef VIA_AP_MODEM_DEBUG
-#undef dbg
-#define dbg(format, arg...) printk("[CBP_POWER]: " format "\n" , ## arg)
-#else
-#undef dbg
-#define dbg(format, arg...) do {} while (0)
-#endif
-
-static struct wake_lock reset_lock;
-
-void oem_power_off_modem(void)
-{
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_EN)){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_PWR_EN, 0);
- }
-
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST)){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_RST, 1);
- /*just hold the reset pin if no power enable pin*/
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_EN)){
- mdelay(MDM_RST_HOLD_DELAY);
- oem_gpio_direction_output(GPIO_VIATEL_MDM_RST, 0);
- }
- }
-}
-EXPORT_SYMBOL(oem_power_off_modem);
-
-ssize_t modem_power_show(
- struct kobject *kobj, struct kobj_attribute *attr, char *buf)
-{
- int power = 0;
- int ret = 0;
-
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_IND)){
- power = !!oem_gpio_get_value(GPIO_VIATEL_MDM_PWR_IND);
- }else if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_EN)){
- printk("No MDM_PWR_IND, just detect MDM_PWR_EN\n");
- power = !!oem_gpio_get_value(GPIO_VIATEL_MDM_PWR_EN);
- }else if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST)){
- printk("No MDM_PWR_IND, just detect MDM_PWR_RST\n");
- power = !!oem_gpio_get_value(GPIO_VIATEL_MDM_RST);
- }
- if(power){
- ret += sprintf(buf + ret, "on\n");
- }else{
- ret += sprintf(buf + ret, "off\n");
- }
-
- return ret;
-}
-
-ssize_t modem_power_store(
- struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- int power;
-
- /* power the modem */
- if ( !strncmp(buf, "on", strlen("on"))) {
- power = 1;
- }else if(!strncmp(buf, "off", strlen("off"))){
- power = 0;
- }else{
- printk("%s: input %s is invalid.\n", __FUNCTION__, buf);
- return n;
- }
-
- printk("Warnning: Power %s modem\n", power ? "on" : "off");
- if(power){
-#if 0
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST)){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_RST, 1);
- mdelay(MDM_RST_HOLD_DELAY);
- }
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_EN)){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_PWR_EN, 0);
- mdelay(MDM_PWR_HOLD_DELAY);
- }
-
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_EN)){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_PWR_EN, 1);
- mdelay(MDM_PWR_HOLD_DELAY);
- }
-
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST)){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_RST, 0);
- mdelay(MDM_RST_HOLD_DELAY);
- }
-
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_EN)){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_PWR_EN, 0);
- }
-#endif
-
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_EN)){
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST)){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_RST, 0);
- mdelay(MDM_RST_HOLD_DELAY);
- }
- oem_gpio_direction_output(GPIO_VIATEL_MDM_PWR_EN, 1);
- mdelay(MDM_PWR_HOLD_DELAY);
- }
- }else{
- oem_power_off_modem();
- }
- return n;
-}
-
-ssize_t modem_reset_show(
- struct kobject *kobj, struct kobj_attribute *attr, char *buf)
-{
- int reset = 0;
- int ret = 0;
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST_IND)){
- reset = !!oem_gpio_get_value(GPIO_VIATEL_MDM_RST_IND);
- }else if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST)){
- reset = !!oem_gpio_get_value(GPIO_VIATEL_MDM_RST);
- }
-
- if(reset){
- ret += sprintf(buf + ret, "reset\n");
- }else{
- ret += sprintf(buf + ret, "work\n");
- }
-
- return ret;
-}
-
-ssize_t modem_reset_store(
- struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- /* reset the modem */
- if ( !strncmp(buf, "reset", strlen("reset"))) {
- wake_lock_timeout(&reset_lock, MDM_RST_LOCK_TIME * HZ);
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST)){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_RST, 1);
- mdelay(MDM_RST_HOLD_DELAY);
- oem_gpio_direction_output(GPIO_VIATEL_MDM_RST, 0);
- mdelay(MDM_RST_HOLD_DELAY);
- }
- printk("Warnning: reset modem\n");
- }
-
- return n;
-}
-
-ssize_t modem_ets_select_show(
- struct kobject *kobj, struct kobj_attribute *attr, char *buf)
-{
- int level = 0;
- int ret = 0;
-
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_ETS_SEL)){
- level = !!oem_gpio_get_value(GPIO_VIATEL_MDM_ETS_SEL);
- }
-
- ret += sprintf(buf, "%d\n", level);
- return ret;
-}
-
-ssize_t modem_ets_select_store(
- struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_ETS_SEL)){
- if ( !strncmp(buf, "1", strlen("1"))) {
- oem_gpio_direction_output(GPIO_VIATEL_MDM_ETS_SEL, 1);
- }else if( !strncmp(buf, "0", strlen("0"))){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_ETS_SEL, 0);
- }else{
- dbg("Unknow command.\n");
- }
- }
-
- return n;
-}
-
-ssize_t modem_boot_select_show(
- struct kobject *kobj, struct kobj_attribute *attr, char *buf)
-{
- int ret = 0;
- int level = 0;
-
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_BOOT_SEL)){
- level = !!oem_gpio_get_value(GPIO_VIATEL_MDM_BOOT_SEL);
- }
-
- ret += sprintf(buf, "%d\n", level);
- return ret;
-}
-
-ssize_t modem_boot_select_store(
- struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_BOOT_SEL)){
- if ( !strncmp(buf, "1", strlen("1"))) {
- oem_gpio_direction_output(GPIO_VIATEL_MDM_BOOT_SEL, 1);
- }else if( !strncmp(buf, "0", strlen("0"))){
- oem_gpio_direction_output(GPIO_VIATEL_MDM_BOOT_SEL, 0);
- }else{
- dbg("Unknow command.\n");
- }
- }
-
- return n;
-}
-
-#define modem_attr(_name) \
-static struct kobj_attribute _name##_attr = { \
- .attr = { \
- .name = __stringify(_name), \
- .mode = 0644, \
- }, \
- .show = modem_##_name##_show, \
- .store = modem_##_name##_store, \
-}
-
-modem_attr(power);
-modem_attr(reset);
-modem_attr(ets_select);
-modem_attr(boot_select);
-
-static struct attribute *g_attr[] = {
- &power_attr.attr,
- &reset_attr.attr,
- &ets_select_attr.attr,
- &boot_select_attr.attr,
- NULL
-};
-
-static struct attribute_group g_attr_group = {
- .attrs = g_attr,
-};
-
-
-static void modem_shutdown(struct platform_device *dev)
-{
- oem_power_off_modem();
-}
-
-static struct platform_driver power_driver = {
- .driver.name = "modem_power",
- .shutdown = modem_shutdown,
-};
-
-static struct platform_device power_device = {
- .name = "modem_power",
-};
-
-static struct kobject *modem_kobj;
-static int __init viatel_power_init(void)
-{
- int ret = 0;
-
- modem_kobj = viatel_kobject_add("modem");
- if(!modem_kobj){
- ret = -ENOMEM;
- goto err_create_kobj;
- }
-
- ret = platform_device_register(&power_device);
- if (ret) {
- printk("platform_device_register failed\n");
- goto err_platform_device_register;
- }
- ret = platform_driver_register(&power_driver);
- if (ret) {
- printk("platform_driver_register failed\n");
- goto err_platform_driver_register;
- }
-
- wake_lock_init(&reset_lock, WAKE_LOCK_SUSPEND, "cbp_rst");
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_IND)){
- oem_gpio_direction_input_for_irq(GPIO_VIATEL_MDM_PWR_IND);
- }
- if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST_IND)){
- oem_gpio_direction_input_for_irq(GPIO_VIATEL_MDM_RST_IND);
- }
-
- //oem_gpio_direction_output(GPIO_VIATEL_MDM_RST, 0);
- //oem_gpio_direction_output(GPIO_VIATEL_MDM_PWR_EN, 1);
- ret = sysfs_create_group(modem_kobj, &g_attr_group);
-
- if(ret){
- printk("sysfs_create_group failed\n");
- goto err_sysfs_create_group;
- }
-
- return 0;
-err_sysfs_create_group:
- platform_driver_unregister(&power_driver);
-err_platform_driver_register:
- platform_device_unregister(&power_device);
-err_platform_device_register:
-err_create_kobj:
- return ret;
-}
-
-static void __exit viatel_power_exit(void)
-{
- wake_lock_destroy(&reset_lock);
-}
-
-late_initcall_sync(viatel_power_init);
-module_exit(viatel_power_exit);
diff --git a/ANDROID_3.4.5/drivers/misc/viatel/sync.c b/ANDROID_3.4.5/drivers/misc/viatel/sync.c
deleted file mode 100755
index 08ddf8ba..00000000
--- a/ANDROID_3.4.5/drivers/misc/viatel/sync.c
+++ /dev/null
@@ -1,2445 +0,0 @@
-/*
- * viatel_cbp_sync.c
- *
- * VIA CBP driver for Linux
- *
- * Copyright (C) 2011 VIA TELECOM Corporation, Inc.
- * Author: VIA TELECOM Corporation, Inc.
- *
- * This package is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/time.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-#include <linux/sched.h>
-#include <linux/wakelock.h>
-#include <linux/delay.h>
-#include <linux/wait.h>
-#include <linux/platform_device.h>
-#include <mach/viatel.h>
-#include "core.h"
-
-//define in oem.c
-extern int isviatelcom;
-extern int ap_ready_always;
-
-static int asc_debug = 0;
-#define ASCDPRT(fmt, arg...) do{ \
- if(asc_debug) \
- printk("[ASC] " fmt, ##arg); \
- }while(0)
-#define ASCPRT(fmt, arg...) printk("[ASC] " fmt, ##arg)
-
-/*mS*/
-#define ASC_RX_WAIT_IDLE_TIME (1000)
-#define ASC_TX_WAIT_READY_TIME (1000)
-#define ASC_TX_WAIT_IDLE_TIME (2000)
-#define ASC_TX_AUTO_DELAY_TIME (2000)
-#define ASC_TX_WAIT_SLEEP_TIME (500)
-#define ASC_TX_TRY_TIMES (3)
-#define ASC_TX_DEBOUNCE_TIME (10)
-
-#define ASC_TX_SYSFS_USER "AscApp"
-#define ASC_TX_AUTO_USER "AscAuto"
-
-/* asc_list contains all registered struct struct asc_handle*/
-static DEFINE_SPINLOCK(hdlock);
-static LIST_HEAD(asc_tx_handle_list);
-static LIST_HEAD(asc_rx_handle_list);
-static struct workqueue_struct *asc_work_queue;
-static struct kobject *asc_kobj;
-
-typedef enum{
- ASC_TX_HD = 0,
- ASC_RX_HD
-}asc_handle_type;
-
-#define ASC_EVENT_POOL_MAX (60)
-typedef enum{
- ASC_EVENT_UNUSE = 0,
- ASC_EVENT_STATIC,
- ASC_EVENT_DYNAMIC
-}asc_event_type;
-
-struct asc_event{
- int id;
- struct list_head list;
- char usage;
-};
-
-static struct asc_event event_pool[ASC_EVENT_POOL_MAX];
-
-struct asc_user{
- struct asc_infor infor;
- atomic_t count;
- struct list_head node;
-};
-
-struct asc_state_dsp{
- char name[ASC_NAME_LEN];
- /*state callback handle for events*/
- int (*handle)(void * hd, int event);
-};
-
-/* TX STATUS and TX EVENT*/
-typedef enum{
- AP_TX_EVENT_REQUEST = 0, /*internal*/
- AP_TX_EVENT_CP_READY,
- AP_TX_EVENT_CP_UNREADY,
- AP_TX_EVENT_WAIT_TIMEOUT,
- AP_TX_EVENT_IDLE_TIMEOUT,
- AP_TX_EVENT_STOP,
- AP_TX_EVENT_RESET,
- AP_TX_EVENT_NUM
-} ap_tx_event;
-
-typedef enum{
- AP_TX_ST_SLEEP = 0,
- AP_TX_ST_WAIT_READY,
- AP_TX_ST_READY, /*wait All Tx channel finished*/
- AP_TX_ST_IDLE,
- AP_TX_ST_NUM
-} ap_tx_state;
-
-struct asc_tx_handle{
- struct asc_config cfg;
- atomic_t state;
- atomic_t count;
- struct list_head user_list;
- struct asc_state_dsp *table;
- /*process the event to switch different states*/
- struct task_struct *thread;
- int ntf;
- int wait_try;
- int auto_delay;
- spinlock_t slock;
- wait_queue_head_t wait;
- wait_queue_head_t wait_tx_state;
- struct mutex mlock;
- struct wake_lock wlock;
- struct timer_list timer_wait_ready;
- struct timer_list timer_wait_idle;
- struct timer_list timer_wait_sleep;
- struct work_struct ntf_work;
- struct list_head event_q;
- struct list_head node;
- struct kobject *kobj;
-};
-
-static int asc_tx_handle_sleep(void *, int );
-static int asc_tx_handle_wait_ready(void *, int );
-static int asc_tx_handle_ready(void *, int );
-static int asc_tx_handle_idle(void *, int );
-
-/*the table used to discribe all tx states*/
-static struct asc_state_dsp asc_tx_table[AP_TX_ST_NUM] = {
- [AP_TX_ST_SLEEP] = {
- .name = "AP_TX_ST_SLEEP",
- .handle = asc_tx_handle_sleep,
- },
- [AP_TX_ST_WAIT_READY] = {
- .name = "AP_TX_ST_WAIT_READY",
- .handle = asc_tx_handle_wait_ready,
- },
- [AP_TX_ST_READY] = {
- .name = "AP_TX_ST_READY",
- .handle = asc_tx_handle_ready,
- },
- [AP_TX_ST_IDLE] = {
- .name = "AP_TX_ST_IDLE",
- .handle = asc_tx_handle_idle,
- },
-};
-
-/* RX STATUS and RX EVENT*/
-typedef enum{
- AP_RX_EVENT_REQUEST = 0,
- AP_RX_EVENT_AP_READY,
- AP_RX_EVENT_AP_UNREADY,
- AP_RX_EVENT_STOP,
- AP_RX_EVENT_IDLE_TIMEOUT,
- AP_RX_EVENT_RESET,
- AP_RX_EVENT_NUM
-} ap_rx_event;
-
-typedef enum{
- AP_RX_ST_SLEEP = 0,
- AP_RX_ST_WAIT_READY,
- AP_RX_ST_READY,
- AP_RX_ST_IDLE,
- AP_RX_ST_NUM
-} ap_rx_state;
-
-struct asc_rx_handle{
- struct asc_config cfg;
- atomic_t state;
- struct list_head user_list;
- struct asc_state_dsp *table;
- int ntf;
- /*process the event to switch different states*/
- struct task_struct *thread;
- spinlock_t slock;
- wait_queue_head_t wait;
- struct mutex mlock;
- struct wake_lock wlock;
- struct timer_list timer;
- struct list_head event_q;
- struct list_head node;
- struct work_struct ntf_work;
-};
-
-static struct asc_config tx_cfg,rx_cfg;
-static int asc_rx_handle_sleep(void *, int );
-static int asc_rx_handle_wait_ready(void *, int );
-static int asc_rx_handle_ready(void *, int );
-static int asc_rx_handle_idle(void *, int );
-
-/*the table used to discribe all rx states*/
-static struct asc_state_dsp asc_rx_table[AP_RX_ST_NUM] = {
- [AP_RX_ST_SLEEP] = {
- .name = "AP_RX_ST_SLEEP",
- .handle = asc_rx_handle_sleep,
- },
- [AP_RX_ST_WAIT_READY] = {
- .name = "AP_RX_ST_WAIT_READY",
- .handle = asc_rx_handle_wait_ready,
- },
- [AP_RX_ST_READY] = {
- .name = "AP_RX_ST_READY",
- .handle = asc_rx_handle_ready,
- },
- [AP_RX_ST_IDLE] = {
- .name = "AP_RX_ST_IDLE",
- .handle = asc_rx_handle_idle,
- },
-};
-
-static int asc_tx_event_send(struct asc_tx_handle *tx, int id);
-static void asc_tx_handle_reset(struct asc_tx_handle *tx);
-static int asc_rx_event_send(struct asc_rx_handle *rx, int id);
-static void asc_rx_handle_reset(struct asc_rx_handle *rx);
-
-static struct asc_event * asc_event_malloc(void)
-{
- int i = 0;
- unsigned long flags = 0;
- struct asc_event *event = NULL;
-
- spin_lock_irqsave(&hdlock, flags);
- for(i = 0; i < ASC_EVENT_POOL_MAX; i++){
- if(ASC_EVENT_UNUSE == event_pool[i].usage){
- event = &(event_pool[i]);
- event->usage = ASC_EVENT_STATIC;
- }
- }
-
- if(NULL == event){
- event = kmalloc(sizeof(struct asc_event), GFP_ATOMIC);
- if(event){
- event->usage = ASC_EVENT_DYNAMIC;
- }
- }
- spin_unlock_irqrestore(&hdlock, flags);
- return event;
-}
-
-static void asc_event_free(struct asc_event * event)
-{
- unsigned long flags = 0;
-
- if(!event)
- return ;
- spin_lock_irqsave(&hdlock, flags);
- if(ASC_EVENT_STATIC == event->usage){
- memset(event, 0, sizeof(struct asc_event));
- }else{
- kfree(event);
- }
- spin_unlock_irqrestore(&hdlock, flags);
-}
-static irqreturn_t asc_irq_cp_indicate_state(int irq, void *data)
-{
- int level;
- struct asc_tx_handle *tx = (struct asc_tx_handle *)data;
- struct asc_config *cfg = &tx->cfg;
-
- if (!oem_gpio_irq_isenable(cfg->gpio_ready) ||
- !oem_gpio_irq_isint(cfg->gpio_ready)){
-
- return IRQ_NONE;
-
- }
- oem_gpio_irq_clear(cfg->gpio_ready);
- level = !!oem_gpio_get_value(cfg->gpio_ready);
- oem_gpio_set_irq_type(cfg->gpio_ready, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
- ASCDPRT("Irq %s cp_indicate_ap %s.\n", cfg->name, (level == cfg->polar)?"WAKEN":"SLEEP");
- if(level == cfg->polar){
- asc_tx_event_send(tx, AP_TX_EVENT_CP_READY);
- }else{
- /*do not care*/
- //asc_tx_event_send(tx, AP_TX_EVENT_CP_UNREADY);
- }
- oem_gpio_irq_unmask(cfg->gpio_ready);
- return IRQ_HANDLED;
-}
-
-
-
-static irqreturn_t asc_irq_cp_wake_ap(int irq, void *data)
-{
- int level;
- struct asc_rx_handle *rx = (struct asc_rx_handle *)data;
- struct asc_config *cfg = &rx->cfg;
-
- if(!cfg||cfg->gpio_wake<=0){
- return IRQ_NONE;
- }
-
- if (!oem_gpio_irq_isenable(cfg->gpio_wake) ||
- !oem_gpio_irq_isint(cfg->gpio_wake)){
- return IRQ_NONE;
- }
-
- oem_gpio_irq_clear(cfg->gpio_wake);
-
- level = !!oem_gpio_get_value(cfg->gpio_wake);
- oem_gpio_set_irq_type(cfg->gpio_wake, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
- ASCDPRT("Irq %s cp_wake_ap, requset ap to be %s.\n", cfg->name, (level == cfg->polar)?"WAKEN":"SLEEP");
-
- if(level == cfg->polar){
- /*Cp requset Ap wake*/
- wake_lock(&rx->wlock);
- /*FIXME: jump to ready as soon as possible to avoid the AP_READY error indication to CBP */
- if(AP_RX_ST_IDLE == atomic_read(&rx->state)){
- ASCDPRT("Rx(%s): process event(%d) in state(%s).\n", cfg->name, AP_RX_EVENT_REQUEST, rx->table[AP_RX_ST_IDLE].name);
- asc_rx_handle_idle(rx, AP_RX_EVENT_REQUEST);
- ASCDPRT("Rx(%s): go into state(%s).\n", cfg->name, rx->table[atomic_read(&rx->state)].name);
- }else{
- asc_rx_event_send(rx, AP_RX_EVENT_REQUEST);
- }
- }else{
- /*Cp allow Ap sleep*/
- asc_rx_event_send(rx, AP_RX_EVENT_STOP);
- }
-
- oem_gpio_irq_unmask(cfg->gpio_wake);
- return IRQ_HANDLED;
-}
-
-
-
-
-static struct asc_tx_handle *asc_tx_handle_lookup(const char *name)
-{
- unsigned long flags;
- struct asc_tx_handle *hd, *tmp, *t;
-
- if (!name)
- return NULL;
-
- hd = NULL;
-
- spin_lock_irqsave(&hdlock, flags);
- list_for_each_entry_safe(tmp, t, &asc_tx_handle_list, node) {
- if (!strncmp(name, tmp->cfg.name, ASC_NAME_LEN - 1)) {
- hd = tmp;
- break;
- }
- }
- spin_unlock_irqrestore(&hdlock, flags);
- return hd;
-}
-
-static struct asc_rx_handle *asc_rx_handle_lookup(const char *name)
-{
- unsigned long flags;
- struct asc_rx_handle *hd, *tmp, *t;
-
- if (!name)
- return NULL;
-
- hd = NULL;
- spin_lock_irqsave(&hdlock, flags);
- list_for_each_entry_safe(tmp, t, &asc_rx_handle_list, node) {
- if (!strncmp(name, tmp->cfg.name, ASC_NAME_LEN - 1)) {
- hd = tmp;
- break;
- }
- }
- spin_unlock_irqrestore(&hdlock, flags);
- return hd;
-}
-
-irqreturn_t viatelcom_irq_cp_wake_ap(int irq, void *data){
- struct asc_rx_handle *rx;
- if(!isviatelcom||ap_ready_always)
- return IRQ_HANDLED;
- rx = asc_rx_handle_lookup(USB_RX_HD_NAME);
- return asc_irq_cp_wake_ap(irq,rx);
-}
-
-static struct asc_user *asc_tx_user_lookup(struct asc_tx_handle *tx, const char *name)
-{
- unsigned long flags = 0;
- struct asc_user *user = NULL, *tmp = NULL, *t = NULL;
-
- if (!name)
- return NULL;
-
- spin_lock_irqsave(&tx->slock, flags);
- list_for_each_entry_safe(tmp, t, &tx->user_list, node) {
- if (!strncmp(name, tmp->infor.name, ASC_NAME_LEN - 1)) {
- user = tmp;
- break;
- }
- }
- spin_unlock_irqrestore(&tx->slock, flags);
-
- return user;
-}
-
-static struct asc_user *asc_rx_user_lookup(struct asc_rx_handle *rx, const char *name)
-{
- unsigned long flags = 0;
- struct asc_user *user = NULL, *tmp = NULL, *t = NULL;
-
- if (!name)
- return NULL;
-
- spin_lock_irqsave(&rx->slock, flags);
- list_for_each_entry_safe(tmp, t, &rx->user_list, node) {
- if (!strncmp(name, tmp->infor.name, ASC_NAME_LEN - 1)) {
- user = tmp;
- break;
- }
- }
- spin_unlock_irqrestore(&rx->slock, flags);
-
- return user;
-}
-
-static inline void asc_rx_indicate_wake(struct asc_rx_handle *rx)
-{
- if(rx->cfg.gpio_ready >= 0)
- oem_gpio_direction_output(rx->cfg.gpio_ready, rx->cfg.polar);
-}
-
-static inline void asc_rx_indicate_sleep(struct asc_rx_handle *rx)
-{
- if(rx->cfg.gpio_ready >= 0)
- oem_gpio_direction_output(rx->cfg.gpio_ready, !rx->cfg.polar);
-}
-
-static int asc_rx_event_send(struct asc_rx_handle *rx, int id)
-{
- unsigned long flags = 0;
- struct asc_event *event = NULL;
- int ret = -ENODEV;
-
- if(rx->thread == NULL){
- ASCPRT("%s:no thread for event\n", __FUNCTION__);
- return ret;
- }
-
- /*check whether the event is cared by current charge state*/
- if(id >= 0){
- event = asc_event_malloc();
- if(!event){
- ASCPRT("No memory to create new event.\n");
- ret = -ENOMEM;
- goto send_event_error;
- }
- /*insert a new event to the list tail and wakeup the process thread*/
- //ASCDPRT("Rx(%s):send event(%d) to state(%s).\n", rx->name, id, rx->table[atomic_read(&rx->state)].name);
- event->id = id;
- spin_lock_irqsave(&rx->slock, flags);
- if(AP_RX_EVENT_RESET == id){
- list_add(&event->list, &rx->event_q);
- }else{
- list_add_tail(&event->list, &rx->event_q);
- }
- spin_unlock_irqrestore(&rx->slock, flags);
- wake_up(&rx->wait);
- }
- ret = 0;
-send_event_error:
- return ret;
-}
-
-static int asc_rx_event_recv(struct asc_rx_handle *rx)
-{
- unsigned long flags = 0;
- struct asc_event *event = NULL;
- int ret = -ENODEV;
-
- if(rx->thread == NULL){
- ASCPRT("%s:no thread for event\n", __FUNCTION__);
- return ret;
- }
-
- spin_lock_irqsave(&rx->slock, flags);
- if(!list_empty(&rx->event_q)){
- event = list_first_entry(&rx->event_q, struct asc_event, list);
- list_del(&event->list);
- }
- spin_unlock_irqrestore(&rx->slock, flags);
-
- if(event){
- ret = event->id;
- asc_event_free(event);
- }
- return ret;
-}
-
-static int asc_rx_event_thread(void *data)
-{
- struct asc_rx_handle *rx = (struct asc_rx_handle *)data;
- int id = 0, index;
- char name[ASC_NAME_LEN] = {0};
- struct asc_state_dsp *dsp = NULL;
-
- rx->thread = current;
- snprintf(name, ASC_NAME_LEN, "asc_rx_%s", rx->cfg.name);
- daemonize(name);
- ASCDPRT("%s thread start now.\n", name);
-
- while(1){
- /*sleep until receive an evnet or thread exist*/
- wait_event(rx->wait, ((id=asc_rx_event_recv(rx)) >= 0) || (!rx->thread));
- /*thread is existed*/
- if(!rx->thread){
- break;
- }
-
- mutex_lock(&rx->mlock);
- if(AP_RX_EVENT_RESET == id){
- asc_rx_handle_reset(rx);
- }else{
- index = atomic_read(&rx->state);
- dsp = rx->table + index;
- if(dsp->handle){
- ASCDPRT("Rx(%s): process event(%d) in state(%s).\n", rx->cfg.name, id, dsp->name);
- dsp->handle(rx, id);
- ASCDPRT("Rx(%s): go into state(%s).\n", rx->cfg.name, rx->table[atomic_read(&rx->state)].name);
- }
- }
- mutex_unlock(&rx->mlock);
- }
-
- ASCDPRT("%s thread exit.\n", name);
- kfree(rx);
- return 0;
-}
-
-static void asc_rx_event_timer(unsigned long data)
-{
- struct asc_rx_handle *rx = (struct asc_rx_handle *)data;
- //ASCDPRT("%s timer is time out.\n", rx->name);
- asc_rx_event_send(rx, AP_RX_EVENT_IDLE_TIMEOUT);
-}
-
-static void asc_tx_notifier_work(struct work_struct *work)
-{
- struct asc_infor *infor;
- struct asc_user *user = NULL, *t = NULL;
- struct asc_tx_handle *tx = container_of(work, struct asc_tx_handle,
- ntf_work);
-
- list_for_each_entry_safe(user, t, &tx->user_list, node){
- infor = &user->infor;
- if(infor->notifier){
- infor->notifier(tx->ntf, infor->data);
- }
- }
-}
-
-static void asc_rx_notifier_work(struct work_struct *work)
-{
- struct asc_infor *infor;
- struct asc_user *user = NULL, *t = NULL;
- struct asc_rx_handle *rx = container_of(work, struct asc_rx_handle,
- ntf_work);
-
- list_for_each_entry_safe(user, t, &rx->user_list, node){
- infor = &user->infor;
- if(infor->notifier){
- infor->notifier(rx->ntf, infor->data);
- }
- }
-}
-
-static void asc_tx_notifier(struct asc_tx_handle *tx, int ntf)
-{
- tx->ntf = ntf;
- queue_work(asc_work_queue, &tx->ntf_work);
-}
-
-static void asc_rx_notifier(struct asc_rx_handle *rx, int ntf)
-{
- rx->ntf = ntf;
- queue_work(asc_work_queue, &rx->ntf_work);
-}
-
-static int asc_rx_handle_init(struct asc_rx_handle *rx)
-{
- int ret = 0;
- char *name = NULL;
- struct asc_config *cfg = &rx->cfg;
-
- if(cfg->gpio_ready >= 0){
- ret = oem_gpio_request(cfg->gpio_ready, "ap_ready");
- if(ret < 0){
- ASCPRT("Fail to requset ap_ready gpio %d for %s.\n", cfg->gpio_ready, cfg->name);
- goto err_request_gpio_ap_ready;
- }
- if(ap_ready_always)
- oem_gpio_output(cfg->gpio_ready, cfg->polar);
- else
- asc_rx_indicate_sleep(rx);
- }
-
- if(cfg->gpio_wake >= 0){
- ret = oem_gpio_request(cfg->gpio_wake, "cp_wake_ap");
- if(ret < 0){
- ASCPRT("Fail to requset cp_wake_ap gpio %d for %s.\n", cfg->gpio_wake, cfg->name);
- goto err_request_gpio_cp_wake_ap;
- }
-
- oem_gpio_irq_mask(cfg->gpio_wake);
- oem_gpio_direction_input_for_irq(cfg->gpio_wake);
- oem_gpio_set_irq_type(cfg->gpio_wake, IRQF_TRIGGER_RISING);
- ret = oem_gpio_request_irq(cfg->gpio_wake, asc_irq_cp_wake_ap, IRQF_SHARED | IRQF_NO_SUSPEND, "cp_wake_ap", rx);
- printk("asc_rx_handle_init call oem_gpio_irq_unmask %d\n",cfg->gpio_wake);
- oem_gpio_irq_unmask(cfg->gpio_wake);
- if (ret < 0) {
- ASCPRT("fail to request cp_wake_ap irq for %s\n", cfg->name);
- goto err_req_irq_cp_wake_ap;
- }
- }
-
- rx->table = asc_rx_table;
- mutex_init(&rx->mlock);
- INIT_LIST_HEAD(&rx->event_q);
- INIT_LIST_HEAD(&rx->user_list);
- spin_lock_init(&rx->slock);
- setup_timer(&rx->timer, asc_rx_event_timer, (unsigned long)rx);
- name = kzalloc(ASC_NAME_LEN, GFP_KERNEL);
- if(!name){
- ret = -ENOMEM;
- ASCPRT("%s: no memory to malloc for wake lock name\n", __FUNCTION__);
- goto err_malloc_name;
- }
- snprintf(name, ASC_NAME_LEN, "asc_rx_%s", rx->cfg.name);
- wake_lock_init(&rx->wlock, WAKE_LOCK_SUSPEND, name);
- init_waitqueue_head(&rx->wait);
- INIT_WORK(&rx->ntf_work, asc_rx_notifier_work);
- if(ap_ready_always)
- atomic_set(&rx->state, AP_RX_ST_READY);
- else
- atomic_set(&rx->state, AP_RX_ST_SLEEP);
- ret = kernel_thread(asc_rx_event_thread, rx, 0);
- if(ret < 0){
- ASCPRT("Fail to create %s rx thread.\n", rx->cfg.name);
- goto err_create_rx_thread;
- }
-
- if(!!oem_gpio_get_value(cfg->gpio_wake) == cfg->polar){
- asc_rx_event_send(rx, AP_RX_EVENT_REQUEST);
- }
-
- return 0;
-
-err_create_rx_thread:
- if(name)
- kfree(name);
-err_malloc_name:
- if(cfg->gpio_wake >= 0)
- free_irq(oem_gpio_to_irq(cfg->gpio_wake), rx);
-err_req_irq_cp_wake_ap:
- if(cfg->gpio_wake)
- oem_gpio_free(cfg->gpio_wake);
-err_request_gpio_cp_wake_ap:
- if(cfg->gpio_ready >= 0)
- oem_gpio_free(cfg->gpio_ready);
-err_request_gpio_ap_ready:
- return ret;
-}
-
-static int asc_rx_handle_sleep(void *data, int event)
-{
- int ret = 0;
- struct asc_rx_handle *rx = (struct asc_rx_handle *)data;
-
- //ASCDPRT("Rx(%s): process event(%d) in state(%s).\n", rx->name, event, rx->table[atomic_read(&rx->state)].name);
-
- if(AP_RX_ST_SLEEP != atomic_read(&rx->state)){
- return 0;
- }
-
- switch(event){
- case AP_RX_EVENT_REQUEST:
- wake_lock(&rx->wlock);
- atomic_set(&rx->state, AP_RX_ST_WAIT_READY);
- asc_rx_notifier(rx, ASC_NTF_RX_PREPARE);
- break;
- default:
- ASCDPRT("ignore the rx event %d in state(%s)", event, rx->table[atomic_read(&rx->state)].name);
- }
-
- //ASCDPRT("Rx(%s): go into state(%s).\n", rx->name, rx->table[atomic_read(&rx->state)].name);
- return ret;
-}
-
-static int asc_rx_handle_wait_ready(void *data, int event)
-{
- int ret = 0;
- struct asc_rx_handle *rx = (struct asc_rx_handle *)data;
-
- //ASCDPRT("Rx(%s): process event(%d) in state(%s).\n", rx->name, event, rx->table[atomic_read(&rx->state)].name);
-
- if(AP_RX_ST_WAIT_READY != atomic_read(&rx->state)){
- return 0;
- }
-
- switch(event){
- case AP_RX_EVENT_AP_READY:
- /*need ack ready to cp, do nothing if no gpio for ap_ready*/
- asc_rx_indicate_wake(rx);
- atomic_set(&rx->state, AP_RX_ST_READY);
- break;
- case AP_RX_EVENT_AP_UNREADY:
- case AP_RX_EVENT_STOP:
- atomic_set(&rx->state, AP_RX_ST_SLEEP);
- asc_rx_notifier(rx, ASC_NTF_RX_POST);
- /*need ack ready to cp, do nothing if no gpio for ap_ready*/
- asc_rx_indicate_sleep(rx);
- wake_unlock(&rx->wlock);
- break;
- default:
- ASCDPRT("ignore the rx event %d in state(%s)", event, rx->table[atomic_read(&rx->state)].name);
- }
-
- //ASCDPRT("Rx(%s): go into state(%s).\n", rx->name, rx->table[atomic_read(&rx->state)].name);
- return ret;
-}
-
-static int asc_rx_handle_ready(void *data, int event)
-{
- int ret = 0;
- struct asc_rx_handle *rx = (struct asc_rx_handle *)data;
-
- //ASCDPRT("Rx(%s): process event(%d) in state(%s).\n", rx->name, event, rx->table[atomic_read(&rx->state)].name);
-
- if(AP_RX_ST_READY != atomic_read(&rx->state)){
- return 0;
- }
-
- switch(event){
- case AP_RX_EVENT_STOP:
- atomic_set(&rx->state, AP_RX_ST_IDLE);
- mod_timer(&rx->timer, jiffies + msecs_to_jiffies(ASC_RX_WAIT_IDLE_TIME));
- break;
- default:
- ASCDPRT("ignore the rx event %d in state(%s)", event, rx->table[atomic_read(&rx->state)].name);
- }
-
- //ASCDPRT("Rx(%s): go into state(%s).\n", rx->name, rx->table[atomic_read(&rx->state)].name);
- return ret;
-}
-
-static int asc_rx_handle_idle(void *data, int event)
-{
- int ret = 0;
- unsigned long flags = 0;
- struct asc_rx_handle *rx = (struct asc_rx_handle *)data;
-
- //ASCDPRT("Rx(%s): process event(%d) in state(%s).\n", rx->name, event, rx->table[atomic_read(&rx->state)].name);
-
- if(AP_RX_ST_IDLE != atomic_read(&rx->state)){
- return 0;
- }
-
- /*FIXME: prevent from scheduled and interrupted to avoid error indication to CBP*/
- spin_lock_irqsave(&rx->slock, flags);
-
- switch(event){
- case AP_RX_EVENT_REQUEST:
- del_timer(&rx->timer);
- atomic_set(&rx->state, AP_RX_ST_READY);
- break;
-
- case AP_RX_EVENT_IDLE_TIMEOUT:
- asc_rx_notifier(rx, ASC_NTF_RX_POST);
- atomic_set(&rx->state, AP_RX_ST_SLEEP);
- /*need ack ready to cp, do nothing if no gpio for ap_ready*/
- asc_rx_indicate_sleep(rx);
- wake_unlock(&rx->wlock);
- break;
-
- default:
- ASCDPRT("ignore the rx event %d in state(%s)", event, rx->table[atomic_read(&rx->state)].name);
- }
-
- spin_unlock_irqrestore(&rx->slock, flags);
-
- //ASCDPRT("Rx(%s): go into state(%s).\n", rx->name, rx->table[atomic_read(&rx->state)].name);
- return ret;
-}
-
-static void asc_tx_trig_busy(struct asc_tx_handle *tx)
-{
- mod_timer(&tx->timer_wait_idle, jiffies + msecs_to_jiffies(tx->auto_delay));
-}
-
-static inline void asc_tx_wake_cp(struct asc_tx_handle *tx)
-{
- if(tx->cfg.gpio_wake >= 0)
- oem_gpio_direction_output(tx->cfg.gpio_wake, tx->cfg.polar);
-}
-
-static inline void asc_tx_sleep_cp(struct asc_tx_handle *tx)
-{
- if(tx->cfg.gpio_wake >= 0)
- oem_gpio_direction_output(tx->cfg.gpio_wake, !tx->cfg.polar);
-}
-
-static inline int asc_tx_cp_be_ready(struct asc_tx_handle *tx)
-{
- int ret = 0;
-
- if(tx->cfg.gpio_ready >= 0)
- ret = ((!!oem_gpio_get_value(tx->cfg.gpio_ready)) == (tx->cfg.polar));
-
- return ret;
-}
-
-
-static int asc_tx_event_send(struct asc_tx_handle *tx, int id)
-{
- unsigned long flags = 0;
- struct asc_event *event = NULL;
- int ret = -ENODEV;
-
- if(tx->thread == NULL){
- ASCPRT("%s:no thread for event\n", __FUNCTION__);
- return ret;
- }
-
- /*check whether the event is cared by current charge state*/
- if(id >= 0){
- event = asc_event_malloc();
- if(!event){
- ASCPRT("No memory to create new event.\n");
- ret = -ENOMEM;
- goto send_event_error;
- }
- /*insert a new event to the list tail and wakeup the process thread*/
- //ASCDPRT("Send tx event(%d) to state(%s).\n", id, tx->table[atomic_read(&tx->state)].name);
- event->id = id;
- spin_lock_irqsave(&tx->slock, flags);
- if(AP_TX_EVENT_RESET == id){
- list_add(&event->list, &tx->event_q);
- }else{
- list_add_tail(&event->list, &tx->event_q);
- }
- spin_unlock_irqrestore(&tx->slock, flags);
- wake_up(&tx->wait);
- }
-send_event_error:
- return ret;
-}
-
-static int asc_tx_event_recv(struct asc_tx_handle *tx)
-{
- unsigned long flags = 0;
- struct asc_event *event = NULL;
- int ret = -ENODEV;
-
- if(tx->thread == NULL){
- ASCPRT("%s:no thread for event\n", __FUNCTION__);
- return ret;
- }
-
- spin_lock_irqsave(&tx->slock, flags);
- if(!list_empty(&tx->event_q)){
- event = list_first_entry(&tx->event_q, struct asc_event, list);
- list_del(&event->list);
- }
- spin_unlock_irqrestore(&tx->slock, flags);
-
- if(event){
- ret = event->id;
- asc_event_free(event);
- }
- return ret;
-}
-
-static int asc_tx_get_user(struct asc_tx_handle *tx, const char *name)
-{
- int ret = 0;
- struct asc_user *user = NULL;
-
- user = asc_tx_user_lookup(tx, name);
- if(user){
- atomic_inc(&user->count);
- }else{
- ret = -ENODEV;
- }
-
- return ret;
-}
-static int asc_tx_put_user(struct asc_tx_handle *tx, const char *name)
-{
- struct asc_user *user = NULL;
- int ret = 0;
-
- user = asc_tx_user_lookup(tx, name);
-
- if(user){
- if(atomic_read(&user->count) >= 1){
- atomic_dec(&user->count);
- }
- }else{
- ret = -ENODEV;
- }
-
- return ret;
-}
-
-static int asc_tx_refer(struct asc_tx_handle *tx, const char *name)
-{
- unsigned long flags = 0;
- struct asc_user *user = NULL, *t = NULL;
- int count = 0;
-
- if(name){
- /*get the reference count of the user*/
- user = asc_tx_user_lookup(tx, name);
- if(user){
- count = atomic_read(&user->count);
- }
- }else{
- spin_lock_irqsave(&tx->slock, flags);
- list_for_each_entry_safe(user, t, &tx->user_list, node) {
- count += atomic_read(&user->count);
- }
- spin_unlock_irqrestore(&tx->slock, flags);
- }
-
- return count;
-}
-
-static int asc_rx_refer(struct asc_rx_handle *rx, const char *name)
-{
- unsigned long flags = 0;
- struct asc_user *user = NULL, *t = NULL;
- int count = 0;
-
- if(name){
- /*get the reference count of the user*/
- user = asc_rx_user_lookup(rx, name);
- if(user){
- count = atomic_read(&user->count);
- }
- }else{
- spin_lock_irqsave(&rx->slock, flags);
- list_for_each_entry_safe(user, t, &rx->user_list, node) {
- count += atomic_read(&user->count);
- }
- spin_unlock_irqrestore(&rx->slock, flags);
- }
-
- return count;
-}
-
-static void asc_tx_refer_clear(struct asc_tx_handle *tx)
-{
- unsigned long flags = 0;
- struct asc_user *user = NULL, *t = NULL;
-
- spin_lock_irqsave(&tx->slock, flags);
- list_for_each_entry_safe(user, t, &tx->user_list, node) {
- atomic_set(&user->count, 0);
- }
- spin_unlock_irqrestore(&tx->slock, flags);
-}
-
-static int asc_tx_event_thread(void *data)
-{
- struct asc_tx_handle *tx = (struct asc_tx_handle *)data;
- int id = 0, index;
- char name[ASC_NAME_LEN] = {0};
- struct asc_state_dsp *dsp = NULL;
-
- snprintf(name, ASC_NAME_LEN, "asc_tx_%s", tx->cfg.name);
- tx->thread = current;
- daemonize(name);
- ASCDPRT("%s thread start now.\n", name);
-
- while(1){
- /*sleep until receive an evnet or thread exist*/
- wait_event(tx->wait, ((id=asc_tx_event_recv(tx)) >= 0) || (!tx->thread) );
- /*thread is existed*/
- if(!tx->thread){
- break;
- }
-
- mutex_lock(&tx->mlock);
- if(AP_TX_EVENT_RESET == id){
- asc_tx_handle_reset(tx);
- }else{
- index = atomic_read(&tx->state);
- dsp = tx->table + index;
- if(dsp->handle){
- ASCDPRT("Tx(%s): process event(%d) in state(%s).\n", tx->cfg.name, id, dsp->name);
- dsp->handle(tx, id);
- ASCDPRT("Tx(%s): go into state(%s) .\n", tx->cfg.name, tx->table[atomic_read(&tx->state)].name);
- }
- }
- mutex_unlock(&tx->mlock);
- }
-
- ASCDPRT("%s thread exit.\n", name);
- kfree(tx);
- return 0;
-}
-
-static void asc_tx_wait_ready_timer(unsigned long data)
-{
- struct asc_tx_handle *tx = (struct asc_tx_handle *)data;
- //ASCDPRT("%s tx wait ready timer is timeout.\n", tx->name);
- asc_tx_event_send(tx, AP_TX_EVENT_WAIT_TIMEOUT);
-}
-
-static void asc_tx_wait_idle_timer(unsigned long data)
-{
- char path[ASC_NAME_LEN] = {0};
- struct asc_tx_handle *tx = (struct asc_tx_handle *)data;
- //ASCDPRT("%s tx wait idle timer is timeout.\n", tx->name);
- snprintf(path, ASC_NAME_LEN, "%s.%s", tx->cfg.name, ASC_TX_AUTO_USER);
- asc_tx_put_ready(path, 0);
-}
-
-static void asc_tx_wait_sleep_timer(unsigned long data)
-{
- struct asc_tx_handle *tx = (struct asc_tx_handle *)data;
- //ASCDPRT("%s tx wait sleep timer is timeout.\n", tx->name);
- asc_tx_event_send(tx, AP_TX_EVENT_IDLE_TIMEOUT);
-}
-
-static int asc_tx_handle_init(struct asc_tx_handle *tx)
-{
- int ret = 0;
- char *name = NULL;
- struct asc_config *cfg = &tx->cfg;
-
- ret = oem_gpio_request(cfg->gpio_wake, "ap_wake_cp");
- if(ret < 0){
- ASCPRT("Fail to requset ap_wake_cp gpio %d for %s.\n", cfg->gpio_wake, cfg->name);
- goto err_request_gpio_ap_wake_cp;
- }
-
- if(cfg->gpio_ready >= 0){
- ret = oem_gpio_request(cfg->gpio_ready, "cp_ready");
- if(ret < 0){
- ASCPRT("Fail to requset cp_ready gpio %d for %s.\n", cfg->gpio_ready, cfg->name);
- goto err_request_gpio_cp_ready;
- }
-
- oem_gpio_irq_mask(cfg->gpio_ready);
- oem_gpio_direction_input_for_irq(cfg->gpio_ready);
- oem_gpio_set_irq_type(cfg->gpio_ready, IRQF_TRIGGER_RISING);
- ret = oem_gpio_request_irq(cfg->gpio_ready, asc_irq_cp_indicate_state,
- IRQF_SHARED, "cp_indicate_state", tx);
- oem_gpio_irq_unmask(cfg->gpio_ready);
- if (ret < 0) {
- ASCPRT("fail to request irq for %s:cp_ready\n", cfg->name);
- goto err_req_irq_cp_indicate_state;
- }
- }
- asc_tx_sleep_cp(tx);
-
- tx->auto_delay = ASC_TX_AUTO_DELAY_TIME;
- tx->table = asc_tx_table;
- mutex_init(&tx->mlock);
- INIT_LIST_HEAD(&tx->event_q);
- INIT_LIST_HEAD(&tx->user_list);
- spin_lock_init(&tx->slock);
- name = kzalloc(ASC_NAME_LEN, GFP_KERNEL);
- if(!name){
- ret = -ENOMEM;
- ASCPRT("%s: no memory to malloc for wake lock name\n", __FUNCTION__);
- goto err_malloc_name;
- }
- snprintf(name, ASC_NAME_LEN, "asc_tx_%s", tx->cfg.name);
- wake_lock_init(&tx->wlock, WAKE_LOCK_SUSPEND, name);
- init_waitqueue_head(&tx->wait);
- init_waitqueue_head(&tx->wait_tx_state);
- setup_timer(&tx->timer_wait_ready, asc_tx_wait_ready_timer, (unsigned long)tx);
- setup_timer(&tx->timer_wait_idle, asc_tx_wait_idle_timer, (unsigned long)tx);
- setup_timer(&tx->timer_wait_sleep, asc_tx_wait_sleep_timer, (unsigned long)tx);
- atomic_set(&tx->state, AP_TX_ST_SLEEP);
- atomic_set(&tx->count, 0);
- INIT_WORK(&tx->ntf_work, asc_tx_notifier_work);
- ret = kernel_thread(asc_tx_event_thread, tx, 0);
- if(ret < 0){
- ASCPRT("Fail to create %s tx thread.\n", tx->cfg.name);
- goto err_create_tx_event_thread;
- }
-
- return 0;
-err_create_tx_event_thread:
- if(cfg->gpio_ready >= 0)
- free_irq(oem_gpio_to_irq(cfg->gpio_ready), tx);
-err_malloc_name:
- if(name)
- kfree(name);
-err_req_irq_cp_indicate_state:
- if(cfg->gpio_ready >= 0)
- oem_gpio_free(cfg->gpio_ready);
-err_request_gpio_cp_ready:
- if(cfg->gpio_wake >= 0)
- oem_gpio_free(cfg->gpio_wake);
-err_request_gpio_ap_wake_cp:
- return ret;
-}
-
-static int asc_tx_handle_sleep(void *data, int event)
-{
- int ret = 0;
- struct asc_tx_handle *tx = (struct asc_tx_handle *)data;
-
- //ASCDPRT("Tx(%s): process event(%d) in state(%s).\n", tx->name, event, tx->table[atomic_read(&tx->state)].name);
-
- if(AP_TX_ST_SLEEP != atomic_read(&tx->state)){
- return 0;
- }
-
- switch(event){
- case AP_TX_EVENT_REQUEST:
- wake_lock(&tx->wlock);
- asc_tx_wake_cp(tx);
- if(tx->cfg.gpio_ready >= 0){
- mod_timer(&tx->timer_wait_ready, jiffies + msecs_to_jiffies(ASC_TX_WAIT_READY_TIME));
- atomic_set(&tx->state, AP_TX_ST_WAIT_READY);
- if(asc_tx_cp_be_ready(tx)){
- mdelay(ASC_TX_DEBOUNCE_TIME);//debounce wait, make sure CBP has already be ready
- if(asc_tx_cp_be_ready(tx)){
- ASCDPRT("Tx:cp %s was ready now.\n", tx->cfg.name);
- asc_tx_handle_wait_ready(tx, AP_TX_EVENT_CP_READY);
- }
- }
- }else{
- mdelay(ASC_TX_DEBOUNCE_TIME);
- atomic_set(&tx->state, AP_TX_ST_WAIT_READY);
- asc_tx_handle_wait_ready(tx, AP_TX_EVENT_CP_READY);
- }
- break;
- default:
- ASCDPRT("Tx: ignore event %d in state(%s)", event, tx->table[atomic_read(&tx->state)].name);
- }
-
- //ASCDPRT("Tx(%s): go into state(%s).\n", tx->name, tx->table[atomic_read(&tx->state)].name);
- return ret;
-}
-
-static int asc_tx_handle_wait_ready(void *data, int event)
-{
- int ret = 0;
- struct asc_tx_handle *tx = (struct asc_tx_handle *)data;
-
- if(AP_TX_ST_WAIT_READY != atomic_read(&tx->state)){
- return 0;
- }
- //ASCDPRT("Tx(%s): process event(%d) in state(%s).\n", tx->name, event, tx->table[atomic_read(&tx->state)].name);
- switch(event){
- case AP_TX_EVENT_CP_READY:
- del_timer(&tx->timer_wait_ready);
- tx->wait_try = 0;
- atomic_set(&tx->state, AP_TX_ST_READY);
- wake_up_interruptible_all(&tx->wait_tx_state);
- if(asc_tx_refer(tx, ASC_TX_AUTO_USER) > 0){
- asc_tx_trig_busy(tx);
- }
- asc_tx_notifier(tx, ASC_NTF_TX_READY);
- break;
- case AP_TX_EVENT_WAIT_TIMEOUT:
- ASCPRT("Tx: %s wait cp ready timeout, try=%d.\n", tx->cfg.name, tx->wait_try);
-
- {
- //kevin add .i dont know who disable irq after resume,so i reeanble it
- oem_gpio_direction_input_for_irq(GPIO_VIATEL_USB_MDM_RDY);
- oem_gpio_set_irq_type(GPIO_VIATEL_USB_MDM_RDY,(IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING));
- oem_gpio_irq_unmask(GPIO_VIATEL_USB_MDM_RDY);
-
- }
-
- asc_tx_sleep_cp(tx);
- mdelay(ASC_TX_DEBOUNCE_TIME);//delay to create a implus
- atomic_set(&tx->state, AP_TX_ST_SLEEP);
- if(tx->wait_try++ <= ASC_TX_TRY_TIMES){
- asc_tx_event_send(tx, AP_TX_EVENT_REQUEST);
- }else{
- tx->wait_try = 0;
- atomic_set(&tx->state, AP_TX_ST_SLEEP);
- asc_tx_refer_clear(tx);
- wake_up_interruptible_all(&tx->wait_tx_state);
- wake_unlock(&tx->wlock);
- asc_tx_notifier(tx, ASC_NTF_TX_UNREADY);
- ASCPRT("try out to wake %s.\n", tx->cfg.name);
- }
- break;
- case AP_TX_EVENT_STOP:
- asc_tx_sleep_cp(tx);
- del_timer(&tx->timer_wait_ready);
- tx->wait_try = 0;
- atomic_set(&tx->state, AP_TX_ST_SLEEP);
- wake_unlock(&tx->wlock);
- wake_up_interruptible_all(&tx->wait_tx_state);
- break;
- default:
- ASCDPRT("Tx: ignore event %d in state(%s)", event, tx->table[atomic_read(&tx->state)].name);
- }
-
- //ASCDPRT("Tx(%s): go into state(%s).\n", tx->name, tx->table[atomic_read(&tx->state)].name);
- return ret;
-}
-
-static int asc_tx_handle_ready(void *data, int event)
-{
- int ret = 0;
- struct asc_tx_handle *tx = (struct asc_tx_handle *)data;
-
- if(AP_TX_ST_READY != atomic_read(&tx->state)){
- return 0;
- }
- //ASCDPRT("Tx(%s): process event(%d) in state(%s).\n", tx->name, event, tx->table[atomic_read(&tx->state)].name);
- switch(event){
- case AP_TX_EVENT_STOP:
- del_timer(&tx->timer_wait_idle);
- asc_tx_sleep_cp(tx);
- atomic_set(&tx->state, AP_TX_ST_SLEEP);
- wake_unlock(&tx->wlock);
- //mod_timer(&tx->timer_wait_sleep, jiffies + msecs_to_jiffies(ASC_TX_WAIT_IDLE_TIME));
- break;
- default:
- ASCDPRT("Tx: ignore event %d in state(%s)", event, tx->table[atomic_read(&tx->state)].name);
- }
-
- //ASCDPRT("Tx(%s): go into state(%s).\n", tx->name, tx->table[atomic_read(&tx->state)].name);
- return ret;
-}
-
-/*Ignore the idle state, wait for a while to let CBP go to sleep*/
-static int asc_tx_handle_idle(void *data, int event)
-{
- int ret = 0;
- struct asc_tx_handle *tx = (struct asc_tx_handle *)data;
-
- if(AP_TX_ST_IDLE != atomic_read(&tx->state)){
- return 0;
- }
-
- //ASCDPRT("Tx(%s): process event(%d) in state(%s).\n", tx->name, event, tx->table[atomic_read(&tx->state)].name);
- switch(event){
- case AP_TX_EVENT_IDLE_TIMEOUT:
- atomic_set(&tx->state, AP_TX_ST_SLEEP);
- wake_unlock(&tx->wlock);
- break;
- case AP_TX_EVENT_REQUEST:
- del_timer(&tx->timer_wait_sleep);
- atomic_set(&tx->state, AP_TX_ST_SLEEP);
- /*loop back to SLEEP handle*/
- asc_tx_event_send(tx, AP_TX_EVENT_REQUEST);
- break;
- default:
- ASCDPRT("Tx: ignore event %d in state(%s)", event, tx->table[atomic_read(&tx->state)].name);
- }
-
- //ASCDPRT("Tx(%s): go into state(%s).\n", tx->name, tx->table[atomic_read(&tx->state)].name);
- return ret;
-}
-
-static void asc_tx_handle_reset(struct asc_tx_handle *tx)
-{
- unsigned long flags;
-
- ASCDPRT("%s %s\n", __FUNCTION__, tx->cfg.name);
- del_timer(&tx->timer_wait_ready);
- del_timer(&tx->timer_wait_idle);
- del_timer(&tx->timer_wait_sleep);
- spin_lock_irqsave(&tx->slock, flags);
- INIT_LIST_HEAD(&tx->event_q);
- spin_unlock_irqrestore(&tx->slock, flags);
- asc_tx_sleep_cp(tx);
- atomic_set(&tx->state, AP_TX_ST_SLEEP);
- wake_unlock(&tx->wlock);
-}
-
-/**
- * asc_tx_reset - reset the tx handle
- * @name: the config name for the handle
- *
- * return 0 ok, others be error
- */
-void asc_tx_reset(const char *name)
-{
- struct asc_tx_handle *tx = NULL;
-
- tx = asc_tx_handle_lookup(name);
- if(tx){
- asc_tx_event_send(tx, AP_TX_EVENT_RESET);
- }
-}
-EXPORT_SYMBOL(asc_tx_reset);
-
-/**
- * asc_tx_set_auto_delay - change the delay time for auto ready
- * @name: the config name for the handle
- * @delay: the time for auto ready which is valid while more than default value
- * return 0 ok,others be error
- */
-int asc_tx_set_auto_delay(const char *name, int delay)
-{
- int ret = 0;
- unsigned long flags;
- struct asc_tx_handle *tx;
-
- tx = asc_tx_handle_lookup(name);
- if(!tx){
- ret = -ENODEV;
- goto end;
- }
- if(delay > 0){
- spin_lock_irqsave(&tx->slock, flags);
- tx->auto_delay = delay;
- spin_unlock_irqrestore(&tx->slock, flags);
- }
-
-end:
- return ret;
-}
-EXPORT_SYMBOL(asc_tx_set_auto_delay);
-
-/**
- * asc_tx_check_ready - check whether tx tanslation has alreay be ready
- * @name: the config name for the handle
- *
- * return 1 waken, 0 not, others be error
- */
-int asc_tx_check_ready(const char *name)
-{
- int ret = 0;
- struct asc_tx_handle *tx;
-
- tx = asc_tx_handle_lookup(name);
- if(NULL == tx)
- return -ENODEV;
-
- ret = atomic_read(&tx->state);
-
- if(ret == AP_TX_ST_READY){
- ret = 1;
- }else{
- ret = 0;
- }
-
- return ret;
-}
-EXPORT_SYMBOL(asc_tx_check_ready);
-
-/**
- * asc_tx_user_counts - get the refernce count of the user or the handle
- * @path: (handle name).[user name]
- * If user name is NULL, return the count of tx handle.
- * others return the count of the tx user
- */
-int asc_tx_user_count(const char *path)
-{
- const char *name;
- char hname[ASC_NAME_LEN] = {0};
- struct asc_tx_handle *tx = NULL;
-
- name = strchr(path, '.');
- if (name){
- memcpy(hname, path, min(name - path, ASC_NAME_LEN - 1));
- name++;
- }else {
- strncpy(hname, path, ASC_NAME_LEN - 1);
- }
-
- tx = asc_tx_handle_lookup(hname);
-
- if(NULL == tx)
- return -ENODEV;
-
- return asc_tx_refer(tx, name);
-}
-EXPORT_SYMBOL(asc_tx_user_count);
-
-/**
- * asc_tx_add_user - add a user for tx handle
- * @name: the config name for the handle
- * @infor: the user information
- *
- * return 0, others be error
- */
-int asc_tx_add_user(const char *name, struct asc_infor *infor)
-{
- int ret = 0;
- unsigned long flags = 0;
- struct asc_tx_handle *tx;
- struct asc_user *user;
-
- tx = asc_tx_handle_lookup(name);
- if(NULL == tx)
- return -ENODEV;
-
- user = asc_tx_user_lookup(tx, infor->name);
- if(NULL == user){
- user = kzalloc(sizeof(*user), GFP_KERNEL);
- if(!user){
- ASCPRT("No memory to create new user reference.\n");
- ret = -ENOMEM;
- goto error;
- }
- user->infor.data = infor->data;
- user->infor.notifier = infor->notifier;
- strncpy(user->infor.name, infor->name, ASC_NAME_LEN - 1);
- atomic_set(&user->count, 0);
- spin_lock_irqsave(&tx->slock, flags);
- list_add_tail(&user->node, &tx->user_list);
- spin_unlock_irqrestore(&tx->slock, flags);
- }else{
- ASCPRT("%s error: user %s already exist!!\n", __FUNCTION__, infor->name);
- ret = -EINVAL;
- }
-error:
- return ret;
-}
-EXPORT_SYMBOL(asc_tx_add_user);
-
-/**
- * asc_tx_del_user - delete a user for tx handle
- * @path: (handle name).(user name)
- *
- * no return
- */
-void asc_tx_del_user(const char *path)
-{
- unsigned long flags = 0;
- char hname[ASC_NAME_LEN] = {0};
- const char *name;
- struct asc_user *user = NULL;
- struct asc_tx_handle *tx = NULL;
-
- name = strchr(path, '.');
- if (name) {
- memcpy(hname, path, min(name - path, ASC_NAME_LEN - 1));
- name++;
- }else{
- ASCPRT("%s: invalid path %s\n", __FUNCTION__, path);
- return ;
- }
-
- /*if reserve user, do nothing*/
- if (!strncmp(name, ASC_TX_SYSFS_USER, ASC_NAME_LEN - 1) || \
- !strncmp(name, ASC_TX_AUTO_USER, ASC_NAME_LEN - 1) ) {
- ASCPRT("Can not delete reserve user %s\n", path);
- return ;
- }
-
- tx = asc_tx_handle_lookup(hname);
-
- if(NULL == tx)
- return ;
-
- user = asc_tx_user_lookup(tx, name);
- if(user){
- /*put ready if the user had operated Tx handle*/
- if(atomic_read(&user->count) > 0){
- atomic_set(&user->count, 1);
- asc_tx_put_ready(path, 0);
- }
- spin_lock_irqsave(&tx->slock, flags);
- list_del(&user->node);
- spin_unlock_irqrestore(&tx->slock, flags);
- kfree(user);
- }
-
- return ;
-}
-EXPORT_SYMBOL(asc_tx_del_user);
-
-/**
- * asc_tx_get_ready - lock CBP to work
- * @path: (handle name).(user name)
- * @block: whether block wait for CBP has already waken
- *
- * This function try to wake the CBP and add the reference count.
- * It will block wait for CBP has already be waken if set sync parameter,
- * otherwise it just trig the action to wake CBP, which can not make sure
- * that CBP has be waken after return.
- * return 0 is ok, otherwise something error
- */
-int asc_tx_get_ready(const char *path, int sync)
-{
- int ret = 0;
- char hname[ASC_NAME_LEN] = {0};
- const char *name;
- struct asc_tx_handle *tx = NULL;
-
- name = strchr(path, '.');
- if (name) {
- memcpy(hname, path, min(name - path, ASC_NAME_LEN - 1));
- name++;
- } else {
- ASCPRT("Invalid path %s\n", path);
- return -EINVAL;
- }
- tx = asc_tx_handle_lookup(hname);
- if(NULL == tx)
- return -ENODEV;
-
- if(asc_tx_get_user(tx, name) < 0){
- ASCPRT("%s:tx user name %s is unknow\n", __FUNCTION__, name);
- return -ENODEV;
- }
- ASCDPRT("%s: %s=%d, %s=%d\n", __FUNCTION__,\
- tx->cfg.name, asc_tx_refer(tx, NULL), path, asc_tx_refer(tx, name));
- switch(atomic_read(&tx->state)){
- case AP_TX_ST_SLEEP:
- //To make CP wake ASAP,call the funtion directly
- if(!list_empty(&tx->event_q)){
- asc_tx_handle_sleep(tx, AP_TX_EVENT_REQUEST);
- }else{
- asc_tx_event_send(tx, AP_TX_EVENT_REQUEST);
- }
- break;
- case AP_TX_ST_IDLE:
- asc_tx_event_send(tx, AP_TX_EVENT_REQUEST);
- break;
- case AP_TX_ST_WAIT_READY:
- case AP_TX_ST_READY:
- if(!strncmp(name, ASC_TX_AUTO_USER, strlen(ASC_TX_AUTO_USER))){
- asc_tx_trig_busy(tx);
- }
- break;
- default:
- ASCPRT("Unknow tx state %d\n", atomic_read(&tx->state));
- return -EINVAL;
- }
-
- if(sync){
- if(AP_TX_ST_READY != atomic_read(&tx->state)){
- interruptible_sleep_on(&tx->wait_tx_state);
- if(AP_TX_ST_READY != atomic_read(&tx->state)){
- ret = -EBUSY;
- }
- }
- }
-
- return ret;
-}
-EXPORT_SYMBOL(asc_tx_get_ready);
-
-/**
- * asc_tx_put_ready - lock CBP to work if not set auto sleep
- * @path: (config name).[user name]
- * @block: whether block wait for CBP has already waken
- *
- * This function try to wake the CBP. It will block wait for CBP
- * has already be sleep if set sync parameter, otherwise it just
- * trig the action to sleep CBP, which can not make sure that
- * CBP has be sleep after return. If the reference count is not 1. it
- * do nothing but sub one.
- * return 0 is ok, otherwise something error
- */
-int asc_tx_put_ready(const char *path, int sync)
-{
- int ret = 0;
- char hname[ASC_NAME_LEN] = {0};
- const char *name;
- struct asc_tx_handle *tx = NULL;
-
- name = strchr(path, '.');
- if (name) {
- memcpy(hname, path, min(name - path, ASC_NAME_LEN - 1));
- name++;
- } else {
- ASCPRT("Invalid path %s\n", path);
- return -EINVAL;
- }
-
- tx = asc_tx_handle_lookup(hname);
- if(NULL == tx)
- return -ENODEV;
-
- if(asc_tx_put_user(tx, name) < 0){
- ASCPRT("%s:tx user name %s is unknow\n", __FUNCTION__, name);
- return -ENODEV;
- }
- ASCDPRT("%s: %s=%d, %s=%d\n", __FUNCTION__,\
- tx->cfg.name, asc_tx_refer(tx, NULL), path, asc_tx_refer(tx, name));
- /*count is not 0, so do nothing*/
- if(asc_tx_refer(tx, NULL) != 0){
- return 0;
- }
-
- switch(atomic_read(&tx->state)){
- case AP_TX_ST_SLEEP:
- break;
- case AP_TX_ST_WAIT_READY:
- case AP_TX_ST_READY:
- asc_tx_event_send(tx, AP_TX_EVENT_STOP);
- break;
- case AP_TX_ST_IDLE:
- asc_tx_event_send(tx, AP_TX_EVENT_IDLE_TIMEOUT);
- break;
- default:
- ASCPRT("Unknow tx state %d\n", atomic_read(&tx->state));
- return -EINVAL;
- }
-
- if(sync){
- if(AP_TX_ST_SLEEP != atomic_read(&tx->state)){
- interruptible_sleep_on(&tx->wait_tx_state);
- if(AP_TX_ST_SLEEP != atomic_read(&tx->state)){
- ret = -EBUSY;
- }
- }
- }
-
- return ret;
-}
-EXPORT_SYMBOL(asc_tx_put_ready);
-
-/**
- * asc_tx_auto_ready - call each time before operate for CBP if set auto sleep
- * @name: the cofnig name for the handle
- * @sync: whether block wait for CBP has already waken
- *
- * This function try to wake the CBP and trig the tx state. It will
- * block wait for CBP has already be waken if set sync parameter,
- * otherwise it just trig the action to wake CBP, which can not make
- * sure that CBP has be waken after return.
- * return 0 is ok, otherwise something error
- */
-int asc_tx_auto_ready(const char *name, int sync)
-{
- int ret = 0;
- struct asc_user *user;
- struct asc_tx_handle *tx;
-
- if (!name) {
- ASCPRT("%s:Invalid name\n", __FUNCTION__);
- return -EINVAL;
- }
-
- tx = asc_tx_handle_lookup(name);
- if(NULL == tx)
- return -ENODEV;
-
- user = asc_tx_user_lookup(tx, ASC_TX_AUTO_USER);
- if(!user){
- return -ENODEV;
- }
-
- if(atomic_read(&user->count) == 0){
- ASCDPRT("%s: %s=%d, %s=%d\n", __FUNCTION__,\
- tx->cfg.name, asc_tx_refer(tx, NULL), ASC_TX_AUTO_USER, asc_tx_refer(tx, ASC_TX_AUTO_USER));
- atomic_inc(&user->count);
- }
-
- switch(atomic_read(&tx->state)){
- case AP_TX_ST_SLEEP:
- //To make CP wake ASAP,call the funtion directly
- if(!list_empty(&tx->event_q)){
- asc_tx_handle_sleep(tx, AP_TX_EVENT_REQUEST);
- }else{
- asc_tx_event_send(tx, AP_TX_EVENT_REQUEST);
- }
- break;
- case AP_TX_ST_IDLE:
- asc_tx_event_send(tx, AP_TX_EVENT_REQUEST);
- break;
- case AP_TX_ST_WAIT_READY:
- case AP_TX_ST_READY:
- asc_tx_trig_busy(tx);
- break;
- default:
- ASCPRT("Unknow tx state %d\n", atomic_read(&tx->state));
- return -EINVAL;
- }
-
- if(sync){
- if(AP_TX_ST_READY != atomic_read(&tx->state)){
- interruptible_sleep_on(&tx->wait_tx_state);
- if(AP_TX_ST_READY != atomic_read(&tx->state)){
- ret = -EBUSY;
- }
- }
- }
-
- return ret;
-
-}
-EXPORT_SYMBOL(asc_tx_auto_ready);
-
-static void asc_rx_handle_reset(struct asc_rx_handle *rx)
-{
- unsigned long flags;
-
- ASCDPRT("%s %s\n", __FUNCTION__, rx->cfg.name);
- del_timer(&rx->timer);
- wake_unlock(&rx->wlock);
- asc_rx_indicate_sleep(rx);
- atomic_set(&rx->state, AP_RX_ST_SLEEP);
- spin_lock_irqsave(&rx->slock, flags);
- INIT_LIST_HEAD(&rx->event_q);
- spin_unlock_irqrestore(&rx->slock, flags);
-
-}
-
-/**
- * asc_rx_reset - reset the rx handle
- * @name: the config name for the handle
- *
- * return 0 ok, others be error
- */
-void asc_rx_reset(const char *name)
-{
- struct asc_rx_handle *rx = NULL;
-
- rx = asc_rx_handle_lookup(name);
- if(rx){
- asc_rx_event_send(rx, AP_RX_EVENT_RESET);
- }
-}
-EXPORT_SYMBOL(asc_rx_reset);
-
-/**
- * asc_rx_add_user - add a user for rx handle
- * @name: the config name for the handle
- * @infor: the user information
- *
- * return 0, others be error
- */
-int asc_rx_add_user(const char *name, struct asc_infor *infor)
-{
- int ret = 0;
- unsigned long flags = 0;
- struct asc_rx_handle *rx;
- struct asc_user *user;
-
- rx = asc_rx_handle_lookup(name);
- if(NULL == rx)
- return -ENODEV;
-
- user = asc_rx_user_lookup(rx, infor->name);
- if(NULL == user){
- user = kzalloc(sizeof(*user), GFP_KERNEL);
- if(!user){
- ASCPRT("No memory to create new user reference.\n");
- ret = -ENOMEM;
- goto error;
- }
- user->infor.data = infor->data;
- user->infor.notifier = infor->notifier;
- strncpy(user->infor.name, infor->name, ASC_NAME_LEN - 1);
- atomic_set(&user->count, 0);
- spin_lock_irqsave(&rx->slock, flags);
- list_add_tail(&user->node, &rx->user_list);
- spin_unlock_irqrestore(&rx->slock, flags);
- if(AP_RX_ST_WAIT_READY == atomic_read(&rx->state)){
- if(infor->notifier){
- infor->notifier(ASC_NTF_RX_PREPARE, infor->data);
- }
- }
- }else{
- ASCPRT("%s error: user %s already exist!!\n", __FUNCTION__, infor->name);
- ret = -EINVAL;
- }
-error:
- return ret;
-}
-EXPORT_SYMBOL(asc_rx_add_user);
-
-/**
- * asc_rx_del_user - add a user for rx handle
- * @path: (config name).[user name]
- *
- * no return
- */
-void asc_rx_del_user(const char *path)
-{
- unsigned long flags = 0;
- const char *name;
- char hname[ASC_NAME_LEN] = {0};
- struct asc_user *user;
- struct asc_rx_handle *rx;
-
-
- name = strchr(path, '.');
- if (name) {
- memcpy(hname, path, min(name - path, ASC_NAME_LEN - 1));
- name++;
- }else{
- ASCPRT("%s: Invalid path %s\n",__FUNCTION__, path);
- return ;
- }
-
- rx = asc_rx_handle_lookup(hname);
- if(NULL == rx)
- return ;
-
- user = asc_rx_user_lookup(rx, name);
- if(user){
- atomic_set(&user->count, 0);
- spin_lock_irqsave(&rx->slock, flags);
- list_del(&user->node);
- spin_unlock_irqrestore(&rx->slock, flags);
- kfree(user);
- if(list_empty(&rx->user_list)){
- asc_rx_handle_reset(rx);
- }
- }
- return ;
-}
-EXPORT_SYMBOL(asc_rx_del_user);
-
-/**
- * asc_rx_confirm_ready - echo AP state to rx CBP data
- * @name: the config name to rx handle
- * @ready: whether AP has been ready to rx data
- *
- * After CBP request AP to rx data, the function can be used to
- * tell CBP whether AP has been ready to receive.
- * return 0 is ok, otherwise something error
- */
-int asc_rx_confirm_ready(const char *name, int ready)
-{
- struct asc_rx_handle *rx = NULL;
-
- rx = asc_rx_handle_lookup(name);
- if(!rx){
- ASCDPRT("%s: name %s is unknow\n", __FUNCTION__, name);
- return -ENODEV;
- }
-
- ASCDPRT("Rx(%s) cnofirm ready=%d\n", rx->cfg.name, ready);
- return asc_rx_event_send(rx, ready ? AP_RX_EVENT_AP_READY : AP_RX_EVENT_AP_UNREADY);
-}
-EXPORT_SYMBOL(asc_rx_confirm_ready);
-
-/**
- * check_on_start - prevent from missing cp waking
- * @name: the name of rx handle
- *
- * Before the rx user is registed,CP may wake up AP.Usually AP will ignore
- * the waking.Because the interrupt don't be register at that time.So the
- * signal will be missed.When opening the tty device, we should check whether CP
- * has waken up AP or not.If CP did that,we should send the signal "AP READY"
- * to CP.
- */
-
-int asc_rx_check_on_start(const char *name)
-{
- int level;
- struct asc_config *cfg = NULL;
- struct asc_rx_handle *rx = NULL;
- int ret = 1;
-
- rx = asc_rx_handle_lookup(name);
- if(!rx){
- ASCPRT("config %s has not already exist.\n", name);
- return -EINVAL;
- }
-
- cfg = &(rx->cfg);
- level = !!oem_gpio_get_value(cfg->gpio_wake);
- if(level == cfg->polar){
- /*Cp has requested Ap wake*/
- if(AP_RX_ST_SLEEP == atomic_read(&rx->state)){
- ASCDPRT("Rx(%s):check_on_start--send event AP_RX_EVENT_REQUEST.\n", cfg->name);
- ret = asc_rx_event_send(rx, AP_RX_EVENT_REQUEST);
- }else{
- ASCDPRT("Rx(%s): check_on_start--send event AP_RX_EVENT_AP_READY.\n", cfg->name);
- ret = asc_rx_event_send(rx, AP_RX_EVENT_AP_READY);
- }
- }
-
- return ret;
-}
-EXPORT_SYMBOL(asc_rx_check_on_start);
-
-static ssize_t asc_debug_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- char *s = buf;
- s += sprintf(s, "%d\n", asc_debug);
-
- return (s - buf);
-}
-
-static ssize_t asc_debug_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- unsigned long val;
-
- if (strict_strtoul(buf, 10, &val))
- return -EINVAL;
-
- if (val < 0)
- return -EINVAL;
-
- asc_debug = val;
-
- return n;
-}
-
-
-
-static ssize_t asc_infor_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- char *s = buf;
- int val1, val2;
- struct asc_config *cfg;
- struct asc_infor *infor;
- struct asc_user *user = NULL, *tuser = NULL;
- struct asc_tx_handle *tx = NULL, *ttmp = NULL;
- struct asc_rx_handle *rx = NULL, *rtmp = NULL;
-
- list_for_each_entry_safe(tx, ttmp, &asc_tx_handle_list, node){
- cfg = &tx->cfg;
- val1 = val2 = -1;
- if(cfg->gpio_wake >= 0)
- val1 = !!oem_gpio_get_value(cfg->gpio_wake);
- if(cfg->gpio_ready >= 0)
- val2 = !!oem_gpio_get_value(cfg->gpio_ready);
-
- s += sprintf(s, "Tx %s: ref=%d, ap_wake_cp(%d)=%d, cp_ready(%d)=%d, polar=%d, auto_delay=%d mS\n",
- cfg->name, asc_tx_refer(tx, NULL), cfg->gpio_wake, val1, cfg->gpio_ready, val2, cfg->polar, tx->auto_delay);
-
- list_for_each_entry_safe(user, tuser, &tx->user_list, node) {
- infor = &user->infor;
- s += sprintf(s, " user %s: ref=%d\n", infor->name, atomic_read(&user->count));
- }
- }
-
- s += sprintf(s, "\n");
-
- list_for_each_entry_safe(rx, rtmp, &asc_rx_handle_list, node){
- cfg = &rx->cfg;
- val1 = val2 = -1;
- if(cfg->gpio_wake >= 0)
- val1 = !!oem_gpio_get_value(cfg->gpio_wake);
- if(cfg->gpio_ready >= 0)
- val2 = !!oem_gpio_get_value(cfg->gpio_ready);
-
- s += sprintf(s, "Rx %s: ref=%d, cp_wake_ap(%d)=%d, ap_ready(%d)=%d, polar=%d\n", \
- cfg->name, asc_rx_refer(rx, NULL), cfg->gpio_wake, val1, cfg->gpio_ready, val2, cfg->polar);
- list_for_each_entry_safe(user, tuser, &rx->user_list, node) {
- infor = &user->infor;
- s += sprintf(s, " user %s: ref=%d\n", infor->name, atomic_read(&user->count));
- }
- }
-
- return (s - buf);
-}
-static ssize_t asc_infor_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- return n;
-}
-
-static ssize_t asc_refer_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- unsigned long flags;
- char *s = buf;
- struct asc_tx_handle *tx, *tmp, *t;
-
- tx = tmp = NULL;
- spin_lock_irqsave(&hdlock, flags);
- list_for_each_entry_safe(tmp, t, &asc_tx_handle_list, node){
- if(tmp->kobj == kobj){
- tx = tmp;
- break;
- }
- }
- spin_unlock_irqrestore(&hdlock, flags);
-
- if(tx){
- s += sprintf(s, "%d\n", asc_tx_refer(tx, ASC_TX_SYSFS_USER));
- return s - buf;
- }else{
- ASCPRT("%s read error\n", __FUNCTION__);
- return -EINVAL;
- }
-
-}
-
-
-static ssize_t asc_setcpmode_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- char *s = buf;
- s += sprintf(s, "nothing\n");
-
- return (s - buf);
-}
-
-static ssize_t asc_setcpmode_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- unsigned long val;
-
- if (strict_strtoul(buf, 10, &val))
- return -EINVAL;
-
- if (val < 0)
- return -EINVAL;
-
- if(val>0)
- oem_gpio_output(GPIO_VIATEL_USB_AP_WAKE_MDM,1);
- else
- oem_gpio_output(GPIO_VIATEL_USB_AP_WAKE_MDM,0);
-
-
- //asc_debug = val;
-
- return n;
-}
-
-
-static ssize_t asc_refer_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- unsigned long flags;
- char *p;
- int error = 0, len;
- char path[ASC_NAME_LEN] = {0};
- struct asc_tx_handle *tx, *tmp, *t;
-
- tx = tmp = NULL;
- spin_lock_irqsave(&hdlock, flags);
- list_for_each_entry_safe(tmp, t, &asc_tx_handle_list, node){
- if(tmp->kobj == kobj){
- tx = tmp;
- break;
- }
- }
- spin_unlock_irqrestore(&hdlock, flags);
-
- if(tx){
- p = memchr(buf, '\n', n);
- len = p ? p - buf : n;
- snprintf(path, ASC_NAME_LEN, "%s.%s", tx->cfg.name, ASC_TX_SYSFS_USER);
-
- if (len == 3 && !strncmp(buf, "get", len)) {
- error = asc_tx_get_ready(path, 1);
- }else if (len == 3 && !strncmp(buf, "put", len)) {
- error= asc_tx_put_ready(path, 1);
- }
- }
-
- return error ? error : n;
-}
-
-static ssize_t asc_state_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- unsigned long flags;
- char *s = buf;
- struct asc_tx_handle *tx, *tmp, *t;
-
- tx = tmp = NULL;
- spin_lock_irqsave(&hdlock, flags);
- list_for_each_entry_safe(tmp, t, &asc_tx_handle_list, node){
- if(tmp->kobj == kobj){
- tx = tmp;
- break;
- }
- }
- spin_unlock_irqrestore(&hdlock, flags);
-
- if(tx){
- s += sprintf(s, "%s\n", tx->table[atomic_read(&tx->state)].name);
- return s - buf;
- }else{
- ASCPRT("%s read error\n", __FUNCTION__);
- return -EINVAL;
- }
-
-}
-
-static ssize_t asc_state_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- return n;
-}
-
-static ssize_t asc_auto_ready_show(struct kobject *kobj, struct kobj_attribute *attr,
- char *buf)
-{
- unsigned long flags;
- char *s = buf;
- struct asc_tx_handle *tx, *tmp, *t;
-
- tx = tmp = NULL;
- spin_lock_irqsave(&hdlock, flags);
- list_for_each_entry_safe(tmp, t, &asc_tx_handle_list, node){
- if(tmp->kobj == kobj){
- tx = tmp;
- break;
- }
- }
- spin_unlock_irqrestore(&hdlock, flags);
-
- if(tx){
- s += sprintf(s, "%d\n", tx->auto_delay);
- return s - buf;
- }else{
- ASCPRT("%s read error\n", __FUNCTION__);
- return -EINVAL;
- }
-
-}
-
-static ssize_t asc_auto_ready_store(struct kobject *kobj, struct kobj_attribute *attr,
- const char *buf, size_t n)
-{
- int error = 0;
- long val;
- unsigned long flags;
- struct asc_tx_handle *tx, *tmp, *t;
-
- tx = tmp = NULL;
- spin_lock_irqsave(&hdlock, flags);
- list_for_each_entry_safe(tmp, t, &asc_tx_handle_list, node){
- if(tmp->kobj == kobj){
- tx = tmp;
- break;
- }
- }
- spin_unlock_irqrestore(&hdlock, flags);
-
- if(tx){
- error = strict_strtol(buf, 10, &val);
- if(error || (val < 0)){
- error = -EINVAL;
- goto end;
- }
-
- if(val > 0){
- spin_lock_irqsave(&tx->slock, flags);
- tx->auto_delay = val;
- spin_unlock_irqrestore(&tx->slock, flags);
- }
- error = asc_tx_auto_ready(tx->cfg.name, 1);
- }else{
- ASCPRT("%s read error\n", __FUNCTION__);
- error = -EINVAL;
- }
-
-end:
- return error ? error : n;
-}
-
-#define asc_attr(_name) \
-static struct kobj_attribute _name##_attr = { \
- .attr = { \
- .name = __stringify(_name), \
- .mode = 0644, \
- }, \
- .show = asc_##_name##_show, \
- .store = asc_##_name##_store, \
-}
-
-asc_attr(debug);
-asc_attr(infor);
-asc_attr(setcpmode);
-
-static struct attribute * g_attr[] = {
- &debug_attr.attr,
- &infor_attr.attr,
- &setcpmode_attr.attr,
- NULL,
-};
-
-static struct attribute_group g_attr_group = {
- .attrs = g_attr,
-};
-
-asc_attr(refer);
-asc_attr(state);
-asc_attr(auto_ready);
-
-static struct attribute * tx_hd_attr[] = {
- &refer_attr.attr,
- &state_attr.attr,
- &auto_ready_attr.attr,
- NULL,
-};
-
-int asc_suspend(struct platform_device *pdev, pm_message_t state)
-{
- oem_gpio_irq_mask(tx_cfg.gpio_ready);
- oem_gpio_irq_mask(rx_cfg.gpio_wake);
- if(ap_ready_always)
- oem_gpio_output(rx_cfg.gpio_ready,!rx_cfg.polar);
-
- return 0;
-}
-
-
-int asc_resume(struct platform_device *pdev)
-{
-
- msleep(500);
- printk("asc_resume\n");
- oem_gpio_direction_output(tx_cfg.gpio_wake, tx_cfg.polar);
- oem_gpio_direction_input_for_irq(tx_cfg.gpio_ready);
- oem_gpio_set_irq_type(tx_cfg.gpio_ready, IRQF_TRIGGER_RISING);
- oem_gpio_irq_unmask(tx_cfg.gpio_ready);
-
- oem_gpio_output(rx_cfg.gpio_ready, rx_cfg.polar);
- oem_gpio_direction_input_for_irq(rx_cfg.gpio_wake);
- oem_gpio_set_irq_type(rx_cfg.gpio_wake, IRQF_TRIGGER_RISING);
- oem_gpio_irq_unmask(rx_cfg.gpio_wake);
-
- return 0;
-}
-
-static struct attribute_group tx_hd_attr_group = {
- .attrs = tx_hd_attr,
-};
-
-
-static struct platform_driver asc_driver = {
- .driver.name = "asc",
- .suspend = asc_suspend,
- .resume = asc_resume,
-};
-
-static struct platform_device asc_device = {
- .name = "asc",
-};
-
-
-/**
- * asc_rx_register_handle - register the rx handle
- * @cfg: the config for the handle
- *
- * the device which receive data from CBP can register a notifier to
- * listen the event according to the changes from CBP.
- * ASC_PREPARE_RX_DATA event will be send when CBP start tx data
- * to the device which must be ready to work;
- * ASC_POST_RX_DATA event will be send when CBP stop tx data to
- * the device which can go to sleep.
- * The gpio for ap_ready can be -1 which be ignored when the device
- * can receive the data from CBP correctly any time.
- * return index according to the notifier in handle, otherwise something error
- */
-int asc_rx_register_handle(struct asc_config *cfg)
-{
- int ret = 0;
- unsigned long flags;
- struct asc_rx_handle *rx = NULL;
-
- if(NULL == asc_work_queue){
- ASCPRT("%s: error Asc has not been init\n", __FUNCTION__);
- return -EINVAL;
- }
-
- if(NULL == cfg){
- return -EINVAL;
- }
-
- if(cfg->gpio_wake < 0){
- ASCPRT("%s: config %s gpio is invalid.\n", __FUNCTION__, cfg->name);
- return -EINVAL;
- }
-
- rx = asc_rx_handle_lookup(cfg->name);
- if(rx){
- ASCPRT("config %s has already exist.\n", cfg->name);
- return -EINVAL;
- }
-
- rx = kzalloc(sizeof(struct asc_rx_handle), GFP_KERNEL);
- if(NULL == rx){
- ASCPRT("No memory to alloc rx handle.\n");
- return -ENOMEM;
- }
-
- rx->cfg.gpio_ready = cfg->gpio_ready;
- rx->cfg.gpio_wake = cfg->gpio_wake;
- rx->cfg.polar = !!cfg->polar;
- strncpy(rx->cfg.name, cfg->name, ASC_NAME_LEN - 1);
- memcpy(&rx_cfg, &rx->cfg, sizeof(struct asc_config));
-
- ret = asc_rx_handle_init(rx);
- if(ret < 0){
- kfree(rx);
- ASCPRT("fail to init rx handle %s\n", rx->cfg.name);
- return -EINVAL;
- }
-
- /* Add the handle to the asc list */
- spin_lock_irqsave(&hdlock, flags);
- list_add(&rx->node, &asc_rx_handle_list);
- spin_unlock_irqrestore(&hdlock, flags);
- ASCDPRT("Register rx handle %s\n", rx->cfg.name);
- return ret;
-}
-EXPORT_SYMBOL(asc_rx_register_handle);
-
-/**
- * asc_tx_register_handle - register the tx handle for state change
- * @cfg: the config for the handle
- *
- * the chip which exchanged data with CBP must create a handle.
- * There is only one tx state handle between the AP and CBP because
- * all devices in CBP will be ready to receive data after CBP has been
- * waken. But servial rx state handles can be exist because different
- * devices in AP maybe waken indivially. Each rx state handle must be
- * registed a notifier to listen the evnets.
- * return 0 is ok, otherwise something error
- */
-int asc_tx_register_handle(struct asc_config *cfg)
-{
- int ret=0;
- unsigned long flags;
- struct asc_infor infor;
- struct asc_tx_handle *tx = NULL;
-
- if(NULL == asc_work_queue){
- ASCPRT("%s: error Asc has not been init\n", __FUNCTION__);
- return -EINVAL;
- }
-
- if(NULL == cfg){
- return -EINVAL;
- }
-
- if(cfg->gpio_wake < 0){
- ASCPRT("%s: config %s gpio is invalid.\n", __FUNCTION__, cfg->name);
- return -EINVAL;
- }
-
- tx = asc_tx_handle_lookup(cfg->name);
- if(tx){
- ASCPRT("config %s has already exist.\n", cfg->name);
- return -EINVAL;
- }
-
- tx = kzalloc(sizeof(struct asc_tx_handle), GFP_KERNEL);
- if(NULL == tx){
- ASCPRT("Fail to alloc memory for tx handle.\n");
- return -ENOMEM;
- }
-
- tx->cfg.gpio_ready = cfg->gpio_ready;
- tx->cfg.gpio_wake = cfg->gpio_wake;
- tx->cfg.polar = !!cfg->polar;
- strncpy(tx->cfg.name, cfg->name, ASC_NAME_LEN - 1);
- memcpy(&tx_cfg, &tx->cfg, sizeof(struct asc_config));
- ret = asc_tx_handle_init(tx);
- if(ret < 0){
- ASCPRT("Fail to init tx handle %s.\n", tx->cfg.name);
- goto err_tx_handle_init;
- }
-
- /* Add the handle to the asc list */
- spin_lock_irqsave(&hdlock, flags);
- list_add(&tx->node, &asc_tx_handle_list);
- spin_unlock_irqrestore(&hdlock, flags);
- ASCDPRT("Register tx handle %s.\n", tx->cfg.name);
-
- tx->kobj = kobject_create_and_add(cfg->name, asc_kobj);
- if(!tx->kobj){
- ret = -ENOMEM;
- goto err_create_kobj;
- }
-
- /*add default user for application*/
- memset(&infor, 0, sizeof(infor));
- strncpy(infor.name, ASC_TX_SYSFS_USER, ASC_NAME_LEN);
- asc_tx_add_user(tx->cfg.name, &infor);
- memset(&infor, 0, sizeof(infor));
- strncpy(infor.name, ASC_TX_AUTO_USER, ASC_NAME_LEN);
- asc_tx_add_user(tx->cfg.name, &infor);
- return sysfs_create_group(tx->kobj, &tx_hd_attr_group);
-
-err_create_kobj:
- list_del(&tx->node);
-err_tx_handle_init:
- if(tx){
- kfree(tx);
- }
-
- return ret;
-}
-EXPORT_SYMBOL(asc_tx_register_handle);
-
-static int __init asc_init(void)
-{
- int ret;
- ret = oem_gpio_convert_init();
- if(ret){
- printk("Warnning:viatel gpio not set.\n");
- return -EIO;
- }
-
- ret = platform_device_register(&asc_device);
- if (ret) {
- ASCPRT("platform_device_register failed\n");
- goto err_platform_device_register;
- }
- ret = platform_driver_register(&asc_driver);
- if (ret) {
- ASCPRT("platform_driver_register failed\n");
- goto err_platform_driver_register;
- }
-
- asc_work_queue = create_singlethread_workqueue("asc_work");
- if (asc_work_queue == NULL) {
- ret = -ENOMEM;
- goto err_create_work_queue;
- }
-
- asc_kobj = viatel_kobject_add("asc");
- if (!asc_kobj){
- ret = -ENOMEM;
- goto err_create_kobj;
- }
-
- return sysfs_create_group(asc_kobj, &g_attr_group);
-
-err_create_kobj:
- destroy_workqueue(asc_work_queue);
-err_create_work_queue:
- platform_driver_unregister(&asc_driver);
-err_platform_driver_register:
- platform_device_unregister(&asc_device);
-err_platform_device_register:
- return ret;
-}
-
-device_initcall(asc_init);
-
diff --git a/ANDROID_3.4.5/drivers/misc/vmw_balloon.c b/ANDROID_3.4.5/drivers/misc/vmw_balloon.c
deleted file mode 100644
index cb56e270..00000000
--- a/ANDROID_3.4.5/drivers/misc/vmw_balloon.c
+++ /dev/null
@@ -1,838 +0,0 @@
-/*
- * VMware Balloon driver.
- *
- * Copyright (C) 2000-2010, VMware, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; version 2 of the License and no 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained by: Dmitry Torokhov <dtor@vmware.com>
- */
-
-/*
- * This is VMware physical memory management driver for Linux. The driver
- * acts like a "balloon" that can be inflated to reclaim physical pages by
- * reserving them in the guest and invalidating them in the monitor,
- * freeing up the underlying machine pages so they can be allocated to
- * other guests. The balloon can also be deflated to allow the guest to
- * use more physical memory. Higher level policies can control the sizes
- * of balloons in VMs in order to manage physical memory resources.
- */
-
-//#define DEBUG
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/workqueue.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <asm/hypervisor.h>
-
-MODULE_AUTHOR("VMware, Inc.");
-MODULE_DESCRIPTION("VMware Memory Control (Balloon) Driver");
-MODULE_VERSION("1.2.1.3-k");
-MODULE_ALIAS("dmi:*:svnVMware*:*");
-MODULE_ALIAS("vmware_vmmemctl");
-MODULE_LICENSE("GPL");
-
-/*
- * Various constants controlling rate of inflaint/deflating balloon,
- * measured in pages.
- */
-
-/*
- * Rate of allocating memory when there is no memory pressure
- * (driver performs non-sleeping allocations).
- */
-#define VMW_BALLOON_NOSLEEP_ALLOC_MAX 16384U
-
-/*
- * Rates of memory allocaton when guest experiences memory pressure
- * (driver performs sleeping allocations).
- */
-#define VMW_BALLOON_RATE_ALLOC_MIN 512U
-#define VMW_BALLOON_RATE_ALLOC_MAX 2048U
-#define VMW_BALLOON_RATE_ALLOC_INC 16U
-
-/*
- * Rates for releasing pages while deflating balloon.
- */
-#define VMW_BALLOON_RATE_FREE_MIN 512U
-#define VMW_BALLOON_RATE_FREE_MAX 16384U
-#define VMW_BALLOON_RATE_FREE_INC 16U
-
-/*
- * When guest is under memory pressure, use a reduced page allocation
- * rate for next several cycles.
- */
-#define VMW_BALLOON_SLOW_CYCLES 4
-
-/*
- * Use __GFP_HIGHMEM to allow pages from HIGHMEM zone. We don't
- * allow wait (__GFP_WAIT) for NOSLEEP page allocations. Use
- * __GFP_NOWARN, to suppress page allocation failure warnings.
- */
-#define VMW_PAGE_ALLOC_NOSLEEP (__GFP_HIGHMEM|__GFP_NOWARN)
-
-/*
- * Use GFP_HIGHUSER when executing in a separate kernel thread
- * context and allocation can sleep. This is less stressful to
- * the guest memory system, since it allows the thread to block
- * while memory is reclaimed, and won't take pages from emergency
- * low-memory pools.
- */
-#define VMW_PAGE_ALLOC_CANSLEEP (GFP_HIGHUSER)
-
-/* Maximum number of page allocations without yielding processor */
-#define VMW_BALLOON_YIELD_THRESHOLD 1024
-
-/* Maximum number of refused pages we accumulate during inflation cycle */
-#define VMW_BALLOON_MAX_REFUSED 16
-
-/*
- * Hypervisor communication port definitions.
- */
-#define VMW_BALLOON_HV_PORT 0x5670
-#define VMW_BALLOON_HV_MAGIC 0x456c6d6f
-#define VMW_BALLOON_PROTOCOL_VERSION 2
-#define VMW_BALLOON_GUEST_ID 1 /* Linux */
-
-#define VMW_BALLOON_CMD_START 0
-#define VMW_BALLOON_CMD_GET_TARGET 1
-#define VMW_BALLOON_CMD_LOCK 2
-#define VMW_BALLOON_CMD_UNLOCK 3
-#define VMW_BALLOON_CMD_GUEST_ID 4
-
-/* error codes */
-#define VMW_BALLOON_SUCCESS 0
-#define VMW_BALLOON_FAILURE -1
-#define VMW_BALLOON_ERROR_CMD_INVALID 1
-#define VMW_BALLOON_ERROR_PPN_INVALID 2
-#define VMW_BALLOON_ERROR_PPN_LOCKED 3
-#define VMW_BALLOON_ERROR_PPN_UNLOCKED 4
-#define VMW_BALLOON_ERROR_PPN_PINNED 5
-#define VMW_BALLOON_ERROR_PPN_NOTNEEDED 6
-#define VMW_BALLOON_ERROR_RESET 7
-#define VMW_BALLOON_ERROR_BUSY 8
-
-#define VMWARE_BALLOON_CMD(cmd, data, result) \
-({ \
- unsigned long __stat, __dummy1, __dummy2; \
- __asm__ __volatile__ ("inl (%%dx)" : \
- "=a"(__stat), \
- "=c"(__dummy1), \
- "=d"(__dummy2), \
- "=b"(result) : \
- "0"(VMW_BALLOON_HV_MAGIC), \
- "1"(VMW_BALLOON_CMD_##cmd), \
- "2"(VMW_BALLOON_HV_PORT), \
- "3"(data) : \
- "memory"); \
- result &= -1UL; \
- __stat & -1UL; \
-})
-
-#ifdef CONFIG_DEBUG_FS
-struct vmballoon_stats {
- unsigned int timer;
-
- /* allocation statistics */
- unsigned int alloc;
- unsigned int alloc_fail;
- unsigned int sleep_alloc;
- unsigned int sleep_alloc_fail;
- unsigned int refused_alloc;
- unsigned int refused_free;
- unsigned int free;
-
- /* monitor operations */
- unsigned int lock;
- unsigned int lock_fail;
- unsigned int unlock;
- unsigned int unlock_fail;
- unsigned int target;
- unsigned int target_fail;
- unsigned int start;
- unsigned int start_fail;
- unsigned int guest_type;
- unsigned int guest_type_fail;
-};
-
-#define STATS_INC(stat) (stat)++
-#else
-#define STATS_INC(stat)
-#endif
-
-struct vmballoon {
-
- /* list of reserved physical pages */
- struct list_head pages;
-
- /* transient list of non-balloonable pages */
- struct list_head refused_pages;
- unsigned int n_refused_pages;
-
- /* balloon size in pages */
- unsigned int size;
- unsigned int target;
-
- /* reset flag */
- bool reset_required;
-
- /* adjustment rates (pages per second) */
- unsigned int rate_alloc;
- unsigned int rate_free;
-
- /* slowdown page allocations for next few cycles */
- unsigned int slow_allocation_cycles;
-
-#ifdef CONFIG_DEBUG_FS
- /* statistics */
- struct vmballoon_stats stats;
-
- /* debugfs file exporting statistics */
- struct dentry *dbg_entry;
-#endif
-
- struct sysinfo sysinfo;
-
- struct delayed_work dwork;
-};
-
-static struct vmballoon balloon;
-
-/*
- * Send "start" command to the host, communicating supported version
- * of the protocol.
- */
-static bool vmballoon_send_start(struct vmballoon *b)
-{
- unsigned long status, dummy;
-
- STATS_INC(b->stats.start);
-
- status = VMWARE_BALLOON_CMD(START, VMW_BALLOON_PROTOCOL_VERSION, dummy);
- if (status == VMW_BALLOON_SUCCESS)
- return true;
-
- pr_debug("%s - failed, hv returns %ld\n", __func__, status);
- STATS_INC(b->stats.start_fail);
- return false;
-}
-
-static bool vmballoon_check_status(struct vmballoon *b, unsigned long status)
-{
- switch (status) {
- case VMW_BALLOON_SUCCESS:
- return true;
-
- case VMW_BALLOON_ERROR_RESET:
- b->reset_required = true;
- /* fall through */
-
- default:
- return false;
- }
-}
-
-/*
- * Communicate guest type to the host so that it can adjust ballooning
- * algorithm to the one most appropriate for the guest. This command
- * is normally issued after sending "start" command and is part of
- * standard reset sequence.
- */
-static bool vmballoon_send_guest_id(struct vmballoon *b)
-{
- unsigned long status, dummy;
-
- status = VMWARE_BALLOON_CMD(GUEST_ID, VMW_BALLOON_GUEST_ID, dummy);
-
- STATS_INC(b->stats.guest_type);
-
- if (vmballoon_check_status(b, status))
- return true;
-
- pr_debug("%s - failed, hv returns %ld\n", __func__, status);
- STATS_INC(b->stats.guest_type_fail);
- return false;
-}
-
-/*
- * Retrieve desired balloon size from the host.
- */
-static bool vmballoon_send_get_target(struct vmballoon *b, u32 *new_target)
-{
- unsigned long status;
- unsigned long target;
- unsigned long limit;
- u32 limit32;
-
- /*
- * si_meminfo() is cheap. Moreover, we want to provide dynamic
- * max balloon size later. So let us call si_meminfo() every
- * iteration.
- */
- si_meminfo(&b->sysinfo);
- limit = b->sysinfo.totalram;
-
- /* Ensure limit fits in 32-bits */
- limit32 = (u32)limit;
- if (limit != limit32)
- return false;
-
- /* update stats */
- STATS_INC(b->stats.target);
-
- status = VMWARE_BALLOON_CMD(GET_TARGET, limit, target);
- if (vmballoon_check_status(b, status)) {
- *new_target = target;
- return true;
- }
-
- pr_debug("%s - failed, hv returns %ld\n", __func__, status);
- STATS_INC(b->stats.target_fail);
- return false;
-}
-
-/*
- * Notify the host about allocated page so that host can use it without
- * fear that guest will need it. Host may reject some pages, we need to
- * check the return value and maybe submit a different page.
- */
-static int vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
- unsigned int *hv_status)
-{
- unsigned long status, dummy;
- u32 pfn32;
-
- pfn32 = (u32)pfn;
- if (pfn32 != pfn)
- return -1;
-
- STATS_INC(b->stats.lock);
-
- *hv_status = status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy);
- if (vmballoon_check_status(b, status))
- return 0;
-
- pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
- STATS_INC(b->stats.lock_fail);
- return 1;
-}
-
-/*
- * Notify the host that guest intends to release given page back into
- * the pool of available (to the guest) pages.
- */
-static bool vmballoon_send_unlock_page(struct vmballoon *b, unsigned long pfn)
-{
- unsigned long status, dummy;
- u32 pfn32;
-
- pfn32 = (u32)pfn;
- if (pfn32 != pfn)
- return false;
-
- STATS_INC(b->stats.unlock);
-
- status = VMWARE_BALLOON_CMD(UNLOCK, pfn, dummy);
- if (vmballoon_check_status(b, status))
- return true;
-
- pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
- STATS_INC(b->stats.unlock_fail);
- return false;
-}
-
-/*
- * Quickly release all pages allocated for the balloon. This function is
- * called when host decides to "reset" balloon for one reason or another.
- * Unlike normal "deflate" we do not (shall not) notify host of the pages
- * being released.
- */
-static void vmballoon_pop(struct vmballoon *b)
-{
- struct page *page, *next;
- unsigned int count = 0;
-
- list_for_each_entry_safe(page, next, &b->pages, lru) {
- list_del(&page->lru);
- __free_page(page);
- STATS_INC(b->stats.free);
- b->size--;
-
- if (++count >= b->rate_free) {
- count = 0;
- cond_resched();
- }
- }
-}
-
-/*
- * Perform standard reset sequence by popping the balloon (in case it
- * is not empty) and then restarting protocol. This operation normally
- * happens when host responds with VMW_BALLOON_ERROR_RESET to a command.
- */
-static void vmballoon_reset(struct vmballoon *b)
-{
- /* free all pages, skipping monitor unlock */
- vmballoon_pop(b);
-
- if (vmballoon_send_start(b)) {
- b->reset_required = false;
- if (!vmballoon_send_guest_id(b))
- pr_err("failed to send guest ID to the host\n");
- }
-}
-
-/*
- * Allocate (or reserve) a page for the balloon and notify the host. If host
- * refuses the page put it on "refuse" list and allocate another one until host
- * is satisfied. "Refused" pages are released at the end of inflation cycle
- * (when we allocate b->rate_alloc pages).
- */
-static int vmballoon_reserve_page(struct vmballoon *b, bool can_sleep)
-{
- struct page *page;
- gfp_t flags;
- unsigned int hv_status;
- int locked;
- flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
-
- do {
- if (!can_sleep)
- STATS_INC(b->stats.alloc);
- else
- STATS_INC(b->stats.sleep_alloc);
-
- page = alloc_page(flags);
- if (!page) {
- if (!can_sleep)
- STATS_INC(b->stats.alloc_fail);
- else
- STATS_INC(b->stats.sleep_alloc_fail);
- return -ENOMEM;
- }
-
- /* inform monitor */
- locked = vmballoon_send_lock_page(b, page_to_pfn(page), &hv_status);
- if (locked > 0) {
- STATS_INC(b->stats.refused_alloc);
-
- if (hv_status == VMW_BALLOON_ERROR_RESET ||
- hv_status == VMW_BALLOON_ERROR_PPN_NOTNEEDED) {
- __free_page(page);
- return -EIO;
- }
-
- /*
- * Place page on the list of non-balloonable pages
- * and retry allocation, unless we already accumulated
- * too many of them, in which case take a breather.
- */
- list_add(&page->lru, &b->refused_pages);
- if (++b->n_refused_pages >= VMW_BALLOON_MAX_REFUSED)
- return -EIO;
- }
- } while (locked != 0);
-
- /* track allocated page */
- list_add(&page->lru, &b->pages);
-
- /* update balloon size */
- b->size++;
-
- return 0;
-}
-
-/*
- * Release the page allocated for the balloon. Note that we first notify
- * the host so it can make sure the page will be available for the guest
- * to use, if needed.
- */
-static int vmballoon_release_page(struct vmballoon *b, struct page *page)
-{
- if (!vmballoon_send_unlock_page(b, page_to_pfn(page)))
- return -EIO;
-
- list_del(&page->lru);
-
- /* deallocate page */
- __free_page(page);
- STATS_INC(b->stats.free);
-
- /* update balloon size */
- b->size--;
-
- return 0;
-}
-
-/*
- * Release pages that were allocated while attempting to inflate the
- * balloon but were refused by the host for one reason or another.
- */
-static void vmballoon_release_refused_pages(struct vmballoon *b)
-{
- struct page *page, *next;
-
- list_for_each_entry_safe(page, next, &b->refused_pages, lru) {
- list_del(&page->lru);
- __free_page(page);
- STATS_INC(b->stats.refused_free);
- }
-
- b->n_refused_pages = 0;
-}
-
-/*
- * Inflate the balloon towards its target size. Note that we try to limit
- * the rate of allocation to make sure we are not choking the rest of the
- * system.
- */
-static void vmballoon_inflate(struct vmballoon *b)
-{
- unsigned int goal;
- unsigned int rate;
- unsigned int i;
- unsigned int allocations = 0;
- int error = 0;
- bool alloc_can_sleep = false;
-
- pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
-
- /*
- * First try NOSLEEP page allocations to inflate balloon.
- *
- * If we do not throttle nosleep allocations, we can drain all
- * free pages in the guest quickly (if the balloon target is high).
- * As a side-effect, draining free pages helps to inform (force)
- * the guest to start swapping if balloon target is not met yet,
- * which is a desired behavior. However, balloon driver can consume
- * all available CPU cycles if too many pages are allocated in a
- * second. Therefore, we throttle nosleep allocations even when
- * the guest is not under memory pressure. OTOH, if we have already
- * predicted that the guest is under memory pressure, then we
- * slowdown page allocations considerably.
- */
-
- goal = b->target - b->size;
- /*
- * Start with no sleep allocation rate which may be higher
- * than sleeping allocation rate.
- */
- rate = b->slow_allocation_cycles ?
- b->rate_alloc : VMW_BALLOON_NOSLEEP_ALLOC_MAX;
-
- pr_debug("%s - goal: %d, no-sleep rate: %d, sleep rate: %d\n",
- __func__, goal, rate, b->rate_alloc);
-
- for (i = 0; i < goal; i++) {
-
- error = vmballoon_reserve_page(b, alloc_can_sleep);
- if (error) {
- if (error != -ENOMEM) {
- /*
- * Not a page allocation failure, stop this
- * cycle. Maybe we'll get new target from
- * the host soon.
- */
- break;
- }
-
- if (alloc_can_sleep) {
- /*
- * CANSLEEP page allocation failed, so guest
- * is under severe memory pressure. Quickly
- * decrease allocation rate.
- */
- b->rate_alloc = max(b->rate_alloc / 2,
- VMW_BALLOON_RATE_ALLOC_MIN);
- break;
- }
-
- /*
- * NOSLEEP page allocation failed, so the guest is
- * under memory pressure. Let us slow down page
- * allocations for next few cycles so that the guest
- * gets out of memory pressure. Also, if we already
- * allocated b->rate_alloc pages, let's pause,
- * otherwise switch to sleeping allocations.
- */
- b->slow_allocation_cycles = VMW_BALLOON_SLOW_CYCLES;
-
- if (i >= b->rate_alloc)
- break;
-
- alloc_can_sleep = true;
- /* Lower rate for sleeping allocations. */
- rate = b->rate_alloc;
- }
-
- if (++allocations > VMW_BALLOON_YIELD_THRESHOLD) {
- cond_resched();
- allocations = 0;
- }
-
- if (i >= rate) {
- /* We allocated enough pages, let's take a break. */
- break;
- }
- }
-
- /*
- * We reached our goal without failures so try increasing
- * allocation rate.
- */
- if (error == 0 && i >= b->rate_alloc) {
- unsigned int mult = i / b->rate_alloc;
-
- b->rate_alloc =
- min(b->rate_alloc + mult * VMW_BALLOON_RATE_ALLOC_INC,
- VMW_BALLOON_RATE_ALLOC_MAX);
- }
-
- vmballoon_release_refused_pages(b);
-}
-
-/*
- * Decrease the size of the balloon allowing guest to use more memory.
- */
-static void vmballoon_deflate(struct vmballoon *b)
-{
- struct page *page, *next;
- unsigned int i = 0;
- unsigned int goal;
- int error;
-
- pr_debug("%s - size: %d, target %d\n", __func__, b->size, b->target);
-
- /* limit deallocation rate */
- goal = min(b->size - b->target, b->rate_free);
-
- pr_debug("%s - goal: %d, rate: %d\n", __func__, goal, b->rate_free);
-
- /* free pages to reach target */
- list_for_each_entry_safe(page, next, &b->pages, lru) {
- error = vmballoon_release_page(b, page);
- if (error) {
- /* quickly decrease rate in case of error */
- b->rate_free = max(b->rate_free / 2,
- VMW_BALLOON_RATE_FREE_MIN);
- return;
- }
-
- if (++i >= goal)
- break;
- }
-
- /* slowly increase rate if there were no errors */
- b->rate_free = min(b->rate_free + VMW_BALLOON_RATE_FREE_INC,
- VMW_BALLOON_RATE_FREE_MAX);
-}
-
-/*
- * Balloon work function: reset protocol, if needed, get the new size and
- * adjust balloon as needed. Repeat in 1 sec.
- */
-static void vmballoon_work(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct vmballoon *b = container_of(dwork, struct vmballoon, dwork);
- unsigned int target;
-
- STATS_INC(b->stats.timer);
-
- if (b->reset_required)
- vmballoon_reset(b);
-
- if (b->slow_allocation_cycles > 0)
- b->slow_allocation_cycles--;
-
- if (vmballoon_send_get_target(b, &target)) {
- /* update target, adjust size */
- b->target = target;
-
- if (b->size < target)
- vmballoon_inflate(b);
- else if (b->size > target)
- vmballoon_deflate(b);
- }
-
- /*
- * We are using a freezable workqueue so that balloon operations are
- * stopped while the system transitions to/from sleep/hibernation.
- */
- queue_delayed_work(system_freezable_wq,
- dwork, round_jiffies_relative(HZ));
-}
-
-/*
- * DEBUGFS Interface
- */
-#ifdef CONFIG_DEBUG_FS
-
-static int vmballoon_debug_show(struct seq_file *f, void *offset)
-{
- struct vmballoon *b = f->private;
- struct vmballoon_stats *stats = &b->stats;
-
- /* format size info */
- seq_printf(f,
- "target: %8d pages\n"
- "current: %8d pages\n",
- b->target, b->size);
-
- /* format rate info */
- seq_printf(f,
- "rateNoSleepAlloc: %8d pages/sec\n"
- "rateSleepAlloc: %8d pages/sec\n"
- "rateFree: %8d pages/sec\n",
- VMW_BALLOON_NOSLEEP_ALLOC_MAX,
- b->rate_alloc, b->rate_free);
-
- seq_printf(f,
- "\n"
- "timer: %8u\n"
- "start: %8u (%4u failed)\n"
- "guestType: %8u (%4u failed)\n"
- "lock: %8u (%4u failed)\n"
- "unlock: %8u (%4u failed)\n"
- "target: %8u (%4u failed)\n"
- "primNoSleepAlloc: %8u (%4u failed)\n"
- "primCanSleepAlloc: %8u (%4u failed)\n"
- "primFree: %8u\n"
- "errAlloc: %8u\n"
- "errFree: %8u\n",
- stats->timer,
- stats->start, stats->start_fail,
- stats->guest_type, stats->guest_type_fail,
- stats->lock, stats->lock_fail,
- stats->unlock, stats->unlock_fail,
- stats->target, stats->target_fail,
- stats->alloc, stats->alloc_fail,
- stats->sleep_alloc, stats->sleep_alloc_fail,
- stats->free,
- stats->refused_alloc, stats->refused_free);
-
- return 0;
-}
-
-static int vmballoon_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, vmballoon_debug_show, inode->i_private);
-}
-
-static const struct file_operations vmballoon_debug_fops = {
- .owner = THIS_MODULE,
- .open = vmballoon_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int __init vmballoon_debugfs_init(struct vmballoon *b)
-{
- int error;
-
- b->dbg_entry = debugfs_create_file("vmmemctl", S_IRUGO, NULL, b,
- &vmballoon_debug_fops);
- if (IS_ERR(b->dbg_entry)) {
- error = PTR_ERR(b->dbg_entry);
- pr_err("failed to create debugfs entry, error: %d\n", error);
- return error;
- }
-
- return 0;
-}
-
-static void __exit vmballoon_debugfs_exit(struct vmballoon *b)
-{
- debugfs_remove(b->dbg_entry);
-}
-
-#else
-
-static inline int vmballoon_debugfs_init(struct vmballoon *b)
-{
- return 0;
-}
-
-static inline void vmballoon_debugfs_exit(struct vmballoon *b)
-{
-}
-
-#endif /* CONFIG_DEBUG_FS */
-
-static int __init vmballoon_init(void)
-{
- int error;
-
- /*
- * Check if we are running on VMware's hypervisor and bail out
- * if we are not.
- */
- if (x86_hyper != &x86_hyper_vmware)
- return -ENODEV;
-
- INIT_LIST_HEAD(&balloon.pages);
- INIT_LIST_HEAD(&balloon.refused_pages);
-
- /* initialize rates */
- balloon.rate_alloc = VMW_BALLOON_RATE_ALLOC_MAX;
- balloon.rate_free = VMW_BALLOON_RATE_FREE_MAX;
-
- INIT_DELAYED_WORK(&balloon.dwork, vmballoon_work);
-
- /*
- * Start balloon.
- */
- if (!vmballoon_send_start(&balloon)) {
- pr_err("failed to send start command to the host\n");
- return -EIO;
- }
-
- if (!vmballoon_send_guest_id(&balloon)) {
- pr_err("failed to send guest ID to the host\n");
- return -EIO;
- }
-
- error = vmballoon_debugfs_init(&balloon);
- if (error)
- return error;
-
- queue_delayed_work(system_freezable_wq, &balloon.dwork, 0);
-
- return 0;
-}
-module_init(vmballoon_init);
-
-static void __exit vmballoon_exit(void)
-{
- cancel_delayed_work_sync(&balloon.dwork);
-
- vmballoon_debugfs_exit(&balloon);
-
- /*
- * Deallocate all reserved memory, and reset connection with monitor.
- * Reset connection before deallocating memory to avoid potential for
- * additional spurious resets from guest touching deallocated pages.
- */
- vmballoon_send_start(&balloon);
- vmballoon_pop(&balloon);
-}
-module_exit(vmballoon_exit);
diff --git a/ANDROID_3.4.5/drivers/misc/wl127x-rfkill.c b/ANDROID_3.4.5/drivers/misc/wl127x-rfkill.c
deleted file mode 100644
index f5b95152..00000000
--- a/ANDROID_3.4.5/drivers/misc/wl127x-rfkill.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Bluetooth TI wl127x rfkill power control via GPIO
- *
- * Copyright (C) 2009 Motorola, Inc.
- * Copyright (C) 2008 Texas Instruments
- * Initial code: Pavan Savoy <pavan.savoy@gmail.com> (wl127x_power.c)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/rfkill.h>
-#include <linux/platform_device.h>
-#include <linux/wl127x-rfkill.h>
-
-static int wl127x_rfkill_set_power(void *data, enum rfkill_state state)
-{
- int nshutdown_gpio = (int) data;
-
- switch (state) {
- case RFKILL_STATE_UNBLOCKED:
- gpio_set_value(nshutdown_gpio, 1);
- break;
- case RFKILL_STATE_SOFT_BLOCKED:
- gpio_set_value(nshutdown_gpio, 0);
- break;
- default:
- printk(KERN_ERR "invalid bluetooth rfkill state %d\n", state);
- }
- return 0;
-}
-
-static int wl127x_rfkill_probe(struct platform_device *pdev)
-{
- int rc = 0;
- struct wl127x_rfkill_platform_data *pdata = pdev->dev.platform_data;
- enum rfkill_state default_state = RFKILL_STATE_SOFT_BLOCKED; /* off */
-
- rc = gpio_request(pdata->nshutdown_gpio, "wl127x_nshutdown_gpio");
- if (unlikely(rc))
- return rc;
-
- rc = gpio_direction_output(pdata->nshutdown_gpio, 0);
- if (unlikely(rc))
- return rc;
-
- rfkill_set_default(RFKILL_TYPE_BLUETOOTH, default_state);
- wl127x_rfkill_set_power(NULL, default_state);
-
- pdata->rfkill = rfkill_allocate(&pdev->dev, RFKILL_TYPE_BLUETOOTH);
- if (unlikely(!pdata->rfkill))
- return -ENOMEM;
-
- pdata->rfkill->name = "wl127x";
- pdata->rfkill->state = default_state;
- /* userspace cannot take exclusive control */
- pdata->rfkill->user_claim_unsupported = 1;
- pdata->rfkill->user_claim = 0;
- pdata->rfkill->data = (void *) pdata->nshutdown_gpio;
- pdata->rfkill->toggle_radio = wl127x_rfkill_set_power;
-
- rc = rfkill_register(pdata->rfkill);
-
- if (unlikely(rc))
- rfkill_free(pdata->rfkill);
-
- return 0;
-}
-
-static int wl127x_rfkill_remove(struct platform_device *pdev)
-{
- struct wl127x_rfkill_platform_data *pdata = pdev->dev.platform_data;
-
- rfkill_unregister(pdata->rfkill);
- rfkill_free(pdata->rfkill);
- gpio_free(pdata->nshutdown_gpio);
-
- return 0;
-}
-
-static struct platform_driver wl127x_rfkill_platform_driver = {
- .probe = wl127x_rfkill_probe,
- .remove = wl127x_rfkill_remove,
- .driver = {
- .name = "wl127x-rfkill",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init wl127x_rfkill_init(void)
-{
- return platform_driver_register(&wl127x_rfkill_platform_driver);
-}
-
-static void __exit wl127x_rfkill_exit(void)
-{
- platform_driver_unregister(&wl127x_rfkill_platform_driver);
-}
-
-module_init(wl127x_rfkill_init);
-module_exit(wl127x_rfkill_exit);
-
-MODULE_ALIAS("platform:wl127x");
-MODULE_DESCRIPTION("wl127x-rfkill");
-MODULE_AUTHOR("Motorola");
-MODULE_LICENSE("GPL");