[OpenWrt-Devel] [PATCH 2/3] brcm2708: remove linux 4.1 support

Álvaro Fernández Rojas noltari at gmail.com
Sun Feb 21 07:38:19 EST 2016


Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
---
 target/linux/brcm2708/bcm2708/config-4.1           |   355 -
 target/linux/brcm2708/bcm2709/config-4.1           |   386 -
 target/linux/brcm2708/modules.mk                   |    83 +-
 .../0001-Main-bcm2708-bcm2709-linux-port.patch     |  6829 ---
 .../patches-4.1/0002-Add-bcm2708_gpio-driver.patch |   615 -
 .../0003-mailbox-bcm2708-Add-bcm2708-vcio.patch    |   623 -
 .../patches-4.1/0004-Add-dwc_otg-driver.patch      | 61067 -------------------
 .../patches-4.1/0005-bcm2708-watchdog-driver.patch |   432 -
 .../0006-bcm2708-framebuffer-driver.patch          |  3432 --
 .../0007-dmaengine-Add-support-for-BCM2708.patch   |  1756 -
 .../0008-MMC-added-alternative-MMC-driver.patch    |  1805 -
 ...835-sdhost-driver-and-an-overlay-to-enabl.patch |  1765 -
 ...ma-Add-vc_cma-driver-to-enable-use-of-CMA.patch |  1308 -
 .../0011-bcm2708-alsa-sound-driver.patch           |  2818 -
 .../patches-4.1/0012-bcm2708-vchiq-driver.patch    | 13145 ----
 .../0013-vc_mem-Add-vc_mem-driver.patch            |   992 -
 ...deoCore-shared-memory-service-for-BCM2835.patch |  4387 --
 ...g-hardware-random-number-generator-driver.patch |   172 -
 ...6-lirc-added-support-for-RaspberryPi-GPIO.patch |   848 -
 .../patches-4.1/0017-Add-cpufreq-driver.patch      |   268 -
 ...-thermal-driver-for-reporting-core-temper.patch |   288 -
 .../0019-Add-Chris-Boot-s-spi-driver.patch         |   901 -
 .../0020-Add-Chris-Boot-s-i2c-driver.patch         |   792 -
 .../0021-bcm2835-add-v4l2-camera-device.patch      |  7280 ---
 ...-Update-to-upstream-version-with-overlay-.patch |  5175 --
 ...-mkknlimg-and-knlinfo-scripts-from-tools-.patch |   481 -
 ...port-for-the-CONFIG_CMDLINE_EXTEND-option.patch |    58 -
 ...0025-BCM2708-Add-core-Device-Tree-support.patch |  3750 --
 .../0026-fbdev-add-FBIOCOPYAREA-ioctl.patch        |    91 -
 ...up-console-framebuffer-imageblit-function.patch |   209 -
 ...0-Allow-mac-address-to-be-set-in-smsc95xx.patch |    91 -
 ...e-realtime-clock-1-wire-chip-DS1307-and-1.patch |   386 -
 ...032-Added-Device-IDs-for-August-DVB-T-205.patch |    22 -
 ...le-CONFIG_MEMCG-but-leave-it-disabled-due.patch |    53 -
 .../0034-ASoC-Add-support-for-BCM2708.patch        |  1135 -
 .../0035-ASoC-Add-support-for-PCM5102A-codec.patch |   120 -
 ...036-BCM2708-Add-I2S-support-to-board-file.patch |    87 -
 .../0037-ASoC-Add-support-for-HifiBerry-DAC.patch  |   144 -
 ...8-BCM2708-Add-HifiBerry-DAC-to-board-file.patch |    48 -
 ...0039-ASoC-BCM2708-Add-support-for-RPi-DAC.patch |   281 -
 ...-Implement-MCLK-configuration-options-add.patch |    40 -
 ...d-support-for-HiFiBerry-Digi.-Driver-is-b.patch |   260 -
 ...ed-support-for-HiFiBerry-Digi-board-Board.patch |    47 -
 ...-Set-idle_bias_off-to-false-Idle-bias-has.patch |    22 -
 ...audIO-Sound-Card-support-for-Raspberry-Pi.patch |   201 -
 ...around-for-issue-where-dirty-page-count-g.patch |    27 -
 ...ce-default-mouse-polling-interval-to-60Hz.patch |    36 -
 .../0047-Added-support-for-HiFiBerry-DAC.patch     |   204 -
 ...r-for-HiFiBerry-Amp-amplifier-add-on-boar.patch |   852 -
 ...ow-option-card-devices-to-be-configured-v.patch |    25 -
 ...ice-Tree-support-for-some-RPi-audio-cards.patch |   353 -
 ...rt-to-reserve-enable-a-GPIO-pin-to-be-use.patch |   134 -
 ...ate-ds1307-driver-for-device-tree-support.patch |    27 -
 ...Add-pwr_led-and-the-required-input-trigge.patch |   106 -
 ...m2709-Simplify-and-strip-down-IRQ-handler.patch |   222 -
 ...LED-input-trigger-implementation-for-3.19.patch |    83 -
 ...2835-Set-base-to-0-give-expected-gpio-num.patch |    22 -
 ...2835-bcm2835_gpio_direction_output-must-s.patch |    28 -
 ...2835-Fix-interrupt-handling-for-GPIOs-28-.patch |   146 -
 ...2835-Only-request-the-interrupts-listed-i.patch |    27 -
 ...d-device-tree-compatible-string-and-an-ov.patch |    34 -
 .../0061-Add-driver-for-rpi-proto.patch            |   210 -
 .../0062-Add-Device-Tree-support-for-RPi-DAC.patch |    73 -
 .../0063-config-Add-default-configs.patch          |  2421 -
 ...0064-smsx95xx-fix-crimes-against-truesize.patch |    33 -
 ...65-smsc95xx-Disable-turbo-mode-by-default.patch |    20 -
 ...-parameter-to-mmc-multi_io_quirk-callback.patch |    75 -
 .../0067-bcm2835-bcm2835_defconfig.patch           |  1330 -
 .../0068-BCM270x_DT-Add-mailbox-bcm2708-vcio.patch |    39 -
 ...Add-touchscreen-driver-for-pi-LCD-display.patch |   310 -
 ...opy_to_user-and-__copy_from_user-performa.patch |  1496 -
 ...io-Create-the-platform-device-if-the-DT-n.patch |    52 -
 ...RM-bcm2835-Set-Serial-number-and-Revision.patch |    59 -
 ...d-force_core-command-line-setting-to-boot.patch |    69 -
 ...0x-Enable-the-building-of-pinctrl-bcm2835.patch |    19 -
 ...-BCM270X_DT-Document-the-i2s-mmap-overlay.patch |    24 -
 ...dhost-Improve-error-handling-and-recovery.patch |  1088 -
 ...2835-Add-the-Raspberry-Pi-firmware-driver.patch |   426 -
 ...-Enable-ZSMALLOC-ZRAM-and-PGTABLE_MAPPING.patch |    50 -
 ...406-overlay-Add-rpi-ft5406-driver-as-modu.patch |    78 -
 ...detection-failure-Check-that-the-buffer-r.patch |    21 -
 .../0081-config-Enable-8250-serial-port.patch      |    46 -
 .../0082-config-Enable-POWER_RESET_GPIO.patch      |    32 -
 ...o-Remove-restriction-of-only-a-single-ins.patch |    45 -
 ...Create-a-core-clock-use-it-for-SPI-and-sd.patch |   141 -
 ...CM270X_DT-Add-MCP7941X-to-i2c-rtc-overlay.patch |    51 -
 .../0086-dts-overlays-document-DHT11-overlay.patch |    26 -
 ...poweroff-Allow-it-to-work-on-Raspberry-Pi.patch |   108 -
 ...Default-Compute-Module-i2c-i2s-and-spi-su.patch |    90 -
 ...Sort-nodes-by-bus-address-and-consolidate.patch |   234 -
 ...c-bcm2708-BCM270X_DT-Add-support-for-I2C2.patch |   163 -
 ...Correct-the-lirc-rpi-overlay-documentatio.patch |    26 -
 ...sdhost-Further-improve-overclock-back-off.patch |   292 -
 ...-Increase-timeouts-to-allow-larger-transf.patch |    38 -
 ...bcm2708-Increase-timeout-from-150ms-to-1s.patch |    24 -
 ...-Don-t-use-static-pin-configuration-with-.patch |    39 -
 ...-Don-t-use-static-pin-configuration-with-.patch |    23 -
 ...erial-8250-Don-t-crash-when-nr_uarts-is-0.patch |    20 -
 ...98-BCM270X_DT-Add-overlay-to-enable-uart1.patch |   152 -
 ...cm2835-Support-pin-groups-other-than-7-11.patch |    80 -
 ...DT-Change-pio_limit-of-sdhost-driver-to-1.patch |    20 -
 ...01-bcm2835-sdhost-Clear-HBLC-for-PIO-mode.patch |    34 -
 .../0102-BCM270X_DT-I2S-needs-function-Alt2.patch  |    56 -
 ...nfigs-Incorporate-v4.1-dependency-changes.patch |   159 -
 ...onfigs-Add-SND_SOC_WM8804_I2C-for-HifiBer.patch |    33 -
 ...h-BCM270X_DT-I2S-only-needs-Alt2-on-28-31.patch |    45 -
 .../0106-vchiq_arm-Two-cacheing-fixes.patch        |   268 -
 ...DT-Overlay-for-the-Fen-Logic-VGA666-board.patch |    77 -
 ...08-Added-support-for-2-mcp2515-CAN-Bus-IC.patch |   122 -
 ...09-mailbox-Enable-BCM2835-mailbox-support.patch |   274 -
 ...ailbox-bcm2835-Fix-mailbox-full-detection.patch |    39 -
 ...0111-mailbox-bcm2835-Support-ARCH_BCM270x.patch |   112 -
 ...-Add-the-firmware-driver-information-to-t.patch |    34 -
 ...irmware-bcm2835-Add-missing-property-tags.patch |    62 -
 ...114-firmware-bcm2835-Support-ARCH_BCM270x.patch |   106 -
 ...rmware-bcm2835-Support-legacy-mailbox-API.patch |    88 -
 .../0116-char-broadcom-Add-vcio-module.patch       |   219 -
 .../0117-BCM270x-Switch-to-firmware-driver.patch   |   595 -
 .../0118-bcm2835-Switch-to-firmware-driver.patch   |    54 -
 ...-pull-request-1059-from-pelwell-rpi-4.0.y.patch |   190 -
 .../0120-vchiq_arm-Sort-out-the-vmalloc-case.patch |    39 -
 ...spidev-compatible-string-to-silence-warni.patch |    21 -
 ...ull-request-1043-from-XECDesign-sense-4.0.patch |   894 -
 ...-gpio-Implement-the-brightness_get-method.patch |    43 -
 ...cm2708-dmaengine-Fix-memory-leak-when-sto.patch |    20 -
 .../0125-BCM270X_DT-Fix-I2S-register-map.patch     |    22 -
 .../0126-BCM2835_DT-Fix-I2S-register-map.patch     |    50 -
 ...onfig-Enable-SHT-drivers-for-raspberry-pi.patch |    40 -
 ...CM270X_DT-Correct-typo-in-overlays-README.patch |    20 -
 ...9-bcm2835-sdhost-Add-the-ERASE-capability.patch |    21 -
 ...0-bcm2835-sdhost-Ignore-CRC7-for-MMC-CMD1.patch |    64 -
 ...70X_DT-Add-unit-address-to-gpio-node-name.patch |    20 -
 ...T-Use-i2c_arm-for-rtc-and-bmp085-overlays.patch |    32 -
 ...DT-CM-dtparams-for-audio-watchdog-and-RNG.patch |    30 -
 .../patches-4.1/0134-vchiq-Use-firmware-API.patch  |   112 -
 .../0135-thermal-bcm2835-Use-firmware-API.patch    |   281 -
 .../0136-cpufreq-bcm2835-Use-firmware-API.patch    |   186 -
 .../0137-fbdev-bcm2708-Use-firmware-API.patch      |   413 -
 ...Add-firmware-property-to-affected-devices.patch |    79 -
 .../0139-rpi-ft5406-Use-firmware-API.patch         |   138 -
 .../0140-irqchip-bcm2835-Add-FIQ-support.patch     |   130 -
 .../0141-dwc_otg-Add-ARCH_BCM2835-support.patch    |    49 -
 .../patches-4.1/0142-bcm2835-Use-DWC_OTG.patch     |    41 -
 .../0143-Fix-RASPBERRYPI_FIRMWARE-dependents.patch |    73 -
 .../0144-vc_mem-Remove-unnecessary-include.patch   |    23 -
 .../0145-configs-Remove-BCM2708_MBOX.patch         |    45 -
 .../0146-bcm2708-vcio-Remove-module.patch          |   266 -
 ...rmware-bcm2835-Support-legacy-mailbox-API.patch |    89 -
 ...2835-Clear-the-event-latch-register-when-.patch |    37 -
 ..._fsm-Make-high-speed-isochronous-strided-.patch |   134 -
 .../0150-added-basic-docker-support.patch          |    62 -
 ...cm2835-camera-planar-packed-stride-length.patch |   170 -
 ...BCM270X_DT-Add-pwm-and-pwm-2chan-overlays.patch |   250 -
 ...-fallback-to-interrupt-for-polling-timeou.patch |   136 -
 ...-enable-dma-modes-for-transfers-meeting-c.patch |   423 -
 ...-fix-kbuild-compile-warnings-errors-and-a.patch |    56 -
 ...bcm2835-bcm2835_dma_release-can-be-static.patch |    32 -
 ...9-dt-overlay-to-enable-dma-for-spi-driver.patch |    45 -
 ...ay-added-documentation-of-spi-dma-overlay.patch |    25 -
 ...e-fb-add-low-light-mode-and-gamma-control.patch |   141 -
 ...BCM270X_DT-README-add-note-on-indentation.patch |    22 -
 ...maengine-Use-more-DMA-channels-but-not-12.patch |   173 -
 ...-fbtft-Add-reset-to-fbtft_init_display_dt.patch |    32 -
 ...-BCM270X_DT-mz61581-Revert-to-spi-bcm2708.patch |    31 -
 ...omem-device-for-rootless-user-GPIO-access.patch |   336 -
 ...67-tpa6130a2-Add-headphone-switch-control.patch |    91 -
 .../patches-4.1/0168-RaspiDAC3-support.patch       |   335 -
 .../0169-config-Add-SND_SOC_ADAU1701-module.patch  |    30 -
 ...ULL-pointer-dereference-when-closing-driv.patch |    98 -
 ...remove-redundant-code-as-detected-by-stat.patch |    32 -
 ...remove-unnecessary-initialization-of-resu.patch |    29 -
 ...ent-res_stats-MAP_FAIL-stats-before-we-po.patch |    34 -
 ...35-camera-check-for-scene-not-being-found.patch |    31 -
 ...35-memcpy-port-data-to-m-rather-than-rmsg.patch |    25 -
 ...-fix-overflow-in-calculation-of-transfer-.patch |    53 -
 .../0177-BCM270X_DT-Add-SDIO-overlay.patch         |    80 -
 ...M270X_DT-Use-fixed-factor-clock-for-uart1.patch |    92 -
 ...-Don-t-overwrite-MMC-capabilities-from-DT.patch |    23 -
 ...-BCM270X_DT-mz61581-Revert-to-spi-bcm2708.patch |    28 -
 ...81-BCM270X_DT-mz61581-Set-txbuflen-to-32k.patch |    47 -
 ...pi-bcm2835-BUG-fix-wrong-use-of-PAGE_MASK.patch |    44 -
 .../0183-Use-dts-dirs-feature-for-overlays.patch   |    37 -
 ...CIFS_DFS_UPCALL-CIFS_ACL-CIFS_SMB2-CIFS_F.patch |    37 -
 .../brcm2708/patches-4.1/0189-Add-SMI-driver.patch |  2028 -
 .../patches-4.1/0190-Add-SMI-NAND-driver.patch     |   491 -
 .../0191-BCM270X_DT-Document-SMI-overlay.patch     |    59 -
 ...ce-host-mode-to-fix-incorrect-compute-mod.patch |    21 -
 .../patches-4.1/0193-config-Add-CONFIG_UHID.patch  |    30 -
 ...194-Add-support-for-the-HiFiBerry-DAC-Pro.patch |   539 -
 ...onfig-Add-CONFIG_CRYPTO_USER_API_SKCIPHER.patch |    30 -
 ...options-for-supporting-openlabs-802.15.4-.patch |    55 -
 .../0197-BCM270X_DT-Add-at86rf233-overlay.patch    |   130 -
 ...m2835-gpiomem-Fix-for-ARCH_BCM2835-builds.patch |    67 -
 ...s-mkknlimg-Improve-ARCH_BCM2835-detection.patch |    90 -
 ...Make-mmc-overlay-compatible-with-current-.patch |    39 -
 ...DT-Reduce-default-at86rf233-SPI-frequency.patch |    36 -
 .../0202-New-overlay-for-PiScreen2r.patch          |   148 -
 ..._display-add-backlight-driver-and-overlay.patch |   250 -
 ...upport-for-FocalTech-FT6236-touchscreen-c.patch |   434 -
 ...6236-do-not-explicitly-set-driver-s-owner.patch |    24 -
 ...6-change-module-license-string-to-match-c.patch |    22 -
 .../0208-config-Add-TOUCHSCREEN_FT6236.patch       |    30 -
 ...pio-module-and-add-a-device-tree-overlay-.patch |    96 -
 .../patches-4.1/0210-config-Add-MCP320X.patch      |    31 -
 ...verlay-for-Adafruit-PiTFT-2.8-capacitive-.patch |   145 -
 ...Use-interruptible-sleep-to-avoid-high-loa.patch |    21 -
 ...-ADD-CONFIG_FB_UDL-module-USB-displaylink.patch |    30 -
 ...2-Return-buffers-to-videobuf2-on-shutdown.patch |    23 -
 .../0215-config-Add-FB_TFT_ILI9163-module.patch    |    30 -
 ...refine-appropriate-behaviors-to-unsupport.patch |    38 -
 ...dts-Added-overlay-for-gpio_ir_recv-driver.patch |    95 -
 ...8-BCM270X_DT-Fix-overlay-README-anomalies.patch |    73 -
 ...O-overlay-add-poll_once-boolean-parameter.patch |    46 -
 ...CM270X_DT-Use-clk_core-for-I2C-interfaces.patch |   110 -
 ...-Use-the-sdhost-MMC-controller-by-default.patch |   269 -
 ...ost-Don-t-log-timeout-errors-unless-debug.patch |    43 -
 216 files changed, 10 insertions(+), 151539 deletions(-)
 delete mode 100644 target/linux/brcm2708/bcm2708/config-4.1
 delete mode 100644 target/linux/brcm2708/bcm2709/config-4.1
 delete mode 100644 target/linux/brcm2708/patches-4.1/0001-Main-bcm2708-bcm2709-linux-port.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0002-Add-bcm2708_gpio-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0003-mailbox-bcm2708-Add-bcm2708-vcio.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0004-Add-dwc_otg-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0005-bcm2708-watchdog-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0006-bcm2708-framebuffer-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0007-dmaengine-Add-support-for-BCM2708.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0008-MMC-added-alternative-MMC-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0009-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0010-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0011-bcm2708-alsa-sound-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0012-bcm2708-vchiq-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0013-vc_mem-Add-vc_mem-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0014-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0015-Add-hwrng-hardware-random-number-generator-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0016-lirc-added-support-for-RaspberryPi-GPIO.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0017-Add-cpufreq-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0018-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0019-Add-Chris-Boot-s-spi-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0020-Add-Chris-Boot-s-i2c-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0021-bcm2835-add-v4l2-camera-device.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0022-scripts-dtc-Update-to-upstream-version-with-overlay-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0023-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0024-fdt-Add-support-for-the-CONFIG_CMDLINE_EXTEND-option.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0025-BCM2708-Add-core-Device-Tree-support.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0026-fbdev-add-FBIOCOPYAREA-ioctl.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0029-Speed-up-console-framebuffer-imageblit-function.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0030-Allow-mac-address-to-be-set-in-smsc95xx.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0031-enabling-the-realtime-clock-1-wire-chip-DS1307-and-1.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0032-Added-Device-IDs-for-August-DVB-T-205.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0033-config-Enable-CONFIG_MEMCG-but-leave-it-disabled-due.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0034-ASoC-Add-support-for-BCM2708.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0035-ASoC-Add-support-for-PCM5102A-codec.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0036-BCM2708-Add-I2S-support-to-board-file.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0037-ASoC-Add-support-for-HifiBerry-DAC.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0038-BCM2708-Add-HifiBerry-DAC-to-board-file.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0039-ASoC-BCM2708-Add-support-for-RPi-DAC.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0040-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0041-ASoC-BCM-Add-support-for-HiFiBerry-Digi.-Driver-is-b.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0042-BCM2708-Added-support-for-HiFiBerry-Digi-board-Board.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0043-ASoC-wm8804-Set-idle_bias_off-to-false-Idle-bias-has.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0044-Add-IQaudIO-Sound-Card-support-for-Raspberry-Pi.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0045-vmstat-Workaround-for-issue-where-dirty-page-count-g.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0046-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0047-Added-support-for-HiFiBerry-DAC.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0048-Added-driver-for-HiFiBerry-Amp-amplifier-add-on-boar.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0049-bcm2708-Allow-option-card-devices-to-be-configured-v.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0050-Adding-Device-Tree-support-for-some-RPi-audio-cards.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0051-Added-support-to-reserve-enable-a-GPIO-pin-to-be-use.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0052-Update-ds1307-driver-for-device-tree-support.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0053-BCM270x_DT-Add-pwr_led-and-the-required-input-trigge.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0054-bcm2709-Simplify-and-strip-down-IRQ-handler.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0055-Fix-LED-input-trigger-implementation-for-3.19.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0056-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0057-pinctrl-bcm2835-bcm2835_gpio_direction_output-must-s.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0058-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0059-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0060-enc28j60-Add-device-tree-compatible-string-and-an-ov.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0061-Add-driver-for-rpi-proto.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0062-Add-Device-Tree-support-for-RPi-DAC.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0063-config-Add-default-configs.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0064-smsx95xx-fix-crimes-against-truesize.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0065-smsc95xx-Disable-turbo-mode-by-default.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0066-Add-blk_pos-parameter-to-mmc-multi_io_quirk-callback.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0067-bcm2835-bcm2835_defconfig.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0068-BCM270x_DT-Add-mailbox-bcm2708-vcio.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0069-rpi-ft5406-Add-touchscreen-driver-for-pi-LCD-display.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0070-Improve-__copy_to_user-and-__copy_from_user-performa.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0071-bcm2835-audio-Create-the-platform-device-if-the-DT-n.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0072-ARM-bcm2835-Set-Serial-number-and-Revision.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0073-platform-Add-force_core-command-line-setting-to-boot.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0074-mach-bcm270x-Enable-the-building-of-pinctrl-bcm2835.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0075-BCM270X_DT-Document-the-i2s-mmap-overlay.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0076-bcm2835-sdhost-Improve-error-handling-and-recovery.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0077-ARM-bcm2835-Add-the-Raspberry-Pi-firmware-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0078-config-Enable-ZSMALLOC-ZRAM-and-PGTABLE_MAPPING.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0079-Add-rpi-ft5406-overlay-Add-rpi-ft5406-driver-as-modu.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0080-Fix-driver-detection-failure-Check-that-the-buffer-r.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0081-config-Enable-8250-serial-port.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0082-config-Enable-POWER_RESET_GPIO.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0083-bcm2708-vcio-Remove-restriction-of-only-a-single-ins.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0084-BCM270X_DT-Create-a-core-clock-use-it-for-SPI-and-sd.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0085-BCM270X_DT-Add-MCP7941X-to-i2c-rtc-overlay.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0086-dts-overlays-document-DHT11-overlay.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0087-gpio-poweroff-Allow-it-to-work-on-Raspberry-Pi.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0088-BCM270x_DT-Default-Compute-Module-i2c-i2s-and-spi-su.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0089-BCM270X_DT-Sort-nodes-by-bus-address-and-consolidate.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0090-i2c-bcm2708-BCM270X_DT-Add-support-for-I2C2.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0091-BCM270X_DT-Correct-the-lirc-rpi-overlay-documentatio.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0092-bcm2835-sdhost-Further-improve-overclock-back-off.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0093-i2c-bcm2708-Increase-timeouts-to-allow-larger-transf.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0094-spi-bcm2708-Increase-timeout-from-150ms-to-1s.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0095-bcm2708-spi-Don-t-use-static-pin-configuration-with-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0096-bcm2708-i2s-Don-t-use-static-pin-configuration-with-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0097-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0098-BCM270X_DT-Add-overlay-to-enable-uart1.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0099-spi-bcm2835-Support-pin-groups-other-than-7-11.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0100-BCM270X_DT-Change-pio_limit-of-sdhost-driver-to-1.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0101-bcm2835-sdhost-Clear-HBLC-for-PIO-mode.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0102-BCM270X_DT-I2S-needs-function-Alt2.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0103-configs-Incorporate-v4.1-dependency-changes.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0104-bcmrpi_defconfigs-Add-SND_SOC_WM8804_I2C-for-HifiBer.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0105-squash-BCM270X_DT-I2S-only-needs-Alt2-on-28-31.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0106-vchiq_arm-Two-cacheing-fixes.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0107-BCM270X_DT-Overlay-for-the-Fen-Logic-VGA666-board.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0108-Added-support-for-2-mcp2515-CAN-Bus-IC.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0109-mailbox-Enable-BCM2835-mailbox-support.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0110-mailbox-bcm2835-Fix-mailbox-full-detection.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0111-mailbox-bcm2835-Support-ARCH_BCM270x.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0112-ARM-bcm2835-Add-the-firmware-driver-information-to-t.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0113-firmware-bcm2835-Add-missing-property-tags.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0114-firmware-bcm2835-Support-ARCH_BCM270x.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0115-firmware-bcm2835-Support-legacy-mailbox-API.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0116-char-broadcom-Add-vcio-module.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0117-BCM270x-Switch-to-firmware-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0118-bcm2835-Switch-to-firmware-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0119-Merge-pull-request-1059-from-pelwell-rpi-4.0.y.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0120-vchiq_arm-Sort-out-the-vmalloc-case.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0121-spidev-Add-spidev-compatible-string-to-silence-warni.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0122-Merge-pull-request-1043-from-XECDesign-sense-4.0.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0123-leds-gpio-Implement-the-brightness_get-method.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0124-dmaengine-bcm2708-dmaengine-Fix-memory-leak-when-sto.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0125-BCM270X_DT-Fix-I2S-register-map.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0126-BCM2835_DT-Fix-I2S-register-map.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0127-config-Enable-SHT-drivers-for-raspberry-pi.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0128-BCM270X_DT-Correct-typo-in-overlays-README.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0129-bcm2835-sdhost-Add-the-ERASE-capability.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0130-bcm2835-sdhost-Ignore-CRC7-for-MMC-CMD1.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0131-BCM270X_DT-Add-unit-address-to-gpio-node-name.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0132-BCM270X_DT-Use-i2c_arm-for-rtc-and-bmp085-overlays.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0133-BCM2708_DT-CM-dtparams-for-audio-watchdog-and-RNG.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0134-vchiq-Use-firmware-API.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0135-thermal-bcm2835-Use-firmware-API.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0136-cpufreq-bcm2835-Use-firmware-API.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0137-fbdev-bcm2708-Use-firmware-API.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0138-bcm2835-Add-firmware-property-to-affected-devices.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0139-rpi-ft5406-Use-firmware-API.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0140-irqchip-bcm2835-Add-FIQ-support.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0141-dwc_otg-Add-ARCH_BCM2835-support.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0142-bcm2835-Use-DWC_OTG.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0143-Fix-RASPBERRYPI_FIRMWARE-dependents.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0144-vc_mem-Remove-unnecessary-include.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0145-configs-Remove-BCM2708_MBOX.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0146-bcm2708-vcio-Remove-module.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0147-Revert-firmware-bcm2835-Support-legacy-mailbox-API.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0148-pinctrl-bcm2835-Clear-the-event-latch-register-when-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0149-dwc_otg-fiq_fsm-Make-high-speed-isochronous-strided-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0150-added-basic-docker-support.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0151-bcm2835-camera-planar-packed-stride-length.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0154-BCM270X_DT-Add-pwm-and-pwm-2chan-overlays.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0155-spi-bcm2835-fallback-to-interrupt-for-polling-timeou.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0156-spi-bcm2835-enable-dma-modes-for-transfers-meeting-c.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0157-spi-bcm2835-fix-kbuild-compile-warnings-errors-and-a.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0158-spi-bcm2835-bcm2835_dma_release-can-be-static.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0159-dt-overlay-to-enable-dma-for-spi-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0160-dt-overlay-added-documentation-of-spi-dma-overlay.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0161-rpisense-fb-add-low-light-mode-and-gamma-control.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0162-BCM270X_DT-README-add-note-on-indentation.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0163-bcm2708-dmaengine-Use-more-DMA-channels-but-not-12.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0164-staging-fbtft-Add-reset-to-fbtft_init_display_dt.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0165-BCM270X_DT-mz61581-Revert-to-spi-bcm2708.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0166-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0167-tpa6130a2-Add-headphone-switch-control.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0168-RaspiDAC3-support.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0169-config-Add-SND_SOC_ADAU1701-module.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0170-vchiq-fix-NULL-pointer-dereference-when-closing-driv.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0171-bcm2708_fb-remove-redundant-code-as-detected-by-stat.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0172-bcm2708_fb-remove-unnecessary-initialization-of-resu.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0173-vcsm-increment-res_stats-MAP_FAIL-stats-before-we-po.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0174-bcm2835-camera-check-for-scene-not-being-found.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0175-bcm2835-memcpy-port-data-to-m-rather-than-rmsg.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0176-spi-bcm2835-fix-overflow-in-calculation-of-transfer-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0177-BCM270X_DT-Add-SDIO-overlay.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0178-BCM270X_DT-Use-fixed-factor-clock-for-uart1.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0179-bcm2835-mmc-Don-t-overwrite-MMC-capabilities-from-DT.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0180-Revert-BCM270X_DT-mz61581-Revert-to-spi-bcm2708.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0181-BCM270X_DT-mz61581-Set-txbuflen-to-32k.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0182-backport-spi-bcm2835-BUG-fix-wrong-use-of-PAGE_MASK.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0183-Use-dts-dirs-feature-for-overlays.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0188-config-Add-CIFS_DFS_UPCALL-CIFS_ACL-CIFS_SMB2-CIFS_F.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0189-Add-SMI-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0190-Add-SMI-NAND-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0191-BCM270X_DT-Document-SMI-overlay.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0192-dwc_otg-Force-host-mode-to-fix-incorrect-compute-mod.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0193-config-Add-CONFIG_UHID.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0194-Add-support-for-the-HiFiBerry-DAC-Pro.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0195-config-Add-CONFIG_CRYPTO_USER_API_SKCIPHER.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0196-config-Add-options-for-supporting-openlabs-802.15.4-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0197-BCM270X_DT-Add-at86rf233-overlay.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0198-bcm2835-gpiomem-Fix-for-ARCH_BCM2835-builds.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0199-scripts-mkknlimg-Improve-ARCH_BCM2835-detection.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0200-BCM270X_DT-Make-mmc-overlay-compatible-with-current-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0201-BCM270X_DT-Reduce-default-at86rf233-SPI-frequency.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0202-New-overlay-for-PiScreen2r.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0203-rpi_display-add-backlight-driver-and-overlay.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0205-Input-add-support-for-FocalTech-FT6236-touchscreen-c.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0206-Input-ft6236-do-not-explicitly-set-driver-s-owner.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0207-Input-ft6236-change-module-license-string-to-match-c.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0208-config-Add-TOUCHSCREEN_FT6236.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0209-Build-i2c_gpio-module-and-add-a-device-tree-overlay-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0210-config-Add-MCP320X.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0211-dts-Added-overlay-for-Adafruit-PiTFT-2.8-capacitive-.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0212-rpi-ft5406-Use-interruptible-sleep-to-avoid-high-loa.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0213-config-ADD-CONFIG_FB_UDL-module-USB-displaylink.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0214-BCM2835-V4L2-Return-buffers-to-videobuf2-on-shutdown.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0215-config-Add-FB_TFT_ILI9163-module.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0216-bcm2709_fb-refine-appropriate-behaviors-to-unsupport.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0217-dts-Added-overlay-for-gpio_ir_recv-driver.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0218-BCM270X_DT-Fix-overlay-README-anomalies.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0219-SDIO-overlay-add-poll_once-boolean-parameter.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0220-BCM270X_DT-Use-clk_core-for-I2C-interfaces.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0221-bcm270x_dt-Use-the-sdhost-MMC-controller-by-default.patch
 delete mode 100644 target/linux/brcm2708/patches-4.1/0222-bcm2835-sdhost-Don-t-log-timeout-errors-unless-debug.patch

diff --git a/target/linux/brcm2708/bcm2708/config-4.1 b/target/linux/brcm2708/bcm2708/config-4.1
deleted file mode 100644
index 63801a2..0000000
--- a/target/linux/brcm2708/bcm2708/config-4.1
+++ /dev/null
@@ -1,355 +0,0 @@
-# CONFIG_AIO is not set
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_AMBA_PL08X is not set
-# CONFIG_APM_EMULATION is not set
-CONFIG_ARCH_BCM2708=y
-# CONFIG_ARCH_BCM2709 is not set
-CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
-CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
-CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
-# CONFIG_ARCH_HAS_SG_CHAIN is not set
-CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
-CONFIG_ARCH_SUPPORTS_UPROBES=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_USE_BUILTIN_BSWAP=y
-CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
-CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
-CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-# CONFIG_ARM_CPUIDLE is not set
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_ERRATA_411920=y
-CONFIG_ARM_L1_CACHE_SHIFT=5
-# CONFIG_ARM_SP805_WATCHDOG is not set
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_UNWIND=y
-CONFIG_AVERAGE=y
-# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_BACKLIGHT_RPI=y
-CONFIG_BCM2708_DT=y
-CONFIG_BCM2708_GPIO=y
-# CONFIG_BCM2708_NOL2CACHE is not set
-CONFIG_BCM2708_VCHIQ=y
-CONFIG_BCM2708_VCMEM=y
-# CONFIG_BCM2708_WDT is not set
-# CONFIG_BCM2835_DEVGPIOMEM is not set
-CONFIG_BCM2835_MBOX=y
-# CONFIG_BCM2835_SMI is not set
-CONFIG_BCM2835_WDT=y
-CONFIG_BCM_VCIO=y
-CONFIG_BCM_VC_CMA=y
-CONFIG_BCM_VC_SM=y
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_SD=y
-CONFIG_BRCM_CHAR_DRIVERS=y
-CONFIG_BUILD_BIN2C=y
-# CONFIG_CACHE_L2X0 is not set
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=16
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
-CONFIG_COMMON_CLK=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CPU_32v6=y
-CONFIG_CPU_ABRT_EV6=y
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-CONFIG_CPU_CACHE_V6=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_HAS_ASID=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_PABRT_V6=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_TLB_V6=y
-CONFIG_CPU_V6=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_WORKQUEUE=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-# CONFIG_DEBUG_UART_8250 is not set
-# CONFIG_DEBUG_USER is not set
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_DMADEVICES=y
-CONFIG_DMA_BCM2708=y
-CONFIG_DMA_BCM2708_LEGACY=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_FB=y
-CONFIG_FB_BCM2708=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_CMDLINE=y
-# CONFIG_FB_RPISENSE is not set
-CONFIG_FIQ=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x16=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_SUPPORT=y
-# CONFIG_FPE_FASTFPE is not set
-# CONFIG_FPE_NWFPE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-CONFIG_FREEZER=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IO=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_DEVRES=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
-# CONFIG_HAVE_ARCH_BITREVERSE is not set
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_HAVE_ARCH_PFN_VALID=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
-CONFIG_HAVE_BPF_JIT=y
-CONFIG_HAVE_CC_STACKPROTECTOR=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_CLK_PREPARE=y
-CONFIG_HAVE_CONTEXT_TRACKING=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DEBUG_KMEMLEAK=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DMA_CONTIGUOUS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_LZ4=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_HAVE_KERNEL_XZ=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
-CONFIG_HAVE_NET_DSA=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_OPTPROBES=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HAVE_PERF_REGS=y
-CONFIG_HAVE_PERF_USER_STACK_DUMP=y
-CONFIG_HAVE_PROC_CPU=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
-CONFIG_HAVE_UID16=y
-CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HZ_FIXED=0
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INPUT=y
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_IOMMU_HELPER=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_XZ is not set
-# CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGER_INPUT=y
-CONFIG_LIBFDT=y
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_MACH_BCM2708=y
-CONFIG_MAC_PARTITION=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MAILBOX=y
-CONFIG_MAX_RAW_DEVS=256
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BCM2835=y
-CONFIG_MMC_BCM2835_DMA=y
-CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2
-CONFIG_MMC_BCM2835_SDHOST=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=32
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MTD is not set
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_MACH_IO_H=y
-CONFIG_NEED_MACH_MEMORY_H=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NLS=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NO_BOOTMEM=y
-CONFIG_NO_HZ=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_OABI_COMPAT=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_NET=y
-CONFIG_OF_RESERVED_MEM=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_PAGE_OFFSET=0xC0000000
-# CONFIG_PCI_DOMAINS_GENERIC is not set
-# CONFIG_PCI_SYSCALL is not set
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYS_OFFSET=0
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_BCM2835=y
-# CONFIG_PL330_DMA is not set
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_PM_SLEEP=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_PWM=y
-CONFIG_PWM_BCM2835=y
-CONFIG_RASPBERRYPI_FIRMWARE=y
-CONFIG_RAW_DRIVER=y
-# CONFIG_RCU_STALL_COMMON is not set
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_SCHED_HRTICK=y
-CONFIG_SCSI=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_PROC_FS is not set
-# CONFIG_SERIAL_8250_DMA is not set
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_RUNTIME_UARTS=0
-# CONFIG_SERIAL_AMBA_PL010 is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_SERIAL_OF_PLATFORM=y
-# CONFIG_SQUASHFS is not set
-CONFIG_SRCU=y
-# CONFIG_STAGING is not set
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWIOTLB=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_TEXTSEARCH is not set
-CONFIG_THERMAL=y
-CONFIG_THERMAL_BCM2835=y
-# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
-# CONFIG_THERMAL_EMULATION is not set
-# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
-CONFIG_THERMAL_GOV_STEP_WISE=y
-# CONFIG_THERMAL_GOV_USER_SPACE is not set
-CONFIG_THERMAL_OF=y
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_UEVENT_HELPER_PATH=""
-# CONFIG_UID16 is not set
-CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_DWCOTG=y
-# CONFIG_USB_EHCI_HCD is not set
-CONFIG_USB_NET_DRIVERS=y
-CONFIG_USB_NET_SMSC95XX=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_UAS=y
-CONFIG_USB_USBNET=y
-CONFIG_USE_OF=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_VFP=y
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_CONSOLE_SLEEP=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/brcm2708/bcm2709/config-4.1 b/target/linux/brcm2708/bcm2709/config-4.1
deleted file mode 100644
index 65b80a3..0000000
--- a/target/linux/brcm2708/bcm2709/config-4.1
+++ /dev/null
@@ -1,386 +0,0 @@
-# CONFIG_AIO is not set
-CONFIG_ALIGNMENT_TRAP=y
-# CONFIG_AMBA_PL08X is not set
-# CONFIG_APM_EMULATION is not set
-# CONFIG_ARCH_BCM2708 is not set
-CONFIG_ARCH_BCM2709=y
-CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
-CONFIG_ARCH_HAS_BARRIERS=y
-CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
-CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
-# CONFIG_ARCH_HAS_SG_CHAIN is not set
-CONFIG_ARCH_HAS_TICK_BROADCAST=y
-CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_NR_GPIO=0
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
-CONFIG_ARCH_SUPPORTS_UPROBES=y
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_ARCH_USE_BUILTIN_BSWAP=y
-CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
-CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
-CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
-CONFIG_ARM=y
-CONFIG_ARM_AMBA=y
-CONFIG_ARM_ARCH_TIMER=y
-CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
-# CONFIG_ARM_CPUIDLE is not set
-CONFIG_ARM_CPU_SUSPEND=y
-CONFIG_ARM_L1_CACHE_SHIFT=6
-CONFIG_ARM_L1_CACHE_SHIFT_6=y
-# CONFIG_ARM_LPAE is not set
-# CONFIG_ARM_SP805_WATCHDOG is not set
-CONFIG_ARM_THUMB=y
-# CONFIG_ARM_THUMBEE is not set
-CONFIG_ARM_UNWIND=y
-CONFIG_ARM_VIRT_EXT=y
-CONFIG_AVERAGE=y
-# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_BACKLIGHT_RPI=y
-CONFIG_BCM2708_GPIO=y
-CONFIG_BCM2708_NOL2CACHE=y
-CONFIG_BCM2708_VCHIQ=y
-CONFIG_BCM2708_VCMEM=y
-# CONFIG_BCM2708_WDT is not set
-CONFIG_BCM2709_DT=y
-# CONFIG_BCM2835_DEVGPIOMEM is not set
-CONFIG_BCM2835_MBOX=y
-# CONFIG_BCM2835_SMI is not set
-CONFIG_BCM2835_WDT=y
-CONFIG_BCM_VCIO=y
-CONFIG_BCM_VC_CMA=y
-CONFIG_BCM_VC_SM=y
-# CONFIG_BLK_DEV_INITRD is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_SD=y
-CONFIG_BRCM_CHAR_DRIVERS=y
-CONFIG_BUILD_BIN2C=y
-# CONFIG_CACHE_L2X0 is not set
-CONFIG_CLKDEV_LOOKUP=y
-CONFIG_CLKSRC_OF=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_CMA=y
-CONFIG_CMA_ALIGNMENT=8
-CONFIG_CMA_AREAS=7
-# CONFIG_CMA_DEBUG is not set
-# CONFIG_CMA_DEBUGFS is not set
-CONFIG_CMA_SIZE_MBYTES=16
-# CONFIG_CMA_SIZE_SEL_MAX is not set
-CONFIG_CMA_SIZE_SEL_MBYTES=y
-# CONFIG_CMA_SIZE_SEL_MIN is not set
-# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
-CONFIG_CMDLINE="dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
-CONFIG_COMMON_CLK=y
-CONFIG_CONFIGFS_FS=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_CPU_32v6K=y
-CONFIG_CPU_32v7=y
-CONFIG_CPU_ABRT_EV7=y
-# CONFIG_CPU_BPREDICT_DISABLE is not set
-CONFIG_CPU_CACHE_V7=y
-CONFIG_CPU_CACHE_VIPT=y
-CONFIG_CPU_COPY_V6=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-CONFIG_CPU_HAS_ASID=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-CONFIG_CPU_IDLE=y
-CONFIG_CPU_IDLE_GOV_LADDER=y
-CONFIG_CPU_IDLE_GOV_MENU=y
-CONFIG_CPU_PABRT_V7=y
-CONFIG_CPU_PM=y
-CONFIG_CPU_RMAP=y
-CONFIG_CPU_TLB_V7=y
-CONFIG_CPU_V7=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_CRC32C=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_WORKQUEUE=y
-CONFIG_DCACHE_WORD_ACCESS=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
-# CONFIG_DEBUG_UART_8250 is not set
-# CONFIG_DEBUG_USER is not set
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_DMADEVICES=y
-CONFIG_DMA_BCM2708=y
-CONFIG_DMA_BCM2708_LEGACY=y
-CONFIG_DMA_CMA=y
-CONFIG_DMA_ENGINE=y
-CONFIG_DMA_OF=y
-CONFIG_DMA_VIRTUAL_CHANNELS=y
-CONFIG_DNOTIFY=y
-CONFIG_DTC=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_FB=y
-CONFIG_FB_BCM2708=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_CMDLINE=y
-# CONFIG_FB_RPISENSE is not set
-CONFIG_FIQ=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x16=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_SUPPORT=y
-# CONFIG_FPE_FASTFPE is not set
-# CONFIG_FPE_NWFPE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-CONFIG_FREEZER=y
-CONFIG_FS_MBCACHE=y
-CONFIG_FS_POSIX_ACL=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GENERIC_BUG=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
-CONFIG_GENERIC_IDLE_POLL_SETUP=y
-CONFIG_GENERIC_IO=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PINCONF=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_STRNCPY_FROM_USER=y
-CONFIG_GENERIC_STRNLEN_USER=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_DEVRES=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
-CONFIG_HAVE_ARCH_BITREVERSE=y
-CONFIG_HAVE_ARCH_JUMP_LABEL=y
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_HAVE_ARCH_PFN_VALID=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_HAVE_ARM_ARCH_TIMER=y
-# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
-CONFIG_HAVE_BPF_JIT=y
-CONFIG_HAVE_CC_STACKPROTECTOR=y
-CONFIG_HAVE_CLK=y
-CONFIG_HAVE_CLK_PREPARE=y
-CONFIG_HAVE_CONTEXT_TRACKING=y
-CONFIG_HAVE_C_RECORDMCOUNT=y
-CONFIG_HAVE_DEBUG_KMEMLEAK=y
-CONFIG_HAVE_DMA_API_DEBUG=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_HAVE_DMA_CONTIGUOUS=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
-CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
-CONFIG_HAVE_KERNEL_GZIP=y
-CONFIG_HAVE_KERNEL_LZ4=y
-CONFIG_HAVE_KERNEL_LZMA=y
-CONFIG_HAVE_KERNEL_LZO=y
-CONFIG_HAVE_KERNEL_XZ=y
-CONFIG_HAVE_MEMBLOCK=y
-CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
-CONFIG_HAVE_NET_DSA=y
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_OPTPROBES=y
-CONFIG_HAVE_PERF_EVENTS=y
-CONFIG_HAVE_PERF_REGS=y
-CONFIG_HAVE_PERF_USER_STACK_DUMP=y
-CONFIG_HAVE_PROC_CPU=y
-CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
-CONFIG_HAVE_SMP=y
-CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
-CONFIG_HAVE_UID16=y
-CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_HW_CONSOLE=y
-CONFIG_HZ_FIXED=0
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INPUT=y
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_IOMMU_HELPER=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_WORK=y
-CONFIG_JBD2=y
-CONFIG_KERNEL_GZIP=y
-# CONFIG_KERNEL_XZ is not set
-# CONFIG_LCD_CLASS_DEVICE is not set
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGER_INPUT=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_SPIN_ON_OWNER=y
-CONFIG_LOGO=y
-CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_MACH_BCM2709=y
-CONFIG_MAC_PARTITION=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_MAILBOX=y
-CONFIG_MAX_RAW_DEVS=256
-CONFIG_MEMORY_ISOLATION=y
-CONFIG_MIGHT_HAVE_CACHE_L2X0=y
-CONFIG_MIGRATION=y
-CONFIG_MMC=y
-CONFIG_MMC_BCM2835=y
-CONFIG_MMC_BCM2835_DMA=y
-CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2
-CONFIG_MMC_BCM2835_SDHOST=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_BLOCK_MINORS=32
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_PLTFM=y
-CONFIG_MODULES_USE_ELF_REL=y
-# CONFIG_MTD is not set
-CONFIG_MUTEX_SPIN_ON_OWNER=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_MACH_IO_H=y
-CONFIG_NEED_MACH_MEMORY_H=y
-CONFIG_NEON=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NLS=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NO_BOOTMEM=y
-CONFIG_NO_HZ=y
-CONFIG_NO_HZ_COMMON=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_NR_CPUS=4
-CONFIG_OABI_COMPAT=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_NET=y
-CONFIG_OF_RESERVED_MEM=y
-CONFIG_OLD_SIGACTION=y
-CONFIG_OLD_SIGSUSPEND3=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_PAGE_OFFSET=0x80000000
-# CONFIG_PCI_DOMAINS_GENERIC is not set
-# CONFIG_PCI_SYSCALL is not set
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYS_OFFSET=0
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_BCM2835=y
-# CONFIG_PL330_DMA is not set
-CONFIG_PM=y
-CONFIG_PM_CLK=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_PM_SLEEP=y
-CONFIG_PM_SLEEP_SMP=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_PRINTK_TIME=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_PWM=y
-CONFIG_PWM_BCM2835=y
-CONFIG_RASPBERRYPI_FIRMWARE=y
-CONFIG_RAW_DRIVER=y
-CONFIG_RCU_STALL_COMMON=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RWSEM_SPIN_ON_OWNER=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_SCHED_HRTICK=y
-CONFIG_SCSI=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_PROC_FS is not set
-# CONFIG_SERIAL_8250_DMA is not set
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_RUNTIME_UARTS=0
-# CONFIG_SERIAL_AMBA_PL010 is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SMP=y
-CONFIG_SMP_ON_UP=y
-# CONFIG_SQUASHFS is not set
-CONFIG_SRCU=y
-# CONFIG_STAGING is not set
-CONFIG_STOP_MACHINE=y
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_SWIOTLB=y
-CONFIG_SWP_EMULATE=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-# CONFIG_TEXTSEARCH is not set
-CONFIG_THERMAL=y
-CONFIG_THERMAL_BCM2835=y
-# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
-CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
-# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
-# CONFIG_THERMAL_EMULATION is not set
-# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
-CONFIG_THERMAL_GOV_STEP_WISE=y
-# CONFIG_THERMAL_GOV_USER_SPACE is not set
-CONFIG_THERMAL_OF=y
-# CONFIG_THUMB2_KERNEL is not set
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_TREE_RCU=y
-CONFIG_UEVENT_HELPER_PATH=""
-# CONFIG_UID16 is not set
-CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
-CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_DWCOTG=y
-# CONFIG_USB_EHCI_HCD is not set
-CONFIG_USB_NET_DRIVERS=y
-CONFIG_USB_NET_SMSC95XX=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_UAS=y
-CONFIG_USB_USBNET=y
-CONFIG_USE_OF=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_VFP=y
-CONFIG_VFPv3=y
-CONFIG_VMSPLIT_2G=y
-# CONFIG_VMSPLIT_3G is not set
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_VT_CONSOLE_SLEEP=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_WATCHDOG_CORE=y
-CONFIG_XPS=y
-CONFIG_XZ_DEC_ARM=y
-CONFIG_XZ_DEC_BCJ=y
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/brcm2708/modules.mk b/target/linux/brcm2708/modules.mk
index 4a00152..d7ce7ea 100644
--- a/target/linux/brcm2708/modules.mk
+++ b/target/linux/brcm2708/modules.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012 OpenWrt.org
+# Copyright (C) 2012-2016 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -25,27 +25,6 @@ endef
 $(eval $(call KernelPackage,sound-arm-bcm2835))
 
 
-define KernelPackage/sound-soc-bcm2708-i2s
-  TITLE:=SoC Audio support for the Broadcom 2708 I2S module
-  KCONFIG:= \
-	CONFIG_BCM2708_SPIDEV=n \
-	CONFIG_MFD_RPISENSE_CORE=n \
-	CONFIG_SND_BCM2708_SOC_I2S \
-	CONFIG_SND_SOC_DMAENGINE_PCM=y \
-	CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
-  FILES:= \
-	$(LINUX_DIR)/sound/soc/bcm/snd-soc-bcm2708-i2s.ko
-  AUTOLOAD:=$(call AutoLoad,68,snd-soc-bcm2708-i2s)
-  DEPENDS:=@TARGET_brcm2708 @LINUX_4_1 +kmod-regmap +kmod-sound-soc-core
-  $(call AddDepends/sound)
-endef
-
-define KernelPackage/sound-soc-bcm2708-i2s/description
-  This package contains support for codecs attached to the Broadcom 2708 I2S interface
-endef
-
-$(eval $(call KernelPackage,sound-soc-bcm2708-i2s))
-
 define KernelPackage/sound-soc-bcm2835-i2s
   TITLE:=SoC Audio support for the Broadcom 2835 I2S module
   KCONFIG:= \
@@ -55,7 +34,7 @@ define KernelPackage/sound-soc-bcm2835-i2s
   FILES:= \
 	$(LINUX_DIR)/sound/soc/bcm/snd-soc-bcm2835-i2s.ko
   AUTOLOAD:=$(call AutoLoad,68,snd-soc-bcm2835-i2s)
-  DEPENDS:=@TARGET_brcm2708 @LINUX_4_4 +kmod-regmap +kmod-sound-soc-core
+  DEPENDS:=@TARGET_brcm2708 +kmod-regmap +kmod-sound-soc-core
   $(call AddDepends/sound)
 endef
 
@@ -75,8 +54,7 @@ define KernelPackage/sound-soc-hifiberry-dac
 	$(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm5102a.ko
   AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm5102a snd-soc-hifiberry-dac)
   DEPENDS:= \
-	LINUX_4_1:kmod-sound-soc-bcm2708-i2s \
-	LINUX_4_4:kmod-sound-soc-bcm2835-i2s \
+	kmod-sound-soc-bcm2835-i2s \
 	+kmod-i2c-bcm2708
   $(call AddDepends/sound)
 endef
@@ -98,8 +76,7 @@ define KernelPackage/sound-soc-hifiberry-dacplus
 	$(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x.ko
   AUTOLOAD:=$(call AutoLoad,68,clk-hifiberry-dacpro snd-soc-pcm512x snd-soc-hifiberry-dacplus)
   DEPENDS:= \
-	LINUX_4_1:kmod-sound-soc-bcm2708-i2s \
-	LINUX_4_4:kmod-sound-soc-bcm2835-i2s \
+	kmod-sound-soc-bcm2835-i2s \
 	+kmod-i2c-bcm2708
   $(call AddDepends/sound)
 endef
@@ -120,8 +97,7 @@ define KernelPackage/sound-soc-hifiberry-digi
 	$(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8804.ko
   AUTOLOAD:=$(call AutoLoad,68,snd-soc-wm8804 snd-soc-hifiberry-digi)
   DEPENDS:= \
-	LINUX_4_1:kmod-sound-soc-bcm2708-i2s \
-	LINUX_4_4:kmod-sound-soc-bcm2835-i2s \
+	kmod-sound-soc-bcm2835-i2s \
 	+kmod-i2c-bcm2708
   $(call AddDepends/sound)
 endef
@@ -142,8 +118,7 @@ define KernelPackage/sound-soc-hifiberry-amp
 	$(LINUX_DIR)/sound/soc/codecs/snd-soc-tas5713.ko
   AUTOLOAD:=$(call AutoLoad,68,snd-soc-tas5713 snd-soc-hifiberry-amp)
   DEPENDS:= \
-	LINUX_4_1:kmod-sound-soc-bcm2708-i2s \
-	LINUX_4_4:kmod-sound-soc-bcm2835-i2s \
+	kmod-sound-soc-bcm2835-i2s \
 	+kmod-i2c-bcm2708
   $(call AddDepends/sound)
 endef
@@ -164,8 +139,7 @@ define KernelPackage/sound-soc-rpi-dac
 	$(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm1794a.ko
   AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm1794a snd-soc-rpi-dac)
   DEPENDS:= \
-	LINUX_4_1:kmod-sound-soc-bcm2708-i2s \
-	LINUX_4_4:kmod-sound-soc-bcm2835-i2s \
+	kmod-sound-soc-bcm2835-i2s \
 	+kmod-i2c-bcm2708
   $(call AddDepends/sound)
 endef
@@ -186,8 +160,7 @@ define KernelPackage/sound-soc-rpi-proto
 	$(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8731.ko
   AUTOLOAD:=$(call AutoLoad,68,snd-soc-wm8731 snd-soc-rpi-proto)
   DEPENDS:= \
-	LINUX_4_1:kmod-sound-soc-bcm2708-i2s \
-	LINUX_4_4:kmod-sound-soc-bcm2835-i2s \
+	kmod-sound-soc-bcm2835-i2s \
 	+kmod-i2c-bcm2708
   $(call AddDepends/sound)
 endef
@@ -210,8 +183,7 @@ define KernelPackage/sound-soc-iqaudio-dac
 	$(LINUX_DIR)/sound/soc/codecs/snd-soc-pcm512x-i2c.ko
   AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm512x snd-soc-pcm512x-i2c snd-soc-iqaudio-dac)
   DEPENDS:= \
-	LINUX_4_1:kmod-sound-soc-bcm2708-i2s \
-	LINUX_4_4:kmod-sound-soc-bcm2835-i2s \
+	kmod-sound-soc-bcm2835-i2s \
 	+kmod-i2c-bcm2708
   $(call AddDepends/sound)
 endef
@@ -236,8 +208,7 @@ define KernelPackage/sound-soc-raspidac3
 	$(LINUX_DIR)/sound/soc/codecs/snd-soc-tpa6130a2.ko
   AUTOLOAD:=$(call AutoLoad,68,snd-soc-pcm512x snd-soc-pcm512x-i2c snd-soc-tpa6130a2 snd-soc-raspidac3)
   DEPENDS:= \
-	LINUX_4_1:kmod-sound-soc-bcm2708-i2s \
-	LINUX_4_4:kmod-sound-soc-bcm2835-i2s \
+	kmod-sound-soc-bcm2835-i2s \
 	+kmod-i2c-bcm2708
   $(call AddDepends/sound)
 endef
@@ -249,21 +220,6 @@ endef
 $(eval $(call KernelPackage,sound-soc-raspidac3))
 
 
-define KernelPackage/random-bcm2708
-  SUBMENU:=$(OTHER_MENU)
-  TITLE:=BCM2708 HW Random Number Generator
-  KCONFIG:=CONFIG_HW_RANDOM_BCM2708
-  FILES:=$(LINUX_DIR)/drivers/char/hw_random/bcm2708-rng.ko
-  AUTOLOAD:=$(call AutoLoad,11,bcm2708-rng)
-  DEPENDS:=@TARGET_brcm2708 @LINUX_4_1 +kmod-random-core
-endef
-
-define KernelPackage/random-bcm2708/description
-  This package contains the Broadcom 2708 HW random number generator driver
-endef
-
-$(eval $(call KernelPackage,random-bcm2708))
-
 define KernelPackage/random-bcm2835
   SUBMENU:=$(OTHER_MENU)
   TITLE:=BCM2835 HW Random Number Generator
@@ -314,25 +270,6 @@ endef
 $(eval $(call KernelPackage,smi-bcm2835-dev))
 
 
-define KernelPackage/spi-bcm2708
-  SUBMENU:=$(SPI_MENU)
-  TITLE:=BCM2708 SPI controller driver
-  KCONFIG:= \
-    CONFIG_BCM2708_SPIDEV=n \
-    CONFIG_SPI=y \
-    CONFIG_SPI_BCM2708 \
-    CONFIG_SPI_MASTER=y
-  FILES:=$(LINUX_DIR)/drivers/spi/spi-bcm2708.ko
-  AUTOLOAD:=$(call AutoLoad,89,spi-bcm2708)
-  DEPENDS:=@TARGET_brcm2708 @LINUX_4_1
-endef
-
-define KernelPackage/spi-bcm2708/description
-  This package contains the Broadcom 2708 SPI master controller driver
-endef
-
-$(eval $(call KernelPackage,spi-bcm2708))
-
 define KernelPackage/spi-bcm2835
   SUBMENU:=$(SPI_MENU)
   TITLE:=BCM2835 SPI controller driver
diff --git a/target/linux/brcm2708/patches-4.1/0001-Main-bcm2708-bcm2709-linux-port.patch b/target/linux/brcm2708/patches-4.1/0001-Main-bcm2708-bcm2709-linux-port.patch
deleted file mode 100644
index 0981a06..0000000
--- a/target/linux/brcm2708/patches-4.1/0001-Main-bcm2708-bcm2709-linux-port.patch
+++ /dev/null
@@ -1,6829 +0,0 @@
-From 9d6e36d79fe6515b1392ad1a4e4d4aca72bc770e Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix at gmail.com>
-Date: Sun, 12 May 2013 12:24:19 +0100
-Subject: [PATCH 001/222] Main bcm2708/bcm2709 linux port
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: popcornmix <popcornmix at gmail.com>
-Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
----
- arch/arm/Kconfig                                 |  39 ++
- arch/arm/Kconfig.debug                           |   8 +
- arch/arm/Makefile                                |   2 +
- arch/arm/kernel/head.S                           |   8 +
- arch/arm/kernel/process.c                        |  10 +
- arch/arm/mach-bcm2708/Kconfig                    |  30 +
- arch/arm/mach-bcm2708/Makefile                   |   5 +
- arch/arm/mach-bcm2708/Makefile.boot              |   3 +
- arch/arm/mach-bcm2708/armctrl.c                  | 304 +++++++++
- arch/arm/mach-bcm2708/armctrl.h                  |  27 +
- arch/arm/mach-bcm2708/bcm2708.c                  | 622 ++++++++++++++++++
- arch/arm/mach-bcm2708/bcm2708.h                  |  49 ++
- arch/arm/mach-bcm2708/include/mach/arm_control.h | 419 ++++++++++++
- arch/arm/mach-bcm2708/include/mach/clkdev.h      |   7 +
- arch/arm/mach-bcm2708/include/mach/debug-macro.S |  22 +
- arch/arm/mach-bcm2708/include/mach/entry-macro.S |  69 ++
- arch/arm/mach-bcm2708/include/mach/frc.h         |  38 ++
- arch/arm/mach-bcm2708/include/mach/hardware.h    |  28 +
- arch/arm/mach-bcm2708/include/mach/io.h          |  27 +
- arch/arm/mach-bcm2708/include/mach/irqs.h        | 196 ++++++
- arch/arm/mach-bcm2708/include/mach/memory.h      |  57 ++
- arch/arm/mach-bcm2708/include/mach/platform.h    | 228 +++++++
- arch/arm/mach-bcm2708/include/mach/system.h      |  38 ++
- arch/arm/mach-bcm2708/include/mach/timex.h       |  23 +
- arch/arm/mach-bcm2708/include/mach/uncompress.h  |  84 +++
- arch/arm/mach-bcm2708/include/mach/vmalloc.h     |  20 +
- arch/arm/mach-bcm2709/Kconfig                    |  42 ++
- arch/arm/mach-bcm2709/Makefile                   |   6 +
- arch/arm/mach-bcm2709/Makefile.boot              |   3 +
- arch/arm/mach-bcm2709/armctrl.c                  | 361 ++++++++++
- arch/arm/mach-bcm2709/armctrl.h                  |  27 +
- arch/arm/mach-bcm2709/bcm2708_gpio.c             | 426 ++++++++++++
- arch/arm/mach-bcm2709/bcm2709.c                  | 801 +++++++++++++++++++++++
- arch/arm/mach-bcm2709/bcm2709.h                  |  49 ++
- arch/arm/mach-bcm2709/delay.S                    |  21 +
- arch/arm/mach-bcm2709/include/mach/arm_control.h | 493 ++++++++++++++
- arch/arm/mach-bcm2709/include/mach/barriers.h    |   3 +
- arch/arm/mach-bcm2709/include/mach/clkdev.h      |   7 +
- arch/arm/mach-bcm2709/include/mach/debug-macro.S |  22 +
- arch/arm/mach-bcm2709/include/mach/entry-macro.S | 123 ++++
- arch/arm/mach-bcm2709/include/mach/frc.h         |  38 ++
- arch/arm/mach-bcm2709/include/mach/gpio.h        |  17 +
- arch/arm/mach-bcm2709/include/mach/hardware.h    |  28 +
- arch/arm/mach-bcm2709/include/mach/io.h          |  27 +
- arch/arm/mach-bcm2709/include/mach/irqs.h        | 225 +++++++
- arch/arm/mach-bcm2709/include/mach/memory.h      |  57 ++
- arch/arm/mach-bcm2709/include/mach/platform.h    | 225 +++++++
- arch/arm/mach-bcm2709/include/mach/system.h      |  38 ++
- arch/arm/mach-bcm2709/include/mach/timex.h       |  23 +
- arch/arm/mach-bcm2709/include/mach/uncompress.h  |  84 +++
- arch/arm/mach-bcm2709/include/mach/vc_mem.h      |  35 +
- arch/arm/mach-bcm2709/include/mach/vc_support.h  |  69 ++
- arch/arm/mach-bcm2709/include/mach/vmalloc.h     |  20 +
- arch/arm/mach-bcm2709/vc_mem.c                   | 431 ++++++++++++
- arch/arm/mach-bcm2709/vc_support.c               | 318 +++++++++
- arch/arm/mm/Kconfig                              |   2 +-
- arch/arm/mm/proc-v6.S                            |  15 +-
- arch/arm/mm/proc-v7.S                            |   1 +
- arch/arm/tools/mach-types                        |   2 +
- drivers/clocksource/arm_arch_timer.c             |  36 +
- drivers/tty/serial/amba-pl011.c                  |   2 +-
- include/linux/mmc/host.h                         |   1 +
- 62 files changed, 6436 insertions(+), 5 deletions(-)
- create mode 100644 arch/arm/mach-bcm2708/Kconfig
- create mode 100644 arch/arm/mach-bcm2708/Makefile
- create mode 100644 arch/arm/mach-bcm2708/Makefile.boot
- create mode 100644 arch/arm/mach-bcm2708/armctrl.c
- create mode 100644 arch/arm/mach-bcm2708/armctrl.h
- create mode 100644 arch/arm/mach-bcm2708/bcm2708.c
- create mode 100644 arch/arm/mach-bcm2708/bcm2708.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/arm_control.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/clkdev.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/debug-macro.S
- create mode 100644 arch/arm/mach-bcm2708/include/mach/entry-macro.S
- create mode 100644 arch/arm/mach-bcm2708/include/mach/frc.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/hardware.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/io.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/irqs.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/memory.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/platform.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/system.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/timex.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/uncompress.h
- create mode 100644 arch/arm/mach-bcm2708/include/mach/vmalloc.h
- create mode 100644 arch/arm/mach-bcm2709/Kconfig
- create mode 100644 arch/arm/mach-bcm2709/Makefile
- create mode 100644 arch/arm/mach-bcm2709/Makefile.boot
- create mode 100644 arch/arm/mach-bcm2709/armctrl.c
- create mode 100644 arch/arm/mach-bcm2709/armctrl.h
- create mode 100644 arch/arm/mach-bcm2709/bcm2708_gpio.c
- create mode 100644 arch/arm/mach-bcm2709/bcm2709.c
- create mode 100644 arch/arm/mach-bcm2709/bcm2709.h
- create mode 100644 arch/arm/mach-bcm2709/delay.S
- create mode 100644 arch/arm/mach-bcm2709/include/mach/arm_control.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/barriers.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/clkdev.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/debug-macro.S
- create mode 100644 arch/arm/mach-bcm2709/include/mach/entry-macro.S
- create mode 100644 arch/arm/mach-bcm2709/include/mach/frc.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/gpio.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/hardware.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/io.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/irqs.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/memory.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/platform.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/system.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/timex.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/uncompress.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h
- create mode 100755 arch/arm/mach-bcm2709/include/mach/vc_support.h
- create mode 100644 arch/arm/mach-bcm2709/include/mach/vmalloc.h
- create mode 100644 arch/arm/mach-bcm2709/vc_mem.c
- create mode 100644 arch/arm/mach-bcm2709/vc_support.c
-
---- a/arch/arm/Kconfig
-+++ b/arch/arm/Kconfig
-@@ -314,6 +314,42 @@ choice
- 	default ARCH_VERSATILE if !MMU
- 	default ARCH_MULTIPLATFORM if MMU
- 
-+config ARCH_BCM2708
-+	bool "Broadcom BCM2708 family"
-+	select CPU_V6
-+	select ARM_AMBA
-+	select HAVE_SCHED_CLOCK
-+	select NEED_MACH_GPIO_H
-+	select NEED_MACH_MEMORY_H
-+	select COMMON_CLK
-+	select ARCH_HAS_CPUFREQ
-+	select GENERIC_CLOCKEVENTS
-+	select ARM_ERRATA_411920
-+	select MACH_BCM2708
-+	select VC4
-+	select FIQ
-+	help
-+	  This enables support for Broadcom BCM2708 boards.
-+
-+config ARCH_BCM2709
-+	bool "Broadcom BCM2709 family"
-+	select ARCH_HAS_BARRIERS if SMP
-+	select CPU_V7
-+	select HAVE_SMP
-+	select ARM_AMBA
-+	select MIGHT_HAVE_CACHE_L2X0
-+	select HAVE_SCHED_CLOCK
-+	select NEED_MACH_MEMORY_H
-+	select NEED_MACH_IO_H
-+	select COMMON_CLK
-+	select ARCH_HAS_CPUFREQ
-+	select GENERIC_CLOCKEVENTS
-+	select MACH_BCM2709
-+	select VC4
-+	select FIQ
-+	help
-+	  This enables support for Broadcom BCM2709 boards.
-+
- config ARCH_MULTIPLATFORM
- 	bool "Allow multiple platforms to be selected"
- 	depends on MMU
-@@ -824,6 +860,9 @@ config ARCH_VIRT
- # Kconfigs may be included either alphabetically (according to the
- # plat- suffix) or along side the corresponding mach-* source.
- #
-+source "arch/arm/mach-bcm2708/Kconfig"
-+source "arch/arm/mach-bcm2709/Kconfig"
-+
- source "arch/arm/mach-mvebu/Kconfig"
- 
- source "arch/arm/mach-alpine/Kconfig"
---- a/arch/arm/Kconfig.debug
-+++ b/arch/arm/Kconfig.debug
-@@ -1197,6 +1197,14 @@ choice
- 		  options; the platform specific options are deprecated
- 		  and will be soon removed.
- 
-+	config DEBUG_BCM2708_UART0
-+		bool "Broadcom BCM2708 UART0 (PL011)"
-+		depends on MACH_BCM2708
-+		help
-+		  Say Y here if you want the debug print routines to direct
-+		  their output to UART 0. The port must have been initialised
-+		  by the boot-loader before use.
-+
- endchoice
- 
- config DEBUG_AT91_UART
---- a/arch/arm/Makefile
-+++ b/arch/arm/Makefile
-@@ -155,6 +155,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x003080
- 
- # Machine directory name.  This list is sorted alphanumerically
- # by CONFIG_* macro name.
-+machine-$(CONFIG_ARCH_BCM2708)		+= bcm2708
-+machine-$(CONFIG_ARCH_BCM2709)		+= bcm2709
- machine-$(CONFIG_ARCH_ALPINE)		+= alpine
- machine-$(CONFIG_ARCH_AT91)		+= at91
- machine-$(CONFIG_ARCH_AXXIA)		+= axxia
---- a/arch/arm/kernel/head.S
-+++ b/arch/arm/kernel/head.S
-@@ -680,6 +680,14 @@ ARM_BE8(rev16	ip, ip)
- 	ldrcc	r7, [r4], #4	@ use branch for delay slot
- 	bcc	1b
- 	ret	lr
-+	nop
-+	nop
-+	nop
-+	nop
-+	nop
-+	nop
-+	nop
-+	nop
- #endif
- ENDPROC(__fixup_a_pv_table)
- 
---- a/arch/arm/kernel/process.c
-+++ b/arch/arm/kernel/process.c
-@@ -98,6 +98,16 @@ void arch_cpu_idle_dead(void)
- }
- #endif
- 
-+char bcm2708_reboot_mode = 'h';
-+
-+int __init reboot_setup(char *str)
-+{
-+	bcm2708_reboot_mode = str[0];
-+	return 1;
-+}
-+
-+__setup("reboot=", reboot_setup);
-+
- void __show_regs(struct pt_regs *regs)
- {
- 	unsigned long flags;
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/Kconfig
-@@ -0,0 +1,30 @@
-+menu "Broadcom BCM2708 Implementations"
-+	depends on ARCH_BCM2708
-+
-+config MACH_BCM2708
-+	bool "Broadcom BCM2708 Development Platform"
-+	select NEED_MACH_MEMORY_H
-+	select NEED_MACH_IO_H
-+	select CPU_V6
-+	help
-+	  Include support for the Broadcom(R) BCM2708 platform.
-+
-+config BCM2708_DT
-+	bool "BCM2708 Device Tree support"
-+	depends on MACH_BCM2708
-+	default n
-+	select USE_OF
-+	select ARCH_REQUIRE_GPIOLIB
-+	select PINCTRL
-+	select PINCTRL_BCM2835
-+	help
-+	  Enable Device Tree support for BCM2708
-+
-+config BCM2708_NOL2CACHE
-+	bool "Videocore L2 cache disable"
-+	depends on MACH_BCM2708
-+        default n
-+        help
-+          Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt.
-+
-+endmenu
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/Makefile
-@@ -0,0 +1,5 @@
-+#
-+# Makefile for the linux kernel.
-+#
-+
-+obj-$(CONFIG_MACH_BCM2708) 	+= bcm2708.o armctrl.o
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/Makefile.boot
-@@ -0,0 +1,3 @@
-+   zreladdr-y	:= 0x00008000
-+params_phys-y	:= 0x00000100
-+initrd_phys-y	:= 0x00800000
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/armctrl.c
-@@ -0,0 +1,304 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/armctrl.c
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/io.h>
-+#include <linux/version.h>
-+#include <linux/syscore_ops.h>
-+#include <linux/interrupt.h>
-+#include <linux/irqdomain.h>
-+#include <linux/of.h>
-+
-+#include <asm/mach/irq.h>
-+#include <mach/hardware.h>
-+#include "armctrl.h"
-+
-+/* For support of kernels >= 3.0 assume only one VIC for now*/
-+static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = {
-+	INTERRUPT_VC_JPEG,
-+	INTERRUPT_VC_USB,
-+	INTERRUPT_VC_3D,
-+	INTERRUPT_VC_DMA2,
-+	INTERRUPT_VC_DMA3,
-+	INTERRUPT_VC_I2C,
-+	INTERRUPT_VC_SPI,
-+	INTERRUPT_VC_I2SPCM,
-+	INTERRUPT_VC_SDIO,
-+	INTERRUPT_VC_UART,
-+	INTERRUPT_VC_ARASANSDIO
-+};
-+
-+static void armctrl_mask_irq(struct irq_data *d)
-+{
-+	static const unsigned int disables[4] = {
-+		ARM_IRQ_DIBL1,
-+		ARM_IRQ_DIBL2,
-+		ARM_IRQ_DIBL3,
-+		0
-+	};
-+
-+	unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
-+	writel(1 << (data & 0x1f), __io_address(disables[(data >> 5) & 0x3]));
-+}
-+
-+static void armctrl_unmask_irq(struct irq_data *d)
-+{
-+	static const unsigned int enables[4] = {
-+		ARM_IRQ_ENBL1,
-+		ARM_IRQ_ENBL2,
-+		ARM_IRQ_ENBL3,
-+		0
-+	};
-+
-+	unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
-+	writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3]));
-+}
-+
-+#ifdef CONFIG_OF
-+
-+#define NR_IRQS_BANK0           21
-+#define NR_BANKS                3
-+#define IRQS_PER_BANK           32
-+
-+/* from drivers/irqchip/irq-bcm2835.c */
-+static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
-+        const u32 *intspec, unsigned int intsize,
-+        unsigned long *out_hwirq, unsigned int *out_type)
-+{
-+        if (WARN_ON(intsize != 2))
-+                return -EINVAL;
-+
-+        if (WARN_ON(intspec[0] >= NR_BANKS))
-+                return -EINVAL;
-+
-+        if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
-+                return -EINVAL;
-+
-+        if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
-+                return -EINVAL;
-+
-+	if (intspec[0] == 0)
-+		*out_hwirq = ARM_IRQ0_BASE + intspec[1];
-+	else if (intspec[0] == 1)
-+		*out_hwirq = ARM_IRQ1_BASE + intspec[1];
-+	else
-+		*out_hwirq = ARM_IRQ2_BASE + intspec[1];
-+
-+	/* reverse remap_irqs[] */
-+	switch (*out_hwirq) {
-+	case INTERRUPT_VC_JPEG:
-+		*out_hwirq = INTERRUPT_JPEG;
-+		break;
-+	case INTERRUPT_VC_USB:
-+		*out_hwirq = INTERRUPT_USB;
-+		break;
-+	case INTERRUPT_VC_3D:
-+		*out_hwirq = INTERRUPT_3D;
-+		break;
-+	case INTERRUPT_VC_DMA2:
-+		*out_hwirq = INTERRUPT_DMA2;
-+		break;
-+	case INTERRUPT_VC_DMA3:
-+		*out_hwirq = INTERRUPT_DMA3;
-+		break;
-+	case INTERRUPT_VC_I2C:
-+		*out_hwirq = INTERRUPT_I2C;
-+		break;
-+	case INTERRUPT_VC_SPI:
-+		*out_hwirq = INTERRUPT_SPI;
-+		break;
-+	case INTERRUPT_VC_I2SPCM:
-+		*out_hwirq = INTERRUPT_I2SPCM;
-+		break;
-+	case INTERRUPT_VC_SDIO:
-+		*out_hwirq = INTERRUPT_SDIO;
-+		break;
-+	case INTERRUPT_VC_UART:
-+		*out_hwirq = INTERRUPT_UART;
-+		break;
-+	case INTERRUPT_VC_ARASANSDIO:
-+		*out_hwirq = INTERRUPT_ARASANSDIO;
-+		break;
-+	}
-+
-+        *out_type = IRQ_TYPE_NONE;
-+        return 0;
-+}
-+
-+static struct irq_domain_ops armctrl_ops = {
-+        .xlate = armctrl_xlate
-+};
-+
-+void __init armctrl_dt_init(void)
-+{
-+	struct device_node *np;
-+	struct irq_domain *domain;
-+
-+	np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
-+	if (!np)
-+		return;
-+
-+	domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS,
-+					IRQ_ARMCTRL_START, 0,
-+					&armctrl_ops, NULL);
-+        WARN_ON(!domain);
-+}
-+#else
-+void __init armctrl_dt_init(void) { }
-+#endif /* CONFIG_OF */
-+
-+#if defined(CONFIG_PM)
-+
-+/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
-+
-+/* Static defines
-+ * struct armctrl_device - VIC PM device (< 3.xx)
-+ * @sysdev: The system device which is registered. (< 3.xx)
-+ * @irq: The IRQ number for the base of the VIC.
-+ * @base: The register base for the VIC.
-+ * @resume_sources: A bitmask of interrupts for resume.
-+ * @resume_irqs: The IRQs enabled for resume.
-+ * @int_select: Save for VIC_INT_SELECT.
-+ * @int_enable: Save for VIC_INT_ENABLE.
-+ * @soft_int: Save for VIC_INT_SOFT.
-+ * @protect: Save for VIC_PROTECT.
-+ */
-+struct armctrl_info {
-+	void __iomem *base;
-+	int irq;
-+	u32 resume_sources;
-+	u32 resume_irqs;
-+	u32 int_select;
-+	u32 int_enable;
-+	u32 soft_int;
-+	u32 protect;
-+} armctrl;
-+
-+static int armctrl_suspend(void)
-+{
-+	return 0;
-+}
-+
-+static void armctrl_resume(void)
-+{
-+	return;
-+}
-+
-+/**
-+ * armctrl_pm_register - Register a VIC for later power management control
-+ * @base: The base address of the VIC.
-+ * @irq: The base IRQ for the VIC.
-+ * @resume_sources: bitmask of interrupts allowed for resume sources.
-+ *
-+ * For older kernels (< 3.xx) do -
-+ * Register the VIC with the system device tree so that it can be notified
-+ * of suspend and resume requests and ensure that the correct actions are
-+ * taken to re-instate the settings on resume.
-+ */
-+static void __init armctrl_pm_register(void __iomem * base, unsigned int irq,
-+				       u32 resume_sources)
-+{
-+	armctrl.base = base;
-+	armctrl.resume_sources = resume_sources;
-+	armctrl.irq = irq;
-+}
-+
-+static int armctrl_set_wake(struct irq_data *d, unsigned int on)
-+{
-+	unsigned int off = d->irq & 31;
-+	u32 bit = 1 << off;
-+
-+	if (!(bit & armctrl.resume_sources))
-+		return -EINVAL;
-+
-+	if (on)
-+		armctrl.resume_irqs |= bit;
-+	else
-+		armctrl.resume_irqs &= ~bit;
-+
-+	return 0;
-+}
-+
-+#else
-+static inline void armctrl_pm_register(void __iomem * base, unsigned int irq,
-+				       u32 arg1)
-+{
-+}
-+
-+#define armctrl_suspend NULL
-+#define armctrl_resume NULL
-+#define armctrl_set_wake NULL
-+#endif /* CONFIG_PM */
-+
-+static struct syscore_ops armctrl_syscore_ops = {
-+	.suspend = armctrl_suspend,
-+	.resume = armctrl_resume,
-+};
-+
-+/**
-+ * armctrl_syscore_init - initicall to register VIC pm functions
-+ *
-+ * This is called via late_initcall() to register
-+ * the resources for the VICs due to the early
-+ * nature of the VIC's registration.
-+*/
-+static int __init armctrl_syscore_init(void)
-+{
-+	register_syscore_ops(&armctrl_syscore_ops);
-+	return 0;
-+}
-+
-+late_initcall(armctrl_syscore_init);
-+
-+static struct irq_chip armctrl_chip = {
-+	.name = "ARMCTRL",
-+	.irq_ack = NULL,
-+	.irq_mask = armctrl_mask_irq,
-+	.irq_unmask = armctrl_unmask_irq,
-+	.irq_set_wake = armctrl_set_wake,
-+};
-+
-+/**
-+ * armctrl_init - initialise a vectored interrupt controller
-+ * @base: iomem base address
-+ * @irq_start: starting interrupt number, must be muliple of 32
-+ * @armctrl_sources: bitmask of interrupt sources to allow
-+ * @resume_sources: bitmask of interrupt sources to allow for resume
-+ */
-+int __init armctrl_init(void __iomem * base, unsigned int irq_start,
-+			u32 armctrl_sources, u32 resume_sources)
-+{
-+	unsigned int irq;
-+
-+	for (irq = 0; irq < BCM2708_ALLOC_IRQS; irq++) {
-+		unsigned int data = irq;
-+		if (irq >= INTERRUPT_JPEG && irq <= INTERRUPT_ARASANSDIO)
-+			data = remap_irqs[irq - INTERRUPT_JPEG];
-+
-+		irq_set_chip(irq, &armctrl_chip);
-+		irq_set_chip_data(irq, (void *)data);
-+		irq_set_handler(irq, handle_level_irq);
-+		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-+	}
-+
-+	armctrl_pm_register(base, irq_start, resume_sources);
-+	armctrl_dt_init();
-+	return 0;
-+}
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/armctrl.h
-@@ -0,0 +1,27 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/armctrl.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef __BCM2708_ARMCTRL_H
-+#define __BCM2708_ARMCTRL_H
-+
-+extern int __init armctrl_init(void __iomem * base, unsigned int irq_start,
-+			       u32 armctrl_sources, u32 resume_sources);
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/bcm2708.c
-@@ -0,0 +1,622 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/bcm2708.c
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/serial_8250.h>
-+#include <linux/platform_device.h>
-+#include <linux/syscore_ops.h>
-+#include <linux/interrupt.h>
-+#include <linux/amba/bus.h>
-+#include <linux/amba/clcd.h>
-+#include <linux/clk-provider.h>
-+#include <linux/clkdev.h>
-+#include <linux/clockchips.h>
-+#include <linux/cnt32_to_63.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/gpio/machine.h>
-+
-+#include <linux/version.h>
-+#include <linux/clkdev.h>
-+#include <asm/system_info.h>
-+#include <mach/hardware.h>
-+#include <asm/irq.h>
-+#include <linux/leds.h>
-+#include <asm/mach-types.h>
-+#include <linux/sched_clock.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/flash.h>
-+#include <asm/mach/irq.h>
-+#include <asm/mach/time.h>
-+#include <asm/mach/map.h>
-+
-+#include <mach/timex.h>
-+#include <mach/system.h>
-+
-+#include <linux/delay.h>
-+
-+#include "bcm2708.h"
-+#include "armctrl.h"
-+
-+#ifdef CONFIG_BCM_VC_CMA
-+#include <linux/broadcom/vc_cma.h>
-+#endif
-+
-+
-+/* Effectively we have an IOMMU (ARM<->VideoCore map) that is set up to
-+ * give us IO access only to 64Mbytes of physical memory (26 bits).  We could
-+ * represent this window by setting our dmamasks to 26 bits but, in fact
-+ * we're not going to use addresses outside this range (they're not in real
-+ * memory) so we don't bother.
-+ *
-+ * In the future we might include code to use this IOMMU to remap other
-+ * physical addresses onto VideoCore memory then the use of 32-bits would be
-+ * more legitimate.
-+ */
-+#define DMA_MASK_BITS_COMMON 32
-+
-+/* command line parameters */
-+static unsigned boardrev, serial;
-+static unsigned uart_clock = UART0_CLOCK;
-+static unsigned disk_led_gpio = 16;
-+static unsigned disk_led_active_low = 1;
-+static unsigned reboot_part = 0;
-+
-+static unsigned use_dt = 0;
-+
-+static void __init bcm2708_init_led(void);
-+
-+void __init bcm2708_init_irq(void)
-+{
-+	armctrl_init(__io_address(ARMCTRL_IC_BASE), 0, 0, 0);
-+}
-+
-+static struct map_desc bcm2708_io_desc[] __initdata = {
-+	{
-+	 .virtual = IO_ADDRESS(ARMCTRL_BASE),
-+	 .pfn = __phys_to_pfn(ARMCTRL_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(UART0_BASE),
-+	 .pfn = __phys_to_pfn(UART0_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(UART1_BASE),
-+	 .pfn = __phys_to_pfn(UART1_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(DMA_BASE),
-+	 .pfn = __phys_to_pfn(DMA_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(MCORE_BASE),
-+	 .pfn = __phys_to_pfn(MCORE_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(ST_BASE),
-+	 .pfn = __phys_to_pfn(ST_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(USB_BASE),
-+	 .pfn = __phys_to_pfn(USB_BASE),
-+	 .length = SZ_128K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(PM_BASE),
-+	 .pfn = __phys_to_pfn(PM_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(GPIO_BASE),
-+	 .pfn = __phys_to_pfn(GPIO_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE}
-+};
-+
-+void __init bcm2708_map_io(void)
-+{
-+	iotable_init(bcm2708_io_desc, ARRAY_SIZE(bcm2708_io_desc));
-+}
-+
-+/* The STC is a free running counter that increments at the rate of 1MHz */
-+#define STC_FREQ_HZ 1000000
-+
-+static inline uint32_t timer_read(void)
-+{
-+	/* STC: a free running counter that increments at the rate of 1MHz */
-+	return readl(__io_address(ST_BASE + 0x04));
-+}
-+
-+static unsigned long bcm2708_read_current_timer(void)
-+{
-+	return timer_read();
-+}
-+
-+static u64 notrace bcm2708_read_sched_clock(void)
-+{
-+	return timer_read();
-+}
-+
-+static cycle_t clksrc_read(struct clocksource *cs)
-+{
-+	return timer_read();
-+}
-+
-+static struct clocksource clocksource_stc = {
-+	.name = "stc",
-+	.rating = 300,
-+	.read = clksrc_read,
-+	.mask = CLOCKSOURCE_MASK(32),
-+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
-+};
-+
-+unsigned long frc_clock_ticks32(void)
-+{
-+	return timer_read();
-+}
-+
-+static void __init bcm2708_clocksource_init(void)
-+{
-+	if (clocksource_register_hz(&clocksource_stc, STC_FREQ_HZ)) {
-+		printk(KERN_ERR "timer: failed to initialize clock "
-+		       "source %s\n", clocksource_stc.name);
-+	}
-+}
-+
-+struct clk __init *bcm2708_clk_register(const char *name, unsigned long fixed_rate)
-+{
-+	struct clk *clk;
-+
-+	clk = clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT,
-+						fixed_rate);
-+	if (IS_ERR(clk))
-+		pr_err("%s not registered\n", name);
-+
-+	return clk;
-+}
-+
-+void __init bcm2708_register_clkdev(struct clk *clk, const char *name)
-+{
-+	int ret;
-+
-+	ret = clk_register_clkdev(clk, NULL, name);
-+	if (ret)
-+		pr_err("%s alias not registered\n", name);
-+}
-+
-+void __init bcm2708_init_clocks(void)
-+{
-+	struct clk *clk;
-+
-+	clk = bcm2708_clk_register("uart0_clk", uart_clock);
-+	bcm2708_register_clkdev(clk, "dev:f1");
-+
-+	clk = bcm2708_clk_register("sdhost_clk", 250000000);
-+	bcm2708_register_clkdev(clk, "mmc-bcm2835.0");
-+	bcm2708_register_clkdev(clk, "bcm2708_spi.0");
-+	bcm2708_register_clkdev(clk, "bcm2708_i2c.0");
-+	bcm2708_register_clkdev(clk, "bcm2708_i2c.1");
-+}
-+
-+#define UART0_IRQ	{ IRQ_UART, 0 /*NO_IRQ*/ }
-+#define UART0_DMA	{ 15, 14 }
-+
-+AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
-+
-+static struct amba_device *amba_devs[] __initdata = {
-+	&uart0_device,
-+};
-+
-+static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
-+
-+static struct platform_device bcm2708_fb_device = {
-+	.name = "bcm2708_fb",
-+	.id = -1,		/* only one bcm2708_fb */
-+	.resource = NULL,
-+	.num_resources = 0,
-+	.dev = {
-+		.dma_mask = &fb_dmamask,
-+		.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
-+		},
-+};
-+
-+static struct resource bcm2708_usb_resources[] = {
-+	[0] = {
-+		.start = USB_BASE,
-+		.end = USB_BASE + SZ_128K - 1,
-+		.flags = IORESOURCE_MEM,
-+		},
-+	[1] = {
-+		.start = IRQ_USB,
-+		.end = IRQ_USB,
-+		.flags = IORESOURCE_IRQ,
-+		},
-+};
-+
-+static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
-+
-+static struct platform_device bcm2708_usb_device = {
-+	.name = "bcm2708_usb",
-+	.id = -1,		/* only one bcm2708_usb */
-+	.resource = bcm2708_usb_resources,
-+	.num_resources = ARRAY_SIZE(bcm2708_usb_resources),
-+	.dev = {
-+		.dma_mask = &usb_dmamask,
-+		.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
-+		},
-+};
-+
-+static struct resource bcm2708_vcio_resources[] = {
-+	{
-+		.start = ARMCTRL_0_MAIL0_BASE,
-+		.end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1,
-+		.flags = IORESOURCE_MEM,
-+	}, {
-+		.start = IRQ_ARM_MAILBOX,
-+		.end = IRQ_ARM_MAILBOX,
-+		.flags = IORESOURCE_IRQ,
-+	},
-+};
-+
-+static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
-+
-+static struct platform_device bcm2708_vcio_device = {
-+	.name = "bcm2708_vcio",
-+	.id = -1,		/* only one VideoCore I/O area */
-+	.resource = bcm2708_vcio_resources,
-+	.num_resources = ARRAY_SIZE(bcm2708_vcio_resources),
-+	.dev = {
-+		.dma_mask = &vcio_dmamask,
-+		.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
-+		},
-+};
-+
-+int __init bcm_register_device(struct platform_device *pdev)
-+{
-+	int ret;
-+
-+	ret = platform_device_register(pdev);
-+	if (ret)
-+		pr_debug("Unable to register platform device '%s': %d\n",
-+			 pdev->name, ret);
-+
-+	return ret;
-+}
-+
-+/*
-+ * Use these macros for platform and i2c devices that are present in the
-+ * Device Tree. This way the devices are only added on non-DT systems.
-+ */
-+#define bcm_register_device_dt(pdev) \
-+    if (!use_dt) bcm_register_device(pdev)
-+
-+#define i2c_register_board_info_dt(busnum, info, n) \
-+    if (!use_dt) i2c_register_board_info(busnum, info, n)
-+
-+int calc_rsts(int partition)
-+{
-+	return PM_PASSWORD |
-+		((partition & (1 << 0))  << 0) |
-+		((partition & (1 << 1))  << 1) |
-+		((partition & (1 << 2))  << 2) |
-+		((partition & (1 << 3))  << 3) |
-+		((partition & (1 << 4))  << 4) |
-+		((partition & (1 << 5))  << 5);
-+}
-+
-+static void bcm2708_restart(enum reboot_mode mode, const char *cmd)
-+{
-+	extern char bcm2708_reboot_mode;
-+	uint32_t pm_rstc, pm_wdog;
-+	uint32_t timeout = 10;
-+	uint32_t pm_rsts = 0;
-+
-+	if(bcm2708_reboot_mode == 'q')
-+	{
-+		// NOOBS < 1.3 booting with reboot=q
-+		pm_rsts = readl(__io_address(PM_RSTS));
-+		pm_rsts = PM_PASSWORD | pm_rsts | PM_RSTS_HADWRQ_SET;
-+	}
-+	else if(bcm2708_reboot_mode == 'p')
-+	{
-+		// NOOBS < 1.3 halting
-+		pm_rsts = readl(__io_address(PM_RSTS));
-+		pm_rsts = PM_PASSWORD | pm_rsts | PM_RSTS_HADWRH_SET;
-+	}
-+	else
-+	{
-+		pm_rsts = calc_rsts(reboot_part);
-+	}
-+
-+	writel(pm_rsts, __io_address(PM_RSTS));
-+
-+	/* Setup watchdog for reset */
-+	pm_rstc = readl(__io_address(PM_RSTC));
-+
-+	pm_wdog = PM_PASSWORD | (timeout & PM_WDOG_TIME_SET); // watchdog timer = timer clock / 16; need password (31:16) + value (11:0)
-+	pm_rstc = PM_PASSWORD | (pm_rstc & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET;
-+
-+	writel(pm_wdog, __io_address(PM_WDOG));
-+	writel(pm_rstc, __io_address(PM_RSTC));
-+}
-+
-+/* We can't really power off, but if we do the normal reset scheme, and indicate to bootcode.bin not to reboot, then most of the chip will be powered off */
-+static void bcm2708_power_off(void)
-+{
-+	extern char bcm2708_reboot_mode;
-+	if(bcm2708_reboot_mode == 'q')
-+	{
-+		// NOOBS < v1.3
-+		bcm2708_restart('p', "");
-+	}
-+	else
-+	{
-+		/* partition 63 is special code for HALT the bootloader knows not to boot*/
-+		reboot_part = 63;
-+		/* continue with normal reset mechanism */
-+		bcm2708_restart(0, "");
-+	}
-+}
-+
-+static void __init bcm2708_init_uart1(void)
-+{
-+	struct device_node *np;
-+
-+	np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart");
-+	if (of_device_is_available(np)) {
-+		pr_info("bcm2708: Mini UART enabled\n");
-+		writel(1, __io_address(UART1_BASE + 0x4));
-+	}
-+}
-+
-+#ifdef CONFIG_OF
-+static void __init bcm2708_dt_init(void)
-+{
-+	int ret;
-+
-+	of_clk_init(NULL);
-+	ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-+	if (ret) {
-+		pr_err("of_platform_populate failed: %d\n", ret);
-+		/* Proceed as if CONFIG_OF was not defined */
-+	} else {
-+		use_dt = 1;
-+	}
-+}
-+#else
-+static void __init bcm2708_dt_init(void) { }
-+#endif /* CONFIG_OF */
-+
-+void __init bcm2708_init(void)
-+{
-+	int i;
-+
-+#if defined(CONFIG_BCM_VC_CMA)
-+	vc_cma_early_init();
-+#endif
-+	printk("bcm2708.uart_clock = %d\n", uart_clock);
-+	pm_power_off = bcm2708_power_off;
-+
-+	bcm2708_init_clocks();
-+	bcm2708_dt_init();
-+
-+	bcm_register_device(&bcm2708_vcio_device);
-+#ifdef CONFIG_BCM2708_GPIO
-+	bcm_register_device_dt(&bcm2708_gpio_device);
-+#endif
-+	bcm_register_device_dt(&bcm2708_fb_device);
-+	bcm_register_device_dt(&bcm2708_usb_device);
-+
-+	bcm2708_init_led();
-+	bcm2708_init_uart1();
-+
-+	if (!use_dt) {
-+		for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-+			struct amba_device *d = amba_devs[i];
-+			amba_device_register(d, &iomem_resource);
-+		}
-+	}
-+	system_rev = boardrev;
-+	system_serial_low = serial;
-+}
-+
-+static void timer_set_mode(enum clock_event_mode mode,
-+			   struct clock_event_device *clk)
-+{
-+	switch (mode) {
-+	case CLOCK_EVT_MODE_ONESHOT: /* Leave the timer disabled, .set_next_event will enable it */
-+	case CLOCK_EVT_MODE_SHUTDOWN:
-+		break;
-+	case CLOCK_EVT_MODE_PERIODIC:
-+
-+	case CLOCK_EVT_MODE_UNUSED:
-+	case CLOCK_EVT_MODE_RESUME:
-+
-+	default:
-+		printk(KERN_ERR "timer_set_mode: unhandled mode:%d\n",
-+		       (int)mode);
-+		break;
-+	}
-+
-+}
-+
-+static int timer_set_next_event(unsigned long cycles,
-+				struct clock_event_device *unused)
-+{
-+	unsigned long stc;
-+	do {
-+		stc = readl(__io_address(ST_BASE + 0x04));
-+		/* We could take a FIQ here, which may push ST above STC3 */
-+		writel(stc + cycles, __io_address(ST_BASE + 0x18));
-+	} while ((signed long) cycles >= 0 &&
-+				(signed long) (readl(__io_address(ST_BASE + 0x04)) - stc)
-+				>= (signed long) cycles);
-+	return 0;
-+}
-+
-+static struct clock_event_device timer0_clockevent = {
-+	.name = "timer0",
-+	.shift = 32,
-+	.features = CLOCK_EVT_FEAT_ONESHOT,
-+	.set_mode = timer_set_mode,
-+	.set_next_event = timer_set_next_event,
-+};
-+
-+/*
-+ * IRQ handler for the timer
-+ */
-+static irqreturn_t bcm2708_timer_interrupt(int irq, void *dev_id)
-+{
-+	struct clock_event_device *evt = &timer0_clockevent;
-+
-+	writel(1 << 3, __io_address(ST_BASE + 0x00));	/* stcs clear timer int */
-+
-+	evt->event_handler(evt);
-+
-+	return IRQ_HANDLED;
-+}
-+
-+static struct irqaction bcm2708_timer_irq = {
-+	.name = "BCM2708 Timer Tick",
-+	.flags = IRQF_TIMER | IRQF_IRQPOLL,
-+	.handler = bcm2708_timer_interrupt,
-+};
-+
-+/*
-+ * Set up timer interrupt, and return the current time in seconds.
-+ */
-+
-+static struct delay_timer bcm2708_delay_timer = {
-+	.read_current_timer = bcm2708_read_current_timer,
-+	.freq = STC_FREQ_HZ,
-+};
-+
-+static void __init bcm2708_timer_init(void)
-+{
-+	/* init high res timer */
-+	bcm2708_clocksource_init();
-+
-+	/*
-+	 * Make irqs happen for the system timer
-+	 */
-+	setup_irq(IRQ_TIMER3, &bcm2708_timer_irq);
-+
-+	sched_clock_register(bcm2708_read_sched_clock, 32, STC_FREQ_HZ);
-+
-+	timer0_clockevent.mult =
-+	    div_sc(STC_FREQ_HZ, NSEC_PER_SEC, timer0_clockevent.shift);
-+	timer0_clockevent.max_delta_ns =
-+	    clockevent_delta2ns(0xffffffff, &timer0_clockevent);
-+	timer0_clockevent.min_delta_ns =
-+	    clockevent_delta2ns(0xf, &timer0_clockevent);
-+
-+	timer0_clockevent.cpumask = cpumask_of(0);
-+	clockevents_register_device(&timer0_clockevent);
-+
-+	register_current_timer_delay(&bcm2708_delay_timer);
-+}
-+
-+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-+#include <linux/leds.h>
-+
-+static struct gpio_led bcm2708_leds[] = {
-+	[0] = {
-+	       .gpio = 16,
-+	       .name = "led0",
-+	       .default_trigger = "mmc0",
-+	       .active_low = 1,
-+	       },
-+};
-+
-+static struct gpio_led_platform_data bcm2708_led_pdata = {
-+	.num_leds = ARRAY_SIZE(bcm2708_leds),
-+	.leds = bcm2708_leds,
-+};
-+
-+static struct platform_device bcm2708_led_device = {
-+	.name = "leds-gpio",
-+	.id = -1,
-+	.dev = {
-+		.platform_data = &bcm2708_led_pdata,
-+		},
-+};
-+
-+static void __init bcm2708_init_led(void)
-+{
-+	bcm2708_leds[0].gpio = disk_led_gpio;
-+	bcm2708_leds[0].active_low = disk_led_active_low;
-+	bcm_register_device_dt(&bcm2708_led_device);
-+}
-+#else
-+static inline void bcm2708_init_led(void)
-+{
-+}
-+#endif
-+
-+void __init bcm2708_init_early(void)
-+{
-+	/*
-+	 * Some devices allocate their coherent buffers from atomic
-+	 * context. Increase size of atomic coherent pool to make sure such
-+	 * the allocations won't fail.
-+	 */
-+	init_dma_coherent_pool_size(SZ_4M);
-+}
-+
-+static void __init board_reserve(void)
-+{
-+#if defined(CONFIG_BCM_VC_CMA)
-+	vc_cma_reserve();
-+#endif
-+}
-+
-+static const char * const bcm2708_compat[] = {
-+	"brcm,bcm2708",
-+	NULL
-+};
-+
-+MACHINE_START(BCM2708, "BCM2708")
-+    /* Maintainer: Broadcom Europe Ltd. */
-+	.map_io = bcm2708_map_io,
-+	.init_irq = bcm2708_init_irq,
-+	.init_time = bcm2708_timer_init,
-+	.init_machine = bcm2708_init,
-+	.init_early = bcm2708_init_early,
-+	.reserve = board_reserve,
-+	.restart	= bcm2708_restart,
-+	.dt_compat = bcm2708_compat,
-+MACHINE_END
-+
-+module_param(boardrev, uint, 0644);
-+module_param(serial, uint, 0644);
-+module_param(uart_clock, uint, 0644);
-+module_param(disk_led_gpio, uint, 0644);
-+module_param(disk_led_active_low, uint, 0644);
-+module_param(reboot_part, uint, 0644);
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/bcm2708.h
-@@ -0,0 +1,49 @@
-+/*
-+ * linux/arch/arm/mach-bcm2708/bcm2708.h
-+ *
-+ * BCM2708 machine support header
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef __BCM2708_BCM2708_H
-+#define __BCM2708_BCM2708_H
-+
-+#include <linux/amba/bus.h>
-+
-+extern void __init bcm2708_init(void);
-+extern void __init bcm2708_init_irq(void);
-+extern void __init bcm2708_map_io(void);
-+extern struct sys_timer bcm2708_timer;
-+extern unsigned int mmc_status(struct device *dev);
-+
-+#define AMBA_DEVICE(name, busid, base, plat)			\
-+static struct amba_device name##_device = {			\
-+	.dev		= {					\
-+		.coherent_dma_mask = ~0,			\
-+		.init_name = busid,				\
-+		.platform_data = plat,				\
-+	},							\
-+	.res		= {					\
-+		.start	= base##_BASE,		\
-+		.end	= (base##_BASE) + SZ_4K - 1,\
-+		.flags	= IORESOURCE_MEM,			\
-+	},							\
-+	.irq		= base##_IRQ,				\
-+}
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/arm_control.h
-@@ -0,0 +1,419 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/arm_control.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef __BCM2708_ARM_CONTROL_H
-+#define __BCM2708_ARM_CONTROL_H
-+
-+/*
-+ * Definitions and addresses for the ARM CONTROL logic
-+ * This file is manually generated.
-+ */
-+
-+#define ARM_BASE  0x7E00B000
-+
-+/* Basic configuration */
-+#define ARM_CONTROL0  HW_REGISTER_RW(ARM_BASE+0x000)
-+#define ARM_C0_SIZ128M   0x00000000
-+#define ARM_C0_SIZ256M   0x00000001
-+#define ARM_C0_SIZ512M   0x00000002
-+#define ARM_C0_SIZ1G     0x00000003
-+#define ARM_C0_BRESP0    0x00000000
-+#define ARM_C0_BRESP1    0x00000004
-+#define ARM_C0_BRESP2    0x00000008
-+#define ARM_C0_BOOTHI    0x00000010
-+#define ARM_C0_UNUSED05  0x00000020 /* free */
-+#define ARM_C0_FULLPERI  0x00000040
-+#define ARM_C0_UNUSED78  0x00000180 /* free */
-+#define ARM_C0_JTAGMASK  0x00000E00
-+#define ARM_C0_JTAGOFF   0x00000000
-+#define ARM_C0_JTAGBASH  0x00000800 /* Debug on GPIO off */
-+#define ARM_C0_JTAGGPIO  0x00000C00 /* Debug on GPIO on */
-+#define ARM_C0_APROTMSK  0x0000F000
-+#define ARM_C0_DBG0SYNC  0x00010000 /* VPU0 halt sync */
-+#define ARM_C0_DBG1SYNC  0x00020000 /* VPU1 halt sync */
-+#define ARM_C0_SWDBGREQ  0x00040000 /* HW debug request */
-+#define ARM_C0_PASSHALT  0x00080000 /* ARM halt passed to debugger */
-+#define ARM_C0_PRIO_PER  0x00F00000 /* per priority mask */
-+#define ARM_C0_PRIO_L2   0x0F000000
-+#define ARM_C0_PRIO_UC   0xF0000000
-+
-+#define ARM_C0_APROTPASS  0x0000A000 /* Translate 1:1 */
-+#define ARM_C0_APROTUSER  0x00000000 /* Only user mode */
-+#define ARM_C0_APROTSYST  0x0000F000 /* Only system mode */
-+
-+
-+#define ARM_CONTROL1  HW_REGISTER_RW(ARM_BASE+0x440)
-+#define ARM_C1_TIMER     0x00000001 /* re-route timer IRQ  to VC */
-+#define ARM_C1_MAIL      0x00000002 /* re-route Mail IRQ   to VC */
-+#define ARM_C1_BELL0     0x00000004 /* re-route Doorbell 0 to VC */
-+#define ARM_C1_BELL1     0x00000008 /* re-route Doorbell 1 to VC */
-+#define ARM_C1_PERSON    0x00000100 /* peripherals on */
-+#define ARM_C1_REQSTOP   0x00000200 /* ASYNC bridge request stop */
-+
-+#define ARM_STATUS    HW_REGISTER_RW(ARM_BASE+0x444)
-+#define ARM_S_ACKSTOP    0x80000000 /* Bridge stopped */
-+#define ARM_S_READPEND   0x000003FF /* pending reads counter */
-+#define ARM_S_WRITPEND   0x000FFC00 /* pending writes counter */
-+
-+#define ARM_ERRHALT   HW_REGISTER_RW(ARM_BASE+0x448)
-+#define ARM_EH_PERIBURST  0x00000001 /* Burst write seen on peri bus */
-+#define ARM_EH_ILLADDRS1  0x00000002 /* Address bits 25-27 error */
-+#define ARM_EH_ILLADDRS2  0x00000004 /* Address bits 31-28 error */
-+#define ARM_EH_VPU0HALT   0x00000008 /* VPU0 halted & in debug mode */
-+#define ARM_EH_VPU1HALT   0x00000010 /* VPU1 halted & in debug mode */
-+#define ARM_EH_ARMHALT    0x00000020 /* ARM in halted debug mode */
-+
-+#define ARM_ID_SECURE HW_REGISTER_RW(ARM_BASE+0x00C)
-+#define ARM_ID        HW_REGISTER_RW(ARM_BASE+0x44C)
-+#define ARM_IDVAL        0x364D5241
-+
-+/* Translation memory */
-+#define ARM_TRANSLATE HW_REGISTER_RW(ARM_BASE+0x100)
-+/* 32 locations: 0x100.. 0x17F */
-+/* 32 spare means we CAN go to 64 pages.... */
-+
-+
-+/* Interrupts */
-+#define ARM_IRQ_PEND0 HW_REGISTER_RW(ARM_BASE+0x200)        /* Top IRQ bits */
-+#define ARM_I0_TIMER    0x00000001 /* timer IRQ */
-+#define ARM_I0_MAIL     0x00000002 /* Mail IRQ */
-+#define ARM_I0_BELL0    0x00000004 /* Doorbell 0 */
-+#define ARM_I0_BELL1    0x00000008 /* Doorbell 1 */
-+#define ARM_I0_BANK1    0x00000100 /* Bank1 IRQ */
-+#define ARM_I0_BANK2    0x00000200 /* Bank2 IRQ */
-+
-+#define ARM_IRQ_PEND1 HW_REGISTER_RW(ARM_BASE+0x204) /* All bank1 IRQ bits */
-+/* todo: all I1_interrupt sources */
-+#define ARM_IRQ_PEND2 HW_REGISTER_RW(ARM_BASE+0x208) /* All bank2 IRQ bits */
-+/* todo: all I2_interrupt sources */
-+
-+#define ARM_IRQ_FAST  HW_REGISTER_RW(ARM_BASE+0x20C) /* FIQ control */
-+#define ARM_IF_INDEX    0x0000007F     /* FIQ select */
-+#define ARM_IF_ENABLE   0x00000080     /* FIQ enable */
-+#define ARM_IF_VCMASK   0x0000003F     /* FIQ = (index from VC source) */
-+#define ARM_IF_TIMER    0x00000040     /* FIQ = ARM timer */
-+#define ARM_IF_MAIL     0x00000041     /* FIQ = ARM Mail */
-+#define ARM_IF_BELL0    0x00000042     /* FIQ = ARM Doorbell 0 */
-+#define ARM_IF_BELL1    0x00000043     /* FIQ = ARM Doorbell 1 */
-+#define ARM_IF_VP0HALT  0x00000044     /* FIQ = VPU0 Halt seen */
-+#define ARM_IF_VP1HALT  0x00000045     /* FIQ = VPU1 Halt seen */
-+#define ARM_IF_ILLEGAL  0x00000046     /* FIQ = Illegal access seen */
-+
-+#define ARM_IRQ_ENBL1 HW_REGISTER_RW(ARM_BASE+0x210) /* Bank1 enable bits */
-+#define ARM_IRQ_ENBL2 HW_REGISTER_RW(ARM_BASE+0x214) /* Bank2 enable bits */
-+#define ARM_IRQ_ENBL3 HW_REGISTER_RW(ARM_BASE+0x218) /* ARM irqs enable bits */
-+#define ARM_IRQ_DIBL1 HW_REGISTER_RW(ARM_BASE+0x21C) /* Bank1 disable bits */
-+#define ARM_IRQ_DIBL2 HW_REGISTER_RW(ARM_BASE+0x220) /* Bank2 disable bits */
-+#define ARM_IRQ_DIBL3 HW_REGISTER_RW(ARM_BASE+0x224) /* ARM irqs disable bits */
-+#define ARM_IE_TIMER    0x00000001     /* Timer IRQ */
-+#define ARM_IE_MAIL     0x00000002     /* Mail IRQ */
-+#define ARM_IE_BELL0    0x00000004     /* Doorbell 0 */
-+#define ARM_IE_BELL1    0x00000008     /* Doorbell 1 */
-+#define ARM_IE_VP0HALT  0x00000010     /* VPU0 Halt */
-+#define ARM_IE_VP1HALT  0x00000020     /* VPU1 Halt */
-+#define ARM_IE_ILLEGAL  0x00000040     /* Illegal access seen */
-+
-+/* Timer */
-+/* For reg. fields see sp804 spec. */
-+#define ARM_T_LOAD    HW_REGISTER_RW(ARM_BASE+0x400)
-+#define ARM_T_VALUE   HW_REGISTER_RW(ARM_BASE+0x404)
-+#define ARM_T_CONTROL HW_REGISTER_RW(ARM_BASE+0x408)
-+#define ARM_T_IRQCNTL HW_REGISTER_RW(ARM_BASE+0x40C)
-+#define ARM_T_RAWIRQ  HW_REGISTER_RW(ARM_BASE+0x410)
-+#define ARM_T_MSKIRQ  HW_REGISTER_RW(ARM_BASE+0x414)
-+#define ARM_T_RELOAD  HW_REGISTER_RW(ARM_BASE+0x418)
-+#define ARM_T_PREDIV  HW_REGISTER_RW(ARM_BASE+0x41c)
-+#define ARM_T_FREECNT HW_REGISTER_RW(ARM_BASE+0x420)
-+
-+#define TIMER_CTRL_ONESHOT  (1 << 0)
-+#define TIMER_CTRL_32BIT    (1 << 1)
-+#define TIMER_CTRL_DIV1     (0 << 2)
-+#define TIMER_CTRL_DIV16    (1 << 2)
-+#define TIMER_CTRL_DIV256   (2 << 2)
-+#define TIMER_CTRL_IE       (1 << 5)
-+#define TIMER_CTRL_PERIODIC (1 << 6)
-+#define TIMER_CTRL_ENABLE   (1 << 7)
-+#define TIMER_CTRL_DBGHALT  (1 << 8)
-+#define TIMER_CTRL_ENAFREE  (1 << 9)
-+#define TIMER_CTRL_FREEDIV_SHIFT 16)
-+#define TIMER_CTRL_FREEDIV_MASK  0xff
-+
-+/* Semaphores, Doorbells, Mailboxes */
-+#define ARM_SBM_OWN0  (ARM_BASE+0x800)
-+#define ARM_SBM_OWN1  (ARM_BASE+0x900)
-+#define ARM_SBM_OWN2  (ARM_BASE+0xA00)
-+#define ARM_SBM_OWN3  (ARM_BASE+0xB00)
-+
-+/* MAILBOXES
-+ * Register flags are common across all
-+ * owner registers. See end of this section
-+ *
-+ * Semaphores, Doorbells, Mailboxes Owner 0
-+ *
-+ */
-+
-+#define ARM_0_SEMS       HW_REGISTER_RW(ARM_SBM_OWN0+0x00)
-+#define ARM_0_SEM0       HW_REGISTER_RW(ARM_SBM_OWN0+0x00)
-+#define ARM_0_SEM1       HW_REGISTER_RW(ARM_SBM_OWN0+0x04)
-+#define ARM_0_SEM2       HW_REGISTER_RW(ARM_SBM_OWN0+0x08)
-+#define ARM_0_SEM3       HW_REGISTER_RW(ARM_SBM_OWN0+0x0C)
-+#define ARM_0_SEM4       HW_REGISTER_RW(ARM_SBM_OWN0+0x10)
-+#define ARM_0_SEM5       HW_REGISTER_RW(ARM_SBM_OWN0+0x14)
-+#define ARM_0_SEM6       HW_REGISTER_RW(ARM_SBM_OWN0+0x18)
-+#define ARM_0_SEM7       HW_REGISTER_RW(ARM_SBM_OWN0+0x1C)
-+#define ARM_0_BELL0      HW_REGISTER_RW(ARM_SBM_OWN0+0x40)
-+#define ARM_0_BELL1      HW_REGISTER_RW(ARM_SBM_OWN0+0x44)
-+#define ARM_0_BELL2      HW_REGISTER_RW(ARM_SBM_OWN0+0x48)
-+#define ARM_0_BELL3      HW_REGISTER_RW(ARM_SBM_OWN0+0x4C)
-+/* MAILBOX 0 access in Owner 0 area */
-+/* Some addresses should ONLY be used by owner 0 */
-+#define ARM_0_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN0+0x80)  /* .. 0x8C (4 locations) */
-+#define ARM_0_MAIL0_RD   HW_REGISTER_RW(ARM_SBM_OWN0+0x80)  /* .. 0x8C (4 locations) Normal read */
-+#define ARM_0_MAIL0_POL  HW_REGISTER_RW(ARM_SBM_OWN0+0x90)  /* none-pop read */
-+#define ARM_0_MAIL0_SND  HW_REGISTER_RW(ARM_SBM_OWN0+0x94)  /* Sender read (only LS 2 bits) */
-+#define ARM_0_MAIL0_STA  HW_REGISTER_RW(ARM_SBM_OWN0+0x98)  /* Status read */
-+#define ARM_0_MAIL0_CNF  HW_REGISTER_RW(ARM_SBM_OWN0+0x9C)  /* Config read/write */
-+/* MAILBOX 1 access in Owner 0 area */
-+/* Owner 0 should only WRITE to this mailbox */
-+#define ARM_0_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN0+0xA0)   /* .. 0xAC (4 locations) */
-+/*#define ARM_0_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN0+0xA0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_0_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN0+0xB0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_0_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN0+0xB4) */ /* DO NOT USE THIS !!!!! */
-+#define ARM_0_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN0+0xB8)   /* Status read */
-+/*#define ARM_0_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN0+0xBC) */ /* DO NOT USE THIS !!!!! */
-+/* General SEM, BELL, MAIL config/status */
-+#define ARM_0_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN0+0xE0)  /* semaphore clear/debug register */
-+#define ARM_0_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN0+0xE4)  /* Doorbells clear/debug register */
-+#define ARM_0_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN0+0xF8)  /* ALL interrupts */
-+#define ARM_0_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN0+0xFC)  /* IRQS pending for owner 0 */
-+
-+/* Semaphores, Doorbells, Mailboxes Owner 1 */
-+#define ARM_1_SEMS       HW_REGISTER_RW(ARM_SBM_OWN1+0x00)
-+#define ARM_1_SEM0       HW_REGISTER_RW(ARM_SBM_OWN1+0x00)
-+#define ARM_1_SEM1       HW_REGISTER_RW(ARM_SBM_OWN1+0x04)
-+#define ARM_1_SEM2       HW_REGISTER_RW(ARM_SBM_OWN1+0x08)
-+#define ARM_1_SEM3       HW_REGISTER_RW(ARM_SBM_OWN1+0x0C)
-+#define ARM_1_SEM4       HW_REGISTER_RW(ARM_SBM_OWN1+0x10)
-+#define ARM_1_SEM5       HW_REGISTER_RW(ARM_SBM_OWN1+0x14)
-+#define ARM_1_SEM6       HW_REGISTER_RW(ARM_SBM_OWN1+0x18)
-+#define ARM_1_SEM7       HW_REGISTER_RW(ARM_SBM_OWN1+0x1C)
-+#define ARM_1_BELL0      HW_REGISTER_RW(ARM_SBM_OWN1+0x40)
-+#define ARM_1_BELL1      HW_REGISTER_RW(ARM_SBM_OWN1+0x44)
-+#define ARM_1_BELL2      HW_REGISTER_RW(ARM_SBM_OWN1+0x48)
-+#define ARM_1_BELL3      HW_REGISTER_RW(ARM_SBM_OWN1+0x4C)
-+/* MAILBOX 0 access in Owner 0 area */
-+/* Owner 1 should only WRITE to this mailbox */
-+#define ARM_1_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN1+0x80)  /* .. 0x8C (4 locations) */
-+/*#define ARM_1_MAIL0_RD  HW_REGISTER_RW(ARM_SBM_OWN1+0x80) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_1_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN1+0x90) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_1_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN1+0x94) */ /* DO NOT USE THIS !!!!! */
-+#define ARM_1_MAIL0_STA  HW_REGISTER_RW(ARM_SBM_OWN1+0x98)  /* Status read */
-+/*#define ARM_1_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN1+0x9C) */ /* DO NOT USE THIS !!!!! */
-+/* MAILBOX 1 access in Owner 0 area */
-+#define ARM_1_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN1+0xA0)  /* .. 0xAC (4 locations) */
-+#define ARM_1_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN1+0xA0)  /* .. 0xAC (4 locations) Normal read */
-+#define ARM_1_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN1+0xB0)  /* none-pop read */
-+#define ARM_1_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN1+0xB4)  /* Sender read (only LS 2 bits) */
-+#define ARM_1_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN1+0xB8)  /* Status read */
-+#define ARM_1_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN1+0xBC)
-+/* General SEM, BELL, MAIL config/status */
-+#define ARM_1_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN1+0xE0)  /* semaphore clear/debug register */
-+#define ARM_1_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN1+0xE4)  /* Doorbells clear/debug register */
-+#define ARM_1_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN1+0xFC)  /* IRQS pending for owner 1 */
-+#define ARM_1_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN1+0xF8)  /* ALL interrupts */
-+
-+/* Semaphores, Doorbells, Mailboxes Owner 2 */
-+#define ARM_2_SEMS       HW_REGISTER_RW(ARM_SBM_OWN2+0x00)
-+#define ARM_2_SEM0       HW_REGISTER_RW(ARM_SBM_OWN2+0x00)
-+#define ARM_2_SEM1       HW_REGISTER_RW(ARM_SBM_OWN2+0x04)
-+#define ARM_2_SEM2       HW_REGISTER_RW(ARM_SBM_OWN2+0x08)
-+#define ARM_2_SEM3       HW_REGISTER_RW(ARM_SBM_OWN2+0x0C)
-+#define ARM_2_SEM4       HW_REGISTER_RW(ARM_SBM_OWN2+0x10)
-+#define ARM_2_SEM5       HW_REGISTER_RW(ARM_SBM_OWN2+0x14)
-+#define ARM_2_SEM6       HW_REGISTER_RW(ARM_SBM_OWN2+0x18)
-+#define ARM_2_SEM7       HW_REGISTER_RW(ARM_SBM_OWN2+0x1C)
-+#define ARM_2_BELL0      HW_REGISTER_RW(ARM_SBM_OWN2+0x40)
-+#define ARM_2_BELL1      HW_REGISTER_RW(ARM_SBM_OWN2+0x44)
-+#define ARM_2_BELL2      HW_REGISTER_RW(ARM_SBM_OWN2+0x48)
-+#define ARM_2_BELL3      HW_REGISTER_RW(ARM_SBM_OWN2+0x4C)
-+/* MAILBOX 0 access in Owner 2 area */
-+/* Owner 2 should only WRITE to this mailbox */
-+#define ARM_2_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN2+0x80)   /* .. 0x8C (4 locations) */
-+/*#define ARM_2_MAIL0_RD  HW_REGISTER_RW(ARM_SBM_OWN2+0x80)  */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_2_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN2+0x90)  */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_2_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN2+0x94)  */ /* DO NOT USE THIS !!!!! */
-+#define ARM_2_MAIL0_STA  HW_REGISTER_RW(ARM_SBM_OWN2+0x98)   /* Status read */
-+/*#define ARM_2_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN2+0x9C)  */ /* DO NOT USE THIS !!!!! */
-+/* MAILBOX 1 access in Owner 2 area */
-+/* Owner 2 should only WRITE to this mailbox */
-+#define ARM_2_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN2+0xA0)   /* .. 0xAC (4 locations) */
-+/*#define ARM_2_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN2+0xA0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_2_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN2+0xB0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_2_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN2+0xB4) */ /* DO NOT USE THIS !!!!! */
-+#define ARM_2_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN2+0xB8)   /* Status read */
-+/*#define ARM_2_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN2+0xBC) */ /* DO NOT USE THIS !!!!! */
-+/* General SEM, BELL, MAIL config/status */
-+#define ARM_2_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN2+0xE0)  /* semaphore clear/debug register */
-+#define ARM_2_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN2+0xE4)  /* Doorbells clear/debug register */
-+#define ARM_2_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN2+0xFC)  /* IRQS pending for owner 2 */
-+#define ARM_2_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN2+0xF8)  /* ALL interrupts */
-+
-+/* Semaphores, Doorbells, Mailboxes Owner 3 */
-+#define ARM_3_SEMS       HW_REGISTER_RW(ARM_SBM_OWN3+0x00)
-+#define ARM_3_SEM0       HW_REGISTER_RW(ARM_SBM_OWN3+0x00)
-+#define ARM_3_SEM1       HW_REGISTER_RW(ARM_SBM_OWN3+0x04)
-+#define ARM_3_SEM2       HW_REGISTER_RW(ARM_SBM_OWN3+0x08)
-+#define ARM_3_SEM3       HW_REGISTER_RW(ARM_SBM_OWN3+0x0C)
-+#define ARM_3_SEM4       HW_REGISTER_RW(ARM_SBM_OWN3+0x10)
-+#define ARM_3_SEM5       HW_REGISTER_RW(ARM_SBM_OWN3+0x14)
-+#define ARM_3_SEM6       HW_REGISTER_RW(ARM_SBM_OWN3+0x18)
-+#define ARM_3_SEM7       HW_REGISTER_RW(ARM_SBM_OWN3+0x1C)
-+#define ARM_3_BELL0      HW_REGISTER_RW(ARM_SBM_OWN3+0x40)
-+#define ARM_3_BELL1      HW_REGISTER_RW(ARM_SBM_OWN3+0x44)
-+#define ARM_3_BELL2      HW_REGISTER_RW(ARM_SBM_OWN3+0x48)
-+#define ARM_3_BELL3      HW_REGISTER_RW(ARM_SBM_OWN3+0x4C)
-+/* MAILBOX 0 access in Owner 3 area */
-+/* Owner 3 should only WRITE to this mailbox */
-+#define ARM_3_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN3+0x80)   /* .. 0x8C (4 locations) */
-+/*#define ARM_3_MAIL0_RD  HW_REGISTER_RW(ARM_SBM_OWN3+0x80)  */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_3_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN3+0x90)  */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_3_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN3+0x94)  */ /* DO NOT USE THIS !!!!! */
-+#define ARM_3_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN3+0x98)    /* Status read */
-+/*#define ARM_3_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN3+0x9C)  */ /* DO NOT USE THIS !!!!! */
-+/* MAILBOX 1 access in Owner 3 area */
-+/* Owner 3 should only WRITE to this mailbox */
-+#define ARM_3_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN3+0xA0)   /* .. 0xAC (4 locations) */
-+/*#define ARM_3_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN3+0xA0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_3_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN3+0xB0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_3_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN3+0xB4) */ /* DO NOT USE THIS !!!!! */
-+#define ARM_3_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN3+0xB8)   /* Status read */
-+/*#define ARM_3_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN3+0xBC) */ /* DO NOT USE THIS !!!!! */
-+/* General SEM, BELL, MAIL config/status */
-+#define ARM_3_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN3+0xE0)  /* semaphore clear/debug register */
-+#define ARM_3_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN3+0xE4)  /* Doorbells clear/debug register */
-+#define ARM_3_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN3+0xFC)  /* IRQS pending for owner 3 */
-+#define ARM_3_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN3+0xF8)  /* ALL interrupts */
-+
-+
-+
-+/*  Mailbox flags. Valid for all owners */
-+
-+/* Mailbox status register (...0x98) */
-+#define ARM_MS_FULL       0x80000000
-+#define ARM_MS_EMPTY      0x40000000
-+#define ARM_MS_LEVEL      0x400000FF /* Max. value depdnds on mailbox depth parameter */
-+
-+/* MAILBOX config/status register (...0x9C) */
-+/* ANY write to this register clears the error bits! */
-+#define ARM_MC_IHAVEDATAIRQEN    0x00000001 /* mailbox irq enable:  has data */
-+#define ARM_MC_IHAVESPACEIRQEN   0x00000002 /* mailbox irq enable:  has space */
-+#define ARM_MC_OPPISEMPTYIRQEN   0x00000004 /* mailbox irq enable: Opp. is empty */
-+#define ARM_MC_MAIL_CLEAR        0x00000008 /* mailbox clear write 1, then  0 */
-+#define ARM_MC_IHAVEDATAIRQPEND  0x00000010 /* mailbox irq pending:  has space */
-+#define ARM_MC_IHAVESPACEIRQPEND 0x00000020 /* mailbox irq pending: Opp. is empty */
-+#define ARM_MC_OPPISEMPTYIRQPEND 0x00000040 /* mailbox irq pending */
-+/* Bit 7 is unused */
-+#define ARM_MC_ERRNOOWN   0x00000100 /* error : none owner read from mailbox */
-+#define ARM_MC_ERROVERFLW 0x00000200 /* error : write to fill mailbox */
-+#define ARM_MC_ERRUNDRFLW 0x00000400 /* error : read from empty mailbox */
-+
-+/* Semaphore clear/debug register (...0xE0) */
-+#define ARM_SD_OWN0      0x00000003  /* Owner of sem 0 */
-+#define ARM_SD_OWN1      0x0000000C  /* Owner of sem 1 */
-+#define ARM_SD_OWN2      0x00000030  /* Owner of sem 2 */
-+#define ARM_SD_OWN3      0x000000C0  /* Owner of sem 3 */
-+#define ARM_SD_OWN4      0x00000300  /* Owner of sem 4 */
-+#define ARM_SD_OWN5      0x00000C00  /* Owner of sem 5 */
-+#define ARM_SD_OWN6      0x00003000  /* Owner of sem 6 */
-+#define ARM_SD_OWN7      0x0000C000  /* Owner of sem 7 */
-+#define ARM_SD_SEM0      0x00010000  /* Status of sem 0 */
-+#define ARM_SD_SEM1      0x00020000  /* Status of sem 1 */
-+#define ARM_SD_SEM2      0x00040000  /* Status of sem 2 */
-+#define ARM_SD_SEM3      0x00080000  /* Status of sem 3 */
-+#define ARM_SD_SEM4      0x00100000  /* Status of sem 4 */
-+#define ARM_SD_SEM5      0x00200000  /* Status of sem 5 */
-+#define ARM_SD_SEM6      0x00400000  /* Status of sem 6 */
-+#define ARM_SD_SEM7      0x00800000  /* Status of sem 7 */
-+
-+/* Doorbells clear/debug register (...0xE4) */
-+#define ARM_BD_OWN0      0x00000003  /* Owner of doorbell 0 */
-+#define ARM_BD_OWN1      0x0000000C  /* Owner of doorbell 1 */
-+#define ARM_BD_OWN2      0x00000030  /* Owner of doorbell 2 */
-+#define ARM_BD_OWN3      0x000000C0  /* Owner of doorbell 3 */
-+#define ARM_BD_BELL0     0x00000100  /* Status of doorbell 0 */
-+#define ARM_BD_BELL1     0x00000200  /* Status of doorbell 1 */
-+#define ARM_BD_BELL2     0x00000400  /* Status of doorbell 2 */
-+#define ARM_BD_BELL3     0x00000800  /* Status of doorbell 3 */
-+
-+/* MY IRQS register (...0xF8) */
-+#define ARM_MYIRQ_BELL   0x00000001  /* This owner has a doorbell IRQ */
-+#define ARM_MYIRQ_MAIL   0x00000002  /* This owner has a mailbox  IRQ */
-+
-+/* ALL IRQS register (...0xF8) */
-+#define ARM_AIS_BELL0 0x00000001  /* Doorbell 0 IRQ pending */
-+#define ARM_AIS_BELL1 0x00000002  /* Doorbell 1 IRQ pending */
-+#define ARM_AIS_BELL2 0x00000004  /* Doorbell 2 IRQ pending */
-+#define ARM_AIS_BELL3 0x00000008  /* Doorbell 3 IRQ pending */
-+#define ARM_AIS0_HAVEDATA 0x00000010  /* MAIL 0 has data IRQ pending */
-+#define ARM_AIS0_HAVESPAC 0x00000020  /* MAIL 0 has space IRQ pending */
-+#define ARM_AIS0_OPPEMPTY 0x00000040  /* MAIL 0 opposite is empty IRQ */
-+#define ARM_AIS1_HAVEDATA 0x00000080  /* MAIL 1 has data IRQ pending */
-+#define ARM_AIS1_HAVESPAC 0x00000100  /* MAIL 1 has space IRQ pending */
-+#define ARM_AIS1_OPPEMPTY 0x00000200  /* MAIL 1 opposite is empty IRQ */
-+/* Note   that bell-0, bell-1 and MAIL0 IRQ go only to the ARM */
-+/* Whilst that bell-2, bell-3 and MAIL1 IRQ go only to the VC */
-+/* */
-+/* ARM JTAG BASH */
-+/* */
-+#define AJB_BASE 0x7e2000c0
-+
-+#define AJBCONF HW_REGISTER_RW(AJB_BASE+0x00)
-+#define   AJB_BITS0    0x000000
-+#define   AJB_BITS4    0x000004
-+#define   AJB_BITS8    0x000008
-+#define   AJB_BITS12   0x00000C
-+#define   AJB_BITS16   0x000010
-+#define   AJB_BITS20   0x000014
-+#define   AJB_BITS24   0x000018
-+#define   AJB_BITS28   0x00001C
-+#define   AJB_BITS32   0x000020
-+#define   AJB_BITS34   0x000022
-+#define   AJB_OUT_MS   0x000040
-+#define   AJB_OUT_LS   0x000000
-+#define   AJB_INV_CLK  0x000080
-+#define   AJB_D0_RISE  0x000100
-+#define   AJB_D0_FALL  0x000000
-+#define   AJB_D1_RISE  0x000200
-+#define   AJB_D1_FALL  0x000000
-+#define   AJB_IN_RISE  0x000400
-+#define   AJB_IN_FALL  0x000000
-+#define   AJB_ENABLE   0x000800
-+#define   AJB_HOLD0    0x000000
-+#define   AJB_HOLD1    0x001000
-+#define   AJB_HOLD2    0x002000
-+#define   AJB_HOLD3    0x003000
-+#define   AJB_RESETN   0x004000
-+#define   AJB_CLKSHFT  16
-+#define   AJB_BUSY     0x80000000
-+#define AJBTMS HW_REGISTER_RW(AJB_BASE+0x04)
-+#define AJBTDI HW_REGISTER_RW(AJB_BASE+0x08)
-+#define AJBTDO HW_REGISTER_RW(AJB_BASE+0x0c)
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/clkdev.h
-@@ -0,0 +1,7 @@
-+#ifndef __ASM_MACH_CLKDEV_H
-+#define __ASM_MACH_CLKDEV_H
-+
-+#define __clk_get(clk) ({ 1; })
-+#define __clk_put(clk) do { } while (0)
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/debug-macro.S
-@@ -0,0 +1,22 @@
-+/* arch/arm/mach-bcm2708/include/mach/debug-macro.S
-+ *
-+ * Debugging macro include header
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *  Copyright (C) 1994-1999 Russell King
-+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+*/
-+
-+#include <mach/platform.h>
-+
-+		.macro	addruart, rp, rv, tmp
-+		ldr	\rp, =UART0_BASE
-+		ldr	\rv, =IO_ADDRESS(UART0_BASE)
-+		.endm
-+
-+#include <debug/pl01x.S>
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/entry-macro.S
-@@ -0,0 +1,69 @@
-+/*
-+ * arch/arm/mach-bcm2708/include/mach/entry-macro.S
-+ *
-+ * Low-level IRQ helper macros for BCM2708 platforms
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <mach/hardware.h>
-+
-+		.macro	disable_fiq
-+		.endm
-+
-+		.macro  get_irqnr_preamble, base, tmp
-+		ldr	\base, =IO_ADDRESS(ARMCTRL_IC_BASE)
-+		.endm
-+
-+		.macro  arch_ret_to_user, tmp1, tmp2
-+		.endm
-+
-+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-+		/* get masked status */
-+		ldr	\irqstat, [\base, #(ARM_IRQ_PEND0 - ARMCTRL_IC_BASE)]
-+		mov	\irqnr, #(ARM_IRQ0_BASE + 31)
-+		and	\tmp, \irqstat, #0x300		 @ save bits 8 and 9
-+		/* clear bits 8 and 9, and test */
-+		bics	\irqstat, \irqstat, #0x300
-+		bne	1010f
-+
-+		tst	\tmp, #0x100
-+		ldrne	\irqstat, [\base, #(ARM_IRQ_PEND1 - ARMCTRL_IC_BASE)]
-+		movne \irqnr, #(ARM_IRQ1_BASE + 31)
-+		@ Mask out the interrupts also present in PEND0 - see SW-5809
-+		bicne \irqstat, #((1<<7) | (1<<9) | (1<<10))
-+		bicne \irqstat, #((1<<18) | (1<<19))
-+		bne	1010f
-+
-+		tst	\tmp, #0x200
-+		ldrne \irqstat, [\base, #(ARM_IRQ_PEND2 - ARMCTRL_IC_BASE)]
-+		movne \irqnr, #(ARM_IRQ2_BASE + 31)
-+		@ Mask out the interrupts also present in PEND0 - see SW-5809
-+		bicne \irqstat, #((1<<21) | (1<<22) | (1<<23) | (1<<24) | (1<<25))
-+		bicne \irqstat, #((1<<30))
-+		beq 1020f
-+
-+1010:
-+		@ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
-+		@ N.B. CLZ is an ARM5 instruction.
-+		sub	\tmp, \irqstat, #1
-+		eor	\irqstat, \irqstat, \tmp
-+		clz	\tmp, \irqstat
-+		sub	\irqnr, \tmp
-+
-+1020:	@ EQ will be set if no irqs pending
-+
-+		.endm
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/frc.h
-@@ -0,0 +1,38 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/timex.h
-+ *
-+ *  BCM2708 free running counter (timer)
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef _MACH_FRC_H
-+#define _MACH_FRC_H
-+
-+#define FRC_TICK_RATE		(1000000)
-+
-+/*! Free running counter incrementing at the CLOCK_TICK_RATE
-+    (slightly faster than frc_clock_ticks63()
-+ */
-+extern unsigned long frc_clock_ticks32(void);
-+
-+/*! Free running counter incrementing at the CLOCK_TICK_RATE
-+ *  Note - top bit should be ignored (see cnt32_to_63)
-+ */
-+extern unsigned long long frc_clock_ticks63(void);
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/hardware.h
-@@ -0,0 +1,28 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/hardware.h
-+ *
-+ *  This file contains the hardware definitions of the BCM2708 devices.
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifndef __ASM_ARCH_HARDWARE_H
-+#define __ASM_ARCH_HARDWARE_H
-+
-+#include <asm/sizes.h>
-+#include <mach/platform.h>
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/io.h
-@@ -0,0 +1,27 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/io.h
-+ *
-+ *  Copyright (C) 2003 ARM Limited
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT 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 __ASM_ARM_ARCH_IO_H
-+#define __ASM_ARM_ARCH_IO_H
-+
-+#define IO_SPACE_LIMIT 0xffffffff
-+
-+#define __io(a)		__typesafe_io(a)
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/irqs.h
-@@ -0,0 +1,196 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/irqs.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *  Copyright (C) 2003 ARM Limited
-+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef _BCM2708_IRQS_H_
-+#define _BCM2708_IRQS_H_
-+
-+#include <mach/platform.h>
-+
-+/*
-+ *  IRQ interrupts definitions are the same as the INT definitions
-+ *  held within platform.h
-+ */
-+#define IRQ_ARMCTRL_START     0
-+#define IRQ_TIMER0            (IRQ_ARMCTRL_START + INTERRUPT_TIMER0)
-+#define IRQ_TIMER1            (IRQ_ARMCTRL_START + INTERRUPT_TIMER1)
-+#define IRQ_TIMER2            (IRQ_ARMCTRL_START + INTERRUPT_TIMER2)
-+#define IRQ_TIMER3            (IRQ_ARMCTRL_START + INTERRUPT_TIMER3)
-+#define IRQ_CODEC0            (IRQ_ARMCTRL_START + INTERRUPT_CODEC0)
-+#define IRQ_CODEC1            (IRQ_ARMCTRL_START + INTERRUPT_CODEC1)
-+#define IRQ_CODEC2            (IRQ_ARMCTRL_START + INTERRUPT_CODEC2)
-+#define IRQ_JPEG              (IRQ_ARMCTRL_START + INTERRUPT_JPEG)
-+#define IRQ_ISP               (IRQ_ARMCTRL_START + INTERRUPT_ISP)
-+#define IRQ_USB               (IRQ_ARMCTRL_START + INTERRUPT_USB)
-+#define IRQ_3D                (IRQ_ARMCTRL_START + INTERRUPT_3D)
-+#define IRQ_TRANSPOSER        (IRQ_ARMCTRL_START + INTERRUPT_TRANSPOSER)
-+#define IRQ_MULTICORESYNC0    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC0)
-+#define IRQ_MULTICORESYNC1    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC1)
-+#define IRQ_MULTICORESYNC2    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC2)
-+#define IRQ_MULTICORESYNC3    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC3)
-+#define IRQ_DMA0              (IRQ_ARMCTRL_START + INTERRUPT_DMA0)
-+#define IRQ_DMA1              (IRQ_ARMCTRL_START + INTERRUPT_DMA1)
-+#define IRQ_DMA2              (IRQ_ARMCTRL_START + INTERRUPT_DMA2)
-+#define IRQ_DMA3              (IRQ_ARMCTRL_START + INTERRUPT_DMA3)
-+#define IRQ_DMA4              (IRQ_ARMCTRL_START + INTERRUPT_DMA4)
-+#define IRQ_DMA5              (IRQ_ARMCTRL_START + INTERRUPT_DMA5)
-+#define IRQ_DMA6              (IRQ_ARMCTRL_START + INTERRUPT_DMA6)
-+#define IRQ_DMA7              (IRQ_ARMCTRL_START + INTERRUPT_DMA7)
-+#define IRQ_DMA8              (IRQ_ARMCTRL_START + INTERRUPT_DMA8)
-+#define IRQ_DMA9              (IRQ_ARMCTRL_START + INTERRUPT_DMA9)
-+#define IRQ_DMA10             (IRQ_ARMCTRL_START + INTERRUPT_DMA10)
-+#define IRQ_DMA11             (IRQ_ARMCTRL_START + INTERRUPT_DMA11)
-+#define IRQ_DMA12             (IRQ_ARMCTRL_START + INTERRUPT_DMA12)
-+#define IRQ_AUX               (IRQ_ARMCTRL_START + INTERRUPT_AUX)
-+#define IRQ_ARM               (IRQ_ARMCTRL_START + INTERRUPT_ARM)
-+#define IRQ_VPUDMA            (IRQ_ARMCTRL_START + INTERRUPT_VPUDMA)
-+#define IRQ_HOSTPORT          (IRQ_ARMCTRL_START + INTERRUPT_HOSTPORT)
-+#define IRQ_VIDEOSCALER       (IRQ_ARMCTRL_START + INTERRUPT_VIDEOSCALER)
-+#define IRQ_CCP2TX            (IRQ_ARMCTRL_START + INTERRUPT_CCP2TX)
-+#define IRQ_SDC               (IRQ_ARMCTRL_START + INTERRUPT_SDC)
-+#define IRQ_DSI0              (IRQ_ARMCTRL_START + INTERRUPT_DSI0)
-+#define IRQ_AVE               (IRQ_ARMCTRL_START + INTERRUPT_AVE)
-+#define IRQ_CAM0              (IRQ_ARMCTRL_START + INTERRUPT_CAM0)
-+#define IRQ_CAM1              (IRQ_ARMCTRL_START + INTERRUPT_CAM1)
-+#define IRQ_HDMI0             (IRQ_ARMCTRL_START + INTERRUPT_HDMI0)
-+#define IRQ_HDMI1             (IRQ_ARMCTRL_START + INTERRUPT_HDMI1)
-+#define IRQ_PIXELVALVE1       (IRQ_ARMCTRL_START + INTERRUPT_PIXELVALVE1)
-+#define IRQ_I2CSPISLV         (IRQ_ARMCTRL_START + INTERRUPT_I2CSPISLV)
-+#define IRQ_DSI1              (IRQ_ARMCTRL_START + INTERRUPT_DSI1)
-+#define IRQ_PWA0              (IRQ_ARMCTRL_START + INTERRUPT_PWA0)
-+#define IRQ_PWA1              (IRQ_ARMCTRL_START + INTERRUPT_PWA1)
-+#define IRQ_CPR               (IRQ_ARMCTRL_START + INTERRUPT_CPR)
-+#define IRQ_SMI               (IRQ_ARMCTRL_START + INTERRUPT_SMI)
-+#define IRQ_GPIO0             (IRQ_ARMCTRL_START + INTERRUPT_GPIO0)
-+#define IRQ_GPIO1             (IRQ_ARMCTRL_START + INTERRUPT_GPIO1)
-+#define IRQ_GPIO2             (IRQ_ARMCTRL_START + INTERRUPT_GPIO2)
-+#define IRQ_GPIO3             (IRQ_ARMCTRL_START + INTERRUPT_GPIO3)
-+#define IRQ_I2C               (IRQ_ARMCTRL_START + INTERRUPT_I2C)
-+#define IRQ_SPI               (IRQ_ARMCTRL_START + INTERRUPT_SPI)
-+#define IRQ_I2SPCM            (IRQ_ARMCTRL_START + INTERRUPT_I2SPCM)
-+#define IRQ_SDIO              (IRQ_ARMCTRL_START + INTERRUPT_SDIO)
-+#define IRQ_UART              (IRQ_ARMCTRL_START + INTERRUPT_UART)
-+#define IRQ_SLIMBUS           (IRQ_ARMCTRL_START + INTERRUPT_SLIMBUS)
-+#define IRQ_VEC               (IRQ_ARMCTRL_START + INTERRUPT_VEC)
-+#define IRQ_CPG               (IRQ_ARMCTRL_START + INTERRUPT_CPG)
-+#define IRQ_RNG               (IRQ_ARMCTRL_START + INTERRUPT_RNG)
-+#define IRQ_ARASANSDIO        (IRQ_ARMCTRL_START + INTERRUPT_ARASANSDIO)
-+#define IRQ_AVSPMON           (IRQ_ARMCTRL_START + INTERRUPT_AVSPMON)
-+
-+#define IRQ_ARM_TIMER         (IRQ_ARMCTRL_START + INTERRUPT_ARM_TIMER)
-+#define IRQ_ARM_MAILBOX       (IRQ_ARMCTRL_START + INTERRUPT_ARM_MAILBOX)
-+#define IRQ_ARM_DOORBELL_0    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_0)
-+#define IRQ_ARM_DOORBELL_1    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_1)
-+#define IRQ_VPU0_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU0_HALTED)
-+#define IRQ_VPU1_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU1_HALTED)
-+#define IRQ_ILLEGAL_TYPE0     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE0)
-+#define IRQ_ILLEGAL_TYPE1     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE1)
-+#define IRQ_PENDING1          (IRQ_ARMCTRL_START + INTERRUPT_PENDING1)
-+#define IRQ_PENDING2          (IRQ_ARMCTRL_START + INTERRUPT_PENDING2)
-+
-+/*
-+ *  FIQ interrupts definitions are the same as the INT definitions.
-+ */
-+#define FIQ_TIMER0            INT_TIMER0
-+#define FIQ_TIMER1            INT_TIMER1
-+#define FIQ_TIMER2            INT_TIMER2
-+#define FIQ_TIMER3            INT_TIMER3
-+#define FIQ_CODEC0            INT_CODEC0
-+#define FIQ_CODEC1            INT_CODEC1
-+#define FIQ_CODEC2            INT_CODEC2
-+#define FIQ_JPEG              INT_JPEG
-+#define FIQ_ISP               INT_ISP
-+#define FIQ_USB               INT_USB
-+#define FIQ_3D                INT_3D
-+#define FIQ_TRANSPOSER        INT_TRANSPOSER
-+#define FIQ_MULTICORESYNC0    INT_MULTICORESYNC0
-+#define FIQ_MULTICORESYNC1    INT_MULTICORESYNC1
-+#define FIQ_MULTICORESYNC2    INT_MULTICORESYNC2
-+#define FIQ_MULTICORESYNC3    INT_MULTICORESYNC3
-+#define FIQ_DMA0              INT_DMA0
-+#define FIQ_DMA1              INT_DMA1
-+#define FIQ_DMA2              INT_DMA2
-+#define FIQ_DMA3              INT_DMA3
-+#define FIQ_DMA4              INT_DMA4
-+#define FIQ_DMA5              INT_DMA5
-+#define FIQ_DMA6              INT_DMA6
-+#define FIQ_DMA7              INT_DMA7
-+#define FIQ_DMA8              INT_DMA8
-+#define FIQ_DMA9              INT_DMA9
-+#define FIQ_DMA10             INT_DMA10
-+#define FIQ_DMA11             INT_DMA11
-+#define FIQ_DMA12             INT_DMA12
-+#define FIQ_AUX               INT_AUX
-+#define FIQ_ARM               INT_ARM
-+#define FIQ_VPUDMA            INT_VPUDMA
-+#define FIQ_HOSTPORT          INT_HOSTPORT
-+#define FIQ_VIDEOSCALER       INT_VIDEOSCALER
-+#define FIQ_CCP2TX            INT_CCP2TX
-+#define FIQ_SDC               INT_SDC
-+#define FIQ_DSI0              INT_DSI0
-+#define FIQ_AVE               INT_AVE
-+#define FIQ_CAM0              INT_CAM0
-+#define FIQ_CAM1              INT_CAM1
-+#define FIQ_HDMI0             INT_HDMI0
-+#define FIQ_HDMI1             INT_HDMI1
-+#define FIQ_PIXELVALVE1       INT_PIXELVALVE1
-+#define FIQ_I2CSPISLV         INT_I2CSPISLV
-+#define FIQ_DSI1              INT_DSI1
-+#define FIQ_PWA0              INT_PWA0
-+#define FIQ_PWA1              INT_PWA1
-+#define FIQ_CPR               INT_CPR
-+#define FIQ_SMI               INT_SMI
-+#define FIQ_GPIO0             INT_GPIO0
-+#define FIQ_GPIO1             INT_GPIO1
-+#define FIQ_GPIO2             INT_GPIO2
-+#define FIQ_GPIO3             INT_GPIO3
-+#define FIQ_I2C               INT_I2C
-+#define FIQ_SPI               INT_SPI
-+#define FIQ_I2SPCM            INT_I2SPCM
-+#define FIQ_SDIO              INT_SDIO
-+#define FIQ_UART              INT_UART
-+#define FIQ_SLIMBUS           INT_SLIMBUS
-+#define FIQ_VEC               INT_VEC
-+#define FIQ_CPG               INT_CPG
-+#define FIQ_RNG               INT_RNG
-+#define FIQ_ARASANSDIO        INT_ARASANSDIO
-+#define FIQ_AVSPMON           INT_AVSPMON
-+
-+#define FIQ_ARM_TIMER         INT_ARM_TIMER
-+#define FIQ_ARM_MAILBOX       INT_ARM_MAILBOX
-+#define FIQ_ARM_DOORBELL_0    INT_ARM_DOORBELL_0
-+#define FIQ_ARM_DOORBELL_1    INT_ARM_DOORBELL_1
-+#define FIQ_VPU0_HALTED       INT_VPU0_HALTED
-+#define FIQ_VPU1_HALTED       INT_VPU1_HALTED
-+#define FIQ_ILLEGAL_TYPE0     INT_ILLEGAL_TYPE0
-+#define FIQ_ILLEGAL_TYPE1     INT_ILLEGAL_TYPE1
-+#define FIQ_PENDING1          INT_PENDING1
-+#define FIQ_PENDING2          INT_PENDING2
-+
-+#define HARD_IRQS	      (64 + 21)
-+#define GPIO_IRQ_START  (HARD_IRQS)
-+#define GPIO_IRQS	      (32*5)
-+#define SPARE_ALLOC_IRQS      64
-+#define BCM2708_ALLOC_IRQS    (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS)
-+#define FREE_IRQS             128
-+#define NR_IRQS               (BCM2708_ALLOC_IRQS+FREE_IRQS)
-+
-+#endif /* _BCM2708_IRQS_H_ */
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/memory.h
-@@ -0,0 +1,57 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/memory.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifndef __ASM_ARCH_MEMORY_H
-+#define __ASM_ARCH_MEMORY_H
-+
-+/* Memory overview:
-+
-+   [ARMcore] <--virtual addr-->
-+   [ARMmmu] <--physical addr-->
-+   [GERTmap] <--bus add-->
-+   [VCperiph]
-+
-+*/
-+
-+/*
-+ * Physical DRAM offset.
-+ */
-+#define BCM_PLAT_PHYS_OFFSET	UL(0x00000000)
-+#define VC_ARMMEM_OFFSET	UL(0x00000000)   /* offset in VC of ARM memory */
-+
-+#ifdef CONFIG_BCM2708_NOL2CACHE
-+ #define _REAL_BUS_OFFSET UL(0xC0000000)   /* don't use L1 or L2 caches */
-+#else
-+ #define _REAL_BUS_OFFSET UL(0x40000000)   /* use L2 cache */
-+#endif
-+
-+/* We're using the memory at 64M in the VideoCore for Linux - this adjustment
-+ * will provide the offset into this area as well as setting the bits that
-+ * stop the L1 and L2 cache from being used
-+ *
-+ * WARNING: this only works because the ARM is given memory at a fixed location
-+ *          (ARMMEM_OFFSET)
-+ */
-+#define BUS_OFFSET          (VC_ARMMEM_OFFSET + _REAL_BUS_OFFSET)
-+#define __virt_to_bus(x)    ((x) + (BUS_OFFSET - PAGE_OFFSET))
-+#define __bus_to_virt(x)    ((x) - (BUS_OFFSET - PAGE_OFFSET))
-+#define __pfn_to_bus(x)     (__pfn_to_phys(x) + (BUS_OFFSET - BCM_PLAT_PHYS_OFFSET))
-+#define __bus_to_pfn(x)     __phys_to_pfn((x) - (BUS_OFFSET - BCM_PLAT_PHYS_OFFSET))
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/platform.h
-@@ -0,0 +1,228 @@
-+/*
-+ * arch/arm/mach-bcm2708/include/mach/platform.h
-+ *
-+ * Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef _BCM2708_PLATFORM_H
-+#define _BCM2708_PLATFORM_H
-+
-+
-+/* macros to get at IO space when running virtually */
-+#define IO_ADDRESS(x)	(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
-+
-+#define __io_address(n)     IOMEM(IO_ADDRESS(n))
-+
-+
-+/*
-+ *  SDRAM
-+ */
-+#define BCM2708_SDRAM_BASE           0x00000000
-+
-+/*
-+ *  Logic expansion modules
-+ *
-+ */
-+
-+
-+/* ------------------------------------------------------------------------
-+ *  BCM2708 ARMCTRL Registers
-+ * ------------------------------------------------------------------------
-+ */
-+
-+#define HW_REGISTER_RW(addr) (addr)
-+#define HW_REGISTER_RO(addr) (addr)
-+
-+#include "arm_control.h"
-+#undef ARM_BASE
-+
-+/*
-+ * Definitions and addresses for the ARM CONTROL logic
-+ * This file is manually generated.
-+ */
-+
-+#define BCM2708_PERI_BASE        0x20000000
-+#define IC0_BASE                 (BCM2708_PERI_BASE + 0x2000)
-+#define ST_BASE                  (BCM2708_PERI_BASE + 0x3000)   /* System Timer */
-+#define MPHI_BASE		 (BCM2708_PERI_BASE + 0x6000)	/* Message -based Parallel Host Interface */
-+#define DMA_BASE		 (BCM2708_PERI_BASE + 0x7000)	/* DMA controller */
-+#define ARM_BASE                 (BCM2708_PERI_BASE + 0xB000)	 /* BCM2708 ARM control block */
-+#define PM_BASE			 (BCM2708_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */
-+#define PCM_CLOCK_BASE           (BCM2708_PERI_BASE + 0x101098) /* PCM Clock */
-+#define RNG_BASE                 (BCM2708_PERI_BASE + 0x104000) /* Hardware RNG */
-+#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO */
-+#define UART0_BASE               (BCM2708_PERI_BASE + 0x201000)	/* Uart 0 */
-+#define MMCI0_BASE               (BCM2708_PERI_BASE + 0x202000) /* MMC interface */
-+#define I2S_BASE                 (BCM2708_PERI_BASE + 0x203000) /* I2S */
-+#define SPI0_BASE		 (BCM2708_PERI_BASE + 0x204000) /* SPI0 */
-+#define BSC0_BASE		 (BCM2708_PERI_BASE + 0x205000) /* BSC0 I2C/TWI */
-+#define UART1_BASE               (BCM2708_PERI_BASE + 0x215000) /* Uart 1 */
-+#define EMMC_BASE                (BCM2708_PERI_BASE + 0x300000) /* eMMC interface */
-+#define SMI_BASE		 (BCM2708_PERI_BASE + 0x600000) /* SMI */
-+#define BSC1_BASE		 (BCM2708_PERI_BASE + 0x804000) /* BSC1 I2C/TWI */
-+#define USB_BASE                 (BCM2708_PERI_BASE + 0x980000) /* DTC_OTG USB controller */
-+#define MCORE_BASE               (BCM2708_PERI_BASE + 0x0000)   /* Fake frame buffer device (actually the multicore sync block*/
-+
-+#define ARMCTRL_BASE             (ARM_BASE + 0x000)
-+#define ARMCTRL_IC_BASE          (ARM_BASE + 0x200)           /* ARM interrupt controller */
-+#define ARMCTRL_TIMER0_1_BASE    (ARM_BASE + 0x400)           /* Timer 0 and 1 */
-+#define ARMCTRL_0_SBM_BASE       (ARM_BASE + 0x800)           /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */
-+
-+
-+/*
-+ * Interrupt assignments
-+ */
-+
-+#define ARM_IRQ1_BASE                  0
-+#define INTERRUPT_TIMER0               (ARM_IRQ1_BASE + 0)
-+#define INTERRUPT_TIMER1               (ARM_IRQ1_BASE + 1)
-+#define INTERRUPT_TIMER2               (ARM_IRQ1_BASE + 2)
-+#define INTERRUPT_TIMER3               (ARM_IRQ1_BASE + 3)
-+#define INTERRUPT_CODEC0               (ARM_IRQ1_BASE + 4)
-+#define INTERRUPT_CODEC1               (ARM_IRQ1_BASE + 5)
-+#define INTERRUPT_CODEC2               (ARM_IRQ1_BASE + 6)
-+#define INTERRUPT_VC_JPEG              (ARM_IRQ1_BASE + 7)
-+#define INTERRUPT_ISP                  (ARM_IRQ1_BASE + 8)
-+#define INTERRUPT_VC_USB               (ARM_IRQ1_BASE + 9)
-+#define INTERRUPT_VC_3D                (ARM_IRQ1_BASE + 10)
-+#define INTERRUPT_TRANSPOSER           (ARM_IRQ1_BASE + 11)
-+#define INTERRUPT_MULTICORESYNC0       (ARM_IRQ1_BASE + 12)
-+#define INTERRUPT_MULTICORESYNC1       (ARM_IRQ1_BASE + 13)
-+#define INTERRUPT_MULTICORESYNC2       (ARM_IRQ1_BASE + 14)
-+#define INTERRUPT_MULTICORESYNC3       (ARM_IRQ1_BASE + 15)
-+#define INTERRUPT_DMA0                 (ARM_IRQ1_BASE + 16)
-+#define INTERRUPT_DMA1                 (ARM_IRQ1_BASE + 17)
-+#define INTERRUPT_VC_DMA2              (ARM_IRQ1_BASE + 18)
-+#define INTERRUPT_VC_DMA3              (ARM_IRQ1_BASE + 19)
-+#define INTERRUPT_DMA4                 (ARM_IRQ1_BASE + 20)
-+#define INTERRUPT_DMA5                 (ARM_IRQ1_BASE + 21)
-+#define INTERRUPT_DMA6                 (ARM_IRQ1_BASE + 22)
-+#define INTERRUPT_DMA7                 (ARM_IRQ1_BASE + 23)
-+#define INTERRUPT_DMA8                 (ARM_IRQ1_BASE + 24)
-+#define INTERRUPT_DMA9                 (ARM_IRQ1_BASE + 25)
-+#define INTERRUPT_DMA10                (ARM_IRQ1_BASE + 26)
-+#define INTERRUPT_DMA11                (ARM_IRQ1_BASE + 27)
-+#define INTERRUPT_DMA12                (ARM_IRQ1_BASE + 28)
-+#define INTERRUPT_AUX                (ARM_IRQ1_BASE + 29)
-+#define INTERRUPT_ARM                  (ARM_IRQ1_BASE + 30)
-+#define INTERRUPT_VPUDMA               (ARM_IRQ1_BASE + 31)
-+
-+#define ARM_IRQ2_BASE                  32
-+#define INTERRUPT_HOSTPORT             (ARM_IRQ2_BASE + 0)
-+#define INTERRUPT_VIDEOSCALER          (ARM_IRQ2_BASE + 1)
-+#define INTERRUPT_CCP2TX               (ARM_IRQ2_BASE + 2)
-+#define INTERRUPT_SDC                  (ARM_IRQ2_BASE + 3)
-+#define INTERRUPT_DSI0                 (ARM_IRQ2_BASE + 4)
-+#define INTERRUPT_AVE                  (ARM_IRQ2_BASE + 5)
-+#define INTERRUPT_CAM0                 (ARM_IRQ2_BASE + 6)
-+#define INTERRUPT_CAM1                 (ARM_IRQ2_BASE + 7)
-+#define INTERRUPT_HDMI0                (ARM_IRQ2_BASE + 8)
-+#define INTERRUPT_HDMI1                (ARM_IRQ2_BASE + 9)
-+#define INTERRUPT_PIXELVALVE1          (ARM_IRQ2_BASE + 10)
-+#define INTERRUPT_I2CSPISLV            (ARM_IRQ2_BASE + 11)
-+#define INTERRUPT_DSI1                 (ARM_IRQ2_BASE + 12)
-+#define INTERRUPT_PWA0                 (ARM_IRQ2_BASE + 13)
-+#define INTERRUPT_PWA1                 (ARM_IRQ2_BASE + 14)
-+#define INTERRUPT_CPR                  (ARM_IRQ2_BASE + 15)
-+#define INTERRUPT_SMI                  (ARM_IRQ2_BASE + 16)
-+#define INTERRUPT_GPIO0                (ARM_IRQ2_BASE + 17)
-+#define INTERRUPT_GPIO1                (ARM_IRQ2_BASE + 18)
-+#define INTERRUPT_GPIO2                (ARM_IRQ2_BASE + 19)
-+#define INTERRUPT_GPIO3                (ARM_IRQ2_BASE + 20)
-+#define INTERRUPT_VC_I2C               (ARM_IRQ2_BASE + 21)
-+#define INTERRUPT_VC_SPI               (ARM_IRQ2_BASE + 22)
-+#define INTERRUPT_VC_I2SPCM            (ARM_IRQ2_BASE + 23)
-+#define INTERRUPT_VC_SDIO              (ARM_IRQ2_BASE + 24)
-+#define INTERRUPT_VC_UART              (ARM_IRQ2_BASE + 25)
-+#define INTERRUPT_SLIMBUS              (ARM_IRQ2_BASE + 26)
-+#define INTERRUPT_VEC                  (ARM_IRQ2_BASE + 27)
-+#define INTERRUPT_CPG                  (ARM_IRQ2_BASE + 28)
-+#define INTERRUPT_RNG                  (ARM_IRQ2_BASE + 29)
-+#define INTERRUPT_VC_ARASANSDIO        (ARM_IRQ2_BASE + 30)
-+#define INTERRUPT_AVSPMON              (ARM_IRQ2_BASE + 31)
-+
-+#define ARM_IRQ0_BASE                  64
-+#define INTERRUPT_ARM_TIMER            (ARM_IRQ0_BASE + 0)
-+#define INTERRUPT_ARM_MAILBOX          (ARM_IRQ0_BASE + 1)
-+#define INTERRUPT_ARM_DOORBELL_0       (ARM_IRQ0_BASE + 2)
-+#define INTERRUPT_ARM_DOORBELL_1       (ARM_IRQ0_BASE + 3)
-+#define INTERRUPT_VPU0_HALTED          (ARM_IRQ0_BASE + 4)
-+#define INTERRUPT_VPU1_HALTED          (ARM_IRQ0_BASE + 5)
-+#define INTERRUPT_ILLEGAL_TYPE0        (ARM_IRQ0_BASE + 6)
-+#define INTERRUPT_ILLEGAL_TYPE1        (ARM_IRQ0_BASE + 7)
-+#define INTERRUPT_PENDING1             (ARM_IRQ0_BASE + 8)
-+#define INTERRUPT_PENDING2             (ARM_IRQ0_BASE + 9)
-+#define INTERRUPT_JPEG                 (ARM_IRQ0_BASE + 10)
-+#define INTERRUPT_USB                  (ARM_IRQ0_BASE + 11)
-+#define INTERRUPT_3D                   (ARM_IRQ0_BASE + 12)
-+#define INTERRUPT_DMA2                 (ARM_IRQ0_BASE + 13)
-+#define INTERRUPT_DMA3                 (ARM_IRQ0_BASE + 14)
-+#define INTERRUPT_I2C                  (ARM_IRQ0_BASE + 15)
-+#define INTERRUPT_SPI                  (ARM_IRQ0_BASE + 16)
-+#define INTERRUPT_I2SPCM               (ARM_IRQ0_BASE + 17)
-+#define INTERRUPT_SDIO                 (ARM_IRQ0_BASE + 18)
-+#define INTERRUPT_UART                 (ARM_IRQ0_BASE + 19)
-+#define INTERRUPT_ARASANSDIO           (ARM_IRQ0_BASE + 20)
-+
-+#define MAXIRQNUM                      (32 + 32 + 20)
-+#define MAXFIQNUM                      (32 + 32 + 20)
-+
-+#define MAX_TIMER                       2
-+#define MAX_PERIOD                      699050
-+#define TICKS_PER_uSEC                  1
-+
-+/*
-+ *  These are useconds NOT ticks.
-+ *
-+ */
-+#define mSEC_1                          1000
-+#define mSEC_5                          (mSEC_1 * 5)
-+#define mSEC_10                         (mSEC_1 * 10)
-+#define mSEC_25                         (mSEC_1 * 25)
-+#define SEC_1                           (mSEC_1 * 1000)
-+
-+/*
-+ * Watchdog
-+ */
-+#define PM_RSTC			       (PM_BASE+0x1c)
-+#define PM_RSTS			       (PM_BASE+0x20)
-+#define PM_WDOG			       (PM_BASE+0x24)
-+
-+#define PM_WDOG_RESET                                         0000000000
-+#define PM_PASSWORD		       0x5a000000
-+#define PM_WDOG_TIME_SET	       0x000fffff
-+#define PM_RSTC_WRCFG_CLR              0xffffffcf
-+#define PM_RSTC_WRCFG_SET              0x00000030
-+#define PM_RSTC_WRCFG_FULL_RESET       0x00000020
-+#define PM_RSTC_RESET                  0x00000102
-+
-+#define PM_RSTS_HADPOR_SET                                 0x00001000
-+#define PM_RSTS_HADSRH_SET                                 0x00000400
-+#define PM_RSTS_HADSRF_SET                                 0x00000200
-+#define PM_RSTS_HADSRQ_SET                                 0x00000100
-+#define PM_RSTS_HADWRH_SET                                 0x00000040
-+#define PM_RSTS_HADWRF_SET                                 0x00000020
-+#define PM_RSTS_HADWRQ_SET                                 0x00000010
-+#define PM_RSTS_HADDRH_SET                                 0x00000004
-+#define PM_RSTS_HADDRF_SET                                 0x00000002
-+#define PM_RSTS_HADDRQ_SET                                 0x00000001
-+
-+#define UART0_CLOCK      3000000
-+
-+#endif
-+
-+/* END */
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/system.h
-@@ -0,0 +1,38 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/system.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *  Copyright (C) 2003 ARM Limited
-+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifndef __ASM_ARCH_SYSTEM_H
-+#define __ASM_ARCH_SYSTEM_H
-+
-+#include <linux/io.h>
-+#include <mach/hardware.h>
-+#include <mach/platform.h>
-+
-+static inline void arch_idle(void)
-+{
-+	/*
-+	 * This should do all the clock switching
-+	 * and wait for interrupt tricks
-+	 */
-+	cpu_do_idle();
-+}
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/timex.h
-@@ -0,0 +1,23 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/timex.h
-+ *
-+ *  BCM2708 sysem clock frequency
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#define CLOCK_TICK_RATE		(1000000)
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/uncompress.h
-@@ -0,0 +1,84 @@
-+/*
-+ *  arch/arm/mach-bcn2708/include/mach/uncompress.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *  Copyright (C) 2003 ARM Limited
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT 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/io.h>
-+#include <linux/amba/serial.h>
-+#include <mach/hardware.h>
-+
-+#define UART_BAUD 115200
-+
-+#define BCM2708_UART_DR   __io(UART0_BASE + UART01x_DR)
-+#define BCM2708_UART_FR   __io(UART0_BASE + UART01x_FR)
-+#define BCM2708_UART_IBRD __io(UART0_BASE + UART011_IBRD)
-+#define BCM2708_UART_FBRD __io(UART0_BASE + UART011_FBRD)
-+#define BCM2708_UART_LCRH __io(UART0_BASE + UART011_LCRH)
-+#define BCM2708_UART_CR   __io(UART0_BASE + UART011_CR)
-+
-+/*
-+ * This does not append a newline
-+ */
-+static inline void putc(int c)
-+{
-+	while (__raw_readl(BCM2708_UART_FR) & UART01x_FR_TXFF)
-+		barrier();
-+
-+	__raw_writel(c, BCM2708_UART_DR);
-+}
-+
-+static inline void flush(void)
-+{
-+	int fr;
-+
-+	do {
-+		fr = __raw_readl(BCM2708_UART_FR);
-+		barrier();
-+	} while ((fr & (UART011_FR_TXFE | UART01x_FR_BUSY)) != UART011_FR_TXFE);
-+}
-+
-+static inline void arch_decomp_setup(void)
-+{
-+	int temp, div, rem, frac;
-+
-+	temp = 16 * UART_BAUD;
-+	div = UART0_CLOCK / temp;
-+	rem = UART0_CLOCK % temp;
-+	temp = (8 * rem) / UART_BAUD;
-+	frac = (temp >> 1) + (temp & 1);
-+
-+	/* Make sure the UART is disabled before we start */
-+	__raw_writel(0, BCM2708_UART_CR);
-+
-+	/* Set the baud rate */
-+	__raw_writel(div, BCM2708_UART_IBRD);
-+	__raw_writel(frac, BCM2708_UART_FBRD);
-+
-+	/* Set the UART to 8n1, FIFO enabled */
-+	__raw_writel(UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN, BCM2708_UART_LCRH);
-+
-+	/* Enable the UART */
-+	__raw_writel(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE,
-+			BCM2708_UART_CR);
-+}
-+
-+/*
-+ * nothing to do
-+ */
-+#define arch_decomp_wdog()
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/vmalloc.h
-@@ -0,0 +1,20 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/vmalloc.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#define VMALLOC_END		(0xe8000000)
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/Kconfig
-@@ -0,0 +1,42 @@
-+menu "Broadcom BCM2709 Implementations"
-+	depends on ARCH_BCM2709
-+
-+config MACH_BCM2709
-+	bool "Broadcom BCM2709 Development Platform"
-+	help
-+	  Include support for the Broadcom(R) BCM2709 platform.
-+
-+config BCM2709_DT
-+	bool "BCM2709 Device Tree support"
-+	depends on MACH_BCM2709
-+	default n
-+	select USE_OF
-+	select ARCH_REQUIRE_GPIOLIB
-+	select PINCTRL
-+	select PINCTRL_BCM2835
-+	help
-+	  Enable Device Tree support for BCM2709
-+
-+config BCM2708_GPIO
-+	bool "BCM2709 gpio support"
-+	depends on MACH_BCM2709
-+	select ARCH_REQUIRE_GPIOLIB
-+        default y
-+	help
-+	  Include support for the Broadcom(R) BCM2709 gpio.
-+
-+config BCM2708_NOL2CACHE
-+	bool "Videocore L2 cache disable"
-+	depends on MACH_BCM2709
-+        default y
-+        help
-+          Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt.
-+
-+config BCM2708_SPIDEV
-+	bool "Bind spidev to SPI0 master"
-+	depends on MACH_BCM2709
-+	depends on SPI
-+	default y
-+	help
-+	  Binds spidev driver to the SPI0 master
-+endmenu
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/Makefile
-@@ -0,0 +1,6 @@
-+#
-+# Makefile for the linux kernel.
-+#
-+
-+obj-$(CONFIG_MACH_BCM2709) 	+= bcm2709.o armctrl.o
-+obj-$(CONFIG_BCM2708_GPIO)	+= bcm2708_gpio.o
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/Makefile.boot
-@@ -0,0 +1,3 @@
-+   zreladdr-y	:= 0x00008000
-+params_phys-y	:= 0x00000100
-+initrd_phys-y	:= 0x00800000
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/armctrl.c
-@@ -0,0 +1,361 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/armctrl.c
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/io.h>
-+#include <linux/version.h>
-+#include <linux/syscore_ops.h>
-+#include <linux/interrupt.h>
-+#include <linux/irqdomain.h>
-+#include <linux/of.h>
-+
-+#include <asm/mach/irq.h>
-+#include <mach/hardware.h>
-+#include "armctrl.h"
-+
-+/* For support of kernels >= 3.0 assume only one VIC for now*/
-+static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = {
-+	INTERRUPT_VC_JPEG,
-+	INTERRUPT_VC_USB,
-+	INTERRUPT_VC_3D,
-+	INTERRUPT_VC_DMA2,
-+	INTERRUPT_VC_DMA3,
-+	INTERRUPT_VC_I2C,
-+	INTERRUPT_VC_SPI,
-+	INTERRUPT_VC_I2SPCM,
-+	INTERRUPT_VC_SDIO,
-+	INTERRUPT_VC_UART,
-+	INTERRUPT_VC_ARASANSDIO
-+};
-+
-+static void armctrl_mask_irq(struct irq_data *d)
-+{
-+	static const unsigned int disables[4] = {
-+		ARM_IRQ_DIBL1,
-+		ARM_IRQ_DIBL2,
-+		ARM_IRQ_DIBL3,
-+		0
-+	};
-+	int i;
-+	if (d->irq >= FIQ_START) {
-+		writel(0, __io_address(ARM_IRQ_FAST));
-+	} else if (d->irq >= IRQ_ARM_LOCAL_CNTPSIRQ && d->irq < IRQ_ARM_LOCAL_CNTPSIRQ + 4) {
-+#if 1
-+		unsigned int data = (unsigned int)irq_get_chip_data(d->irq) - IRQ_ARM_LOCAL_CNTPSIRQ;
-+		for (i=0; i<4; i++) // i = raw_smp_processor_id(); //
-+		{
-+			unsigned int val =   readl(__io_address(ARM_LOCAL_TIMER_INT_CONTROL0 + 4*i));
-+			writel(val &~ (1 << data), __io_address(ARM_LOCAL_TIMER_INT_CONTROL0 + 4*i));
-+		}
-+#endif
-+	} else if (d->irq >= IRQ_ARM_LOCAL_MAILBOX0 && d->irq < IRQ_ARM_LOCAL_MAILBOX0 + 4) {
-+#if 0
-+		unsigned int data = (unsigned int)irq_get_chip_data(d->irq) - IRQ_ARM_LOCAL_MAILBOX0;
-+		for (i=0; i<4; i++) {
-+			unsigned int val = readl(__io_address(ARM_LOCAL_MAILBOX_INT_CONTROL0 + 4*i));
-+			writel(val &~ (1 << data), __io_address(ARM_LOCAL_MAILBOX_INT_CONTROL0 + 4*i));
-+		}
-+#endif
-+	} else if (d->irq >= ARM_IRQ1_BASE && d->irq < ARM_IRQ_LOCAL_BASE) {
-+		unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
-+		writel(1 << (data & 0x1f), __io_address(disables[(data >> 5) & 0x3]));
-+	} else if (d->irq == INTERRUPT_ARM_LOCAL_PMU_FAST) {
-+		writel(0xf, __io_address(ARM_LOCAL_PM_ROUTING_CLR));
-+	} else { printk("%s: %d\n", __func__, d->irq); BUG(); }
-+}
-+
-+static void armctrl_unmask_irq(struct irq_data *d)
-+{
-+	static const unsigned int enables[4] = {
-+		ARM_IRQ_ENBL1,
-+		ARM_IRQ_ENBL2,
-+		ARM_IRQ_ENBL3,
-+		0
-+	};
-+	int i;
-+	if (d->irq >= FIQ_START) {
-+		unsigned int data = (unsigned int)irq_get_chip_data(d->irq) - FIQ_START;
-+		writel(0x80 | data, __io_address(ARM_IRQ_FAST));
-+	} else if (d->irq >= IRQ_ARM_LOCAL_CNTPSIRQ && d->irq < IRQ_ARM_LOCAL_CNTPSIRQ + 4) {
-+#if 1
-+		unsigned int data = (unsigned int)irq_get_chip_data(d->irq) - IRQ_ARM_LOCAL_CNTPSIRQ;
-+		for (i=0; i<4; i++) // i = raw_smp_processor_id();
-+		{
-+			unsigned int val =  readl(__io_address(ARM_LOCAL_TIMER_INT_CONTROL0 + 4*i));
-+			writel(val | (1 << data), __io_address(ARM_LOCAL_TIMER_INT_CONTROL0 + 4*i));
-+		}
-+#endif
-+	} else if (d->irq >= IRQ_ARM_LOCAL_MAILBOX0 && d->irq < IRQ_ARM_LOCAL_MAILBOX0 + 4) {
-+#if 0
-+		unsigned int data = (unsigned int)irq_get_chip_data(d->irq) - IRQ_ARM_LOCAL_MAILBOX0;
-+		for (i=0; i<4; i++) {
-+			unsigned int val = readl(__io_address(ARM_LOCAL_MAILBOX_INT_CONTROL0 + 4*i));
-+			writel(val | (1 << data), __io_address(ARM_LOCAL_MAILBOX_INT_CONTROL0 + 4*i));
-+		}
-+#endif
-+	} else if (d->irq >= ARM_IRQ1_BASE && d->irq < ARM_IRQ_LOCAL_BASE) {
-+		unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
-+		writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3]));
-+	} else if (d->irq == INTERRUPT_ARM_LOCAL_PMU_FAST) {
-+		writel(0xf, __io_address(ARM_LOCAL_PM_ROUTING_SET));
-+	} else { printk("%s: %d\n", __func__, d->irq); BUG(); }
-+}
-+
-+#ifdef CONFIG_OF
-+
-+#define NR_IRQS_BANK0           21
-+#define NR_BANKS                4
-+#define IRQS_PER_BANK           32
-+
-+/* from drivers/irqchip/irq-bcm2835.c */
-+static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr,
-+        const u32 *intspec, unsigned int intsize,
-+        unsigned long *out_hwirq, unsigned int *out_type)
-+{
-+        if (WARN_ON(intsize != 2))
-+                return -EINVAL;
-+
-+        if (WARN_ON(intspec[0] >= NR_BANKS))
-+                return -EINVAL;
-+
-+        if (WARN_ON(intspec[1] >= IRQS_PER_BANK))
-+                return -EINVAL;
-+
-+        if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0))
-+                return -EINVAL;
-+
-+        if (WARN_ON(intspec[0] == 3 && intspec[1] > 3 && intspec[1] != 5 && intspec[1] != 9))
-+                return -EINVAL;
-+
-+	if (intspec[0] == 0)
-+		*out_hwirq = ARM_IRQ0_BASE + intspec[1];
-+	else if (intspec[0] == 1)
-+		*out_hwirq = ARM_IRQ1_BASE + intspec[1];
-+	else if (intspec[0] == 2)
-+		*out_hwirq = ARM_IRQ2_BASE + intspec[1];
-+	else
-+		*out_hwirq = ARM_IRQ_LOCAL_BASE + intspec[1];
-+
-+	/* reverse remap_irqs[] */
-+	switch (*out_hwirq) {
-+	case INTERRUPT_VC_JPEG:
-+		*out_hwirq = INTERRUPT_JPEG;
-+		break;
-+	case INTERRUPT_VC_USB:
-+		*out_hwirq = INTERRUPT_USB;
-+		break;
-+	case INTERRUPT_VC_3D:
-+		*out_hwirq = INTERRUPT_3D;
-+		break;
-+	case INTERRUPT_VC_DMA2:
-+		*out_hwirq = INTERRUPT_DMA2;
-+		break;
-+	case INTERRUPT_VC_DMA3:
-+		*out_hwirq = INTERRUPT_DMA3;
-+		break;
-+	case INTERRUPT_VC_I2C:
-+		*out_hwirq = INTERRUPT_I2C;
-+		break;
-+	case INTERRUPT_VC_SPI:
-+		*out_hwirq = INTERRUPT_SPI;
-+		break;
-+	case INTERRUPT_VC_I2SPCM:
-+		*out_hwirq = INTERRUPT_I2SPCM;
-+		break;
-+	case INTERRUPT_VC_SDIO:
-+		*out_hwirq = INTERRUPT_SDIO;
-+		break;
-+	case INTERRUPT_VC_UART:
-+		*out_hwirq = INTERRUPT_UART;
-+		break;
-+	case INTERRUPT_VC_ARASANSDIO:
-+		*out_hwirq = INTERRUPT_ARASANSDIO;
-+		break;
-+	}
-+
-+        *out_type = IRQ_TYPE_NONE;
-+        return 0;
-+}
-+
-+static struct irq_domain_ops armctrl_ops = {
-+        .xlate = armctrl_xlate
-+};
-+
-+void __init armctrl_dt_init(void)
-+{
-+	struct device_node *np;
-+	struct irq_domain *domain;
-+
-+	np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic");
-+	if (!np)
-+		return;
-+
-+	domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS,
-+					IRQ_ARMCTRL_START, 0,
-+					&armctrl_ops, NULL);
-+        WARN_ON(!domain);
-+}
-+#else
-+void __init armctrl_dt_init(void) { }
-+#endif /* CONFIG_OF */
-+
-+#if defined(CONFIG_PM)
-+
-+/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */
-+
-+/* Static defines
-+ * struct armctrl_device - VIC PM device (< 3.xx)
-+ * @sysdev: The system device which is registered. (< 3.xx)
-+ * @irq: The IRQ number for the base of the VIC.
-+ * @base: The register base for the VIC.
-+ * @resume_sources: A bitmask of interrupts for resume.
-+ * @resume_irqs: The IRQs enabled for resume.
-+ * @int_select: Save for VIC_INT_SELECT.
-+ * @int_enable: Save for VIC_INT_ENABLE.
-+ * @soft_int: Save for VIC_INT_SOFT.
-+ * @protect: Save for VIC_PROTECT.
-+ */
-+struct armctrl_info {
-+	void __iomem *base;
-+	int irq;
-+	u32 resume_sources;
-+	u32 resume_irqs;
-+	u32 int_select;
-+	u32 int_enable;
-+	u32 soft_int;
-+	u32 protect;
-+} armctrl;
-+
-+static int armctrl_suspend(void)
-+{
-+	return 0;
-+}
-+
-+static void armctrl_resume(void)
-+{
-+	return;
-+}
-+
-+/**
-+ * armctrl_pm_register - Register a VIC for later power management control
-+ * @base: The base address of the VIC.
-+ * @irq: The base IRQ for the VIC.
-+ * @resume_sources: bitmask of interrupts allowed for resume sources.
-+ *
-+ * For older kernels (< 3.xx) do -
-+ * Register the VIC with the system device tree so that it can be notified
-+ * of suspend and resume requests and ensure that the correct actions are
-+ * taken to re-instate the settings on resume.
-+ */
-+static void __init armctrl_pm_register(void __iomem * base, unsigned int irq,
-+				       u32 resume_sources)
-+{
-+	armctrl.base = base;
-+	armctrl.resume_sources = resume_sources;
-+	armctrl.irq = irq;
-+}
-+
-+static int armctrl_set_wake(struct irq_data *d, unsigned int on)
-+{
-+	unsigned int off = d->irq & 31;
-+	u32 bit = 1 << off;
-+
-+	if (!(bit & armctrl.resume_sources))
-+		return -EINVAL;
-+
-+	if (on)
-+		armctrl.resume_irqs |= bit;
-+	else
-+		armctrl.resume_irqs &= ~bit;
-+
-+	return 0;
-+}
-+
-+#else
-+static inline void armctrl_pm_register(void __iomem * base, unsigned int irq,
-+				       u32 arg1)
-+{
-+}
-+
-+#define armctrl_suspend NULL
-+#define armctrl_resume NULL
-+#define armctrl_set_wake NULL
-+#endif /* CONFIG_PM */
-+
-+static struct syscore_ops armctrl_syscore_ops = {
-+	.suspend = armctrl_suspend,
-+	.resume = armctrl_resume,
-+};
-+
-+/**
-+ * armctrl_syscore_init - initicall to register VIC pm functions
-+ *
-+ * This is called via late_initcall() to register
-+ * the resources for the VICs due to the early
-+ * nature of the VIC's registration.
-+*/
-+static int __init armctrl_syscore_init(void)
-+{
-+	register_syscore_ops(&armctrl_syscore_ops);
-+	return 0;
-+}
-+
-+late_initcall(armctrl_syscore_init);
-+
-+static struct irq_chip armctrl_chip = {
-+	.name = "ARMCTRL",
-+	.irq_ack = NULL,
-+	.irq_mask = armctrl_mask_irq,
-+	.irq_unmask = armctrl_unmask_irq,
-+	.irq_set_wake = armctrl_set_wake,
-+};
-+
-+/**
-+ * armctrl_init - initialise a vectored interrupt controller
-+ * @base: iomem base address
-+ * @irq_start: starting interrupt number, must be muliple of 32
-+ * @armctrl_sources: bitmask of interrupt sources to allow
-+ * @resume_sources: bitmask of interrupt sources to allow for resume
-+ */
-+int __init armctrl_init(void __iomem * base, unsigned int irq_start,
-+			u32 armctrl_sources, u32 resume_sources)
-+{
-+	unsigned int irq;
-+
-+	for (irq = 0; irq < BCM2708_ALLOC_IRQS; irq++) {
-+		unsigned int data = irq;
-+		if (irq >= INTERRUPT_JPEG && irq <= INTERRUPT_ARASANSDIO)
-+			data = remap_irqs[irq - INTERRUPT_JPEG];
-+		if (irq >= IRQ_ARM_LOCAL_CNTPSIRQ && irq <= IRQ_ARM_LOCAL_TIMER) {
-+			irq_set_percpu_devid(irq);
-+			irq_set_chip_and_handler(irq, &armctrl_chip, handle_percpu_devid_irq);
-+			set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
-+                } else {
-+			irq_set_chip_and_handler(irq, &armctrl_chip, handle_level_irq);
-+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-+                }
-+		irq_set_chip_data(irq, (void *)data);
-+	}
-+
-+	armctrl_pm_register(base, irq_start, resume_sources);
-+	init_FIQ(FIQ_START);
-+	armctrl_dt_init();
-+	return 0;
-+}
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/armctrl.h
-@@ -0,0 +1,27 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/armctrl.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef __BCM2708_ARMCTRL_H
-+#define __BCM2708_ARMCTRL_H
-+
-+extern int __init armctrl_init(void __iomem * base, unsigned int irq_start,
-+			       u32 armctrl_sources, u32 resume_sources);
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/bcm2708_gpio.c
-@@ -0,0 +1,426 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/bcm2708_gpio.c
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+#include <linux/spinlock.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/list.h>
-+#include <linux/io.h>
-+#include <linux/irq.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <mach/gpio.h>
-+#include <linux/gpio.h>
-+#include <linux/platform_device.h>
-+#include <mach/platform.h>
-+#include <linux/pinctrl/consumer.h>
-+
-+#include <linux/platform_data/bcm2708.h>
-+
-+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio"
-+#define DRIVER_NAME BCM_GPIO_DRIVER_NAME
-+#define BCM_GPIO_USE_IRQ 1
-+
-+#define GPIOFSEL(x)  (0x00+(x)*4)
-+#define GPIOSET(x)   (0x1c+(x)*4)
-+#define GPIOCLR(x)   (0x28+(x)*4)
-+#define GPIOLEV(x)   (0x34+(x)*4)
-+#define GPIOEDS(x)   (0x40+(x)*4)
-+#define GPIOREN(x)   (0x4c+(x)*4)
-+#define GPIOFEN(x)   (0x58+(x)*4)
-+#define GPIOHEN(x)   (0x64+(x)*4)
-+#define GPIOLEN(x)   (0x70+(x)*4)
-+#define GPIOAREN(x)  (0x7c+(x)*4)
-+#define GPIOAFEN(x)  (0x88+(x)*4)
-+#define GPIOUD(x)    (0x94+(x)*4)
-+#define GPIOUDCLK(x) (0x98+(x)*4)
-+
-+#define GPIO_BANKS 2
-+
-+enum { GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT,
-+	GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4,
-+	GPIO_FSEL_ALT0, GPIO_FSEL_ALT1,
-+	GPIO_FSEL_ALT2, GPIO_FSEL_ALT3,
-+};
-+
-+	/* Each of the two spinlocks protects a different set of hardware
-+	 * regiters and data structurs. This decouples the code of the IRQ from
-+	 * the GPIO code. This also makes the case of a GPIO routine call from
-+	 * the IRQ code simpler.
-+	 */
-+static DEFINE_SPINLOCK(lock);	/* GPIO registers */
-+
-+struct bcm2708_gpio {
-+	struct list_head list;
-+	void __iomem *base;
-+	struct gpio_chip gc;
-+	unsigned long rising[(BCM2708_NR_GPIOS + 31) / 32];
-+	unsigned long falling[(BCM2708_NR_GPIOS + 31) / 32];
-+	unsigned long high[(BCM2708_NR_GPIOS + 31) / 32];
-+	unsigned long low[(BCM2708_NR_GPIOS + 31) / 32];
-+};
-+
-+static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset,
-+				int function)
-+{
-+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
-+	unsigned long flags;
-+	unsigned gpiodir;
-+	unsigned gpio_bank = offset / 10;
-+	unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3;
-+
-+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set_function %p (%d,%d)\n", gc, offset, function);
-+	if (offset >= BCM2708_NR_GPIOS)
-+		return -EINVAL;
-+
-+	spin_lock_irqsave(&lock, flags);
-+
-+	gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank));
-+	gpiodir &= ~(7 << gpio_field_offset);
-+	gpiodir |= function << gpio_field_offset;
-+	writel(gpiodir, gpio->base + GPIOFSEL(gpio_bank));
-+	spin_unlock_irqrestore(&lock, flags);
-+	gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank));
-+
-+	return 0;
-+}
-+
-+static int bcm2708_gpio_dir_in(struct gpio_chip *gc, unsigned offset)
-+{
-+	return bcm2708_set_function(gc, offset, GPIO_FSEL_INPUT);
-+}
-+
-+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value);
-+static int bcm2708_gpio_dir_out(struct gpio_chip *gc, unsigned offset,
-+				int value)
-+{
-+	int ret;
-+	ret = bcm2708_set_function(gc, offset, GPIO_FSEL_OUTPUT);
-+	if (ret >= 0)
-+		bcm2708_gpio_set(gc, offset, value);
-+	return ret;
-+}
-+
-+static int bcm2708_gpio_get(struct gpio_chip *gc, unsigned offset)
-+{
-+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
-+	unsigned gpio_bank = offset / 32;
-+	unsigned gpio_field_offset = (offset - 32 * gpio_bank);
-+	unsigned lev;
-+
-+	if (offset >= BCM2708_NR_GPIOS)
-+		return 0;
-+	lev = readl(gpio->base + GPIOLEV(gpio_bank));
-+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_get %p (%d)=%d\n", gc, offset, 0x1 & (lev>>gpio_field_offset));
-+	return 0x1 & (lev >> gpio_field_offset);
-+}
-+
-+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
-+{
-+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
-+	unsigned gpio_bank = offset / 32;
-+	unsigned gpio_field_offset = (offset - 32 * gpio_bank);
-+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set %p (%d=%d)\n", gc, offset, value);
-+	if (offset >= BCM2708_NR_GPIOS)
-+		return;
-+	if (value)
-+		writel(1 << gpio_field_offset, gpio->base + GPIOSET(gpio_bank));
-+	else
-+		writel(1 << gpio_field_offset, gpio->base + GPIOCLR(gpio_bank));
-+}
-+
-+/**********************
-+ * extension to configure pullups
-+ */
-+int bcm2708_gpio_setpull(struct gpio_chip *gc, unsigned offset,
-+		bcm2708_gpio_pull_t value)
-+{
-+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
-+	unsigned gpio_bank = offset / 32;
-+	unsigned gpio_field_offset = (offset - 32 * gpio_bank);
-+
-+	if (offset >= BCM2708_NR_GPIOS)
-+		return -EINVAL;
-+
-+	switch (value) {
-+	case BCM2708_PULL_UP:
-+		writel(2, gpio->base + GPIOUD(0));
-+		break;
-+	case BCM2708_PULL_DOWN:
-+		writel(1, gpio->base + GPIOUD(0));
-+		break;
-+	case BCM2708_PULL_OFF:
-+		writel(0, gpio->base + GPIOUD(0));
-+		break;
-+	}
-+
-+	udelay(5);
-+	writel(1 << gpio_field_offset, gpio->base + GPIOUDCLK(gpio_bank));
-+	udelay(5);
-+	writel(0, gpio->base + GPIOUD(0));
-+	writel(0 << gpio_field_offset, gpio->base + GPIOUDCLK(gpio_bank));
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL(bcm2708_gpio_setpull);
-+
-+/*************************************************************************************************************************
-+ * bcm2708 GPIO IRQ
-+ */
-+
-+#if BCM_GPIO_USE_IRQ
-+
-+static int bcm2708_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
-+{
-+	return gpio_to_irq(gpio);
-+}
-+
-+static int bcm2708_gpio_irq_set_type(struct irq_data *d, unsigned type)
-+{
-+	unsigned irq = d->irq;
-+	struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
-+	unsigned gn = irq_to_gpio(irq);
-+	unsigned gb = gn / 32;
-+	unsigned go = gn % 32;
-+
-+	gpio->rising[gb]  &= ~(1 << go);
-+	gpio->falling[gb] &= ~(1 << go);
-+	gpio->high[gb]    &= ~(1 << go);
-+	gpio->low[gb]     &= ~(1 << go);
-+
-+	if (type & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
-+		return -EINVAL;
-+
-+	if (type & IRQ_TYPE_EDGE_RISING)
-+		gpio->rising[gb] |= (1 << go);
-+	if (type & IRQ_TYPE_EDGE_FALLING)
-+		gpio->falling[gb] |= (1 << go);
-+	if (type & IRQ_TYPE_LEVEL_HIGH)
-+		gpio->high[gb] |= (1 << go);
-+	if (type & IRQ_TYPE_LEVEL_LOW)
-+		gpio->low[gb] |= (1 << go);
-+	return 0;
-+}
-+
-+static void bcm2708_gpio_irq_mask(struct irq_data *d)
-+{
-+	unsigned irq = d->irq;
-+	struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
-+	unsigned gn = irq_to_gpio(irq);
-+	unsigned gb = gn / 32;
-+	unsigned long rising  = readl(gpio->base + GPIOREN(gb));
-+	unsigned long falling = readl(gpio->base + GPIOFEN(gb));
-+	unsigned long high    = readl(gpio->base + GPIOHEN(gb));
-+	unsigned long low     = readl(gpio->base + GPIOLEN(gb));
-+
-+	gn = gn % 32;
-+
-+	writel(rising  & ~(1 << gn), gpio->base + GPIOREN(gb));
-+	writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb));
-+	writel(high    & ~(1 << gn), gpio->base + GPIOHEN(gb));
-+	writel(low     & ~(1 << gn), gpio->base + GPIOLEN(gb));
-+}
-+
-+static void bcm2708_gpio_irq_unmask(struct irq_data *d)
-+{
-+	unsigned irq = d->irq;
-+	struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
-+	unsigned gn = irq_to_gpio(irq);
-+	unsigned gb = gn / 32;
-+	unsigned go = gn % 32;
-+	unsigned long rising  = readl(gpio->base + GPIOREN(gb));
-+	unsigned long falling = readl(gpio->base + GPIOFEN(gb));
-+	unsigned long high    = readl(gpio->base + GPIOHEN(gb));
-+	unsigned long low     = readl(gpio->base + GPIOLEN(gb));
-+
-+	if (gpio->rising[gb] & (1 << go)) {
-+		writel(rising |  (1 << go), gpio->base + GPIOREN(gb));
-+	} else {
-+		writel(rising & ~(1 << go), gpio->base + GPIOREN(gb));
-+	}
-+
-+	if (gpio->falling[gb] & (1 << go)) {
-+		writel(falling |  (1 << go), gpio->base + GPIOFEN(gb));
-+	} else {
-+		writel(falling & ~(1 << go), gpio->base + GPIOFEN(gb));
-+	}
-+
-+	if (gpio->high[gb] & (1 << go)) {
-+		writel(high |  (1 << go), gpio->base + GPIOHEN(gb));
-+	} else {
-+		writel(high & ~(1 << go), gpio->base + GPIOHEN(gb));
-+	}
-+
-+	if (gpio->low[gb] & (1 << go)) {
-+		writel(low |  (1 << go), gpio->base + GPIOLEN(gb));
-+	} else {
-+		writel(low & ~(1 << go), gpio->base + GPIOLEN(gb));
-+	}
-+}
-+
-+static struct irq_chip bcm2708_irqchip = {
-+	.name = "GPIO",
-+	.irq_enable = bcm2708_gpio_irq_unmask,
-+	.irq_disable = bcm2708_gpio_irq_mask,
-+	.irq_unmask = bcm2708_gpio_irq_unmask,
-+	.irq_mask = bcm2708_gpio_irq_mask,
-+	.irq_set_type = bcm2708_gpio_irq_set_type,
-+};
-+
-+static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id)
-+{
-+	unsigned long edsr;
-+	unsigned bank;
-+	int i;
-+	unsigned gpio;
-+	unsigned level_bits;
-+	struct bcm2708_gpio *gpio_data = dev_id;
-+
-+	for (bank = 0; bank < GPIO_BANKS; bank++) {
-+		edsr = readl(__io_address(GPIO_BASE) + GPIOEDS(bank));
-+		level_bits = gpio_data->high[bank] | gpio_data->low[bank];
-+
-+		for_each_set_bit(i, &edsr, 32) {
-+			gpio = i + bank * 32;
-+			/* ack edge triggered IRQs immediately */
-+			if (!(level_bits & (1<<i)))
-+				writel(1<<i,
-+				       __io_address(GPIO_BASE) + GPIOEDS(bank));
-+			generic_handle_irq(gpio_to_irq(gpio));
-+			/* ack level triggered IRQ after handling them */
-+			if (level_bits & (1<<i))
-+				writel(1<<i,
-+				       __io_address(GPIO_BASE) + GPIOEDS(bank));
-+		}
-+	}
-+	return IRQ_HANDLED;
-+}
-+
-+static struct irqaction bcm2708_gpio_irq = {
-+	.name = "BCM2708 GPIO catchall handler",
-+	.flags = IRQF_TIMER | IRQF_IRQPOLL,
-+	.handler = bcm2708_gpio_interrupt,
-+};
-+
-+static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb)
-+{
-+	unsigned irq;
-+
-+	ucb->gc.to_irq = bcm2708_gpio_to_irq;
-+
-+	for (irq = GPIO_IRQ_START; irq < (GPIO_IRQ_START + GPIO_IRQS); irq++) {
-+		irq_set_chip_data(irq, ucb);
-+		irq_set_chip_and_handler(irq, &bcm2708_irqchip,
-+					 handle_simple_irq);
-+		set_irq_flags(irq, IRQF_VALID);
-+	}
-+
-+	bcm2708_gpio_irq.dev_id = ucb;
-+	setup_irq(IRQ_GPIO3, &bcm2708_gpio_irq);
-+}
-+
-+#else
-+
-+static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb)
-+{
-+}
-+
-+#endif /* #if BCM_GPIO_USE_IRQ ***************************************************************************************************************** */
-+
-+static int bcm2708_gpio_probe(struct platform_device *dev)
-+{
-+	struct bcm2708_gpio *ucb;
-+	struct resource *res;
-+	int bank;
-+	int err = 0;
-+
-+	printk(KERN_INFO DRIVER_NAME ": bcm2708_gpio_probe %p\n", dev);
-+
-+	ucb = kzalloc(sizeof(*ucb), GFP_KERNEL);
-+	if (NULL == ucb) {
-+		printk(KERN_ERR DRIVER_NAME ": failed to allocate "
-+		       "mailbox memory\n");
-+		err = -ENOMEM;
-+		goto err;
-+	}
-+
-+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-+
-+	platform_set_drvdata(dev, ucb);
-+	ucb->base = __io_address(GPIO_BASE);
-+
-+	ucb->gc.label = "bcm2708_gpio";
-+	ucb->gc.base = 0;
-+	ucb->gc.ngpio = BCM2708_NR_GPIOS;
-+	ucb->gc.owner = THIS_MODULE;
-+
-+	ucb->gc.direction_input = bcm2708_gpio_dir_in;
-+	ucb->gc.direction_output = bcm2708_gpio_dir_out;
-+	ucb->gc.get = bcm2708_gpio_get;
-+	ucb->gc.set = bcm2708_gpio_set;
-+	ucb->gc.can_sleep = 0;
-+
-+	for (bank = 0; bank < GPIO_BANKS; bank++) {
-+		writel(0, ucb->base + GPIOREN(bank));
-+		writel(0, ucb->base + GPIOFEN(bank));
-+		writel(0, ucb->base + GPIOHEN(bank));
-+		writel(0, ucb->base + GPIOLEN(bank));
-+		writel(0, ucb->base + GPIOAREN(bank));
-+		writel(0, ucb->base + GPIOAFEN(bank));
-+		writel(~0, ucb->base + GPIOEDS(bank));
-+	}
-+
-+	bcm2708_gpio_irq_init(ucb);
-+
-+	err = gpiochip_add(&ucb->gc);
-+
-+err:
-+	return err;
-+
-+}
-+
-+static int bcm2708_gpio_remove(struct platform_device *dev)
-+{
-+	int err = 0;
-+	struct bcm2708_gpio *ucb = platform_get_drvdata(dev);
-+
-+	printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_remove %p\n", dev);
-+
-+	gpiochip_remove(&ucb->gc);
-+
-+	platform_set_drvdata(dev, NULL);
-+	kfree(ucb);
-+
-+	return err;
-+}
-+
-+static struct platform_driver bcm2708_gpio_driver = {
-+	.probe = bcm2708_gpio_probe,
-+	.remove = bcm2708_gpio_remove,
-+	.driver = {
-+		   .name = "bcm2708_gpio"},
-+};
-+
-+static int __init bcm2708_gpio_init(void)
-+{
-+	return platform_driver_register(&bcm2708_gpio_driver);
-+}
-+
-+static void __exit bcm2708_gpio_exit(void)
-+{
-+	platform_driver_unregister(&bcm2708_gpio_driver);
-+}
-+
-+module_init(bcm2708_gpio_init);
-+module_exit(bcm2708_gpio_exit);
-+
-+MODULE_DESCRIPTION("Broadcom BCM2708 GPIO driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/bcm2709.c
-@@ -0,0 +1,801 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2709/bcm2709.c
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/serial_8250.h>
-+#include <linux/platform_device.h>
-+#include <linux/syscore_ops.h>
-+#include <linux/interrupt.h>
-+#include <linux/amba/bus.h>
-+#include <linux/amba/clcd.h>
-+#include <linux/clk-provider.h>
-+#include <linux/clkdev.h>
-+#include <linux/clockchips.h>
-+#include <linux/cnt32_to_63.h>
-+#include <linux/io.h>
-+#include <linux/module.h>
-+#include <linux/of_platform.h>
-+#include <linux/gpio/machine.h>
-+
-+#include <linux/version.h>
-+#include <linux/clkdev.h>
-+#include <asm/system_info.h>
-+#include <mach/hardware.h>
-+#include <asm/irq.h>
-+#include <linux/leds.h>
-+#include <asm/mach-types.h>
-+#include <asm/cputype.h>
-+#include <linux/sched_clock.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/flash.h>
-+#include <asm/mach/irq.h>
-+#include <asm/mach/time.h>
-+#include <asm/mach/map.h>
-+
-+#include <mach/timex.h>
-+#include <mach/system.h>
-+
-+#include <linux/delay.h>
-+
-+#include "bcm2709.h"
-+#include "armctrl.h"
-+
-+#ifdef CONFIG_BCM_VC_CMA
-+#include <linux/broadcom/vc_cma.h>
-+#endif
-+
-+//#define SYSTEM_TIMER
-+
-+/* Effectively we have an IOMMU (ARM<->VideoCore map) that is set up to
-+ * give us IO access only to 64Mbytes of physical memory (26 bits).  We could
-+ * represent this window by setting our dmamasks to 26 bits but, in fact
-+ * we're not going to use addresses outside this range (they're not in real
-+ * memory) so we don't bother.
-+ *
-+ * In the future we might include code to use this IOMMU to remap other
-+ * physical addresses onto VideoCore memory then the use of 32-bits would be
-+ * more legitimate.
-+ */
-+#define DMA_MASK_BITS_COMMON 32
-+
-+/* command line parameters */
-+static unsigned boardrev, serial;
-+static unsigned uart_clock = UART0_CLOCK;
-+static unsigned disk_led_gpio = 16;
-+static unsigned disk_led_active_low = 1;
-+static unsigned reboot_part = 0;
-+
-+static unsigned use_dt = 0;
-+
-+static void __init bcm2709_init_led(void);
-+
-+void __init bcm2709_init_irq(void)
-+{
-+	armctrl_init(__io_address(ARMCTRL_IC_BASE), 0, 0, 0);
-+}
-+
-+static struct map_desc bcm2709_io_desc[] __initdata = {
-+	{
-+	 .virtual = IO_ADDRESS(ARMCTRL_BASE),
-+	 .pfn = __phys_to_pfn(ARMCTRL_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(UART0_BASE),
-+	 .pfn = __phys_to_pfn(UART0_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(UART1_BASE),
-+	 .pfn = __phys_to_pfn(UART1_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(DMA_BASE),
-+	 .pfn = __phys_to_pfn(DMA_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(MCORE_BASE),
-+	 .pfn = __phys_to_pfn(MCORE_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(ST_BASE),
-+	 .pfn = __phys_to_pfn(ST_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(USB_BASE),
-+	 .pfn = __phys_to_pfn(USB_BASE),
-+	 .length = SZ_128K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(PM_BASE),
-+	 .pfn = __phys_to_pfn(PM_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(GPIO_BASE),
-+	 .pfn = __phys_to_pfn(GPIO_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+	{
-+	 .virtual = IO_ADDRESS(ARM_LOCAL_BASE),
-+	 .pfn = __phys_to_pfn(ARM_LOCAL_BASE),
-+	 .length = SZ_4K,
-+	 .type = MT_DEVICE},
-+};
-+
-+void __init bcm2709_map_io(void)
-+{
-+	iotable_init(bcm2709_io_desc, ARRAY_SIZE(bcm2709_io_desc));
-+}
-+
-+#ifdef SYSTEM_TIMER
-+
-+/* The STC is a free running counter that increments at the rate of 1MHz */
-+#define STC_FREQ_HZ 1000000
-+
-+static inline uint32_t timer_read(void)
-+{
-+	/* STC: a free running counter that increments at the rate of 1MHz */
-+	return readl(__io_address(ST_BASE + 0x04));
-+}
-+
-+static unsigned long bcm2709_read_current_timer(void)
-+{
-+	return timer_read();
-+}
-+
-+static u64 notrace bcm2709_read_sched_clock(void)
-+{
-+	return timer_read();
-+}
-+
-+static cycle_t clksrc_read(struct clocksource *cs)
-+{
-+	return timer_read();
-+}
-+
-+static struct clocksource clocksource_stc = {
-+	.name = "stc",
-+	.rating = 300,
-+	.read = clksrc_read,
-+	.mask = CLOCKSOURCE_MASK(32),
-+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
-+};
-+
-+unsigned long frc_clock_ticks32(void)
-+{
-+	return timer_read();
-+}
-+
-+static void __init bcm2709_clocksource_init(void)
-+{
-+	if (clocksource_register_hz(&clocksource_stc, STC_FREQ_HZ)) {
-+		printk(KERN_ERR "timer: failed to initialize clock "
-+		       "source %s\n", clocksource_stc.name);
-+	}
-+}
-+#endif
-+
-+struct clk __init *bcm2709_clk_register(const char *name, unsigned long fixed_rate)
-+{
-+	struct clk *clk;
-+
-+	clk = clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT,
-+						fixed_rate);
-+	if (IS_ERR(clk))
-+		pr_err("%s not registered\n", name);
-+
-+	return clk;
-+}
-+
-+void __init bcm2709_register_clkdev(struct clk *clk, const char *name)
-+{
-+	int ret;
-+
-+	ret = clk_register_clkdev(clk, NULL, name);
-+	if (ret)
-+		pr_err("%s alias not registered\n", name);
-+}
-+
-+void __init bcm2709_init_clocks(void)
-+{
-+	struct clk *clk;
-+
-+	clk = bcm2709_clk_register("uart0_clk", uart_clock);
-+	bcm2709_register_clkdev(clk, "dev:f1");
-+
-+	clk = bcm2709_clk_register("sdhost_clk", 250000000);
-+	bcm2709_register_clkdev(clk, "mmc-bcm2835.0");
-+	bcm2709_register_clkdev(clk, "bcm2708_spi.0");
-+	bcm2709_register_clkdev(clk, "bcm2708_i2c.0");
-+	bcm2709_register_clkdev(clk, "bcm2708_i2c.1");
-+}
-+
-+#define UART0_IRQ	{ IRQ_UART, 0 /*NO_IRQ*/ }
-+#define UART0_DMA	{ 15, 14 }
-+
-+AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
-+
-+static struct amba_device *amba_devs[] __initdata = {
-+	&uart0_device,
-+};
-+
-+static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
-+
-+static struct platform_device bcm2708_fb_device = {
-+	.name = "bcm2708_fb",
-+	.id = -1,		/* only one bcm2708_fb */
-+	.resource = NULL,
-+	.num_resources = 0,
-+	.dev = {
-+		.dma_mask = &fb_dmamask,
-+		.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
-+		},
-+};
-+
-+static struct resource bcm2708_usb_resources[] = {
-+	[0] = {
-+	       .start = USB_BASE,
-+	       .end = USB_BASE + SZ_128K - 1,
-+	       .flags = IORESOURCE_MEM,
-+	       },
-+	[1] = {
-+		.start = MPHI_BASE,
-+		.end = MPHI_BASE + SZ_4K - 1,
-+		.flags = IORESOURCE_MEM,
-+	      },
-+	[2] = {
-+	       .start = IRQ_HOSTPORT,
-+	       .end = IRQ_HOSTPORT,
-+	       .flags = IORESOURCE_IRQ,
-+	       },
-+	[3] = {
-+		.start = IRQ_USB,
-+		.end = IRQ_USB,
-+		.flags = IORESOURCE_IRQ,
-+		},
-+	[4] = {
-+		.start = ARM_LOCAL_BASE,
-+		.end = ARM_LOCAL_BASE + SZ_4K - 1,
-+		.flags = IORESOURCE_MEM,
-+		},
-+	[5] = {
-+		.start = IRQ_ARM_LOCAL_MAILBOX1,
-+		.end = IRQ_ARM_LOCAL_MAILBOX1,
-+		.flags = IORESOURCE_IRQ
-+	},
-+};
-+
-+
-+static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
-+
-+static struct platform_device bcm2708_usb_device = {
-+	.name = "bcm2708_usb",
-+	.id = -1,		/* only one bcm2708_usb */
-+	.resource = bcm2708_usb_resources,
-+	.num_resources = ARRAY_SIZE(bcm2708_usb_resources),
-+	.dev = {
-+		.dma_mask = &usb_dmamask,
-+		.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
-+		},
-+};
-+
-+static struct resource bcm2708_vcio_resources[] = {
-+	{
-+		.start = ARMCTRL_0_MAIL0_BASE,
-+		.end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1,
-+		.flags = IORESOURCE_MEM,
-+	}, {
-+		.start = IRQ_ARM_MAILBOX,
-+		.end = IRQ_ARM_MAILBOX,
-+		.flags = IORESOURCE_IRQ,
-+	},
-+};
-+
-+static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
-+
-+static struct platform_device bcm2708_vcio_device = {
-+	.name = "bcm2708_vcio",
-+	.id = -1,		/* only one VideoCore I/O area */
-+	.resource = bcm2708_vcio_resources,
-+	.num_resources = ARRAY_SIZE(bcm2708_vcio_resources),
-+	.dev = {
-+		.dma_mask = &vcio_dmamask,
-+		.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
-+		},
-+};
-+
-+int __init bcm_register_device(struct platform_device *pdev)
-+{
-+	int ret;
-+
-+	ret = platform_device_register(pdev);
-+	if (ret)
-+		pr_debug("Unable to register platform device '%s': %d\n",
-+			 pdev->name, ret);
-+
-+	return ret;
-+}
-+
-+/*
-+ * Use these macros for platform and i2c devices that are present in the
-+ * Device Tree. This way the devices are only added on non-DT systems.
-+ */
-+#define bcm_register_device_dt(pdev) \
-+    if (!use_dt) bcm_register_device(pdev)
-+
-+#define i2c_register_board_info_dt(busnum, info, n) \
-+    if (!use_dt) i2c_register_board_info(busnum, info, n)
-+
-+int calc_rsts(int partition)
-+{
-+	return PM_PASSWORD |
-+		((partition & (1 << 0))  << 0) |
-+		((partition & (1 << 1))  << 1) |
-+		((partition & (1 << 2))  << 2) |
-+		((partition & (1 << 3))  << 3) |
-+		((partition & (1 << 4))  << 4) |
-+		((partition & (1 << 5))  << 5);
-+}
-+
-+static void bcm2709_restart(enum reboot_mode mode, const char *cmd)
-+{
-+	extern char bcm2708_reboot_mode;
-+	uint32_t pm_rstc, pm_wdog;
-+	uint32_t timeout = 10;
-+	uint32_t pm_rsts = 0;
-+
-+	if(bcm2708_reboot_mode == 'q')
-+	{
-+		// NOOBS < 1.3 booting with reboot=q
-+		pm_rsts = readl(__io_address(PM_RSTS));
-+		pm_rsts = PM_PASSWORD | pm_rsts | PM_RSTS_HADWRQ_SET;
-+	}
-+	else if(bcm2708_reboot_mode == 'p')
-+	{
-+		// NOOBS < 1.3 halting
-+		pm_rsts = readl(__io_address(PM_RSTS));
-+		pm_rsts = PM_PASSWORD | pm_rsts | PM_RSTS_HADWRH_SET;
-+	}
-+	else
-+	{
-+		pm_rsts = calc_rsts(reboot_part);
-+	}
-+
-+	writel(pm_rsts, __io_address(PM_RSTS));
-+
-+	/* Setup watchdog for reset */
-+	pm_rstc = readl(__io_address(PM_RSTC));
-+
-+	pm_wdog = PM_PASSWORD | (timeout & PM_WDOG_TIME_SET); // watchdog timer = timer clock / 16; need password (31:16) + value (11:0)
-+	pm_rstc = PM_PASSWORD | (pm_rstc & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET;
-+
-+	writel(pm_wdog, __io_address(PM_WDOG));
-+	writel(pm_rstc, __io_address(PM_RSTC));
-+}
-+
-+/* We can't really power off, but if we do the normal reset scheme, and indicate to bootcode.bin not to reboot, then most of the chip will be powered off */
-+static void bcm2709_power_off(void)
-+{
-+	extern char bcm2708_reboot_mode;
-+	if(bcm2708_reboot_mode == 'q')
-+	{
-+		// NOOBS < v1.3
-+		bcm2709_restart('p', "");
-+	}
-+	else
-+	{
-+		/* partition 63 is special code for HALT the bootloader knows not to boot*/
-+		reboot_part = 63;
-+		/* continue with normal reset mechanism */
-+		bcm2709_restart(0, "");
-+	}
-+}
-+
-+static void __init bcm2709_init_uart1(void)
-+{
-+	struct device_node *np;
-+
-+	np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart");
-+	if (of_device_is_available(np)) {
-+		pr_info("bcm2709: Mini UART enabled\n");
-+		writel(1, __io_address(UART1_BASE + 0x4));
-+	}
-+}
-+
-+#ifdef CONFIG_OF
-+static void __init bcm2709_dt_init(void)
-+{
-+	int ret;
-+
-+	of_clk_init(NULL);
-+	ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-+	if (ret) {
-+		pr_err("of_platform_populate failed: %d\n", ret);
-+		/* Proceed as if CONFIG_OF was not defined */
-+	} else {
-+		use_dt = 1;
-+	}
-+}
-+#else
-+static void __init bcm2709_dt_init(void) { }
-+#endif /* CONFIG_OF */
-+
-+void __init bcm2709_init(void)
-+{
-+	int i;
-+
-+#if defined(CONFIG_BCM_VC_CMA)
-+	vc_cma_early_init();
-+#endif
-+	printk("bcm2709.uart_clock = %d\n", uart_clock);
-+	pm_power_off = bcm2709_power_off;
-+
-+	bcm2709_init_clocks();
-+	bcm2709_dt_init();
-+
-+	bcm_register_device(&bcm2708_vcio_device);
-+#ifdef CONFIG_BCM2708_GPIO
-+	bcm_register_device_dt(&bcm2708_gpio_device);
-+#endif
-+	bcm_register_device_dt(&bcm2708_fb_device);
-+	bcm_register_device_dt(&bcm2708_usb_device);
-+
-+	bcm2708_init_led();
-+	bcm2708_init_uart1();
-+
-+	if (!use_dt) {
-+		for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-+			struct amba_device *d = amba_devs[i];
-+			amba_device_register(d, &iomem_resource);
-+		}
-+	}
-+	system_rev = boardrev;
-+	system_serial_low = serial;
-+}
-+
-+#ifdef SYSTEM_TIMER
-+static void timer_set_mode(enum clock_event_mode mode,
-+			   struct clock_event_device *clk)
-+{
-+	switch (mode) {
-+	case CLOCK_EVT_MODE_ONESHOT: /* Leave the timer disabled, .set_next_event will enable it */
-+	case CLOCK_EVT_MODE_SHUTDOWN:
-+		break;
-+	case CLOCK_EVT_MODE_PERIODIC:
-+
-+	case CLOCK_EVT_MODE_UNUSED:
-+	case CLOCK_EVT_MODE_RESUME:
-+
-+	default:
-+		printk(KERN_ERR "timer_set_mode: unhandled mode:%d\n",
-+		       (int)mode);
-+		break;
-+	}
-+
-+}
-+
-+static int timer_set_next_event(unsigned long cycles,
-+				struct clock_event_device *unused)
-+{
-+	unsigned long stc;
-+	do {
-+		stc = readl(__io_address(ST_BASE + 0x04));
-+		/* We could take a FIQ here, which may push ST above STC3 */
-+		writel(stc + cycles, __io_address(ST_BASE + 0x18));
-+	} while ((signed long) cycles >= 0 &&
-+				(signed long) (readl(__io_address(ST_BASE + 0x04)) - stc)
-+				>= (signed long) cycles);
-+	return 0;
-+}
-+
-+static struct clock_event_device timer0_clockevent = {
-+	.name = "timer0",
-+	.shift = 32,
-+	.features = CLOCK_EVT_FEAT_ONESHOT,
-+	.set_mode = timer_set_mode,
-+	.set_next_event = timer_set_next_event,
-+};
-+
-+/*
-+ * IRQ handler for the timer
-+ */
-+static irqreturn_t bcm2709_timer_interrupt(int irq, void *dev_id)
-+{
-+	struct clock_event_device *evt = &timer0_clockevent;
-+
-+	writel(1 << 3, __io_address(ST_BASE + 0x00));	/* stcs clear timer int */
-+
-+	evt->event_handler(evt);
-+
-+	return IRQ_HANDLED;
-+}
-+
-+static struct irqaction bcm2709_timer_irq = {
-+	.name = "BCM2709 Timer Tick",
-+	.flags = IRQF_TIMER | IRQF_IRQPOLL,
-+	.handler = bcm2709_timer_interrupt,
-+};
-+
-+/*
-+ * Set up timer interrupt, and return the current time in seconds.
-+ */
-+
-+static struct delay_timer bcm2709_delay_timer = {
-+	.read_current_timer = bcm2709_read_current_timer,
-+	.freq = STC_FREQ_HZ,
-+};
-+
-+static void __init bcm2709_timer_init(void)
-+{
-+	/* init high res timer */
-+	bcm2709_clocksource_init();
-+
-+	/*
-+	 * Make irqs happen for the system timer
-+	 */
-+	setup_irq(IRQ_TIMER3, &bcm2709_timer_irq);
-+
-+	sched_clock_register(bcm2709_read_sched_clock, 32, STC_FREQ_HZ);
-+
-+	timer0_clockevent.mult =
-+	    div_sc(STC_FREQ_HZ, NSEC_PER_SEC, timer0_clockevent.shift);
-+	timer0_clockevent.max_delta_ns =
-+	    clockevent_delta2ns(0xffffffff, &timer0_clockevent);
-+	timer0_clockevent.min_delta_ns =
-+	    clockevent_delta2ns(0xf, &timer0_clockevent);
-+
-+	timer0_clockevent.cpumask = cpumask_of(0);
-+	clockevents_register_device(&timer0_clockevent);
-+
-+	register_current_timer_delay(&bcm2709_delay_timer);
-+}
-+
-+#else
-+
-+static void __init bcm2709_timer_init(void)
-+{
-+	extern void dc4_arch_timer_init(void);
-+	// timer control
-+	writel(0, __io_address(ARM_LOCAL_CONTROL));
-+	// timer pre_scaler
-+	writel(0x80000000, __io_address(ARM_LOCAL_PRESCALER)); // 19.2MHz
-+	//writel(0x06AAAAAB, __io_address(ARM_LOCAL_PRESCALER)); // 1MHz
-+
-+	if (use_dt)
-+	{
-+		of_clk_init(NULL);
-+		clocksource_of_init();
-+	}
-+	else
-+		dc4_arch_timer_init();
-+}
-+
-+#endif
-+
-+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-+#include <linux/leds.h>
-+
-+static struct gpio_led bcm2709_leds[] = {
-+	[0] = {
-+	       .gpio = 16,
-+	       .name = "led0",
-+	       .default_trigger = "mmc0",
-+	       .active_low = 1,
-+	       },
-+};
-+
-+static struct gpio_led_platform_data bcm2709_led_pdata = {
-+	.num_leds = ARRAY_SIZE(bcm2709_leds),
-+	.leds = bcm2709_leds,
-+};
-+
-+static struct platform_device bcm2709_led_device = {
-+	.name = "leds-gpio",
-+	.id = -1,
-+	.dev = {
-+		.platform_data = &bcm2709_led_pdata,
-+		},
-+};
-+
-+static void __init bcm2709_init_led(void)
-+{
-+	bcm2709_leds[0].gpio = disk_led_gpio;
-+	bcm2709_leds[0].active_low = disk_led_active_low;
-+	bcm_register_device_dt(&bcm2709_led_device);
-+}
-+#else
-+static inline void bcm2709_init_led(void)
-+{
-+}
-+#endif
-+
-+void __init bcm2709_init_early(void)
-+{
-+	/*
-+	 * Some devices allocate their coherent buffers from atomic
-+	 * context. Increase size of atomic coherent pool to make sure such
-+	 * the allocations won't fail.
-+	 */
-+	init_dma_coherent_pool_size(SZ_4M);
-+}
-+
-+static void __init board_reserve(void)
-+{
-+#if defined(CONFIG_BCM_VC_CMA)
-+	vc_cma_reserve();
-+#endif
-+}
-+
-+
-+#ifdef CONFIG_SMP
-+#include <linux/smp.h>
-+
-+#include <mach/hardware.h>
-+#include <asm/cacheflush.h>
-+#include <asm/smp_plat.h>
-+int dc4=0;
-+//void dc4_log(unsigned x) { if (dc4) writel((x), __io_address(ST_BASE+10 + raw_smp_processor_id()*4)); }
-+void dc4_log_dead(unsigned x) { if (dc4) writel((readl(__io_address(ST_BASE+0x10 + raw_smp_processor_id()*4)) & 0xffff) | ((x)<<16), __io_address(ST_BASE+0x10 + raw_smp_processor_id()*4)); }
-+
-+static void bcm2835_send_doorbell(const struct cpumask *mask, unsigned int irq)
-+{
-+        int cpu;
-+        /*
-+         * Ensure that stores to Normal memory are visible to the
-+         * other CPUs before issuing the IPI.
-+         */
-+        dsb();
-+
-+        /* Convert our logical CPU mask into a physical one. */
-+        for_each_cpu(cpu, mask)
-+	{
-+		/* submit softirq */
-+		writel(1<<irq, __io_address(ARM_LOCAL_MAILBOX0_SET0 + 0x10 * MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 0)));
-+	}
-+}
-+
-+void __init bcm2709_smp_init_cpus(void)
-+{
-+	void secondary_startup(void);
-+	unsigned int i, ncores;
-+
-+	ncores = 4; // xxx scu_get_core_count(NULL);
-+	printk("[%s] enter (%x->%x)\n", __FUNCTION__, (unsigned)virt_to_phys((void *)secondary_startup), (unsigned)__io_address(ST_BASE + 0x10));
-+	printk("[%s] ncores=%d\n", __FUNCTION__, ncores);
-+
-+	for (i = 0; i < ncores; i++) {
-+		set_cpu_possible(i, true);
-+		/* enable IRQ (not FIQ) */
-+		writel(0x1, __io_address(ARM_LOCAL_MAILBOX_INT_CONTROL0 + 0x4 * i));
-+		//writel(0xf, __io_address(ARM_LOCAL_TIMER_INT_CONTROL0   + 0x4 * i));
-+	}
-+	set_smp_cross_call(bcm2835_send_doorbell);
-+}
-+
-+/*
-+ * for arch/arm/kernel/smp.c:smp_prepare_cpus(unsigned int max_cpus)
-+ */
-+void __init bcm2709_smp_prepare_cpus(unsigned int max_cpus)
-+{
-+    //void __iomem *scu_base;
-+
-+    printk("[%s] enter\n", __FUNCTION__);
-+    //scu_base = scu_base_addr();
-+    //scu_enable(scu_base);
-+}
-+
-+/*
-+ * for linux/arch/arm/kernel/smp.c:secondary_start_kernel(void)
-+ */
-+void __cpuinit bcm2709_secondary_init(unsigned int cpu)
-+{
-+    printk("[%s] enter cpu:%d\n", __FUNCTION__, cpu);
-+    //gic_secondary_init(0);
-+}
-+
-+/*
-+ * for linux/arch/arm/kernel/smp.c:__cpu_up(..)
-+ */
-+int __cpuinit bcm2709_boot_secondary(unsigned int cpu, struct task_struct *idle)
-+{
-+    void secondary_startup(void);
-+    void *mbox_set = __io_address(ARM_LOCAL_MAILBOX3_SET0 + 0x10 * MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 0));
-+    void *mbox_clr = __io_address(ARM_LOCAL_MAILBOX3_CLR0 + 0x10 * MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 0));
-+    unsigned secondary_boot = (unsigned)virt_to_phys((void *)secondary_startup);
-+    int timeout=20;
-+    unsigned t = -1;
-+    //printk("[%s] enter cpu:%d (%x->%p) %x\n", __FUNCTION__, cpu, secondary_boot, wake, readl(wake));
-+
-+    dsb();
-+    BUG_ON(readl(mbox_clr) != 0);
-+    writel(secondary_boot, mbox_set);
-+
-+    while (--timeout > 0) {
-+	t = readl(mbox_clr);
-+	if (t == 0) break;
-+	cpu_relax();
-+    }
-+    if (timeout==0)
-+        printk("[%s] cpu:%d failed to start (%x)\n", __FUNCTION__, cpu, t);
-+    else
-+        printk("[%s] cpu:%d started (%x) %d\n", __FUNCTION__, cpu, t, timeout);
-+
-+    return 0;
-+}
-+
-+
-+struct smp_operations  bcm2709_smp_ops __initdata = {
-+	.smp_init_cpus		= bcm2709_smp_init_cpus,
-+	.smp_prepare_cpus	= bcm2709_smp_prepare_cpus,
-+	.smp_secondary_init	= bcm2709_secondary_init,
-+	.smp_boot_secondary	= bcm2709_boot_secondary,
-+};
-+#endif
-+
-+static const char * const bcm2709_compat[] = {
-+	"brcm,bcm2709",
-+	"brcm,bcm2708", /* Could use bcm2708 in a pinch */
-+	NULL
-+};
-+
-+MACHINE_START(BCM2709, "BCM2709")
-+    /* Maintainer: Broadcom Europe Ltd. */
-+#ifdef CONFIG_SMP
-+	.smp		= smp_ops(bcm2709_smp_ops),
-+#endif
-+	.map_io = bcm2709_map_io,
-+	.init_irq = bcm2709_init_irq,
-+	.init_time = bcm2709_timer_init,
-+	.init_machine = bcm2709_init,
-+	.init_early = bcm2709_init_early,
-+	.reserve = board_reserve,
-+	.restart	= bcm2709_restart,
-+	.dt_compat = bcm2709_compat,
-+MACHINE_END
-+
-+MACHINE_START(BCM2708, "BCM2709")
-+    /* Maintainer: Broadcom Europe Ltd. */
-+#ifdef CONFIG_SMP
-+	.smp		= smp_ops(bcm2709_smp_ops),
-+#endif
-+	.map_io = bcm2709_map_io,
-+	.init_irq = bcm2709_init_irq,
-+	.init_time = bcm2709_timer_init,
-+	.init_machine = bcm2709_init,
-+	.init_early = bcm2709_init_early,
-+	.reserve = board_reserve,
-+	.restart	= bcm2709_restart,
-+	.dt_compat = bcm2709_compat,
-+MACHINE_END
-+
-+module_param(boardrev, uint, 0644);
-+module_param(serial, uint, 0644);
-+module_param(uart_clock, uint, 0644);
-+module_param(disk_led_gpio, uint, 0644);
-+module_param(disk_led_active_low, uint, 0644);
-+module_param(reboot_part, uint, 0644);
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/bcm2709.h
-@@ -0,0 +1,49 @@
-+/*
-+ * linux/arch/arm/mach-bcm2708/bcm2708.h
-+ *
-+ * BCM2708 machine support header
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef __BCM2708_BCM2708_H
-+#define __BCM2708_BCM2708_H
-+
-+#include <linux/amba/bus.h>
-+
-+extern void __init bcm2708_init(void);
-+extern void __init bcm2708_init_irq(void);
-+extern void __init bcm2708_map_io(void);
-+extern struct sys_timer bcm2708_timer;
-+extern unsigned int mmc_status(struct device *dev);
-+
-+#define AMBA_DEVICE(name, busid, base, plat)			\
-+static struct amba_device name##_device = {			\
-+	.dev		= {					\
-+		.coherent_dma_mask = ~0,			\
-+		.init_name = busid,				\
-+		.platform_data = plat,				\
-+	},							\
-+	.res		= {					\
-+		.start	= base##_BASE,		\
-+		.end	= (base##_BASE) + SZ_4K - 1,\
-+		.flags	= IORESOURCE_MEM,			\
-+	},							\
-+	.irq		= base##_IRQ,				\
-+}
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/delay.S
-@@ -0,0 +1,21 @@
-+/*
-+ *  linux/arch/arm/lib/delay.S
-+ *
-+ *  Copyright (C) 1995, 1996 Russell King
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/linkage.h>
-+#include <asm/assembler.h>
-+#include <asm/param.h>
-+
-+		.text
-+.align 3	@ 8 byte alignment seems to be needed to avoid fetching stalls
-+@ Delay routine
-+ENTRY(bcm2708_delay)
-+		subs	r0, r0, #1
-+		bhi	bcm2708_delay
-+		mov	pc, lr
-+ENDPROC(bcm2708_delay)
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/arm_control.h
-@@ -0,0 +1,493 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/arm_control.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef __BCM2708_ARM_CONTROL_H
-+#define __BCM2708_ARM_CONTROL_H
-+
-+/*
-+ * Definitions and addresses for the ARM CONTROL logic
-+ * This file is manually generated.
-+ */
-+
-+#define ARM_BASE  0x7E00B000
-+
-+/* Basic configuration */
-+#define ARM_CONTROL0  HW_REGISTER_RW(ARM_BASE+0x000)
-+#define ARM_C0_SIZ128M   0x00000000
-+#define ARM_C0_SIZ256M   0x00000001
-+#define ARM_C0_SIZ512M   0x00000002
-+#define ARM_C0_SIZ1G     0x00000003
-+#define ARM_C0_BRESP0    0x00000000
-+#define ARM_C0_BRESP1    0x00000004
-+#define ARM_C0_BRESP2    0x00000008
-+#define ARM_C0_BOOTHI    0x00000010
-+#define ARM_C0_UNUSED05  0x00000020 /* free */
-+#define ARM_C0_FULLPERI  0x00000040
-+#define ARM_C0_UNUSED78  0x00000180 /* free */
-+#define ARM_C0_JTAGMASK  0x00000E00
-+#define ARM_C0_JTAGOFF   0x00000000
-+#define ARM_C0_JTAGBASH  0x00000800 /* Debug on GPIO off */
-+#define ARM_C0_JTAGGPIO  0x00000C00 /* Debug on GPIO on */
-+#define ARM_C0_APROTMSK  0x0000F000
-+#define ARM_C0_DBG0SYNC  0x00010000 /* VPU0 halt sync */
-+#define ARM_C0_DBG1SYNC  0x00020000 /* VPU1 halt sync */
-+#define ARM_C0_SWDBGREQ  0x00040000 /* HW debug request */
-+#define ARM_C0_PASSHALT  0x00080000 /* ARM halt passed to debugger */
-+#define ARM_C0_PRIO_PER  0x00F00000 /* per priority mask */
-+#define ARM_C0_PRIO_L2   0x0F000000
-+#define ARM_C0_PRIO_UC   0xF0000000
-+
-+#define ARM_C0_APROTPASS  0x0000A000 /* Translate 1:1 */
-+#define ARM_C0_APROTUSER  0x00000000 /* Only user mode */
-+#define ARM_C0_APROTSYST  0x0000F000 /* Only system mode */
-+
-+
-+#define ARM_CONTROL1  HW_REGISTER_RW(ARM_BASE+0x440)
-+#define ARM_C1_TIMER     0x00000001 /* re-route timer IRQ  to VC */
-+#define ARM_C1_MAIL      0x00000002 /* re-route Mail IRQ   to VC */
-+#define ARM_C1_BELL0     0x00000004 /* re-route Doorbell 0 to VC */
-+#define ARM_C1_BELL1     0x00000008 /* re-route Doorbell 1 to VC */
-+#define ARM_C1_PERSON    0x00000100 /* peripherals on */
-+#define ARM_C1_REQSTOP   0x00000200 /* ASYNC bridge request stop */
-+
-+#define ARM_STATUS    HW_REGISTER_RW(ARM_BASE+0x444)
-+#define ARM_S_ACKSTOP    0x80000000 /* Bridge stopped */
-+#define ARM_S_READPEND   0x000003FF /* pending reads counter */
-+#define ARM_S_WRITPEND   0x000FFC00 /* pending writes counter */
-+
-+#define ARM_ERRHALT   HW_REGISTER_RW(ARM_BASE+0x448)
-+#define ARM_EH_PERIBURST  0x00000001 /* Burst write seen on peri bus */
-+#define ARM_EH_ILLADDRS1  0x00000002 /* Address bits 25-27 error */
-+#define ARM_EH_ILLADDRS2  0x00000004 /* Address bits 31-28 error */
-+#define ARM_EH_VPU0HALT   0x00000008 /* VPU0 halted & in debug mode */
-+#define ARM_EH_VPU1HALT   0x00000010 /* VPU1 halted & in debug mode */
-+#define ARM_EH_ARMHALT    0x00000020 /* ARM in halted debug mode */
-+
-+#define ARM_ID_SECURE HW_REGISTER_RW(ARM_BASE+0x00C)
-+#define ARM_ID        HW_REGISTER_RW(ARM_BASE+0x44C)
-+#define ARM_IDVAL        0x364D5241
-+
-+/* Translation memory */
-+#define ARM_TRANSLATE HW_REGISTER_RW(ARM_BASE+0x100)
-+/* 32 locations: 0x100.. 0x17F */
-+/* 32 spare means we CAN go to 64 pages.... */
-+
-+
-+/* Interrupts */
-+#define ARM_IRQ_PEND0 HW_REGISTER_RW(ARM_BASE+0x200)        /* Top IRQ bits */
-+#define ARM_I0_TIMER    0x00000001 /* timer IRQ */
-+#define ARM_I0_MAIL     0x00000002 /* Mail IRQ */
-+#define ARM_I0_BELL0    0x00000004 /* Doorbell 0 */
-+#define ARM_I0_BELL1    0x00000008 /* Doorbell 1 */
-+#define ARM_I0_BANK1    0x00000100 /* Bank1 IRQ */
-+#define ARM_I0_BANK2    0x00000200 /* Bank2 IRQ */
-+
-+#define ARM_IRQ_PEND1 HW_REGISTER_RW(ARM_BASE+0x204) /* All bank1 IRQ bits */
-+/* todo: all I1_interrupt sources */
-+#define ARM_IRQ_PEND2 HW_REGISTER_RW(ARM_BASE+0x208) /* All bank2 IRQ bits */
-+/* todo: all I2_interrupt sources */
-+
-+#define ARM_IRQ_FAST  HW_REGISTER_RW(ARM_BASE+0x20C) /* FIQ control */
-+#define ARM_IF_INDEX    0x0000007F     /* FIQ select */
-+#define ARM_IF_ENABLE   0x00000080     /* FIQ enable */
-+#define ARM_IF_VCMASK   0x0000003F     /* FIQ = (index from VC source) */
-+#define ARM_IF_TIMER    0x00000040     /* FIQ = ARM timer */
-+#define ARM_IF_MAIL     0x00000041     /* FIQ = ARM Mail */
-+#define ARM_IF_BELL0    0x00000042     /* FIQ = ARM Doorbell 0 */
-+#define ARM_IF_BELL1    0x00000043     /* FIQ = ARM Doorbell 1 */
-+#define ARM_IF_VP0HALT  0x00000044     /* FIQ = VPU0 Halt seen */
-+#define ARM_IF_VP1HALT  0x00000045     /* FIQ = VPU1 Halt seen */
-+#define ARM_IF_ILLEGAL  0x00000046     /* FIQ = Illegal access seen */
-+
-+#define ARM_IRQ_ENBL1 HW_REGISTER_RW(ARM_BASE+0x210) /* Bank1 enable bits */
-+#define ARM_IRQ_ENBL2 HW_REGISTER_RW(ARM_BASE+0x214) /* Bank2 enable bits */
-+#define ARM_IRQ_ENBL3 HW_REGISTER_RW(ARM_BASE+0x218) /* ARM irqs enable bits */
-+#define ARM_IRQ_DIBL1 HW_REGISTER_RW(ARM_BASE+0x21C) /* Bank1 disable bits */
-+#define ARM_IRQ_DIBL2 HW_REGISTER_RW(ARM_BASE+0x220) /* Bank2 disable bits */
-+#define ARM_IRQ_DIBL3 HW_REGISTER_RW(ARM_BASE+0x224) /* ARM irqs disable bits */
-+#define ARM_IE_TIMER    0x00000001     /* Timer IRQ */
-+#define ARM_IE_MAIL     0x00000002     /* Mail IRQ */
-+#define ARM_IE_BELL0    0x00000004     /* Doorbell 0 */
-+#define ARM_IE_BELL1    0x00000008     /* Doorbell 1 */
-+#define ARM_IE_VP0HALT  0x00000010     /* VPU0 Halt */
-+#define ARM_IE_VP1HALT  0x00000020     /* VPU1 Halt */
-+#define ARM_IE_ILLEGAL  0x00000040     /* Illegal access seen */
-+
-+/* Timer */
-+/* For reg. fields see sp804 spec. */
-+#define ARM_T_LOAD    HW_REGISTER_RW(ARM_BASE+0x400)
-+#define ARM_T_VALUE   HW_REGISTER_RW(ARM_BASE+0x404)
-+#define ARM_T_CONTROL HW_REGISTER_RW(ARM_BASE+0x408)
-+#define ARM_T_IRQCNTL HW_REGISTER_RW(ARM_BASE+0x40C)
-+#define ARM_T_RAWIRQ  HW_REGISTER_RW(ARM_BASE+0x410)
-+#define ARM_T_MSKIRQ  HW_REGISTER_RW(ARM_BASE+0x414)
-+#define ARM_T_RELOAD  HW_REGISTER_RW(ARM_BASE+0x418)
-+#define ARM_T_PREDIV  HW_REGISTER_RW(ARM_BASE+0x41c)
-+#define ARM_T_FREECNT HW_REGISTER_RW(ARM_BASE+0x420)
-+
-+#define TIMER_CTRL_ONESHOT  (1 << 0)
-+#define TIMER_CTRL_32BIT    (1 << 1)
-+#define TIMER_CTRL_DIV1     (0 << 2)
-+#define TIMER_CTRL_DIV16    (1 << 2)
-+#define TIMER_CTRL_DIV256   (2 << 2)
-+#define TIMER_CTRL_IE       (1 << 5)
-+#define TIMER_CTRL_PERIODIC (1 << 6)
-+#define TIMER_CTRL_ENABLE   (1 << 7)
-+#define TIMER_CTRL_DBGHALT  (1 << 8)
-+#define TIMER_CTRL_ENAFREE  (1 << 9)
-+#define TIMER_CTRL_FREEDIV_SHIFT 16)
-+#define TIMER_CTRL_FREEDIV_MASK  0xff
-+
-+/* Semaphores, Doorbells, Mailboxes */
-+#define ARM_SBM_OWN0  (ARM_BASE+0x800)
-+#define ARM_SBM_OWN1  (ARM_BASE+0x900)
-+#define ARM_SBM_OWN2  (ARM_BASE+0xA00)
-+#define ARM_SBM_OWN3  (ARM_BASE+0xB00)
-+
-+/* MAILBOXES
-+ * Register flags are common across all
-+ * owner registers. See end of this section
-+ *
-+ * Semaphores, Doorbells, Mailboxes Owner 0
-+ *
-+ */
-+
-+#define ARM_0_SEMS       HW_REGISTER_RW(ARM_SBM_OWN0+0x00)
-+#define ARM_0_SEM0       HW_REGISTER_RW(ARM_SBM_OWN0+0x00)
-+#define ARM_0_SEM1       HW_REGISTER_RW(ARM_SBM_OWN0+0x04)
-+#define ARM_0_SEM2       HW_REGISTER_RW(ARM_SBM_OWN0+0x08)
-+#define ARM_0_SEM3       HW_REGISTER_RW(ARM_SBM_OWN0+0x0C)
-+#define ARM_0_SEM4       HW_REGISTER_RW(ARM_SBM_OWN0+0x10)
-+#define ARM_0_SEM5       HW_REGISTER_RW(ARM_SBM_OWN0+0x14)
-+#define ARM_0_SEM6       HW_REGISTER_RW(ARM_SBM_OWN0+0x18)
-+#define ARM_0_SEM7       HW_REGISTER_RW(ARM_SBM_OWN0+0x1C)
-+#define ARM_0_BELL0      HW_REGISTER_RW(ARM_SBM_OWN0+0x40)
-+#define ARM_0_BELL1      HW_REGISTER_RW(ARM_SBM_OWN0+0x44)
-+#define ARM_0_BELL2      HW_REGISTER_RW(ARM_SBM_OWN0+0x48)
-+#define ARM_0_BELL3      HW_REGISTER_RW(ARM_SBM_OWN0+0x4C)
-+/* MAILBOX 0 access in Owner 0 area */
-+/* Some addresses should ONLY be used by owner 0 */
-+#define ARM_0_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN0+0x80)  /* .. 0x8C (4 locations) */
-+#define ARM_0_MAIL0_RD   HW_REGISTER_RW(ARM_SBM_OWN0+0x80)  /* .. 0x8C (4 locations) Normal read */
-+#define ARM_0_MAIL0_POL  HW_REGISTER_RW(ARM_SBM_OWN0+0x90)  /* none-pop read */
-+#define ARM_0_MAIL0_SND  HW_REGISTER_RW(ARM_SBM_OWN0+0x94)  /* Sender read (only LS 2 bits) */
-+#define ARM_0_MAIL0_STA  HW_REGISTER_RW(ARM_SBM_OWN0+0x98)  /* Status read */
-+#define ARM_0_MAIL0_CNF  HW_REGISTER_RW(ARM_SBM_OWN0+0x9C)  /* Config read/write */
-+/* MAILBOX 1 access in Owner 0 area */
-+/* Owner 0 should only WRITE to this mailbox */
-+#define ARM_0_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN0+0xA0)   /* .. 0xAC (4 locations) */
-+/*#define ARM_0_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN0+0xA0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_0_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN0+0xB0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_0_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN0+0xB4) */ /* DO NOT USE THIS !!!!! */
-+#define ARM_0_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN0+0xB8)   /* Status read */
-+/*#define ARM_0_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN0+0xBC) */ /* DO NOT USE THIS !!!!! */
-+/* General SEM, BELL, MAIL config/status */
-+#define ARM_0_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN0+0xE0)  /* semaphore clear/debug register */
-+#define ARM_0_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN0+0xE4)  /* Doorbells clear/debug register */
-+#define ARM_0_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN0+0xF8)  /* ALL interrupts */
-+#define ARM_0_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN0+0xFC)  /* IRQS pending for owner 0 */
-+
-+/* Semaphores, Doorbells, Mailboxes Owner 1 */
-+#define ARM_1_SEMS       HW_REGISTER_RW(ARM_SBM_OWN1+0x00)
-+#define ARM_1_SEM0       HW_REGISTER_RW(ARM_SBM_OWN1+0x00)
-+#define ARM_1_SEM1       HW_REGISTER_RW(ARM_SBM_OWN1+0x04)
-+#define ARM_1_SEM2       HW_REGISTER_RW(ARM_SBM_OWN1+0x08)
-+#define ARM_1_SEM3       HW_REGISTER_RW(ARM_SBM_OWN1+0x0C)
-+#define ARM_1_SEM4       HW_REGISTER_RW(ARM_SBM_OWN1+0x10)
-+#define ARM_1_SEM5       HW_REGISTER_RW(ARM_SBM_OWN1+0x14)
-+#define ARM_1_SEM6       HW_REGISTER_RW(ARM_SBM_OWN1+0x18)
-+#define ARM_1_SEM7       HW_REGISTER_RW(ARM_SBM_OWN1+0x1C)
-+#define ARM_1_BELL0      HW_REGISTER_RW(ARM_SBM_OWN1+0x40)
-+#define ARM_1_BELL1      HW_REGISTER_RW(ARM_SBM_OWN1+0x44)
-+#define ARM_1_BELL2      HW_REGISTER_RW(ARM_SBM_OWN1+0x48)
-+#define ARM_1_BELL3      HW_REGISTER_RW(ARM_SBM_OWN1+0x4C)
-+/* MAILBOX 0 access in Owner 0 area */
-+/* Owner 1 should only WRITE to this mailbox */
-+#define ARM_1_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN1+0x80)  /* .. 0x8C (4 locations) */
-+/*#define ARM_1_MAIL0_RD  HW_REGISTER_RW(ARM_SBM_OWN1+0x80) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_1_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN1+0x90) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_1_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN1+0x94) */ /* DO NOT USE THIS !!!!! */
-+#define ARM_1_MAIL0_STA  HW_REGISTER_RW(ARM_SBM_OWN1+0x98)  /* Status read */
-+/*#define ARM_1_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN1+0x9C) */ /* DO NOT USE THIS !!!!! */
-+/* MAILBOX 1 access in Owner 0 area */
-+#define ARM_1_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN1+0xA0)  /* .. 0xAC (4 locations) */
-+#define ARM_1_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN1+0xA0)  /* .. 0xAC (4 locations) Normal read */
-+#define ARM_1_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN1+0xB0)  /* none-pop read */
-+#define ARM_1_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN1+0xB4)  /* Sender read (only LS 2 bits) */
-+#define ARM_1_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN1+0xB8)  /* Status read */
-+#define ARM_1_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN1+0xBC)
-+/* General SEM, BELL, MAIL config/status */
-+#define ARM_1_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN1+0xE0)  /* semaphore clear/debug register */
-+#define ARM_1_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN1+0xE4)  /* Doorbells clear/debug register */
-+#define ARM_1_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN1+0xFC)  /* IRQS pending for owner 1 */
-+#define ARM_1_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN1+0xF8)  /* ALL interrupts */
-+
-+/* Semaphores, Doorbells, Mailboxes Owner 2 */
-+#define ARM_2_SEMS       HW_REGISTER_RW(ARM_SBM_OWN2+0x00)
-+#define ARM_2_SEM0       HW_REGISTER_RW(ARM_SBM_OWN2+0x00)
-+#define ARM_2_SEM1       HW_REGISTER_RW(ARM_SBM_OWN2+0x04)
-+#define ARM_2_SEM2       HW_REGISTER_RW(ARM_SBM_OWN2+0x08)
-+#define ARM_2_SEM3       HW_REGISTER_RW(ARM_SBM_OWN2+0x0C)
-+#define ARM_2_SEM4       HW_REGISTER_RW(ARM_SBM_OWN2+0x10)
-+#define ARM_2_SEM5       HW_REGISTER_RW(ARM_SBM_OWN2+0x14)
-+#define ARM_2_SEM6       HW_REGISTER_RW(ARM_SBM_OWN2+0x18)
-+#define ARM_2_SEM7       HW_REGISTER_RW(ARM_SBM_OWN2+0x1C)
-+#define ARM_2_BELL0      HW_REGISTER_RW(ARM_SBM_OWN2+0x40)
-+#define ARM_2_BELL1      HW_REGISTER_RW(ARM_SBM_OWN2+0x44)
-+#define ARM_2_BELL2      HW_REGISTER_RW(ARM_SBM_OWN2+0x48)
-+#define ARM_2_BELL3      HW_REGISTER_RW(ARM_SBM_OWN2+0x4C)
-+/* MAILBOX 0 access in Owner 2 area */
-+/* Owner 2 should only WRITE to this mailbox */
-+#define ARM_2_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN2+0x80)   /* .. 0x8C (4 locations) */
-+/*#define ARM_2_MAIL0_RD  HW_REGISTER_RW(ARM_SBM_OWN2+0x80)  */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_2_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN2+0x90)  */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_2_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN2+0x94)  */ /* DO NOT USE THIS !!!!! */
-+#define ARM_2_MAIL0_STA  HW_REGISTER_RW(ARM_SBM_OWN2+0x98)   /* Status read */
-+/*#define ARM_2_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN2+0x9C)  */ /* DO NOT USE THIS !!!!! */
-+/* MAILBOX 1 access in Owner 2 area */
-+/* Owner 2 should only WRITE to this mailbox */
-+#define ARM_2_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN2+0xA0)   /* .. 0xAC (4 locations) */
-+/*#define ARM_2_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN2+0xA0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_2_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN2+0xB0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_2_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN2+0xB4) */ /* DO NOT USE THIS !!!!! */
-+#define ARM_2_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN2+0xB8)   /* Status read */
-+/*#define ARM_2_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN2+0xBC) */ /* DO NOT USE THIS !!!!! */
-+/* General SEM, BELL, MAIL config/status */
-+#define ARM_2_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN2+0xE0)  /* semaphore clear/debug register */
-+#define ARM_2_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN2+0xE4)  /* Doorbells clear/debug register */
-+#define ARM_2_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN2+0xFC)  /* IRQS pending for owner 2 */
-+#define ARM_2_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN2+0xF8)  /* ALL interrupts */
-+
-+/* Semaphores, Doorbells, Mailboxes Owner 3 */
-+#define ARM_3_SEMS       HW_REGISTER_RW(ARM_SBM_OWN3+0x00)
-+#define ARM_3_SEM0       HW_REGISTER_RW(ARM_SBM_OWN3+0x00)
-+#define ARM_3_SEM1       HW_REGISTER_RW(ARM_SBM_OWN3+0x04)
-+#define ARM_3_SEM2       HW_REGISTER_RW(ARM_SBM_OWN3+0x08)
-+#define ARM_3_SEM3       HW_REGISTER_RW(ARM_SBM_OWN3+0x0C)
-+#define ARM_3_SEM4       HW_REGISTER_RW(ARM_SBM_OWN3+0x10)
-+#define ARM_3_SEM5       HW_REGISTER_RW(ARM_SBM_OWN3+0x14)
-+#define ARM_3_SEM6       HW_REGISTER_RW(ARM_SBM_OWN3+0x18)
-+#define ARM_3_SEM7       HW_REGISTER_RW(ARM_SBM_OWN3+0x1C)
-+#define ARM_3_BELL0      HW_REGISTER_RW(ARM_SBM_OWN3+0x40)
-+#define ARM_3_BELL1      HW_REGISTER_RW(ARM_SBM_OWN3+0x44)
-+#define ARM_3_BELL2      HW_REGISTER_RW(ARM_SBM_OWN3+0x48)
-+#define ARM_3_BELL3      HW_REGISTER_RW(ARM_SBM_OWN3+0x4C)
-+/* MAILBOX 0 access in Owner 3 area */
-+/* Owner 3 should only WRITE to this mailbox */
-+#define ARM_3_MAIL0_WRT  HW_REGISTER_RW(ARM_SBM_OWN3+0x80)   /* .. 0x8C (4 locations) */
-+/*#define ARM_3_MAIL0_RD  HW_REGISTER_RW(ARM_SBM_OWN3+0x80)  */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_3_MAIL0_POL HW_REGISTER_RW(ARM_SBM_OWN3+0x90)  */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_3_MAIL0_SND HW_REGISTER_RW(ARM_SBM_OWN3+0x94)  */ /* DO NOT USE THIS !!!!! */
-+#define ARM_3_MAIL0_STA HW_REGISTER_RW(ARM_SBM_OWN3+0x98)    /* Status read */
-+/*#define ARM_3_MAIL0_CNF HW_REGISTER_RW(ARM_SBM_OWN3+0x9C)  */ /* DO NOT USE THIS !!!!! */
-+/* MAILBOX 1 access in Owner 3 area */
-+/* Owner 3 should only WRITE to this mailbox */
-+#define ARM_3_MAIL1_WRT  HW_REGISTER_RW(ARM_SBM_OWN3+0xA0)   /* .. 0xAC (4 locations) */
-+/*#define ARM_3_MAIL1_RD   HW_REGISTER_RW(ARM_SBM_OWN3+0xA0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_3_MAIL1_POL  HW_REGISTER_RW(ARM_SBM_OWN3+0xB0) */ /* DO NOT USE THIS !!!!! */
-+/*#define ARM_3_MAIL1_SND  HW_REGISTER_RW(ARM_SBM_OWN3+0xB4) */ /* DO NOT USE THIS !!!!! */
-+#define ARM_3_MAIL1_STA  HW_REGISTER_RW(ARM_SBM_OWN3+0xB8)   /* Status read */
-+/*#define ARM_3_MAIL1_CNF  HW_REGISTER_RW(ARM_SBM_OWN3+0xBC) */ /* DO NOT USE THIS !!!!! */
-+/* General SEM, BELL, MAIL config/status */
-+#define ARM_3_SEMCLRDBG   HW_REGISTER_RW(ARM_SBM_OWN3+0xE0)  /* semaphore clear/debug register */
-+#define ARM_3_BELLCLRDBG  HW_REGISTER_RW(ARM_SBM_OWN3+0xE4)  /* Doorbells clear/debug register */
-+#define ARM_3_MY_IRQS     HW_REGISTER_RW(ARM_SBM_OWN3+0xFC)  /* IRQS pending for owner 3 */
-+#define ARM_3_ALL_IRQS    HW_REGISTER_RW(ARM_SBM_OWN3+0xF8)  /* ALL interrupts */
-+
-+
-+
-+/*  Mailbox flags. Valid for all owners */
-+
-+/* Mailbox status register (...0x98) */
-+#define ARM_MS_FULL       0x80000000
-+#define ARM_MS_EMPTY      0x40000000
-+#define ARM_MS_LEVEL      0x400000FF /* Max. value depdnds on mailbox depth parameter */
-+
-+/* MAILBOX config/status register (...0x9C) */
-+/* ANY write to this register clears the error bits! */
-+#define ARM_MC_IHAVEDATAIRQEN    0x00000001 /* mailbox irq enable:  has data */
-+#define ARM_MC_IHAVESPACEIRQEN   0x00000002 /* mailbox irq enable:  has space */
-+#define ARM_MC_OPPISEMPTYIRQEN   0x00000004 /* mailbox irq enable: Opp. is empty */
-+#define ARM_MC_MAIL_CLEAR        0x00000008 /* mailbox clear write 1, then  0 */
-+#define ARM_MC_IHAVEDATAIRQPEND  0x00000010 /* mailbox irq pending:  has space */
-+#define ARM_MC_IHAVESPACEIRQPEND 0x00000020 /* mailbox irq pending: Opp. is empty */
-+#define ARM_MC_OPPISEMPTYIRQPEND 0x00000040 /* mailbox irq pending */
-+/* Bit 7 is unused */
-+#define ARM_MC_ERRNOOWN   0x00000100 /* error : none owner read from mailbox */
-+#define ARM_MC_ERROVERFLW 0x00000200 /* error : write to fill mailbox */
-+#define ARM_MC_ERRUNDRFLW 0x00000400 /* error : read from empty mailbox */
-+
-+/* Semaphore clear/debug register (...0xE0) */
-+#define ARM_SD_OWN0      0x00000003  /* Owner of sem 0 */
-+#define ARM_SD_OWN1      0x0000000C  /* Owner of sem 1 */
-+#define ARM_SD_OWN2      0x00000030  /* Owner of sem 2 */
-+#define ARM_SD_OWN3      0x000000C0  /* Owner of sem 3 */
-+#define ARM_SD_OWN4      0x00000300  /* Owner of sem 4 */
-+#define ARM_SD_OWN5      0x00000C00  /* Owner of sem 5 */
-+#define ARM_SD_OWN6      0x00003000  /* Owner of sem 6 */
-+#define ARM_SD_OWN7      0x0000C000  /* Owner of sem 7 */
-+#define ARM_SD_SEM0      0x00010000  /* Status of sem 0 */
-+#define ARM_SD_SEM1      0x00020000  /* Status of sem 1 */
-+#define ARM_SD_SEM2      0x00040000  /* Status of sem 2 */
-+#define ARM_SD_SEM3      0x00080000  /* Status of sem 3 */
-+#define ARM_SD_SEM4      0x00100000  /* Status of sem 4 */
-+#define ARM_SD_SEM5      0x00200000  /* Status of sem 5 */
-+#define ARM_SD_SEM6      0x00400000  /* Status of sem 6 */
-+#define ARM_SD_SEM7      0x00800000  /* Status of sem 7 */
-+
-+/* Doorbells clear/debug register (...0xE4) */
-+#define ARM_BD_OWN0      0x00000003  /* Owner of doorbell 0 */
-+#define ARM_BD_OWN1      0x0000000C  /* Owner of doorbell 1 */
-+#define ARM_BD_OWN2      0x00000030  /* Owner of doorbell 2 */
-+#define ARM_BD_OWN3      0x000000C0  /* Owner of doorbell 3 */
-+#define ARM_BD_BELL0     0x00000100  /* Status of doorbell 0 */
-+#define ARM_BD_BELL1     0x00000200  /* Status of doorbell 1 */
-+#define ARM_BD_BELL2     0x00000400  /* Status of doorbell 2 */
-+#define ARM_BD_BELL3     0x00000800  /* Status of doorbell 3 */
-+
-+/* MY IRQS register (...0xF8) */
-+#define ARM_MYIRQ_BELL   0x00000001  /* This owner has a doorbell IRQ */
-+#define ARM_MYIRQ_MAIL   0x00000002  /* This owner has a mailbox  IRQ */
-+
-+/* ALL IRQS register (...0xF8) */
-+#define ARM_AIS_BELL0 0x00000001  /* Doorbell 0 IRQ pending */
-+#define ARM_AIS_BELL1 0x00000002  /* Doorbell 1 IRQ pending */
-+#define ARM_AIS_BELL2 0x00000004  /* Doorbell 2 IRQ pending */
-+#define ARM_AIS_BELL3 0x00000008  /* Doorbell 3 IRQ pending */
-+#define ARM_AIS0_HAVEDATA 0x00000010  /* MAIL 0 has data IRQ pending */
-+#define ARM_AIS0_HAVESPAC 0x00000020  /* MAIL 0 has space IRQ pending */
-+#define ARM_AIS0_OPPEMPTY 0x00000040  /* MAIL 0 opposite is empty IRQ */
-+#define ARM_AIS1_HAVEDATA 0x00000080  /* MAIL 1 has data IRQ pending */
-+#define ARM_AIS1_HAVESPAC 0x00000100  /* MAIL 1 has space IRQ pending */
-+#define ARM_AIS1_OPPEMPTY 0x00000200  /* MAIL 1 opposite is empty IRQ */
-+/* Note   that bell-0, bell-1 and MAIL0 IRQ go only to the ARM */
-+/* Whilst that bell-2, bell-3 and MAIL1 IRQ go only to the VC */
-+/* */
-+/* ARM JTAG BASH */
-+/* */
-+#define AJB_BASE 0x7e2000c0
-+
-+#define AJBCONF HW_REGISTER_RW(AJB_BASE+0x00)
-+#define   AJB_BITS0    0x000000
-+#define   AJB_BITS4    0x000004
-+#define   AJB_BITS8    0x000008
-+#define   AJB_BITS12   0x00000C
-+#define   AJB_BITS16   0x000010
-+#define   AJB_BITS20   0x000014
-+#define   AJB_BITS24   0x000018
-+#define   AJB_BITS28   0x00001C
-+#define   AJB_BITS32   0x000020
-+#define   AJB_BITS34   0x000022
-+#define   AJB_OUT_MS   0x000040
-+#define   AJB_OUT_LS   0x000000
-+#define   AJB_INV_CLK  0x000080
-+#define   AJB_D0_RISE  0x000100
-+#define   AJB_D0_FALL  0x000000
-+#define   AJB_D1_RISE  0x000200
-+#define   AJB_D1_FALL  0x000000
-+#define   AJB_IN_RISE  0x000400
-+#define   AJB_IN_FALL  0x000000
-+#define   AJB_ENABLE   0x000800
-+#define   AJB_HOLD0    0x000000
-+#define   AJB_HOLD1    0x001000
-+#define   AJB_HOLD2    0x002000
-+#define   AJB_HOLD3    0x003000
-+#define   AJB_RESETN   0x004000
-+#define   AJB_CLKSHFT  16
-+#define   AJB_BUSY     0x80000000
-+#define AJBTMS HW_REGISTER_RW(AJB_BASE+0x04)
-+#define AJBTDI HW_REGISTER_RW(AJB_BASE+0x08)
-+#define AJBTDO HW_REGISTER_RW(AJB_BASE+0x0c)
-+
-+#define ARM_LOCAL_BASE 0x40000000
-+#define ARM_LOCAL_CONTROL		HW_REGISTER_RW(ARM_LOCAL_BASE+0x000)
-+#define ARM_LOCAL_PRESCALER		HW_REGISTER_RW(ARM_LOCAL_BASE+0x008)
-+#define ARM_LOCAL_GPU_INT_ROUTING	HW_REGISTER_RW(ARM_LOCAL_BASE+0x00C)
-+#define ARM_LOCAL_PM_ROUTING_SET	HW_REGISTER_RW(ARM_LOCAL_BASE+0x010)
-+#define ARM_LOCAL_PM_ROUTING_CLR	HW_REGISTER_RW(ARM_LOCAL_BASE+0x014)
-+#define ARM_LOCAL_TIMER_LS		HW_REGISTER_RW(ARM_LOCAL_BASE+0x01C)
-+#define ARM_LOCAL_TIMER_MS		HW_REGISTER_RW(ARM_LOCAL_BASE+0x020)
-+#define ARM_LOCAL_INT_ROUTING		HW_REGISTER_RW(ARM_LOCAL_BASE+0x024)
-+#define ARM_LOCAL_AXI_COUNT		HW_REGISTER_RW(ARM_LOCAL_BASE+0x02C)
-+#define ARM_LOCAL_AXI_IRQ		HW_REGISTER_RW(ARM_LOCAL_BASE+0x030)
-+#define ARM_LOCAL_TIMER_CONTROL		HW_REGISTER_RW(ARM_LOCAL_BASE+0x034)
-+#define ARM_LOCAL_TIMER_WRITE		HW_REGISTER_RW(ARM_LOCAL_BASE+0x038)
-+
-+#define ARM_LOCAL_TIMER_INT_CONTROL0	HW_REGISTER_RW(ARM_LOCAL_BASE+0x040)
-+#define ARM_LOCAL_TIMER_INT_CONTROL1	HW_REGISTER_RW(ARM_LOCAL_BASE+0x044)
-+#define ARM_LOCAL_TIMER_INT_CONTROL2	HW_REGISTER_RW(ARM_LOCAL_BASE+0x048)
-+#define ARM_LOCAL_TIMER_INT_CONTROL3	HW_REGISTER_RW(ARM_LOCAL_BASE+0x04C)
-+
-+#define ARM_LOCAL_MAILBOX_INT_CONTROL0	HW_REGISTER_RW(ARM_LOCAL_BASE+0x050)
-+#define ARM_LOCAL_MAILBOX_INT_CONTROL1	HW_REGISTER_RW(ARM_LOCAL_BASE+0x054)
-+#define ARM_LOCAL_MAILBOX_INT_CONTROL2	HW_REGISTER_RW(ARM_LOCAL_BASE+0x058)
-+#define ARM_LOCAL_MAILBOX_INT_CONTROL3	HW_REGISTER_RW(ARM_LOCAL_BASE+0x05C)
-+
-+#define ARM_LOCAL_IRQ_PENDING0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x060)
-+#define ARM_LOCAL_IRQ_PENDING1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x064)
-+#define ARM_LOCAL_IRQ_PENDING2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x068)
-+#define ARM_LOCAL_IRQ_PENDING3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x06C)
-+
-+#define ARM_LOCAL_FIQ_PENDING0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x070)
-+#define ARM_LOCAL_FIQ_PENDING1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x074)
-+#define ARM_LOCAL_FIQ_PENDING2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x078)
-+#define ARM_LOCAL_FIQ_PENDING3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x07C)
-+
-+#define ARM_LOCAL_MAILBOX0_SET0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x080)
-+#define ARM_LOCAL_MAILBOX1_SET0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x084)
-+#define ARM_LOCAL_MAILBOX2_SET0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x088)
-+#define ARM_LOCAL_MAILBOX3_SET0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x08C)
-+
-+#define ARM_LOCAL_MAILBOX0_SET1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x090)
-+#define ARM_LOCAL_MAILBOX1_SET1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x094)
-+#define ARM_LOCAL_MAILBOX2_SET1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x098)
-+#define ARM_LOCAL_MAILBOX3_SET1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x09C)
-+
-+#define ARM_LOCAL_MAILBOX0_SET2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0A0)
-+#define ARM_LOCAL_MAILBOX1_SET2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0A4)
-+#define ARM_LOCAL_MAILBOX2_SET2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0A8)
-+#define ARM_LOCAL_MAILBOX3_SET2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0AC)
-+
-+#define ARM_LOCAL_MAILBOX0_SET3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0B0)
-+#define ARM_LOCAL_MAILBOX1_SET3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0B4)
-+#define ARM_LOCAL_MAILBOX2_SET3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0B8)
-+#define ARM_LOCAL_MAILBOX3_SET3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0BC)
-+
-+#define ARM_LOCAL_MAILBOX0_CLR0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0C0)
-+#define ARM_LOCAL_MAILBOX1_CLR0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0C4)
-+#define ARM_LOCAL_MAILBOX2_CLR0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0C8)
-+#define ARM_LOCAL_MAILBOX3_CLR0		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0CC)
-+
-+#define ARM_LOCAL_MAILBOX0_CLR1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0D0)
-+#define ARM_LOCAL_MAILBOX1_CLR1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0D4)
-+#define ARM_LOCAL_MAILBOX2_CLR1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0D8)
-+#define ARM_LOCAL_MAILBOX3_CLR1		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0DC)
-+
-+#define ARM_LOCAL_MAILBOX0_CLR2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0E0)
-+#define ARM_LOCAL_MAILBOX1_CLR2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0E4)
-+#define ARM_LOCAL_MAILBOX2_CLR2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0E8)
-+#define ARM_LOCAL_MAILBOX3_CLR2		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0EC)
-+
-+#define ARM_LOCAL_MAILBOX0_CLR3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0F0)
-+#define ARM_LOCAL_MAILBOX1_CLR3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0F4)
-+#define ARM_LOCAL_MAILBOX2_CLR3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0F8)
-+#define ARM_LOCAL_MAILBOX3_CLR3		HW_REGISTER_RW(ARM_LOCAL_BASE+0x0FC)
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/barriers.h
-@@ -0,0 +1,3 @@
-+#define mb()		dsb()
-+#define rmb()		dsb()
-+#define wmb()		mb()
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/clkdev.h
-@@ -0,0 +1,7 @@
-+#ifndef __ASM_MACH_CLKDEV_H
-+#define __ASM_MACH_CLKDEV_H
-+
-+#define __clk_get(clk) ({ 1; })
-+#define __clk_put(clk) do { } while (0)
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/debug-macro.S
-@@ -0,0 +1,22 @@
-+/* arch/arm/mach-bcm2708/include/mach/debug-macro.S
-+ *
-+ * Debugging macro include header
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *  Copyright (C) 1994-1999 Russell King
-+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+*/
-+
-+#include <mach/platform.h>
-+
-+		.macro	addruart, rp, rv, tmp
-+		ldr	\rp, =UART0_BASE
-+		ldr	\rv, =IO_ADDRESS(UART0_BASE)
-+		.endm
-+
-+#include <debug/pl01x.S>
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/entry-macro.S
-@@ -0,0 +1,123 @@
-+/*
-+ * arch/arm/mach-bcm2708/include/mach/entry-macro.S
-+ *
-+ * Low-level IRQ helper macros for BCM2708 platforms
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#include <mach/hardware.h>
-+#include <mach/irqs.h>
-+
-+		.macro	disable_fiq
-+		.endm
-+
-+		.macro  get_irqnr_preamble, base, tmp
-+		ldr	\base, =IO_ADDRESS(ARMCTRL_IC_BASE)
-+		.endm
-+
-+		.macro  arch_ret_to_user, tmp1, tmp2
-+		.endm
-+
-+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-+		/* get core number */
-+		mrc     p15, 0, \tmp, c0, c0, 5
-+		ubfx    \tmp, \tmp, #0, #2
-+
-+		/* get core's local interrupt controller */
-+		ldr	\irqstat, = __io_address(ARM_LOCAL_IRQ_PENDING0)	@ local interrupt source
-+		add	\irqstat, \irqstat, \tmp, lsl #2
-+		ldr	\tmp, [\irqstat]
-+		/* ignore gpu interrupt */
-+		bic     \tmp, #0x100
-+		/* ignore mailbox interrupts */
-+		bics    \tmp, #0xf0
-+		beq	1005f
-+
-+		@ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
-+		@ N.B. CLZ is an ARM5 instruction.
-+		mov	\irqnr, #(ARM_IRQ_LOCAL_BASE + 31)
-+		sub	\irqstat, \tmp, #1
-+		eor	\irqstat, \irqstat, \tmp
-+		clz	\tmp, \irqstat
-+		sub	\irqnr, \tmp
-+		b	1020f
-+1005:
-+		/* get core number */
-+		mrc     p15, 0, \tmp, c0, c0, 5
-+		ubfx    \tmp, \tmp, #0, #2
-+
-+                cmp	\tmp, #1
-+		beq	1020f
-+                cmp	\tmp, #2
-+		beq	1020f
-+                cmp	\tmp, #3
-+		beq	1020f
-+
-+		/* get masked status */
-+		ldr	\irqstat, [\base, #(ARM_IRQ_PEND0 - ARMCTRL_IC_BASE)]
-+		mov	\irqnr, #(ARM_IRQ0_BASE + 31)
-+		and	\tmp, \irqstat, #0x300		 @ save bits 8 and 9
-+		/* clear bits 8 and 9, and test */
-+		bics	\irqstat, \irqstat, #0x300
-+		bne	1010f
-+
-+		tst	\tmp, #0x100
-+		ldrne	\irqstat, [\base, #(ARM_IRQ_PEND1 - ARMCTRL_IC_BASE)]
-+		movne \irqnr, #(ARM_IRQ1_BASE + 31)
-+		@ Mask out the interrupts also present in PEND0 - see SW-5809
-+		bicne \irqstat, #((1<<7) | (1<<9) | (1<<10))
-+		bicne \irqstat, #((1<<18) | (1<<19))
-+		bne	1010f
-+
-+		tst	\tmp, #0x200
-+		ldrne \irqstat, [\base, #(ARM_IRQ_PEND2 - ARMCTRL_IC_BASE)]
-+		movne \irqnr, #(ARM_IRQ2_BASE + 31)
-+		@ Mask out the interrupts also present in PEND0 - see SW-5809
-+		bicne \irqstat, #((1<<21) | (1<<22) | (1<<23) | (1<<24) | (1<<25))
-+		bicne \irqstat, #((1<<30))
-+		beq 1020f
-+
-+1010:
-+		@ For non-zero x, LSB(x) = 31 - CLZ(x^(x-1))
-+		@ N.B. CLZ is an ARM5 instruction.
-+		sub	\tmp, \irqstat, #1
-+		eor	\irqstat, \irqstat, \tmp
-+		clz	\tmp, \irqstat
-+		sub	\irqnr, \tmp
-+
-+1020:	@ EQ will be set if no irqs pending
-+
-+		.endm
-+
-+		.macro  test_for_ipi, irqnr, irqstat, base, tmp
-+		/* get core number */
-+		mrc     p15, 0, \tmp, c0, c0, 5
-+		ubfx    \tmp, \tmp, #0, #2
-+		/* get core's mailbox interrupt control */
-+		ldr	\irqstat, = __io_address(ARM_LOCAL_MAILBOX0_CLR0)	@ mbox_clr
-+		add	\irqstat, \irqstat, \tmp, lsl #4
-+		ldr	\tmp, [\irqstat]
-+		cmp     \tmp, #0
-+		beq	1030f
-+		clz	\tmp, \tmp
-+		rsb	\irqnr, \tmp, #31
-+		mov	\tmp, #1
-+		lsl	\tmp, \irqnr
-+		str	\tmp, [\irqstat]  @ clear interrupt source
-+		dsb
-+1030:	@ EQ will be set if no irqs pending
-+		.endm
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/frc.h
-@@ -0,0 +1,38 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/timex.h
-+ *
-+ *  BCM2708 free running counter (timer)
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef _MACH_FRC_H
-+#define _MACH_FRC_H
-+
-+#define FRC_TICK_RATE		(1000000)
-+
-+/*! Free running counter incrementing at the CLOCK_TICK_RATE
-+    (slightly faster than frc_clock_ticks63()
-+ */
-+extern unsigned long frc_clock_ticks32(void);
-+
-+/*! Free running counter incrementing at the CLOCK_TICK_RATE
-+ *  Note - top bit should be ignored (see cnt32_to_63)
-+ */
-+extern unsigned long long frc_clock_ticks63(void);
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/gpio.h
-@@ -0,0 +1,17 @@
-+/*
-+ * arch/arm/mach-bcm2708/include/mach/gpio.h
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2.  This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#ifndef __ASM_ARCH_GPIO_H
-+#define __ASM_ARCH_GPIO_H
-+
-+#define BCM2708_NR_GPIOS 54 // number of gpio lines
-+
-+#define gpio_to_irq(x)	((x) + GPIO_IRQ_START)
-+#define irq_to_gpio(x)	((x) - GPIO_IRQ_START)
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/hardware.h
-@@ -0,0 +1,28 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/hardware.h
-+ *
-+ *  This file contains the hardware definitions of the BCM2708 devices.
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifndef __ASM_ARCH_HARDWARE_H
-+#define __ASM_ARCH_HARDWARE_H
-+
-+#include <asm/sizes.h>
-+#include <mach/platform.h>
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/io.h
-@@ -0,0 +1,27 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/io.h
-+ *
-+ *  Copyright (C) 2003 ARM Limited
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT 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 __ASM_ARM_ARCH_IO_H
-+#define __ASM_ARM_ARCH_IO_H
-+
-+#define IO_SPACE_LIMIT 0xffffffff
-+
-+#define __io(a)		__typesafe_io(a)
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/irqs.h
-@@ -0,0 +1,225 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/irqs.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *  Copyright (C) 2003 ARM Limited
-+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef _BCM2708_IRQS_H_
-+#define _BCM2708_IRQS_H_
-+
-+#include <mach/platform.h>
-+
-+/*
-+ *  IRQ interrupts definitions are the same as the INT definitions
-+ *  held within platform.h
-+ */
-+#define IRQ_ARMCTRL_START     0
-+#define IRQ_TIMER0            (IRQ_ARMCTRL_START + INTERRUPT_TIMER0)
-+#define IRQ_TIMER1            (IRQ_ARMCTRL_START + INTERRUPT_TIMER1)
-+#define IRQ_TIMER2            (IRQ_ARMCTRL_START + INTERRUPT_TIMER2)
-+#define IRQ_TIMER3            (IRQ_ARMCTRL_START + INTERRUPT_TIMER3)
-+#define IRQ_CODEC0            (IRQ_ARMCTRL_START + INTERRUPT_CODEC0)
-+#define IRQ_CODEC1            (IRQ_ARMCTRL_START + INTERRUPT_CODEC1)
-+#define IRQ_CODEC2            (IRQ_ARMCTRL_START + INTERRUPT_CODEC2)
-+#define IRQ_JPEG              (IRQ_ARMCTRL_START + INTERRUPT_JPEG)
-+#define IRQ_ISP               (IRQ_ARMCTRL_START + INTERRUPT_ISP)
-+#define IRQ_USB               (IRQ_ARMCTRL_START + INTERRUPT_USB)
-+#define IRQ_3D                (IRQ_ARMCTRL_START + INTERRUPT_3D)
-+#define IRQ_TRANSPOSER        (IRQ_ARMCTRL_START + INTERRUPT_TRANSPOSER)
-+#define IRQ_MULTICORESYNC0    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC0)
-+#define IRQ_MULTICORESYNC1    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC1)
-+#define IRQ_MULTICORESYNC2    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC2)
-+#define IRQ_MULTICORESYNC3    (IRQ_ARMCTRL_START + INTERRUPT_MULTICORESYNC3)
-+#define IRQ_DMA0              (IRQ_ARMCTRL_START + INTERRUPT_DMA0)
-+#define IRQ_DMA1              (IRQ_ARMCTRL_START + INTERRUPT_DMA1)
-+#define IRQ_DMA2              (IRQ_ARMCTRL_START + INTERRUPT_DMA2)
-+#define IRQ_DMA3              (IRQ_ARMCTRL_START + INTERRUPT_DMA3)
-+#define IRQ_DMA4              (IRQ_ARMCTRL_START + INTERRUPT_DMA4)
-+#define IRQ_DMA5              (IRQ_ARMCTRL_START + INTERRUPT_DMA5)
-+#define IRQ_DMA6              (IRQ_ARMCTRL_START + INTERRUPT_DMA6)
-+#define IRQ_DMA7              (IRQ_ARMCTRL_START + INTERRUPT_DMA7)
-+#define IRQ_DMA8              (IRQ_ARMCTRL_START + INTERRUPT_DMA8)
-+#define IRQ_DMA9              (IRQ_ARMCTRL_START + INTERRUPT_DMA9)
-+#define IRQ_DMA10             (IRQ_ARMCTRL_START + INTERRUPT_DMA10)
-+#define IRQ_DMA11             (IRQ_ARMCTRL_START + INTERRUPT_DMA11)
-+#define IRQ_DMA12             (IRQ_ARMCTRL_START + INTERRUPT_DMA12)
-+#define IRQ_AUX               (IRQ_ARMCTRL_START + INTERRUPT_AUX)
-+#define IRQ_ARM               (IRQ_ARMCTRL_START + INTERRUPT_ARM)
-+#define IRQ_VPUDMA            (IRQ_ARMCTRL_START + INTERRUPT_VPUDMA)
-+#define IRQ_HOSTPORT          (IRQ_ARMCTRL_START + INTERRUPT_HOSTPORT)
-+#define IRQ_VIDEOSCALER       (IRQ_ARMCTRL_START + INTERRUPT_VIDEOSCALER)
-+#define IRQ_CCP2TX            (IRQ_ARMCTRL_START + INTERRUPT_CCP2TX)
-+#define IRQ_SDC               (IRQ_ARMCTRL_START + INTERRUPT_SDC)
-+#define IRQ_DSI0              (IRQ_ARMCTRL_START + INTERRUPT_DSI0)
-+#define IRQ_AVE               (IRQ_ARMCTRL_START + INTERRUPT_AVE)
-+#define IRQ_CAM0              (IRQ_ARMCTRL_START + INTERRUPT_CAM0)
-+#define IRQ_CAM1              (IRQ_ARMCTRL_START + INTERRUPT_CAM1)
-+#define IRQ_HDMI0             (IRQ_ARMCTRL_START + INTERRUPT_HDMI0)
-+#define IRQ_HDMI1             (IRQ_ARMCTRL_START + INTERRUPT_HDMI1)
-+#define IRQ_PIXELVALVE1       (IRQ_ARMCTRL_START + INTERRUPT_PIXELVALVE1)
-+#define IRQ_I2CSPISLV         (IRQ_ARMCTRL_START + INTERRUPT_I2CSPISLV)
-+#define IRQ_DSI1              (IRQ_ARMCTRL_START + INTERRUPT_DSI1)
-+#define IRQ_PWA0              (IRQ_ARMCTRL_START + INTERRUPT_PWA0)
-+#define IRQ_PWA1              (IRQ_ARMCTRL_START + INTERRUPT_PWA1)
-+#define IRQ_CPR               (IRQ_ARMCTRL_START + INTERRUPT_CPR)
-+#define IRQ_SMI               (IRQ_ARMCTRL_START + INTERRUPT_SMI)
-+#define IRQ_GPIO0             (IRQ_ARMCTRL_START + INTERRUPT_GPIO0)
-+#define IRQ_GPIO1             (IRQ_ARMCTRL_START + INTERRUPT_GPIO1)
-+#define IRQ_GPIO2             (IRQ_ARMCTRL_START + INTERRUPT_GPIO2)
-+#define IRQ_GPIO3             (IRQ_ARMCTRL_START + INTERRUPT_GPIO3)
-+#define IRQ_I2C               (IRQ_ARMCTRL_START + INTERRUPT_I2C)
-+#define IRQ_SPI               (IRQ_ARMCTRL_START + INTERRUPT_SPI)
-+#define IRQ_I2SPCM            (IRQ_ARMCTRL_START + INTERRUPT_I2SPCM)
-+#define IRQ_SDIO              (IRQ_ARMCTRL_START + INTERRUPT_SDIO)
-+#define IRQ_UART              (IRQ_ARMCTRL_START + INTERRUPT_UART)
-+#define IRQ_SLIMBUS           (IRQ_ARMCTRL_START + INTERRUPT_SLIMBUS)
-+#define IRQ_VEC               (IRQ_ARMCTRL_START + INTERRUPT_VEC)
-+#define IRQ_CPG               (IRQ_ARMCTRL_START + INTERRUPT_CPG)
-+#define IRQ_RNG               (IRQ_ARMCTRL_START + INTERRUPT_RNG)
-+#define IRQ_ARASANSDIO        (IRQ_ARMCTRL_START + INTERRUPT_ARASANSDIO)
-+#define IRQ_AVSPMON           (IRQ_ARMCTRL_START + INTERRUPT_AVSPMON)
-+
-+#define IRQ_ARM_TIMER         (IRQ_ARMCTRL_START + INTERRUPT_ARM_TIMER)
-+#define IRQ_ARM_MAILBOX       (IRQ_ARMCTRL_START + INTERRUPT_ARM_MAILBOX)
-+#define IRQ_ARM_DOORBELL_0    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_0)
-+#define IRQ_ARM_DOORBELL_1    (IRQ_ARMCTRL_START + INTERRUPT_ARM_DOORBELL_1)
-+#define IRQ_VPU0_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU0_HALTED)
-+#define IRQ_VPU1_HALTED       (IRQ_ARMCTRL_START + INTERRUPT_VPU1_HALTED)
-+#define IRQ_ILLEGAL_TYPE0     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE0)
-+#define IRQ_ILLEGAL_TYPE1     (IRQ_ARMCTRL_START + INTERRUPT_ILLEGAL_TYPE1)
-+#define IRQ_PENDING1          (IRQ_ARMCTRL_START + INTERRUPT_PENDING1)
-+#define IRQ_PENDING2          (IRQ_ARMCTRL_START + INTERRUPT_PENDING2)
-+
-+#define IRQ_ARM_LOCAL_CNTPSIRQ   (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_CNTPSIRQ)
-+#define IRQ_ARM_LOCAL_CNTPNSIRQ  (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_CNTPNSIRQ)
-+#define IRQ_ARM_LOCAL_CNTHPIRQ   (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_CNTHPIRQ)
-+#define IRQ_ARM_LOCAL_CNTVIRQ    (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_CNTVIRQ)
-+#define IRQ_ARM_LOCAL_MAILBOX0   (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_MAILBOX0)
-+#define IRQ_ARM_LOCAL_MAILBOX1   (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_MAILBOX1)
-+#define IRQ_ARM_LOCAL_MAILBOX2   (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_MAILBOX2)
-+#define IRQ_ARM_LOCAL_MAILBOX3   (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_MAILBOX3)
-+#define IRQ_ARM_LOCAL_GPU_FAST   (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_GPU_FAST)
-+#define IRQ_ARM_LOCAL_PMU_FAST   (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_PMU_FAST)
-+#define IRQ_ARM_LOCAL_ZERO       (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_ZERO)
-+#define IRQ_ARM_LOCAL_TIMER      (IRQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_TIMER)
-+
-+#define FIQ_START             HARD_IRQS
-+
-+/*
-+ *  FIQ interrupts definitions are the same as the INT definitions.
-+ */
-+#define FIQ_TIMER0            (FIQ_START+INTERRUPT_TIMER0)
-+#define FIQ_TIMER1            (FIQ_START+INTERRUPT_TIMER1)
-+#define FIQ_TIMER2            (FIQ_START+INTERRUPT_TIMER2)
-+#define FIQ_TIMER3            (FIQ_START+INTERRUPT_TIMER3)
-+#define FIQ_CODEC0            (FIQ_START+INTERRUPT_CODEC0)
-+#define FIQ_CODEC1            (FIQ_START+INTERRUPT_CODEC1)
-+#define FIQ_CODEC2            (FIQ_START+INTERRUPT_CODEC2)
-+#define FIQ_JPEG              (FIQ_START+INTERRUPT_JPEG)
-+#define FIQ_ISP               (FIQ_START+INTERRUPT_ISP)
-+#define FIQ_USB               (FIQ_START+INTERRUPT_USB)
-+#define FIQ_3D                (FIQ_START+INTERRUPT_3D)
-+#define FIQ_TRANSPOSER        (FIQ_START+INTERRUPT_TRANSPOSER)
-+#define FIQ_MULTICORESYNC0    (FIQ_START+INTERRUPT_MULTICORESYNC0)
-+#define FIQ_MULTICORESYNC1    (FIQ_START+INTERRUPT_MULTICORESYNC1)
-+#define FIQ_MULTICORESYNC2    (FIQ_START+INTERRUPT_MULTICORESYNC2)
-+#define FIQ_MULTICORESYNC3    (FIQ_START+INTERRUPT_MULTICORESYNC3)
-+#define FIQ_DMA0              (FIQ_START+INTERRUPT_DMA0)
-+#define FIQ_DMA1              (FIQ_START+INTERRUPT_DMA1)
-+#define FIQ_DMA2              (FIQ_START+INTERRUPT_DMA2)
-+#define FIQ_DMA3              (FIQ_START+INTERRUPT_DMA3)
-+#define FIQ_DMA4              (FIQ_START+INTERRUPT_DMA4)
-+#define FIQ_DMA5              (FIQ_START+INTERRUPT_DMA5)
-+#define FIQ_DMA6              (FIQ_START+INTERRUPT_DMA6)
-+#define FIQ_DMA7              (FIQ_START+INTERRUPT_DMA7)
-+#define FIQ_DMA8              (FIQ_START+INTERRUPT_DMA8)
-+#define FIQ_DMA9              (FIQ_START+INTERRUPT_DMA9)
-+#define FIQ_DMA10             (FIQ_START+INTERRUPT_DMA10)
-+#define FIQ_DMA11             (FIQ_START+INTERRUPT_DMA11)
-+#define FIQ_DMA12             (FIQ_START+INTERRUPT_DMA12)
-+#define FIQ_AUX               (FIQ_START+INTERRUPT_AUX)
-+#define FIQ_ARM               (FIQ_START+INTERRUPT_ARM)
-+#define FIQ_VPUDMA            (FIQ_START+INTERRUPT_VPUDMA)
-+#define FIQ_HOSTPORT          (FIQ_START+INTERRUPT_HOSTPORT)
-+#define FIQ_VIDEOSCALER       (FIQ_START+INTERRUPT_VIDEOSCALER)
-+#define FIQ_CCP2TX            (FIQ_START+INTERRUPT_CCP2TX)
-+#define FIQ_SDC               (FIQ_START+INTERRUPT_SDC)
-+#define FIQ_DSI0              (FIQ_START+INTERRUPT_DSI0)
-+#define FIQ_AVE               (FIQ_START+INTERRUPT_AVE)
-+#define FIQ_CAM0              (FIQ_START+INTERRUPT_CAM0)
-+#define FIQ_CAM1              (FIQ_START+INTERRUPT_CAM1)
-+#define FIQ_HDMI0             (FIQ_START+INTERRUPT_HDMI0)
-+#define FIQ_HDMI1             (FIQ_START+INTERRUPT_HDMI1)
-+#define FIQ_PIXELVALVE1       (FIQ_START+INTERRUPT_PIXELVALVE1)
-+#define FIQ_I2CSPISLV         (FIQ_START+INTERRUPT_I2CSPISLV)
-+#define FIQ_DSI1              (FIQ_START+INTERRUPT_DSI1)
-+#define FIQ_PWA0              (FIQ_START+INTERRUPT_PWA0)
-+#define FIQ_PWA1              (FIQ_START+INTERRUPT_PWA1)
-+#define FIQ_CPR               (FIQ_START+INTERRUPT_CPR)
-+#define FIQ_SMI               (FIQ_START+INTERRUPT_SMI)
-+#define FIQ_GPIO0             (FIQ_START+INTERRUPT_GPIO0)
-+#define FIQ_GPIO1             (FIQ_START+INTERRUPT_GPIO1)
-+#define FIQ_GPIO2             (FIQ_START+INTERRUPT_GPIO2)
-+#define FIQ_GPIO3             (FIQ_START+INTERRUPT_GPIO3)
-+#define FIQ_I2C               (FIQ_START+INTERRUPT_I2C)
-+#define FIQ_SPI               (FIQ_START+INTERRUPT_SPI)
-+#define FIQ_I2SPCM            (FIQ_START+INTERRUPT_I2SPCM)
-+#define FIQ_SDIO              (FIQ_START+INTERRUPT_SDIO)
-+#define FIQ_UART              (FIQ_START+INTERRUPT_UART)
-+#define FIQ_SLIMBUS           (FIQ_START+INTERRUPT_SLIMBUS)
-+#define FIQ_VEC               (FIQ_START+INTERRUPT_VEC)
-+#define FIQ_CPG               (FIQ_START+INTERRUPT_CPG)
-+#define FIQ_RNG               (FIQ_START+INTERRUPT_RNG)
-+#define FIQ_ARASANSDIO        (FIQ_START+INTERRUPT_ARASANSDIO)
-+#define FIQ_AVSPMON           (FIQ_START+INTERRUPT_AVSPMON)
-+
-+#define FIQ_ARM_TIMER         (FIQ_START+INTERRUPT_ARM_TIMER)
-+#define FIQ_ARM_MAILBOX       (FIQ_START+INTERRUPT_ARM_MAILBOX)
-+#define FIQ_ARM_DOORBELL_0    (FIQ_START+INTERRUPT_ARM_DOORBELL_0)
-+#define FIQ_ARM_DOORBELL_1    (FIQ_START+INTERRUPT_ARM_DOORBELL_1)
-+#define FIQ_VPU0_HALTED       (FIQ_START+INTERRUPT_VPU0_HALTED)
-+#define FIQ_VPU1_HALTED       (FIQ_START+INTERRUPT_VPU1_HALTED)
-+#define FIQ_ILLEGAL_TYPE0     (FIQ_START+INTERRUPT_ILLEGAL_TYPE0)
-+#define FIQ_ILLEGAL_TYPE1     (FIQ_START+INTERRUPT_ILLEGAL_TYPE1)
-+#define FIQ_PENDING1          (FIQ_START+INTERRUPT_PENDING1)
-+#define FIQ_PENDING2          (FIQ_START+INTERRUPT_PENDING2)
-+
-+#define FIQ_ARM_LOCAL_CNTPSIRQ   (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_CNTPSIRQ)
-+#define FIQ_ARM_LOCAL_CNTPNSIRQ  (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_CNTPNSIRQ)
-+#define FIQ_ARM_LOCAL_CNTHPIRQ   (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_CNTHPIRQ)
-+#define FIQ_ARM_LOCAL_CNTVIRQ    (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_CNTVIRQ)
-+#define FIQ_ARM_LOCAL_MAILBOX0   (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_MAILBOX0)
-+#define FIQ_ARM_LOCAL_MAILBOX1   (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_MAILBOX1)
-+#define FIQ_ARM_LOCAL_MAILBOX2   (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_MAILBOX2)
-+#define FIQ_ARM_LOCAL_MAILBOX3   (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_MAILBOX3)
-+#define FIQ_ARM_LOCAL_GPU_FAST   (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_GPU_FAST)
-+#define FIQ_ARM_LOCAL_PMU_FAST   (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_PMU_FAST)
-+#define FIQ_ARM_LOCAL_ZERO       (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_ZERO)
-+#define FIQ_ARM_LOCAL_TIMER      (FIQ_ARMCTRL_START + INTERRUPT_ARM_LOCAL_TIMER)
-+
-+#define HARD_IRQS	(128)
-+#define FIQ_IRQS	(128)
-+#define GPIO_IRQ_START	(HARD_IRQS + FIQ_IRQS)
-+#define GPIO_IRQS	(32*5)
-+#define SPARE_ALLOC_IRQS      64
-+#define BCM2708_ALLOC_IRQS    (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS)
-+#define FREE_IRQS             128
-+#define NR_IRQS               (BCM2708_ALLOC_IRQS+FREE_IRQS)
-+
-+#endif /* _BCM2708_IRQS_H_ */
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/memory.h
-@@ -0,0 +1,57 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/memory.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifndef __ASM_ARCH_MEMORY_H
-+#define __ASM_ARCH_MEMORY_H
-+
-+/* Memory overview:
-+
-+   [ARMcore] <--virtual addr-->
-+   [ARMmmu] <--physical addr-->
-+   [GERTmap] <--bus add-->
-+   [VCperiph]
-+
-+*/
-+
-+/*
-+ * Physical DRAM offset.
-+ */
-+#define BCM_PLAT_PHYS_OFFSET	UL(0x00000000)
-+#define VC_ARMMEM_OFFSET	UL(0x00000000)   /* offset in VC of ARM memory */
-+
-+#ifdef CONFIG_BCM2708_NOL2CACHE
-+ #define _REAL_BUS_OFFSET UL(0xC0000000)   /* don't use L1 or L2 caches */
-+#else
-+ #define _REAL_BUS_OFFSET UL(0x40000000)   /* use L2 cache */
-+#endif
-+
-+/* We're using the memory at 64M in the VideoCore for Linux - this adjustment
-+ * will provide the offset into this area as well as setting the bits that
-+ * stop the L1 and L2 cache from being used
-+ *
-+ * WARNING: this only works because the ARM is given memory at a fixed location
-+ *          (ARMMEM_OFFSET)
-+ */
-+#define BUS_OFFSET          (VC_ARMMEM_OFFSET + _REAL_BUS_OFFSET)
-+#define __virt_to_bus(x)    ((x) + (BUS_OFFSET - PAGE_OFFSET))
-+#define __bus_to_virt(x)    ((x) - (BUS_OFFSET - PAGE_OFFSET))
-+#define __pfn_to_bus(x)     (__pfn_to_phys(x) + (BUS_OFFSET - BCM_PLAT_PHYS_OFFSET))
-+#define __bus_to_pfn(x)     __phys_to_pfn((x) - (BUS_OFFSET - BCM_PLAT_PHYS_OFFSET))
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/platform.h
-@@ -0,0 +1,225 @@
-+/*
-+ * arch/arm/mach-bcm2708/include/mach/platform.h
-+ *
-+ * Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#ifndef _BCM2708_PLATFORM_H
-+#define _BCM2708_PLATFORM_H
-+
-+
-+/* macros to get at IO space when running virtually */
-+#define IO_ADDRESS(x)	(((x) & 0x00ffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
-+
-+#define __io_address(n)     IOMEM(IO_ADDRESS(n))
-+
-+
-+/*
-+ *  SDRAM
-+ */
-+#define BCM2708_SDRAM_BASE           0x00000000
-+
-+/*
-+ *  Logic expansion modules
-+ *
-+ */
-+
-+
-+/* ------------------------------------------------------------------------
-+ *  BCM2708 ARMCTRL Registers
-+ * ------------------------------------------------------------------------
-+ */
-+
-+#define HW_REGISTER_RW(addr) (addr)
-+#define HW_REGISTER_RO(addr) (addr)
-+
-+#include "arm_control.h"
-+#undef ARM_BASE
-+
-+/*
-+ * Definitions and addresses for the ARM CONTROL logic
-+ * This file is manually generated.
-+ */
-+
-+#define BCM2708_PERI_BASE        0x3F000000
-+#define IC0_BASE                 (BCM2708_PERI_BASE + 0x2000)
-+#define ST_BASE                  (BCM2708_PERI_BASE + 0x3000)   /* System Timer */
-+#define MPHI_BASE		 (BCM2708_PERI_BASE + 0x6000)	/* Message -based Parallel Host Interface */
-+#define DMA_BASE		 (BCM2708_PERI_BASE + 0x7000)	/* DMA controller */
-+#define ARM_BASE                 (BCM2708_PERI_BASE + 0xB000)	 /* BCM2708 ARM control block */
-+#define PM_BASE			 (BCM2708_PERI_BASE + 0x100000) /* Power Management, Reset controller and Watchdog registers */
-+#define PCM_CLOCK_BASE           (BCM2708_PERI_BASE + 0x101098) /* PCM Clock */
-+#define RNG_BASE                 (BCM2708_PERI_BASE + 0x104000) /* Hardware RNG */
-+#define GPIO_BASE                (BCM2708_PERI_BASE + 0x200000) /* GPIO */
-+#define UART0_BASE               (BCM2708_PERI_BASE + 0x201000)	/* Uart 0 */
-+#define MMCI0_BASE               (BCM2708_PERI_BASE + 0x202000) /* MMC interface */
-+#define I2S_BASE                 (BCM2708_PERI_BASE + 0x203000) /* I2S */
-+#define SPI0_BASE		 (BCM2708_PERI_BASE + 0x204000) /* SPI0 */
-+#define BSC0_BASE		 (BCM2708_PERI_BASE + 0x205000) /* BSC0 I2C/TWI */
-+#define UART1_BASE               (BCM2708_PERI_BASE + 0x215000) /* Uart 1 */
-+#define EMMC_BASE                (BCM2708_PERI_BASE + 0x300000) /* eMMC interface */
-+#define SMI_BASE		 (BCM2708_PERI_BASE + 0x600000) /* SMI */
-+#define BSC1_BASE		 (BCM2708_PERI_BASE + 0x804000) /* BSC1 I2C/TWI */
-+#define USB_BASE                 (BCM2708_PERI_BASE + 0x980000) /* DTC_OTG USB controller */
-+#define MCORE_BASE               (BCM2708_PERI_BASE + 0x0000)   /* Fake frame buffer device (actually the multicore sync block*/
-+
-+#define ARMCTRL_BASE             (ARM_BASE + 0x000)
-+#define ARMCTRL_IC_BASE          (ARM_BASE + 0x200)           /* ARM interrupt controller */
-+#define ARMCTRL_TIMER0_1_BASE    (ARM_BASE + 0x400)           /* Timer 0 and 1 */
-+#define ARMCTRL_0_SBM_BASE       (ARM_BASE + 0x800)           /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */
-+
-+
-+/*
-+ * Interrupt assignments
-+ */
-+
-+#define ARM_IRQ1_BASE                  0
-+#define INTERRUPT_TIMER0               (ARM_IRQ1_BASE + 0)
-+#define INTERRUPT_TIMER1               (ARM_IRQ1_BASE + 1)
-+#define INTERRUPT_TIMER2               (ARM_IRQ1_BASE + 2)
-+#define INTERRUPT_TIMER3               (ARM_IRQ1_BASE + 3)
-+#define INTERRUPT_CODEC0               (ARM_IRQ1_BASE + 4)
-+#define INTERRUPT_CODEC1               (ARM_IRQ1_BASE + 5)
-+#define INTERRUPT_CODEC2               (ARM_IRQ1_BASE + 6)
-+#define INTERRUPT_VC_JPEG              (ARM_IRQ1_BASE + 7)
-+#define INTERRUPT_ISP                  (ARM_IRQ1_BASE + 8)
-+#define INTERRUPT_VC_USB               (ARM_IRQ1_BASE + 9)
-+#define INTERRUPT_VC_3D                (ARM_IRQ1_BASE + 10)
-+#define INTERRUPT_TRANSPOSER           (ARM_IRQ1_BASE + 11)
-+#define INTERRUPT_MULTICORESYNC0       (ARM_IRQ1_BASE + 12)
-+#define INTERRUPT_MULTICORESYNC1       (ARM_IRQ1_BASE + 13)
-+#define INTERRUPT_MULTICORESYNC2       (ARM_IRQ1_BASE + 14)
-+#define INTERRUPT_MULTICORESYNC3       (ARM_IRQ1_BASE + 15)
-+#define INTERRUPT_DMA0                 (ARM_IRQ1_BASE + 16)
-+#define INTERRUPT_DMA1                 (ARM_IRQ1_BASE + 17)
-+#define INTERRUPT_VC_DMA2              (ARM_IRQ1_BASE + 18)
-+#define INTERRUPT_VC_DMA3              (ARM_IRQ1_BASE + 19)
-+#define INTERRUPT_DMA4                 (ARM_IRQ1_BASE + 20)
-+#define INTERRUPT_DMA5                 (ARM_IRQ1_BASE + 21)
-+#define INTERRUPT_DMA6                 (ARM_IRQ1_BASE + 22)
-+#define INTERRUPT_DMA7                 (ARM_IRQ1_BASE + 23)
-+#define INTERRUPT_DMA8                 (ARM_IRQ1_BASE + 24)
-+#define INTERRUPT_DMA9                 (ARM_IRQ1_BASE + 25)
-+#define INTERRUPT_DMA10                (ARM_IRQ1_BASE + 26)
-+#define INTERRUPT_DMA11                (ARM_IRQ1_BASE + 27)
-+#define INTERRUPT_DMA12                (ARM_IRQ1_BASE + 28)
-+#define INTERRUPT_AUX                (ARM_IRQ1_BASE + 29)
-+#define INTERRUPT_ARM                  (ARM_IRQ1_BASE + 30)
-+#define INTERRUPT_VPUDMA               (ARM_IRQ1_BASE + 31)
-+
-+#define ARM_IRQ2_BASE                  32
-+#define INTERRUPT_HOSTPORT             (ARM_IRQ2_BASE + 0)
-+#define INTERRUPT_VIDEOSCALER          (ARM_IRQ2_BASE + 1)
-+#define INTERRUPT_CCP2TX               (ARM_IRQ2_BASE + 2)
-+#define INTERRUPT_SDC                  (ARM_IRQ2_BASE + 3)
-+#define INTERRUPT_DSI0                 (ARM_IRQ2_BASE + 4)
-+#define INTERRUPT_AVE                  (ARM_IRQ2_BASE + 5)
-+#define INTERRUPT_CAM0                 (ARM_IRQ2_BASE + 6)
-+#define INTERRUPT_CAM1                 (ARM_IRQ2_BASE + 7)
-+#define INTERRUPT_HDMI0                (ARM_IRQ2_BASE + 8)
-+#define INTERRUPT_HDMI1                (ARM_IRQ2_BASE + 9)
-+#define INTERRUPT_PIXELVALVE1          (ARM_IRQ2_BASE + 10)
-+#define INTERRUPT_I2CSPISLV            (ARM_IRQ2_BASE + 11)
-+#define INTERRUPT_DSI1                 (ARM_IRQ2_BASE + 12)
-+#define INTERRUPT_PWA0                 (ARM_IRQ2_BASE + 13)
-+#define INTERRUPT_PWA1                 (ARM_IRQ2_BASE + 14)
-+#define INTERRUPT_CPR                  (ARM_IRQ2_BASE + 15)
-+#define INTERRUPT_SMI                  (ARM_IRQ2_BASE + 16)
-+#define INTERRUPT_GPIO0                (ARM_IRQ2_BASE + 17)
-+#define INTERRUPT_GPIO1                (ARM_IRQ2_BASE + 18)
-+#define INTERRUPT_GPIO2                (ARM_IRQ2_BASE + 19)
-+#define INTERRUPT_GPIO3                (ARM_IRQ2_BASE + 20)
-+#define INTERRUPT_VC_I2C               (ARM_IRQ2_BASE + 21)
-+#define INTERRUPT_VC_SPI               (ARM_IRQ2_BASE + 22)
-+#define INTERRUPT_VC_I2SPCM            (ARM_IRQ2_BASE + 23)
-+#define INTERRUPT_VC_SDIO              (ARM_IRQ2_BASE + 24)
-+#define INTERRUPT_VC_UART              (ARM_IRQ2_BASE + 25)
-+#define INTERRUPT_SLIMBUS              (ARM_IRQ2_BASE + 26)
-+#define INTERRUPT_VEC                  (ARM_IRQ2_BASE + 27)
-+#define INTERRUPT_CPG                  (ARM_IRQ2_BASE + 28)
-+#define INTERRUPT_RNG                  (ARM_IRQ2_BASE + 29)
-+#define INTERRUPT_VC_ARASANSDIO        (ARM_IRQ2_BASE + 30)
-+#define INTERRUPT_AVSPMON              (ARM_IRQ2_BASE + 31)
-+
-+#define ARM_IRQ0_BASE                  64
-+#define INTERRUPT_ARM_TIMER            (ARM_IRQ0_BASE + 0)
-+#define INTERRUPT_ARM_MAILBOX          (ARM_IRQ0_BASE + 1)
-+#define INTERRUPT_ARM_DOORBELL_0       (ARM_IRQ0_BASE + 2)
-+#define INTERRUPT_ARM_DOORBELL_1       (ARM_IRQ0_BASE + 3)
-+#define INTERRUPT_VPU0_HALTED          (ARM_IRQ0_BASE + 4)
-+#define INTERRUPT_VPU1_HALTED          (ARM_IRQ0_BASE + 5)
-+#define INTERRUPT_ILLEGAL_TYPE0        (ARM_IRQ0_BASE + 6)
-+#define INTERRUPT_ILLEGAL_TYPE1        (ARM_IRQ0_BASE + 7)
-+#define INTERRUPT_PENDING1             (ARM_IRQ0_BASE + 8)
-+#define INTERRUPT_PENDING2             (ARM_IRQ0_BASE + 9)
-+#define INTERRUPT_JPEG                 (ARM_IRQ0_BASE + 10)
-+#define INTERRUPT_USB                  (ARM_IRQ0_BASE + 11)
-+#define INTERRUPT_3D                   (ARM_IRQ0_BASE + 12)
-+#define INTERRUPT_DMA2                 (ARM_IRQ0_BASE + 13)
-+#define INTERRUPT_DMA3                 (ARM_IRQ0_BASE + 14)
-+#define INTERRUPT_I2C                  (ARM_IRQ0_BASE + 15)
-+#define INTERRUPT_SPI                  (ARM_IRQ0_BASE + 16)
-+#define INTERRUPT_I2SPCM               (ARM_IRQ0_BASE + 17)
-+#define INTERRUPT_SDIO                 (ARM_IRQ0_BASE + 18)
-+#define INTERRUPT_UART                 (ARM_IRQ0_BASE + 19)
-+#define INTERRUPT_ARASANSDIO           (ARM_IRQ0_BASE + 20)
-+
-+#define ARM_IRQ_LOCAL_BASE             96
-+#define INTERRUPT_ARM_LOCAL_CNTPSIRQ   (ARM_IRQ_LOCAL_BASE + 0)
-+#define INTERRUPT_ARM_LOCAL_CNTPNSIRQ  (ARM_IRQ_LOCAL_BASE + 1)
-+#define INTERRUPT_ARM_LOCAL_CNTHPIRQ   (ARM_IRQ_LOCAL_BASE + 2)
-+#define INTERRUPT_ARM_LOCAL_CNTVIRQ    (ARM_IRQ_LOCAL_BASE + 3)
-+#define INTERRUPT_ARM_LOCAL_MAILBOX0   (ARM_IRQ_LOCAL_BASE + 4)
-+#define INTERRUPT_ARM_LOCAL_MAILBOX1   (ARM_IRQ_LOCAL_BASE + 5)
-+#define INTERRUPT_ARM_LOCAL_MAILBOX2   (ARM_IRQ_LOCAL_BASE + 6)
-+#define INTERRUPT_ARM_LOCAL_MAILBOX3   (ARM_IRQ_LOCAL_BASE + 7)
-+#define INTERRUPT_ARM_LOCAL_GPU_FAST   (ARM_IRQ_LOCAL_BASE + 8)
-+#define INTERRUPT_ARM_LOCAL_PMU_FAST   (ARM_IRQ_LOCAL_BASE + 9)
-+#define INTERRUPT_ARM_LOCAL_ZERO       (ARM_IRQ_LOCAL_BASE + 10)
-+#define INTERRUPT_ARM_LOCAL_TIMER      (ARM_IRQ_LOCAL_BASE + 11)
-+
-+/*
-+ * Watchdog
-+ */
-+#define PM_RSTC			       (PM_BASE+0x1c)
-+#define PM_RSTS			       (PM_BASE+0x20)
-+#define PM_WDOG			       (PM_BASE+0x24)
-+
-+#define PM_WDOG_RESET                                         0000000000
-+#define PM_PASSWORD		       0x5a000000
-+#define PM_WDOG_TIME_SET	       0x000fffff
-+#define PM_RSTC_WRCFG_CLR              0xffffffcf
-+#define PM_RSTC_WRCFG_SET              0x00000030
-+#define PM_RSTC_WRCFG_FULL_RESET       0x00000020
-+#define PM_RSTC_RESET                  0x00000102
-+
-+#define PM_RSTS_HADPOR_SET                                 0x00001000
-+#define PM_RSTS_HADSRH_SET                                 0x00000400
-+#define PM_RSTS_HADSRF_SET                                 0x00000200
-+#define PM_RSTS_HADSRQ_SET                                 0x00000100
-+#define PM_RSTS_HADWRH_SET                                 0x00000040
-+#define PM_RSTS_HADWRF_SET                                 0x00000020
-+#define PM_RSTS_HADWRQ_SET                                 0x00000010
-+#define PM_RSTS_HADDRH_SET                                 0x00000004
-+#define PM_RSTS_HADDRF_SET                                 0x00000002
-+#define PM_RSTS_HADDRQ_SET                                 0x00000001
-+
-+#define UART0_CLOCK      3000000
-+
-+#endif
-+
-+/* END */
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/system.h
-@@ -0,0 +1,38 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/system.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *  Copyright (C) 2003 ARM Limited
-+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#ifndef __ASM_ARCH_SYSTEM_H
-+#define __ASM_ARCH_SYSTEM_H
-+
-+#include <linux/io.h>
-+#include <mach/hardware.h>
-+#include <mach/platform.h>
-+
-+static inline void arch_idle(void)
-+{
-+	/*
-+	 * This should do all the clock switching
-+	 * and wait for interrupt tricks
-+	 */
-+	cpu_do_idle();
-+}
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/timex.h
-@@ -0,0 +1,23 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/timex.h
-+ *
-+ *  BCM2708 sysem clock frequency
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+
-+#define CLOCK_TICK_RATE		(1000000)
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/uncompress.h
-@@ -0,0 +1,84 @@
-+/*
-+ *  arch/arm/mach-bcn2708/include/mach/uncompress.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *  Copyright (C) 2003 ARM Limited
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT 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/io.h>
-+#include <linux/amba/serial.h>
-+#include <mach/hardware.h>
-+
-+#define UART_BAUD 115200
-+
-+#define BCM2708_UART_DR   __io(UART0_BASE + UART01x_DR)
-+#define BCM2708_UART_FR   __io(UART0_BASE + UART01x_FR)
-+#define BCM2708_UART_IBRD __io(UART0_BASE + UART011_IBRD)
-+#define BCM2708_UART_FBRD __io(UART0_BASE + UART011_FBRD)
-+#define BCM2708_UART_LCRH __io(UART0_BASE + UART011_LCRH)
-+#define BCM2708_UART_CR   __io(UART0_BASE + UART011_CR)
-+
-+/*
-+ * This does not append a newline
-+ */
-+static inline void putc(int c)
-+{
-+	while (__raw_readl(BCM2708_UART_FR) & UART01x_FR_TXFF)
-+		barrier();
-+
-+	__raw_writel(c, BCM2708_UART_DR);
-+}
-+
-+static inline void flush(void)
-+{
-+	int fr;
-+
-+	do {
-+		fr = __raw_readl(BCM2708_UART_FR);
-+		barrier();
-+	} while ((fr & (UART011_FR_TXFE | UART01x_FR_BUSY)) != UART011_FR_TXFE);
-+}
-+
-+static inline void arch_decomp_setup(void)
-+{
-+	int temp, div, rem, frac;
-+
-+	temp = 16 * UART_BAUD;
-+	div = UART0_CLOCK / temp;
-+	rem = UART0_CLOCK % temp;
-+	temp = (8 * rem) / UART_BAUD;
-+	frac = (temp >> 1) + (temp & 1);
-+
-+	/* Make sure the UART is disabled before we start */
-+	__raw_writel(0, BCM2708_UART_CR);
-+
-+	/* Set the baud rate */
-+	__raw_writel(div, BCM2708_UART_IBRD);
-+	__raw_writel(frac, BCM2708_UART_FBRD);
-+
-+	/* Set the UART to 8n1, FIFO enabled */
-+	__raw_writel(UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN, BCM2708_UART_LCRH);
-+
-+	/* Enable the UART */
-+	__raw_writel(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE,
-+			BCM2708_UART_CR);
-+}
-+
-+/*
-+ * nothing to do
-+ */
-+#define arch_decomp_wdog()
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/vc_mem.h
-@@ -0,0 +1,35 @@
-+/*****************************************************************************
-+* Copyright 2010 - 2011 Broadcom Corporation.  All rights reserved.
-+*
-+* Unless you and Broadcom execute a separate written software license
-+* agreement governing use of this software, this software is licensed to you
-+* under the terms of the GNU General Public License version 2, available at
-+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-+*
-+* Notwithstanding the above, under no circumstances may you combine this
-+* software in any way with any other Broadcom software provided under a
-+* license other than the GPL, without Broadcom's express prior written
-+* consent.
-+*****************************************************************************/
-+
-+#if !defined( VC_MEM_H )
-+#define VC_MEM_H
-+
-+#include <linux/ioctl.h>
-+
-+#define VC_MEM_IOC_MAGIC  'v'
-+
-+#define VC_MEM_IOC_MEM_PHYS_ADDR    _IOR( VC_MEM_IOC_MAGIC, 0, unsigned long )
-+#define VC_MEM_IOC_MEM_SIZE         _IOR( VC_MEM_IOC_MAGIC, 1, unsigned int )
-+#define VC_MEM_IOC_MEM_BASE         _IOR( VC_MEM_IOC_MAGIC, 2, unsigned int )
-+#define VC_MEM_IOC_MEM_LOAD         _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int )
-+
-+#if defined( __KERNEL__ )
-+#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF
-+
-+extern unsigned long mm_vc_mem_phys_addr;
-+extern unsigned int  mm_vc_mem_size;
-+extern int vc_mem_get_current_size( void );
-+#endif
-+
-+#endif  /* VC_MEM_H */
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/vc_support.h
-@@ -0,0 +1,69 @@
-+#ifndef _VC_SUPPORT_H_
-+#define _VC_SUPPORT_H_
-+
-+/*
-+ * vc_support.h
-+ *
-+ *  Created on: 25 Nov 2012
-+ *      Author: Simon
-+ */
-+
-+enum {
-+/*
-+      If a MEM_HANDLE_T is discardable, the memory manager may resize it to size
-+      0 at any time when it is not locked or retained.
-+   */
-+   MEM_FLAG_DISCARDABLE = 1 << 0,
-+
-+   /*
-+      If a MEM_HANDLE_T is allocating (or normal), its block of memory will be
-+      accessed in an allocating fashion through the cache.
-+   */
-+   MEM_FLAG_NORMAL = 0 << 2,
-+   MEM_FLAG_ALLOCATING = MEM_FLAG_NORMAL,
-+
-+   /*
-+      If a MEM_HANDLE_T is direct, its block of memory will be accessed
-+      directly, bypassing the cache.
-+   */
-+   MEM_FLAG_DIRECT = 1 << 2,
-+
-+   /*
-+      If a MEM_HANDLE_T is coherent, its block of memory will be accessed in a
-+      non-allocating fashion through the cache.
-+   */
-+   MEM_FLAG_COHERENT = 2 << 2,
-+
-+   /*
-+      If a MEM_HANDLE_T is L1-nonallocating, its block of memory will be accessed by
-+      the VPU in a fashion which is allocating in L2, but only coherent in L1.
-+   */
-+   MEM_FLAG_L1_NONALLOCATING = (MEM_FLAG_DIRECT | MEM_FLAG_COHERENT),
-+
-+   /*
-+      If a MEM_HANDLE_T is zero'd, its contents are set to 0 rather than
-+      MEM_HANDLE_INVALID on allocation and resize up.
-+   */
-+   MEM_FLAG_ZERO = 1 << 4,
-+
-+   /*
-+      If a MEM_HANDLE_T is uninitialised, it will not be reset to a defined value
-+      (either zero, or all 1's) on allocation.
-+    */
-+   MEM_FLAG_NO_INIT = 1 << 5,
-+
-+   /*
-+      Hints.
-+   */
-+   MEM_FLAG_HINT_PERMALOCK = 1 << 6, /* Likely to be locked for long periods of time. */
-+};
-+
-+unsigned int AllocateVcMemory(unsigned int *pHandle, unsigned int size, unsigned int alignment, unsigned int flags);
-+unsigned int ReleaseVcMemory(unsigned int handle);
-+unsigned int LockVcMemory(unsigned int *pBusAddress, unsigned int handle);
-+unsigned int UnlockVcMemory(unsigned int handle);
-+
-+unsigned int ExecuteVcCode(unsigned int code,
-+		unsigned int r0, unsigned int r1, unsigned int r2, unsigned int r3, unsigned int r4, unsigned int r5);
-+
-+#endif
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/include/mach/vmalloc.h
-@@ -0,0 +1,20 @@
-+/*
-+ *  arch/arm/mach-bcm2708/include/mach/vmalloc.h
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ */
-+#define VMALLOC_END		(0xff000000)
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/vc_mem.c
-@@ -0,0 +1,431 @@
-+/*****************************************************************************
-+* Copyright 2010 - 2011 Broadcom Corporation.  All rights reserved.
-+*
-+* Unless you and Broadcom execute a separate written software license
-+* agreement governing use of this software, this software is licensed to you
-+* under the terms of the GNU General Public License version 2, available at
-+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-+*
-+* Notwithstanding the above, under no circumstances may you combine this
-+* software in any way with any other Broadcom software provided under a
-+* license other than the GPL, without Broadcom's express prior written
-+* consent.
-+*****************************************************************************/
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/device.h>
-+#include <linux/cdev.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/debugfs.h>
-+#include <asm/uaccess.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/platform_data/mailbox-bcm2708.h>
-+
-+#ifdef CONFIG_ARCH_KONA
-+#include <chal/chal_ipc.h>
-+#elif defined(CONFIG_ARCH_BCM2708) || defined(CONFIG_ARCH_BCM2709)
-+#else
-+#include <csp/chal_ipc.h>
-+#endif
-+
-+#include "mach/vc_mem.h"
-+
-+#define DRIVER_NAME  "vc-mem"
-+
-+// Device (/dev) related variables
-+static dev_t vc_mem_devnum = 0;
-+static struct class *vc_mem_class = NULL;
-+static struct cdev vc_mem_cdev;
-+static int vc_mem_inited = 0;
-+
-+#ifdef CONFIG_DEBUG_FS
-+static struct dentry *vc_mem_debugfs_entry;
-+#endif
-+
-+/*
-+ * Videocore memory addresses and size
-+ *
-+ * Drivers that wish to know the videocore memory addresses and sizes should
-+ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in
-+ * headers. This allows the other drivers to not be tied down to a a certain
-+ * address/size at compile time.
-+ *
-+ * In the future, the goal is to have the videocore memory virtual address and
-+ * size be calculated at boot time rather than at compile time. The decision of
-+ * where the videocore memory resides and its size would be in the hands of the
-+ * bootloader (and/or kernel). When that happens, the values of these variables
-+ * would be calculated and assigned in the init function.
-+ */
-+// in the 2835 VC in mapped above ARM, but ARM has full access to VC space
-+unsigned long mm_vc_mem_phys_addr = 0x00000000;
-+unsigned int mm_vc_mem_size = 0;
-+unsigned int mm_vc_mem_base = 0;
-+
-+EXPORT_SYMBOL(mm_vc_mem_phys_addr);
-+EXPORT_SYMBOL(mm_vc_mem_size);
-+EXPORT_SYMBOL(mm_vc_mem_base);
-+
-+static uint phys_addr = 0;
-+static uint mem_size = 0;
-+static uint mem_base = 0;
-+
-+
-+/****************************************************************************
-+*
-+*   vc_mem_open
-+*
-+***************************************************************************/
-+
-+static int
-+vc_mem_open(struct inode *inode, struct file *file)
-+{
-+	(void) inode;
-+	(void) file;
-+
-+	pr_debug("%s: called file = 0x%p\n", __func__, file);
-+
-+	return 0;
-+}
-+
-+/****************************************************************************
-+*
-+*   vc_mem_release
-+*
-+***************************************************************************/
-+
-+static int
-+vc_mem_release(struct inode *inode, struct file *file)
-+{
-+	(void) inode;
-+	(void) file;
-+
-+	pr_debug("%s: called file = 0x%p\n", __func__, file);
-+
-+	return 0;
-+}
-+
-+/****************************************************************************
-+*
-+*   vc_mem_get_size
-+*
-+***************************************************************************/
-+
-+static void
-+vc_mem_get_size(void)
-+{
-+}
-+
-+/****************************************************************************
-+*
-+*   vc_mem_get_base
-+*
-+***************************************************************************/
-+
-+static void
-+vc_mem_get_base(void)
-+{
-+}
-+
-+/****************************************************************************
-+*
-+*   vc_mem_get_current_size
-+*
-+***************************************************************************/
-+
-+int
-+vc_mem_get_current_size(void)
-+{
-+	return mm_vc_mem_size;
-+}
-+
-+EXPORT_SYMBOL_GPL(vc_mem_get_current_size);
-+
-+/****************************************************************************
-+*
-+*   vc_mem_ioctl
-+*
-+***************************************************************************/
-+
-+static long
-+vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+	int rc = 0;
-+
-+	(void) cmd;
-+	(void) arg;
-+
-+	pr_debug("%s: called file = 0x%p\n", __func__, file);
-+
-+	switch (cmd) {
-+	case VC_MEM_IOC_MEM_PHYS_ADDR:
-+		{
-+			pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n",
-+				__func__, (void *) mm_vc_mem_phys_addr);
-+
-+			if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr,
-+					 sizeof (mm_vc_mem_phys_addr)) != 0) {
-+				rc = -EFAULT;
-+			}
-+			break;
-+		}
-+	case VC_MEM_IOC_MEM_SIZE:
-+		{
-+			// Get the videocore memory size first
-+			vc_mem_get_size();
-+
-+			pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__,
-+				mm_vc_mem_size);
-+
-+			if (copy_to_user((void *) arg, &mm_vc_mem_size,
-+					 sizeof (mm_vc_mem_size)) != 0) {
-+				rc = -EFAULT;
-+			}
-+			break;
-+		}
-+	case VC_MEM_IOC_MEM_BASE:
-+		{
-+			// Get the videocore memory base
-+			vc_mem_get_base();
-+
-+			pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__,
-+				mm_vc_mem_base);
-+
-+			if (copy_to_user((void *) arg, &mm_vc_mem_base,
-+					 sizeof (mm_vc_mem_base)) != 0) {
-+				rc = -EFAULT;
-+			}
-+			break;
-+		}
-+	case VC_MEM_IOC_MEM_LOAD:
-+		{
-+			// Get the videocore memory base
-+			vc_mem_get_base();
-+
-+			pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __func__,
-+				mm_vc_mem_base);
-+
-+			if (copy_to_user((void *) arg, &mm_vc_mem_base,
-+					 sizeof (mm_vc_mem_base)) != 0) {
-+				rc = -EFAULT;
-+			}
-+			break;
-+		}
-+	default:
-+		{
-+			return -ENOTTY;
-+		}
-+	}
-+	pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc);
-+
-+	return rc;
-+}
-+
-+/****************************************************************************
-+*
-+*   vc_mem_mmap
-+*
-+***************************************************************************/
-+
-+static int
-+vc_mem_mmap(struct file *filp, struct vm_area_struct *vma)
-+{
-+	int rc = 0;
-+	unsigned long length = vma->vm_end - vma->vm_start;
-+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-+
-+	pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n",
-+		__func__, (long) vma->vm_start, (long) vma->vm_end,
-+		(long) vma->vm_pgoff);
-+
-+	if (offset + length > mm_vc_mem_size) {
-+		pr_err("%s: length %ld is too big\n", __func__, length);
-+		return -EINVAL;
-+	}
-+	// Do not cache the memory map
-+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-+
-+	rc = remap_pfn_range(vma, vma->vm_start,
-+			     (mm_vc_mem_phys_addr >> PAGE_SHIFT) +
-+			     vma->vm_pgoff, length, vma->vm_page_prot);
-+	if (rc != 0) {
-+		pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc);
-+	}
-+
-+	return rc;
-+}
-+
-+/****************************************************************************
-+*
-+*   File Operations for the driver.
-+*
-+***************************************************************************/
-+
-+static const struct file_operations vc_mem_fops = {
-+	.owner = THIS_MODULE,
-+	.open = vc_mem_open,
-+	.release = vc_mem_release,
-+	.unlocked_ioctl = vc_mem_ioctl,
-+	.mmap = vc_mem_mmap,
-+};
-+
-+#ifdef CONFIG_DEBUG_FS
-+static void vc_mem_debugfs_deinit(void)
-+{
-+	debugfs_remove_recursive(vc_mem_debugfs_entry);
-+	vc_mem_debugfs_entry = NULL;
-+}
-+
-+
-+static int vc_mem_debugfs_init(
-+	struct device *dev)
-+{
-+	vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL);
-+	if (!vc_mem_debugfs_entry) {
-+		dev_warn(dev, "could not create debugfs entry\n");
-+		return -EFAULT;
-+	}
-+
-+	if (!debugfs_create_x32("vc_mem_phys_addr",
-+				0444,
-+				vc_mem_debugfs_entry,
-+				(u32 *)&mm_vc_mem_phys_addr)) {
-+		dev_warn(dev, "%s:could not create vc_mem_phys entry\n",
-+			__func__);
-+		goto fail;
-+	}
-+
-+	if (!debugfs_create_x32("vc_mem_size",
-+				0444,
-+				vc_mem_debugfs_entry,
-+				(u32 *)&mm_vc_mem_size)) {
-+		dev_warn(dev, "%s:could not create vc_mem_size entry\n",
-+			__func__);
-+		goto fail;
-+	}
-+
-+	if (!debugfs_create_x32("vc_mem_base",
-+				0444,
-+				vc_mem_debugfs_entry,
-+				(u32 *)&mm_vc_mem_base)) {
-+		dev_warn(dev, "%s:could not create vc_mem_base entry\n",
-+			 __func__);
-+		goto fail;
-+	}
-+
-+	return 0;
-+
-+fail:
-+	vc_mem_debugfs_deinit();
-+	return -EFAULT;
-+}
-+
-+#endif /* CONFIG_DEBUG_FS */
-+
-+
-+/****************************************************************************
-+*
-+*   vc_mem_init
-+*
-+***************************************************************************/
-+
-+static int __init
-+vc_mem_init(void)
-+{
-+	int rc = -EFAULT;
-+	struct device *dev;
-+
-+	pr_debug("%s: called\n", __func__);
-+
-+	mm_vc_mem_phys_addr = phys_addr;
-+	mm_vc_mem_size = mem_size;
-+	mm_vc_mem_base = mem_base;
-+
-+	vc_mem_get_size();
-+
-+	pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n",
-+		mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024));
-+
-+	if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) {
-+		pr_err("%s: alloc_chrdev_region failed (rc=%d)\n",
-+		       __func__, rc);
-+		goto out_err;
-+	}
-+
-+	cdev_init(&vc_mem_cdev, &vc_mem_fops);
-+	if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) {
-+		pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc);
-+		goto out_unregister;
-+	}
-+
-+	vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME);
-+	if (IS_ERR(vc_mem_class)) {
-+		rc = PTR_ERR(vc_mem_class);
-+		pr_err("%s: class_create failed (rc=%d)\n", __func__, rc);
-+		goto out_cdev_del;
-+	}
-+
-+	dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL,
-+			    DRIVER_NAME);
-+	if (IS_ERR(dev)) {
-+		rc = PTR_ERR(dev);
-+		pr_err("%s: device_create failed (rc=%d)\n", __func__, rc);
-+		goto out_class_destroy;
-+	}
-+
-+#ifdef CONFIG_DEBUG_FS
-+	/* don't fail if the debug entries cannot be created */
-+	vc_mem_debugfs_init(dev);
-+#endif
-+
-+	vc_mem_inited = 1;
-+	return 0;
-+
-+	device_destroy(vc_mem_class, vc_mem_devnum);
-+
-+      out_class_destroy:
-+	class_destroy(vc_mem_class);
-+	vc_mem_class = NULL;
-+
-+      out_cdev_del:
-+	cdev_del(&vc_mem_cdev);
-+
-+      out_unregister:
-+	unregister_chrdev_region(vc_mem_devnum, 1);
-+
-+      out_err:
-+	return -1;
-+}
-+
-+/****************************************************************************
-+*
-+*   vc_mem_exit
-+*
-+***************************************************************************/
-+
-+static void __exit
-+vc_mem_exit(void)
-+{
-+	pr_debug("%s: called\n", __func__);
-+
-+	if (vc_mem_inited) {
-+#if CONFIG_DEBUG_FS
-+		vc_mem_debugfs_deinit();
-+#endif
-+		device_destroy(vc_mem_class, vc_mem_devnum);
-+		class_destroy(vc_mem_class);
-+		cdev_del(&vc_mem_cdev);
-+		unregister_chrdev_region(vc_mem_devnum, 1);
-+	}
-+}
-+
-+module_init(vc_mem_init);
-+module_exit(vc_mem_exit);
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Broadcom Corporation");
-+
-+module_param(phys_addr, uint, 0644);
-+module_param(mem_size, uint, 0644);
-+module_param(mem_base, uint, 0644);
---- /dev/null
-+++ b/arch/arm/mach-bcm2709/vc_support.c
-@@ -0,0 +1,318 @@
-+/*
-+ * vc_support.c
-+ *
-+ *  Created on: 25 Nov 2012
-+ *      Author: Simon
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/platform_data/mailbox-bcm2708.h>
-+
-+#ifdef ECLIPSE_IGNORE
-+
-+#define __user
-+#define __init
-+#define __exit
-+#define __iomem
-+#define KERN_DEBUG
-+#define KERN_ERR
-+#define KERN_WARNING
-+#define KERN_INFO
-+#define _IOWR(a, b, c) b
-+#define _IOW(a, b, c) b
-+#define _IO(a, b) b
-+
-+#endif
-+
-+/****** VC MAILBOX FUNCTIONALITY ******/
-+unsigned int AllocateVcMemory(unsigned int *pHandle, unsigned int size, unsigned int alignment, unsigned int flags)
-+{
-+	struct vc_msg
-+	{
-+		unsigned int m_msgSize;
-+		unsigned int m_response;
-+
-+		struct vc_tag
-+		{
-+			unsigned int m_tagId;
-+			unsigned int m_sendBufferSize;
-+			union {
-+				unsigned int m_sendDataSize;
-+				unsigned int m_recvDataSize;
-+			};
-+
-+			struct args
-+			{
-+				union {
-+					unsigned int m_size;
-+					unsigned int m_handle;
-+				};
-+				unsigned int m_alignment;
-+				unsigned int m_flags;
-+			} m_args;
-+		} m_tag;
-+
-+		unsigned int m_endTag;
-+	} msg;
-+	int s;
-+
-+	msg.m_msgSize = sizeof(msg);
-+	msg.m_response = 0;
-+	msg.m_endTag = 0;
-+
-+	//fill in the tag for the allocation command
-+	msg.m_tag.m_tagId = 0x3000c;
-+	msg.m_tag.m_sendBufferSize = 12;
-+	msg.m_tag.m_sendDataSize = 12;
-+
-+	//fill in our args
-+	msg.m_tag.m_args.m_size = size;
-+	msg.m_tag.m_args.m_alignment = alignment;
-+	msg.m_tag.m_args.m_flags = flags;
-+
-+	//run the command
-+	s = bcm_mailbox_property(&msg, sizeof(msg));
-+
-+	if (s == 0 && msg.m_response == 0x80000000 && msg.m_tag.m_recvDataSize == 0x80000004)
-+	{
-+		*pHandle = msg.m_tag.m_args.m_handle;
-+		return 0;
-+	}
-+	else
-+	{
-+		printk(KERN_ERR "failed to allocate vc memory: s=%d response=%08x recv data size=%08x\n",
-+				s, msg.m_response, msg.m_tag.m_recvDataSize);
-+		return 1;
-+	}
-+}
-+
-+unsigned int ReleaseVcMemory(unsigned int handle)
-+{
-+	struct vc_msg
-+	{
-+		unsigned int m_msgSize;
-+		unsigned int m_response;
-+
-+		struct vc_tag
-+		{
-+			unsigned int m_tagId;
-+			unsigned int m_sendBufferSize;
-+			union {
-+				unsigned int m_sendDataSize;
-+				unsigned int m_recvDataSize;
-+			};
-+
-+			struct args
-+			{
-+				union {
-+					unsigned int m_handle;
-+					unsigned int m_error;
-+				};
-+			} m_args;
-+		} m_tag;
-+
-+		unsigned int m_endTag;
-+	} msg;
-+	int s;
-+
-+	msg.m_msgSize = sizeof(msg);
-+	msg.m_response = 0;
-+	msg.m_endTag = 0;
-+
-+	//fill in the tag for the release command
-+	msg.m_tag.m_tagId = 0x3000f;
-+	msg.m_tag.m_sendBufferSize = 4;
-+	msg.m_tag.m_sendDataSize = 4;
-+
-+	//pass across the handle
-+	msg.m_tag.m_args.m_handle = handle;
-+
-+	s = bcm_mailbox_property(&msg, sizeof(msg));
-+
-+	if (s == 0 && msg.m_response == 0x80000000 && msg.m_tag.m_recvDataSize == 0x80000004 && msg.m_tag.m_args.m_error == 0)
-+		return 0;
-+	else
-+	{
-+		printk(KERN_ERR "failed to release vc memory: s=%d response=%08x recv data size=%08x error=%08x\n",
-+				s, msg.m_response, msg.m_tag.m_recvDataSize, msg.m_tag.m_args.m_error);
-+		return 1;
-+	}
-+}
-+
-+unsigned int LockVcMemory(unsigned int *pBusAddress, unsigned int handle)
-+{
-+	struct vc_msg
-+	{
-+		unsigned int m_msgSize;
-+		unsigned int m_response;
-+
-+		struct vc_tag
-+		{
-+			unsigned int m_tagId;
-+			unsigned int m_sendBufferSize;
-+			union {
-+				unsigned int m_sendDataSize;
-+				unsigned int m_recvDataSize;
-+			};
-+
-+			struct args
-+			{
-+				union {
-+					unsigned int m_handle;
-+					unsigned int m_busAddress;
-+				};
-+			} m_args;
-+		} m_tag;
-+
-+		unsigned int m_endTag;
-+	} msg;
-+	int s;
-+
-+	msg.m_msgSize = sizeof(msg);
-+	msg.m_response = 0;
-+	msg.m_endTag = 0;
-+
-+	//fill in the tag for the lock command
-+	msg.m_tag.m_tagId = 0x3000d;
-+	msg.m_tag.m_sendBufferSize = 4;
-+	msg.m_tag.m_sendDataSize = 4;
-+
-+	//pass across the handle
-+	msg.m_tag.m_args.m_handle = handle;
-+
-+	s = bcm_mailbox_property(&msg, sizeof(msg));
-+
-+	if (s == 0 && msg.m_response == 0x80000000 && msg.m_tag.m_recvDataSize == 0x80000004)
-+	{
-+		//pick out the bus address
-+		*pBusAddress = msg.m_tag.m_args.m_busAddress;
-+		return 0;
-+	}
-+	else
-+	{
-+		printk(KERN_ERR "failed to lock vc memory: s=%d response=%08x recv data size=%08x\n",
-+				s, msg.m_response, msg.m_tag.m_recvDataSize);
-+		return 1;
-+	}
-+}
-+
-+unsigned int UnlockVcMemory(unsigned int handle)
-+{
-+	struct vc_msg
-+	{
-+		unsigned int m_msgSize;
-+		unsigned int m_response;
-+
-+		struct vc_tag
-+		{
-+			unsigned int m_tagId;
-+			unsigned int m_sendBufferSize;
-+			union {
-+				unsigned int m_sendDataSize;
-+				unsigned int m_recvDataSize;
-+			};
-+
-+			struct args
-+			{
-+				union {
-+					unsigned int m_handle;
-+					unsigned int m_error;
-+				};
-+			} m_args;
-+		} m_tag;
-+
-+		unsigned int m_endTag;
-+	} msg;
-+	int s;
-+
-+	msg.m_msgSize = sizeof(msg);
-+	msg.m_response = 0;
-+	msg.m_endTag = 0;
-+
-+	//fill in the tag for the unlock command
-+	msg.m_tag.m_tagId = 0x3000e;
-+	msg.m_tag.m_sendBufferSize = 4;
-+	msg.m_tag.m_sendDataSize = 4;
-+
-+	//pass across the handle
-+	msg.m_tag.m_args.m_handle = handle;
-+
-+	s = bcm_mailbox_property(&msg, sizeof(msg));
-+
-+	//check the error code too
-+	if (s == 0 && msg.m_response == 0x80000000 && msg.m_tag.m_recvDataSize == 0x80000004 && msg.m_tag.m_args.m_error == 0)
-+		return 0;
-+	else
-+	{
-+		printk(KERN_ERR "failed to unlock vc memory: s=%d response=%08x recv data size=%08x error%08x\n",
-+				s, msg.m_response, msg.m_tag.m_recvDataSize, msg.m_tag.m_args.m_error);
-+		return 1;
-+	}
-+}
-+
-+unsigned int ExecuteVcCode(unsigned int code,
-+		unsigned int r0, unsigned int r1, unsigned int r2, unsigned int r3, unsigned int r4, unsigned int r5)
-+{
-+	struct vc_msg
-+	{
-+		unsigned int m_msgSize;
-+		unsigned int m_response;
-+
-+		struct vc_tag
-+		{
-+			unsigned int m_tagId;
-+			unsigned int m_sendBufferSize;
-+			union {
-+				unsigned int m_sendDataSize;
-+				unsigned int m_recvDataSize;
-+			};
-+
-+			struct args
-+			{
-+				union {
-+					unsigned int m_pCode;
-+					unsigned int m_return;
-+				};
-+				unsigned int m_r0;
-+				unsigned int m_r1;
-+				unsigned int m_r2;
-+				unsigned int m_r3;
-+				unsigned int m_r4;
-+				unsigned int m_r5;
-+			} m_args;
-+		} m_tag;
-+
-+		unsigned int m_endTag;
-+	} msg;
-+	int s;
-+
-+	msg.m_msgSize = sizeof(msg);
-+	msg.m_response = 0;
-+	msg.m_endTag = 0;
-+
-+	//fill in the tag for the unlock command
-+	msg.m_tag.m_tagId = 0x30010;
-+	msg.m_tag.m_sendBufferSize = 28;
-+	msg.m_tag.m_sendDataSize = 28;
-+
-+	//pass across the handle
-+	msg.m_tag.m_args.m_pCode = code;
-+	msg.m_tag.m_args.m_r0 = r0;
-+	msg.m_tag.m_args.m_r1 = r1;
-+	msg.m_tag.m_args.m_r2 = r2;
-+	msg.m_tag.m_args.m_r3 = r3;
-+	msg.m_tag.m_args.m_r4 = r4;
-+	msg.m_tag.m_args.m_r5 = r5;
-+
-+	s = bcm_mailbox_property(&msg, sizeof(msg));
-+
-+	//check the error code too
-+	if (s == 0 && msg.m_response == 0x80000000 && msg.m_tag.m_recvDataSize == 0x80000004)
-+		return msg.m_tag.m_args.m_return;
-+	else
-+	{
-+		printk(KERN_ERR "failed to execute: s=%d response=%08x recv data size=%08x\n",
-+				s, msg.m_response, msg.m_tag.m_recvDataSize);
-+		return 1;
-+	}
-+}
---- a/arch/arm/mm/Kconfig
-+++ b/arch/arm/mm/Kconfig
-@@ -358,7 +358,7 @@ config CPU_PJ4B
- 
- # ARMv6
- config CPU_V6
--	bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX)
-+	bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708)
- 	select CPU_32v6
- 	select CPU_ABRT_EV6
- 	select CPU_CACHE_V6
---- a/arch/arm/mm/proc-v6.S
-+++ b/arch/arm/mm/proc-v6.S
-@@ -73,10 +73,19 @@ ENDPROC(cpu_v6_reset)
-  *
-  *	IRQs are already disabled.
-  */
-+
-+/* See jira SW-5991 for details of this workaround */
- ENTRY(cpu_v6_do_idle)
--	mov	r1, #0
--	mcr	p15, 0, r1, c7, c10, 4		@ DWB - WFI may enter a low-power mode
--	mcr	p15, 0, r1, c7, c0, 4		@ wait for interrupt
-+	.align 5
-+	mov     r1, #2
-+1:	subs	r1, #1
-+	nop
-+	mcreq	p15, 0, r1, c7, c10, 4		@ DWB - WFI may enter a low-power mode
-+	mcreq	p15, 0, r1, c7, c0, 4		@ wait for interrupt
-+	nop
-+	nop
-+	nop
-+	bne 1b
- 	ret	lr
- 
- ENTRY(cpu_v6_dcache_clean_area)
---- a/arch/arm/mm/proc-v7.S
-+++ b/arch/arm/mm/proc-v7.S
-@@ -460,6 +460,7 @@ __v7_setup_cont:
- 	orr	r0, r0, r6			@ set them
-  THUMB(	orr	r0, r0, #1 << 30	)	@ Thumb exceptions
- 	ret	lr				@ return to head.S:__ret
-+        .space 256
- ENDPROC(__v7_setup)
- 
- 	.align	2
---- a/arch/arm/tools/mach-types
-+++ b/arch/arm/tools/mach-types
-@@ -522,6 +522,8 @@ torbreck		MACH_TORBRECK		TORBRECK		3090
- prima2_evb		MACH_PRIMA2_EVB		PRIMA2_EVB		3103
- paz00			MACH_PAZ00		PAZ00			3128
- acmenetusfoxg20		MACH_ACMENETUSFOXG20	ACMENETUSFOXG20		3129
-+bcm2708			MACH_BCM2708		BCM2708			3138
-+bcm2709			MACH_BCM2709		BCM2709			3139
- ag5evm			MACH_AG5EVM		AG5EVM			3189
- ics_if_voip		MACH_ICS_IF_VOIP	ICS_IF_VOIP		3206
- wlf_cragg_6410		MACH_WLF_CRAGG_6410	WLF_CRAGG_6410		3207
---- a/drivers/clocksource/arm_arch_timer.c
-+++ b/drivers/clocksource/arm_arch_timer.c
-@@ -882,3 +882,39 @@ void __init acpi_generic_timer_init(void
- 	acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init);
- }
- #endif
-+
-+int __init dc4_arch_timer_init(void)
-+{
-+	if (arch_timers_present & ARCH_CP15_TIMER) {
-+		pr_warn("arch_timer: multiple nodes in dt, skipping\n");
-+		return -1;
-+	}
-+
-+	arch_timers_present |= ARCH_CP15_TIMER;
-+
-+	/* Try to determine the frequency from the device tree or CNTFRQ */
-+	arch_timer_rate = 19200000;
-+
-+	arch_timer_ppi[PHYS_SECURE_PPI]    = IRQ_ARM_LOCAL_CNTPSIRQ;
-+	arch_timer_ppi[PHYS_NONSECURE_PPI] = IRQ_ARM_LOCAL_CNTPNSIRQ;
-+	arch_timer_ppi[VIRT_PPI]           = IRQ_ARM_LOCAL_CNTVIRQ;
-+	arch_timer_ppi[HYP_PPI]            = IRQ_ARM_LOCAL_CNTHPIRQ;
-+
-+	/*
-+	 * If HYP mode is available, we know that the physical timer
-+	 * has been configured to be accessible from PL1. Use it, so
-+	 * that a guest can use the virtual timer instead.
-+	 *
-+	 * If no interrupt provided for virtual timer, we'll have to
-+	 * stick to the physical timer. It'd better be accessible...
-+	 */
-+	if (is_hyp_mode_available() || !arch_timer_ppi[VIRT_PPI]) {
-+		arch_timer_use_virtual = false;
-+	}
-+
-+	arch_timer_c3stop = 0;
-+
-+	arch_timer_register();
-+	arch_timer_common_init();
-+	return 0;
-+}
---- a/drivers/tty/serial/amba-pl011.c
-+++ b/drivers/tty/serial/amba-pl011.c
-@@ -85,7 +85,7 @@ struct vendor_data {
- 
- static unsigned int get_fifosize_arm(struct amba_device *dev)
- {
--	return amba_rev(dev) < 3 ? 16 : 32;
-+	return 16; //TODO: fix: amba_rev(dev) < 3 ? 16 : 32;
- }
- 
- static struct vendor_data vendor_arm = {
---- a/include/linux/mmc/host.h
-+++ b/include/linux/mmc/host.h
-@@ -285,6 +285,7 @@ struct mmc_host {
- 				 MMC_CAP2_HS400_1_2V)
- #define MMC_CAP2_HSX00_1_2V	(MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V)
- #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17)
-+#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31)	/* Always use multiblock transfers */
- 
- 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
- 
diff --git a/target/linux/brcm2708/patches-4.1/0002-Add-bcm2708_gpio-driver.patch b/target/linux/brcm2708/patches-4.1/0002-Add-bcm2708_gpio-driver.patch
deleted file mode 100644
index a735798..0000000
--- a/target/linux/brcm2708/patches-4.1/0002-Add-bcm2708_gpio-driver.patch
+++ /dev/null
@@ -1,615 +0,0 @@
-From c7eee1285590f15010feaf91970b9e3447e757f4 Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix at gmail.com>
-Date: Wed, 8 Oct 2014 18:50:05 +0100
-Subject: [PATCH 002/222] Add bcm2708_gpio driver
-
-Signed-off-by: popcornmix <popcornmix at gmail.com>
-
-bcm2708: Add extension to configure internal pulls
-
-The bcm2708 gpio controller supports internal pulls to be used as pull-up,
-pull-down or being entirely disabled. As it can be useful for a driver to
-change the pull configuration from it's default pull-down state, add an
-extension which allows configuring the pull per gpio.
-
-Signed-off-by: Julian Scheel <julian at jusst.de>
-
-bcm2708-gpio: Revert the use of pinctrl_request_gpio
-
-In non-DT systems, pinctrl_request_gpio always fails causing
-"requests probe deferral" messages. In DT systems, it isn't useful
-because the reference counting is independent of the normal pinctrl
-pin reservations.
-
-gpio: Only clear the currently occurring interrupt. Avoids losing interrupts
-
-See: linux #760
-
-bcm2708_gpio: Avoid calling irq_unmask for all interrupts
-
-When setting up the interrupts, specify that the handle_simple_irq
-handler should be used. This leaves interrupt acknowledgement to
-the caller, and prevents irq_unmask from being called for all
-interrupts.
-
-Issue: linux #760
----
- arch/arm/mach-bcm2708/Kconfig             |   8 +
- arch/arm/mach-bcm2708/Makefile            |   1 +
- arch/arm/mach-bcm2708/bcm2708.c           |  25 ++
- arch/arm/mach-bcm2708/bcm2708_gpio.c      | 426 ++++++++++++++++++++++++++++++
- arch/arm/mach-bcm2708/include/mach/gpio.h |  17 ++
- arch/arm/mach-bcm2709/bcm2709.c           |  25 ++
- include/linux/platform_data/bcm2708.h     |  23 ++
- 7 files changed, 525 insertions(+)
- create mode 100644 arch/arm/mach-bcm2708/bcm2708_gpio.c
- create mode 100644 arch/arm/mach-bcm2708/include/mach/gpio.h
- create mode 100644 include/linux/platform_data/bcm2708.h
-
---- a/arch/arm/mach-bcm2708/Kconfig
-+++ b/arch/arm/mach-bcm2708/Kconfig
-@@ -20,6 +20,14 @@ config BCM2708_DT
- 	help
- 	  Enable Device Tree support for BCM2708
- 
-+config BCM2708_GPIO
-+	bool "BCM2708 gpio support"
-+	depends on MACH_BCM2708
-+	select ARCH_REQUIRE_GPIOLIB
-+        default y
-+	help
-+	  Include support for the Broadcom(R) BCM2708 gpio.
-+
- config BCM2708_NOL2CACHE
- 	bool "Videocore L2 cache disable"
- 	depends on MACH_BCM2708
---- a/arch/arm/mach-bcm2708/Makefile
-+++ b/arch/arm/mach-bcm2708/Makefile
-@@ -3,3 +3,4 @@
- #
- 
- obj-$(CONFIG_MACH_BCM2708) 	+= bcm2708.o armctrl.o
-+obj-$(CONFIG_BCM2708_GPIO)	+= bcm2708_gpio.o
---- a/arch/arm/mach-bcm2708/bcm2708.c
-+++ b/arch/arm/mach-bcm2708/bcm2708.c
-@@ -298,6 +298,31 @@ static struct platform_device bcm2708_vc
- 		},
- };
- 
-+#ifdef CONFIG_BCM2708_GPIO
-+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio"
-+
-+static struct resource bcm2708_gpio_resources[] = {
-+	[0] = {			/* general purpose I/O */
-+	       .start = GPIO_BASE,
-+	       .end = GPIO_BASE + SZ_4K - 1,
-+	       .flags = IORESOURCE_MEM,
-+	       },
-+};
-+
-+static u64 gpio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
-+
-+static struct platform_device bcm2708_gpio_device = {
-+	.name = BCM_GPIO_DRIVER_NAME,
-+	.id = -1,		/* only one VideoCore I/O area */
-+	.resource = bcm2708_gpio_resources,
-+	.num_resources = ARRAY_SIZE(bcm2708_gpio_resources),
-+	.dev = {
-+		.dma_mask = &gpio_dmamask,
-+		.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
-+		},
-+};
-+#endif
-+
- int __init bcm_register_device(struct platform_device *pdev)
- {
- 	int ret;
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c
-@@ -0,0 +1,426 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/bcm2708_gpio.c
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+#include <linux/spinlock.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/list.h>
-+#include <linux/io.h>
-+#include <linux/irq.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <mach/gpio.h>
-+#include <linux/gpio.h>
-+#include <linux/platform_device.h>
-+#include <mach/platform.h>
-+#include <linux/pinctrl/consumer.h>
-+
-+#include <linux/platform_data/bcm2708.h>
-+
-+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio"
-+#define DRIVER_NAME BCM_GPIO_DRIVER_NAME
-+#define BCM_GPIO_USE_IRQ 1
-+
-+#define GPIOFSEL(x)  (0x00+(x)*4)
-+#define GPIOSET(x)   (0x1c+(x)*4)
-+#define GPIOCLR(x)   (0x28+(x)*4)
-+#define GPIOLEV(x)   (0x34+(x)*4)
-+#define GPIOEDS(x)   (0x40+(x)*4)
-+#define GPIOREN(x)   (0x4c+(x)*4)
-+#define GPIOFEN(x)   (0x58+(x)*4)
-+#define GPIOHEN(x)   (0x64+(x)*4)
-+#define GPIOLEN(x)   (0x70+(x)*4)
-+#define GPIOAREN(x)  (0x7c+(x)*4)
-+#define GPIOAFEN(x)  (0x88+(x)*4)
-+#define GPIOUD(x)    (0x94+(x)*4)
-+#define GPIOUDCLK(x) (0x98+(x)*4)
-+
-+#define GPIO_BANKS 2
-+
-+enum { GPIO_FSEL_INPUT, GPIO_FSEL_OUTPUT,
-+	GPIO_FSEL_ALT5, GPIO_FSEL_ALT_4,
-+	GPIO_FSEL_ALT0, GPIO_FSEL_ALT1,
-+	GPIO_FSEL_ALT2, GPIO_FSEL_ALT3,
-+};
-+
-+	/* Each of the two spinlocks protects a different set of hardware
-+	 * regiters and data structurs. This decouples the code of the IRQ from
-+	 * the GPIO code. This also makes the case of a GPIO routine call from
-+	 * the IRQ code simpler.
-+	 */
-+static DEFINE_SPINLOCK(lock);	/* GPIO registers */
-+
-+struct bcm2708_gpio {
-+	struct list_head list;
-+	void __iomem *base;
-+	struct gpio_chip gc;
-+	unsigned long rising[(BCM2708_NR_GPIOS + 31) / 32];
-+	unsigned long falling[(BCM2708_NR_GPIOS + 31) / 32];
-+	unsigned long high[(BCM2708_NR_GPIOS + 31) / 32];
-+	unsigned long low[(BCM2708_NR_GPIOS + 31) / 32];
-+};
-+
-+static int bcm2708_set_function(struct gpio_chip *gc, unsigned offset,
-+				int function)
-+{
-+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
-+	unsigned long flags;
-+	unsigned gpiodir;
-+	unsigned gpio_bank = offset / 10;
-+	unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3;
-+
-+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set_function %p (%d,%d)\n", gc, offset, function);
-+	if (offset >= BCM2708_NR_GPIOS)
-+		return -EINVAL;
-+
-+	spin_lock_irqsave(&lock, flags);
-+
-+	gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank));
-+	gpiodir &= ~(7 << gpio_field_offset);
-+	gpiodir |= function << gpio_field_offset;
-+	writel(gpiodir, gpio->base + GPIOFSEL(gpio_bank));
-+	spin_unlock_irqrestore(&lock, flags);
-+	gpiodir = readl(gpio->base + GPIOFSEL(gpio_bank));
-+
-+	return 0;
-+}
-+
-+static int bcm2708_gpio_dir_in(struct gpio_chip *gc, unsigned offset)
-+{
-+	return bcm2708_set_function(gc, offset, GPIO_FSEL_INPUT);
-+}
-+
-+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value);
-+static int bcm2708_gpio_dir_out(struct gpio_chip *gc, unsigned offset,
-+				int value)
-+{
-+	int ret;
-+	ret = bcm2708_set_function(gc, offset, GPIO_FSEL_OUTPUT);
-+	if (ret >= 0)
-+		bcm2708_gpio_set(gc, offset, value);
-+	return ret;
-+}
-+
-+static int bcm2708_gpio_get(struct gpio_chip *gc, unsigned offset)
-+{
-+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
-+	unsigned gpio_bank = offset / 32;
-+	unsigned gpio_field_offset = (offset - 32 * gpio_bank);
-+	unsigned lev;
-+
-+	if (offset >= BCM2708_NR_GPIOS)
-+		return 0;
-+	lev = readl(gpio->base + GPIOLEV(gpio_bank));
-+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_get %p (%d)=%d\n", gc, offset, 0x1 & (lev>>gpio_field_offset));
-+	return 0x1 & (lev >> gpio_field_offset);
-+}
-+
-+static void bcm2708_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
-+{
-+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
-+	unsigned gpio_bank = offset / 32;
-+	unsigned gpio_field_offset = (offset - 32 * gpio_bank);
-+//printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_set %p (%d=%d)\n", gc, offset, value);
-+	if (offset >= BCM2708_NR_GPIOS)
-+		return;
-+	if (value)
-+		writel(1 << gpio_field_offset, gpio->base + GPIOSET(gpio_bank));
-+	else
-+		writel(1 << gpio_field_offset, gpio->base + GPIOCLR(gpio_bank));
-+}
-+
-+/**********************
-+ * extension to configure pullups
-+ */
-+int bcm2708_gpio_setpull(struct gpio_chip *gc, unsigned offset,
-+		bcm2708_gpio_pull_t value)
-+{
-+	struct bcm2708_gpio *gpio = container_of(gc, struct bcm2708_gpio, gc);
-+	unsigned gpio_bank = offset / 32;
-+	unsigned gpio_field_offset = (offset - 32 * gpio_bank);
-+
-+	if (offset >= BCM2708_NR_GPIOS)
-+		return -EINVAL;
-+
-+	switch (value) {
-+	case BCM2708_PULL_UP:
-+		writel(2, gpio->base + GPIOUD(0));
-+		break;
-+	case BCM2708_PULL_DOWN:
-+		writel(1, gpio->base + GPIOUD(0));
-+		break;
-+	case BCM2708_PULL_OFF:
-+		writel(0, gpio->base + GPIOUD(0));
-+		break;
-+	}
-+
-+	udelay(5);
-+	writel(1 << gpio_field_offset, gpio->base + GPIOUDCLK(gpio_bank));
-+	udelay(5);
-+	writel(0, gpio->base + GPIOUD(0));
-+	writel(0 << gpio_field_offset, gpio->base + GPIOUDCLK(gpio_bank));
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL(bcm2708_gpio_setpull);
-+
-+/*************************************************************************************************************************
-+ * bcm2708 GPIO IRQ
-+ */
-+
-+#if BCM_GPIO_USE_IRQ
-+
-+static int bcm2708_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
-+{
-+	return gpio_to_irq(gpio);
-+}
-+
-+static int bcm2708_gpio_irq_set_type(struct irq_data *d, unsigned type)
-+{
-+	unsigned irq = d->irq;
-+	struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
-+	unsigned gn = irq_to_gpio(irq);
-+	unsigned gb = gn / 32;
-+	unsigned go = gn % 32;
-+
-+	gpio->rising[gb]  &= ~(1 << go);
-+	gpio->falling[gb] &= ~(1 << go);
-+	gpio->high[gb]    &= ~(1 << go);
-+	gpio->low[gb]     &= ~(1 << go);
-+
-+	if (type & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
-+		return -EINVAL;
-+
-+	if (type & IRQ_TYPE_EDGE_RISING)
-+		gpio->rising[gb] |= (1 << go);
-+	if (type & IRQ_TYPE_EDGE_FALLING)
-+		gpio->falling[gb] |= (1 << go);
-+	if (type & IRQ_TYPE_LEVEL_HIGH)
-+		gpio->high[gb] |= (1 << go);
-+	if (type & IRQ_TYPE_LEVEL_LOW)
-+		gpio->low[gb] |= (1 << go);
-+	return 0;
-+}
-+
-+static void bcm2708_gpio_irq_mask(struct irq_data *d)
-+{
-+	unsigned irq = d->irq;
-+	struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
-+	unsigned gn = irq_to_gpio(irq);
-+	unsigned gb = gn / 32;
-+	unsigned long rising  = readl(gpio->base + GPIOREN(gb));
-+	unsigned long falling = readl(gpio->base + GPIOFEN(gb));
-+	unsigned long high    = readl(gpio->base + GPIOHEN(gb));
-+	unsigned long low     = readl(gpio->base + GPIOLEN(gb));
-+
-+	gn = gn % 32;
-+
-+	writel(rising  & ~(1 << gn), gpio->base + GPIOREN(gb));
-+	writel(falling & ~(1 << gn), gpio->base + GPIOFEN(gb));
-+	writel(high    & ~(1 << gn), gpio->base + GPIOHEN(gb));
-+	writel(low     & ~(1 << gn), gpio->base + GPIOLEN(gb));
-+}
-+
-+static void bcm2708_gpio_irq_unmask(struct irq_data *d)
-+{
-+	unsigned irq = d->irq;
-+	struct bcm2708_gpio *gpio = irq_get_chip_data(irq);
-+	unsigned gn = irq_to_gpio(irq);
-+	unsigned gb = gn / 32;
-+	unsigned go = gn % 32;
-+	unsigned long rising  = readl(gpio->base + GPIOREN(gb));
-+	unsigned long falling = readl(gpio->base + GPIOFEN(gb));
-+	unsigned long high    = readl(gpio->base + GPIOHEN(gb));
-+	unsigned long low     = readl(gpio->base + GPIOLEN(gb));
-+
-+	if (gpio->rising[gb] & (1 << go)) {
-+		writel(rising |  (1 << go), gpio->base + GPIOREN(gb));
-+	} else {
-+		writel(rising & ~(1 << go), gpio->base + GPIOREN(gb));
-+	}
-+
-+	if (gpio->falling[gb] & (1 << go)) {
-+		writel(falling |  (1 << go), gpio->base + GPIOFEN(gb));
-+	} else {
-+		writel(falling & ~(1 << go), gpio->base + GPIOFEN(gb));
-+	}
-+
-+	if (gpio->high[gb] & (1 << go)) {
-+		writel(high |  (1 << go), gpio->base + GPIOHEN(gb));
-+	} else {
-+		writel(high & ~(1 << go), gpio->base + GPIOHEN(gb));
-+	}
-+
-+	if (gpio->low[gb] & (1 << go)) {
-+		writel(low |  (1 << go), gpio->base + GPIOLEN(gb));
-+	} else {
-+		writel(low & ~(1 << go), gpio->base + GPIOLEN(gb));
-+	}
-+}
-+
-+static struct irq_chip bcm2708_irqchip = {
-+	.name = "GPIO",
-+	.irq_enable = bcm2708_gpio_irq_unmask,
-+	.irq_disable = bcm2708_gpio_irq_mask,
-+	.irq_unmask = bcm2708_gpio_irq_unmask,
-+	.irq_mask = bcm2708_gpio_irq_mask,
-+	.irq_set_type = bcm2708_gpio_irq_set_type,
-+};
-+
-+static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id)
-+{
-+	unsigned long edsr;
-+	unsigned bank;
-+	int i;
-+	unsigned gpio;
-+	unsigned level_bits;
-+	struct bcm2708_gpio *gpio_data = dev_id;
-+
-+	for (bank = 0; bank < GPIO_BANKS; bank++) {
-+		edsr = readl(__io_address(GPIO_BASE) + GPIOEDS(bank));
-+		level_bits = gpio_data->high[bank] | gpio_data->low[bank];
-+
-+		for_each_set_bit(i, &edsr, 32) {
-+			gpio = i + bank * 32;
-+			/* ack edge triggered IRQs immediately */
-+			if (!(level_bits & (1<<i)))
-+				writel(1<<i,
-+				       __io_address(GPIO_BASE) + GPIOEDS(bank));
-+			generic_handle_irq(gpio_to_irq(gpio));
-+			/* ack level triggered IRQ after handling them */
-+			if (level_bits & (1<<i))
-+				writel(1<<i,
-+				       __io_address(GPIO_BASE) + GPIOEDS(bank));
-+		}
-+	}
-+	return IRQ_HANDLED;
-+}
-+
-+static struct irqaction bcm2708_gpio_irq = {
-+	.name = "BCM2708 GPIO catchall handler",
-+	.flags = IRQF_TIMER | IRQF_IRQPOLL,
-+	.handler = bcm2708_gpio_interrupt,
-+};
-+
-+static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb)
-+{
-+	unsigned irq;
-+
-+	ucb->gc.to_irq = bcm2708_gpio_to_irq;
-+
-+	for (irq = GPIO_IRQ_START; irq < (GPIO_IRQ_START + GPIO_IRQS); irq++) {
-+		irq_set_chip_data(irq, ucb);
-+		irq_set_chip_and_handler(irq, &bcm2708_irqchip,
-+					 handle_simple_irq);
-+		set_irq_flags(irq, IRQF_VALID);
-+	}
-+
-+	bcm2708_gpio_irq.dev_id = ucb;
-+	setup_irq(IRQ_GPIO3, &bcm2708_gpio_irq);
-+}
-+
-+#else
-+
-+static void bcm2708_gpio_irq_init(struct bcm2708_gpio *ucb)
-+{
-+}
-+
-+#endif /* #if BCM_GPIO_USE_IRQ ***************************************************************************************************************** */
-+
-+static int bcm2708_gpio_probe(struct platform_device *dev)
-+{
-+	struct bcm2708_gpio *ucb;
-+	struct resource *res;
-+	int bank;
-+	int err = 0;
-+
-+	printk(KERN_INFO DRIVER_NAME ": bcm2708_gpio_probe %p\n", dev);
-+
-+	ucb = kzalloc(sizeof(*ucb), GFP_KERNEL);
-+	if (NULL == ucb) {
-+		printk(KERN_ERR DRIVER_NAME ": failed to allocate "
-+		       "mailbox memory\n");
-+		err = -ENOMEM;
-+		goto err;
-+	}
-+
-+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-+
-+	platform_set_drvdata(dev, ucb);
-+	ucb->base = __io_address(GPIO_BASE);
-+
-+	ucb->gc.label = "bcm2708_gpio";
-+	ucb->gc.base = 0;
-+	ucb->gc.ngpio = BCM2708_NR_GPIOS;
-+	ucb->gc.owner = THIS_MODULE;
-+
-+	ucb->gc.direction_input = bcm2708_gpio_dir_in;
-+	ucb->gc.direction_output = bcm2708_gpio_dir_out;
-+	ucb->gc.get = bcm2708_gpio_get;
-+	ucb->gc.set = bcm2708_gpio_set;
-+	ucb->gc.can_sleep = 0;
-+
-+	for (bank = 0; bank < GPIO_BANKS; bank++) {
-+		writel(0, ucb->base + GPIOREN(bank));
-+		writel(0, ucb->base + GPIOFEN(bank));
-+		writel(0, ucb->base + GPIOHEN(bank));
-+		writel(0, ucb->base + GPIOLEN(bank));
-+		writel(0, ucb->base + GPIOAREN(bank));
-+		writel(0, ucb->base + GPIOAFEN(bank));
-+		writel(~0, ucb->base + GPIOEDS(bank));
-+	}
-+
-+	bcm2708_gpio_irq_init(ucb);
-+
-+	err = gpiochip_add(&ucb->gc);
-+
-+err:
-+	return err;
-+
-+}
-+
-+static int bcm2708_gpio_remove(struct platform_device *dev)
-+{
-+	int err = 0;
-+	struct bcm2708_gpio *ucb = platform_get_drvdata(dev);
-+
-+	printk(KERN_ERR DRIVER_NAME ": bcm2708_gpio_remove %p\n", dev);
-+
-+	gpiochip_remove(&ucb->gc);
-+
-+	platform_set_drvdata(dev, NULL);
-+	kfree(ucb);
-+
-+	return err;
-+}
-+
-+static struct platform_driver bcm2708_gpio_driver = {
-+	.probe = bcm2708_gpio_probe,
-+	.remove = bcm2708_gpio_remove,
-+	.driver = {
-+		   .name = "bcm2708_gpio"},
-+};
-+
-+static int __init bcm2708_gpio_init(void)
-+{
-+	return platform_driver_register(&bcm2708_gpio_driver);
-+}
-+
-+static void __exit bcm2708_gpio_exit(void)
-+{
-+	platform_driver_unregister(&bcm2708_gpio_driver);
-+}
-+
-+module_init(bcm2708_gpio_init);
-+module_exit(bcm2708_gpio_exit);
-+
-+MODULE_DESCRIPTION("Broadcom BCM2708 GPIO driver");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/arch/arm/mach-bcm2708/include/mach/gpio.h
-@@ -0,0 +1,17 @@
-+/*
-+ * arch/arm/mach-bcm2708/include/mach/gpio.h
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2.  This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+#ifndef __ASM_ARCH_GPIO_H
-+#define __ASM_ARCH_GPIO_H
-+
-+#define BCM2708_NR_GPIOS 54 // number of gpio lines
-+
-+#define gpio_to_irq(x)	((x) + GPIO_IRQ_START)
-+#define irq_to_gpio(x)	((x) - GPIO_IRQ_START)
-+
-+#endif
---- a/arch/arm/mach-bcm2709/bcm2709.c
-+++ b/arch/arm/mach-bcm2709/bcm2709.c
-@@ -329,6 +329,31 @@ static struct platform_device bcm2708_vc
- 		},
- };
- 
-+#ifdef CONFIG_BCM2708_GPIO
-+#define BCM_GPIO_DRIVER_NAME "bcm2708_gpio"
-+
-+static struct resource bcm2708_gpio_resources[] = {
-+	[0] = {			/* general purpose I/O */
-+	       .start = GPIO_BASE,
-+	       .end = GPIO_BASE + SZ_4K - 1,
-+	       .flags = IORESOURCE_MEM,
-+	       },
-+};
-+
-+static u64 gpio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
-+
-+static struct platform_device bcm2708_gpio_device = {
-+	.name = BCM_GPIO_DRIVER_NAME,
-+	.id = -1,		/* only one VideoCore I/O area */
-+	.resource = bcm2708_gpio_resources,
-+	.num_resources = ARRAY_SIZE(bcm2708_gpio_resources),
-+	.dev = {
-+		.dma_mask = &gpio_dmamask,
-+		.coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON),
-+		},
-+};
-+#endif
-+
- int __init bcm_register_device(struct platform_device *pdev)
- {
- 	int ret;
---- /dev/null
-+++ b/include/linux/platform_data/bcm2708.h
-@@ -0,0 +1,23 @@
-+/*
-+ * include/linux/platform_data/bcm2708.h
-+ *
-+ * 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.
-+ *
-+ * (C) 2014 Julian Scheel <julian at jusst.de>
-+ *
-+ */
-+#ifndef __BCM2708_H_
-+#define __BCM2708_H_
-+
-+typedef enum {
-+	BCM2708_PULL_OFF,
-+	BCM2708_PULL_UP,
-+	BCM2708_PULL_DOWN
-+} bcm2708_gpio_pull_t;
-+
-+extern int bcm2708_gpio_setpull(struct gpio_chip *gc, unsigned offset,
-+		bcm2708_gpio_pull_t value);
-+
-+#endif
diff --git a/target/linux/brcm2708/patches-4.1/0003-mailbox-bcm2708-Add-bcm2708-vcio.patch b/target/linux/brcm2708/patches-4.1/0003-mailbox-bcm2708-Add-bcm2708-vcio.patch
deleted file mode 100644
index 1d2d5fc..0000000
--- a/target/linux/brcm2708/patches-4.1/0003-mailbox-bcm2708-Add-bcm2708-vcio.patch
+++ /dev/null
@@ -1,623 +0,0 @@
-From 5de29d9bdc6ec6a368341fc8b59b5c8d3bc0bbf0 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
-Date: Fri, 1 May 2015 19:11:03 +0200
-Subject: [PATCH 003/222] mailbox: bcm2708: Add bcm2708-vcio
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: popcornmix <popcornmix at gmail.com>
-
-Copy the arch vcio.c driver to drivers/mailbox.
-This is done to make it available on ARCH_BCM2835.
-
-Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
-
-mailbox: bcm2708-vcio: Allocation does not need to be atomic
-
-No need to do atomic allocation in a context that can sleep.
-
-Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
-
-mailbox: bcm2708-vcio: Check the correct status register before writing
-
-With the VC reader blocked and the ARM writing, MAIL0_STA reads
-empty permanently while MAIL1_STA goes from empty (0x40000000)
-to non-empty (0x00000001-0x00000007) to full (0x80000008).
-
-Suggested-by: Phil Elwell <phil at raspberrypi.org>
-Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
----
- drivers/mailbox/Kconfig                       |   6 +
- drivers/mailbox/Makefile                      |   2 +
- drivers/mailbox/bcm2708-vcio.c                | 427 ++++++++++++++++++++++++++
- include/linux/platform_data/mailbox-bcm2708.h | 126 ++++++++
- 4 files changed, 561 insertions(+)
- create mode 100644 drivers/mailbox/bcm2708-vcio.c
- create mode 100644 include/linux/platform_data/mailbox-bcm2708.h
-
---- a/drivers/mailbox/Kconfig
-+++ b/drivers/mailbox/Kconfig
-@@ -7,6 +7,12 @@ menuconfig MAILBOX
- 
- if MAILBOX
- 
-+config BCM2708_MBOX
-+	bool "Broadcom BCM2708 Mailbox (vcio)"
-+	depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835
-+	help
-+	  Broadcom BCM2708 Mailbox (vcio)
-+
- config ARM_MHU
- 	tristate "ARM MHU Mailbox"
- 	depends on ARM_AMBA
---- a/drivers/mailbox/Makefile
-+++ b/drivers/mailbox/Makefile
-@@ -2,6 +2,8 @@
- 
- obj-$(CONFIG_MAILBOX)		+= mailbox.o
- 
-+obj-$(CONFIG_BCM2708_MBOX)	+= bcm2708-vcio.o
-+
- obj-$(CONFIG_ARM_MHU)	+= arm_mhu.o
- 
- obj-$(CONFIG_PL320_MBOX)	+= pl320-ipc.o
---- /dev/null
-+++ b/drivers/mailbox/bcm2708-vcio.c
-@@ -0,0 +1,427 @@
-+/*
-+ *  linux/arch/arm/mach-bcm2708/vcio.c
-+ *
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This device provides a shared mechanism for writing to the mailboxes,
-+ * semaphores, doorbells etc. that are shared between the ARM and the
-+ * VideoCore processor
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/fs.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/ioctl.h>
-+#include <linux/platform_data/mailbox-bcm2708.h>
-+#include <linux/platform_device.h>
-+#include <linux/uaccess.h>
-+
-+#define DRIVER_NAME "bcm2708_vcio"
-+#define DEVICE_FILE_NAME "vcio"
-+
-+/* offsets from a mail box base address */
-+#define MAIL0_RD	0x00	/* read - and next 4 words */
-+#define MAIL0_POL	0x10	/* read without popping the fifo */
-+#define MAIL0_SND	0x14	/* sender ID (bottom two bits) */
-+#define MAIL0_STA	0x18	/* status */
-+#define MAIL0_CNF	0x1C	/* configuration */
-+#define MAIL1_WRT	0x20	/* write - and next 4 words */
-+#define MAIL1_STA	0x38	/* status */
-+
-+/* On MACH_BCM270x these come through <linux/interrupt.h> (arm_control.h ) */
-+#ifndef ARM_MS_EMPTY
-+#define ARM_MS_EMPTY   BIT(30)
-+#define ARM_MS_FULL    BIT(31)
-+
-+#define ARM_MC_IHAVEDATAIRQEN  BIT(0)
-+#endif
-+
-+#define MBOX_MSG(chan, data28)		(((data28) & ~0xf) | ((chan) & 0xf))
-+#define MBOX_MSG_LSB(chan, data28)	(((data28) << 4) | ((chan) & 0xf))
-+#define MBOX_CHAN(msg)			((msg) & 0xf)
-+#define MBOX_DATA28(msg)		((msg) & ~0xf)
-+#define MBOX_DATA28_LSB(msg)		(((uint32_t)msg) >> 4)
-+
-+#define MBOX_MAGIC 0xd0d0c0de
-+
-+#define MAJOR_NUM 100
-+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *)
-+
-+static struct class *vcio_class;
-+
-+struct vc_mailbox {
-+	void __iomem *regs;
-+	uint32_t msg[MBOX_CHAN_COUNT];
-+	struct semaphore sema[MBOX_CHAN_COUNT];
-+	uint32_t magic;
-+};
-+
-+static void mbox_init(struct vc_mailbox *mbox_out)
-+{
-+	int i;
-+
-+	for (i = 0; i < MBOX_CHAN_COUNT; i++) {
-+		mbox_out->msg[i] = 0;
-+		sema_init(&mbox_out->sema[i], 0);
-+	}
-+
-+	/* Enable the interrupt on data reception */
-+	writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF);
-+
-+	mbox_out->magic = MBOX_MAGIC;
-+}
-+
-+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28)
-+{
-+	if (mbox->magic != MBOX_MAGIC)
-+		return -EINVAL;
-+
-+	/* wait for the mailbox FIFO to have some space in it */
-+	while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL))
-+		cpu_relax();
-+
-+	writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT);
-+
-+	return 0;
-+}
-+
-+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28)
-+{
-+	if (mbox->magic != MBOX_MAGIC)
-+		return -EINVAL;
-+
-+	down(&mbox->sema[chan]);
-+	*data28 = MBOX_DATA28(mbox->msg[chan]);
-+	mbox->msg[chan] = 0;
-+
-+	return 0;
-+}
-+
-+static irqreturn_t mbox_irq_handler(int irq, void *dev_id)
-+{
-+	/* wait for the mailbox FIFO to have some data in it */
-+	struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id;
-+	int status = readl(mbox->regs + MAIL0_STA);
-+	int ret = IRQ_NONE;
-+
-+	while (!(status & ARM_MS_EMPTY)) {
-+		uint32_t msg = readl(mbox->regs + MAIL0_RD);
-+		int chan = MBOX_CHAN(msg);
-+
-+		if (chan < MBOX_CHAN_COUNT) {
-+			if (mbox->msg[chan]) {
-+				pr_err(DRIVER_NAME
-+				       ": mbox chan %d overflow - drop %08x\n",
-+				       chan, msg);
-+			} else {
-+				mbox->msg[chan] = (msg | 0xf);
-+				up(&mbox->sema[chan]);
-+			}
-+		} else {
-+			pr_err(DRIVER_NAME
-+			       ": invalid channel selector (msg %08x)\n", msg);
-+		}
-+		ret = IRQ_HANDLED;
-+		status = readl(mbox->regs + MAIL0_STA);
-+	}
-+	return ret;
-+}
-+
-+/* Mailbox Methods */
-+
-+static struct device *mbox_dev;	/* we assume there's only one! */
-+
-+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28)
-+{
-+	struct vc_mailbox *mailbox = dev_get_drvdata(dev);
-+	int rc;
-+
-+	device_lock(dev);
-+	rc = mbox_write(mailbox, chan, data28);
-+	device_unlock(dev);
-+
-+	return rc;
-+}
-+
-+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28)
-+{
-+	struct vc_mailbox *mailbox = dev_get_drvdata(dev);
-+	int rc;
-+
-+	device_lock(dev);
-+	rc = mbox_read(mailbox, chan, data28);
-+	device_unlock(dev);
-+
-+	return rc;
-+}
-+
-+extern int bcm_mailbox_write(unsigned chan, uint32_t data28)
-+{
-+	if (!mbox_dev)
-+		return -ENODEV;
-+
-+	return dev_mbox_write(mbox_dev, chan, data28);
-+}
-+EXPORT_SYMBOL_GPL(bcm_mailbox_write);
-+
-+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28)
-+{
-+	if (!mbox_dev)
-+		return -ENODEV;
-+
-+	return dev_mbox_read(mbox_dev, chan, data28);
-+}
-+EXPORT_SYMBOL_GPL(bcm_mailbox_read);
-+
-+static int mbox_copy_from_user(void *dst, const void *src, int size)
-+{
-+	if ((uint32_t)src < TASK_SIZE)
-+		return copy_from_user(dst, src, size);
-+
-+	memcpy(dst, src, size);
-+
-+	return 0;
-+}
-+
-+static int mbox_copy_to_user(void *dst, const void *src, int size)
-+{
-+	if ((uint32_t)dst < TASK_SIZE)
-+		return copy_to_user(dst, src, size);
-+
-+	memcpy(dst, src, size);
-+
-+	return 0;
-+}
-+
-+static DEFINE_MUTEX(mailbox_lock);
-+extern int bcm_mailbox_property(void *data, int size)
-+{
-+	uint32_t success;
-+	dma_addr_t mem_bus; /* the memory address accessed from videocore */
-+	void *mem_kern;     /* the memory address accessed from driver */
-+	int s = 0;
-+
-+	mutex_lock(&mailbox_lock);
-+	/* allocate some memory for the messages communicating with GPU */
-+	mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus,
-+				      GFP_KERNEL);
-+	if (mem_kern) {
-+		/* create the message */
-+		mbox_copy_from_user(mem_kern, data, size);
-+
-+		/* send the message */
-+		wmb();
-+		s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus);
-+		if (s == 0)
-+			s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success);
-+		if (s == 0) {
-+			/* copy the response */
-+			rmb();
-+			mbox_copy_to_user(data, mem_kern, size);
-+		}
-+		dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus);
-+	} else {
-+		s = -ENOMEM;
-+	}
-+	if (s != 0)
-+		pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s);
-+
-+	mutex_unlock(&mailbox_lock);
-+	return s;
-+}
-+EXPORT_SYMBOL_GPL(bcm_mailbox_property);
-+
-+/* Platform Device for Mailbox */
-+
-+/*
-+ * Is the device open right now? Used to prevent
-+ * concurent access into the same device
-+ */
-+static bool device_is_open;
-+
-+/* This is called whenever a process attempts to open the device file */
-+static int device_open(struct inode *inode, struct file *file)
-+{
-+	/* We don't want to talk to two processes at the same time */
-+	if (device_is_open)
-+		return -EBUSY;
-+
-+	device_is_open = true;
-+	try_module_get(THIS_MODULE);
-+
-+	return 0;
-+}
-+
-+static int device_release(struct inode *inode, struct file *file)
-+{
-+	/* We're now ready for our next caller */
-+	device_is_open = false;
-+
-+	module_put(THIS_MODULE);
-+
-+	return 0;
-+}
-+
-+/*
-+ * This function is called whenever a process tries to do an ioctl on our
-+ * device file. We get two extra parameters (additional to the inode and file
-+ * structures, which all device functions get): the number of the ioctl called
-+ * and the parameter given to the ioctl function.
-+ *
-+ * If the ioctl is write or read/write (meaning output is returned to the
-+ * calling process), the ioctl call returns the output of this function.
-+ *
-+ */
-+static long device_ioctl(struct file *file, unsigned int ioctl_num,
-+			 unsigned long ioctl_param)
-+{
-+	unsigned size;
-+
-+	switch (ioctl_num) {
-+	case IOCTL_MBOX_PROPERTY:
-+		/*
-+		 * Receive a pointer to a message (in user space) and set that
-+		 * to be the device's message.  Get the parameter given to
-+		 * ioctl by the process.
-+		 */
-+		mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size));
-+		return bcm_mailbox_property((void *)ioctl_param, size);
-+	default:
-+		pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num);
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-+
-+/* Module Declarations */
-+
-+/*
-+ * This structure will hold the functions to be called
-+ * when a process does something to the device we
-+ * created. Since a pointer to this structure is kept in
-+ * the devices table, it can't be local to
-+ * init_module. NULL is for unimplemented functios.
-+ */
-+const struct file_operations fops = {
-+	.unlocked_ioctl = device_ioctl,
-+	.open = device_open,
-+	.release = device_release,	/* a.k.a. close */
-+};
-+
-+static int bcm_vcio_probe(struct platform_device *pdev)
-+{
-+	struct device *dev = &pdev->dev;
-+	struct device *vdev;
-+	struct vc_mailbox *mailbox;
-+	struct resource *res;
-+	int irq, ret;
-+
-+	mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL);
-+	if (!mailbox)
-+		return -ENOMEM;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	mailbox->regs = devm_ioremap_resource(dev, res);
-+	if (IS_ERR(mailbox->regs))
-+		return PTR_ERR(mailbox->regs);
-+
-+	irq = platform_get_irq(pdev, 0);
-+	ret = devm_request_irq(dev, irq, mbox_irq_handler,
-+			       IRQF_IRQPOLL,
-+			       dev_name(dev), mailbox);
-+	if (ret) {
-+		dev_err(dev, "Interrupt request failed %d\n", ret);
-+		return ret;
-+	}
-+
-+	ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops);
-+	if (ret < 0) {
-+		pr_err("Character device registration failed %d\n", ret);
-+		return ret;
-+	}
-+
-+	vcio_class = class_create(THIS_MODULE, DRIVER_NAME);
-+	if (IS_ERR(vcio_class)) {
-+		ret = PTR_ERR(vcio_class);
-+		pr_err("Class creation failed %d\n", ret);
-+		goto err_class;
-+	}
-+
-+	vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL,
-+			     "vcio");
-+	if (IS_ERR(vdev)) {
-+		ret = PTR_ERR(vdev);
-+		pr_err("Device creation failed %d\n", ret);
-+		goto err_dev;
-+	}
-+
-+	mbox_init(mailbox);
-+	platform_set_drvdata(pdev, mailbox);
-+	mbox_dev = dev;
-+
-+	dev_info(dev, "mailbox at %p\n", mailbox->regs);
-+
-+	return 0;
-+
-+err_dev:
-+	class_destroy(vcio_class);
-+err_class:
-+	unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME);
-+
-+	return ret;
-+}
-+
-+static int bcm_vcio_remove(struct platform_device *pdev)
-+{
-+	mbox_dev = NULL;
-+	platform_set_drvdata(pdev, NULL);
-+	device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0));
-+	class_destroy(vcio_class);
-+	unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME);
-+
-+	return 0;
-+}
-+
-+static const struct of_device_id bcm_vcio_of_match_table[] = {
-+	{ .compatible = "brcm,bcm2708-vcio", },
-+	{},
-+};
-+MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table);
-+
-+static struct platform_driver bcm_mbox_driver = {
-+	.probe = bcm_vcio_probe,
-+	.remove = bcm_vcio_remove,
-+
-+	.driver = {
-+		   .name = DRIVER_NAME,
-+		   .owner = THIS_MODULE,
-+		   .of_match_table = bcm_vcio_of_match_table,
-+		   },
-+};
-+
-+static int __init bcm_mbox_init(void)
-+{
-+	return platform_driver_register(&bcm_mbox_driver);
-+}
-+
-+static void __exit bcm_mbox_exit(void)
-+{
-+	platform_driver_unregister(&bcm_mbox_driver);
-+}
-+
-+arch_initcall(bcm_mbox_init);	/* Initialize early */
-+module_exit(bcm_mbox_exit);
-+
-+MODULE_AUTHOR("Gray Girling");
-+MODULE_DESCRIPTION("ARM I/O to VideoCore processor");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/include/linux/platform_data/mailbox-bcm2708.h
-@@ -0,0 +1,126 @@
-+/*
-+ *  Copyright (C) 2010 Broadcom
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ */
-+#ifndef _PLAT_MAILBOX_BCM2708_H
-+#define _PLAT_MAILBOX_BCM2708_H
-+
-+/* Routines to handle I/O via the VideoCore "ARM control" registers
-+ * (semaphores, doorbells, mailboxes)
-+ */
-+
-+/* Constants shared with the ARM identifying separate mailbox channels */
-+#define MBOX_CHAN_POWER    0 /* for use by the power management interface */
-+#define MBOX_CHAN_FB       1 /* for use by the frame buffer */
-+#define MBOX_CHAN_VCHIQ    3 /* for use by the VCHIQ interface */
-+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */
-+#define MBOX_CHAN_COUNT    9
-+
-+enum {
-+	VCMSG_PROCESS_REQUEST		= 0x00000000
-+};
-+
-+enum {
-+	VCMSG_REQUEST_SUCCESSFUL	= 0x80000000,
-+	VCMSG_REQUEST_FAILED		= 0x80000001
-+};
-+
-+/* Mailbox property tags */
-+enum {
-+	VCMSG_PROPERTY_END               = 0x00000000,
-+	VCMSG_GET_FIRMWARE_REVISION      = 0x00000001,
-+	VCMSG_GET_BOARD_MODEL            = 0x00010001,
-+	VCMSG_GET_BOARD_REVISION	 = 0x00010002,
-+	VCMSG_GET_BOARD_MAC_ADDRESS	 = 0x00010003,
-+	VCMSG_GET_BOARD_SERIAL		 = 0x00010004,
-+	VCMSG_GET_ARM_MEMORY		 = 0x00010005,
-+	VCMSG_GET_VC_MEMORY		 = 0x00010006,
-+	VCMSG_GET_CLOCKS		 = 0x00010007,
-+	VCMSG_GET_COMMAND_LINE           = 0x00050001,
-+	VCMSG_GET_DMA_CHANNELS           = 0x00060001,
-+	VCMSG_GET_POWER_STATE            = 0x00020001,
-+	VCMSG_GET_TIMING		 = 0x00020002,
-+	VCMSG_SET_POWER_STATE            = 0x00028001,
-+	VCMSG_GET_CLOCK_STATE            = 0x00030001,
-+	VCMSG_SET_CLOCK_STATE            = 0x00038001,
-+	VCMSG_GET_CLOCK_RATE             = 0x00030002,
-+	VCMSG_SET_CLOCK_RATE             = 0x00038002,
-+	VCMSG_GET_VOLTAGE                = 0x00030003,
-+	VCMSG_SET_VOLTAGE                = 0x00038003,
-+	VCMSG_GET_MAX_CLOCK              = 0x00030004,
-+	VCMSG_GET_MAX_VOLTAGE            = 0x00030005,
-+	VCMSG_GET_TEMPERATURE            = 0x00030006,
-+	VCMSG_GET_MIN_CLOCK              = 0x00030007,
-+	VCMSG_GET_MIN_VOLTAGE            = 0x00030008,
-+	VCMSG_GET_TURBO                  = 0x00030009,
-+	VCMSG_GET_MAX_TEMPERATURE        = 0x0003000a,
-+	VCMSG_GET_STC                    = 0x0003000b,
-+	VCMSG_SET_TURBO                  = 0x00038009,
-+	VCMSG_SET_ALLOCATE_MEM           = 0x0003000c,
-+	VCMSG_SET_LOCK_MEM               = 0x0003000d,
-+	VCMSG_SET_UNLOCK_MEM             = 0x0003000e,
-+	VCMSG_SET_RELEASE_MEM            = 0x0003000f,
-+	VCMSG_SET_EXECUTE_CODE           = 0x00030010,
-+	VCMSG_SET_EXECUTE_QPU            = 0x00030011,
-+	VCMSG_SET_ENABLE_QPU             = 0x00030012,
-+	VCMSG_GET_RESOURCE_HANDLE        = 0x00030014,
-+	VCMSG_GET_EDID_BLOCK             = 0x00030020,
-+	VCMSG_GET_CUSTOMER_OTP           = 0x00030021,
-+	VCMSG_SET_CUSTOMER_OTP           = 0x00038021,
-+	VCMSG_SET_ALLOCATE_BUFFER        = 0x00040001,
-+	VCMSG_SET_RELEASE_BUFFER         = 0x00048001,
-+	VCMSG_SET_BLANK_SCREEN           = 0x00040002,
-+	VCMSG_TST_BLANK_SCREEN           = 0x00044002,
-+	VCMSG_GET_PHYSICAL_WIDTH_HEIGHT  = 0x00040003,
-+	VCMSG_TST_PHYSICAL_WIDTH_HEIGHT  = 0x00044003,
-+	VCMSG_SET_PHYSICAL_WIDTH_HEIGHT  = 0x00048003,
-+	VCMSG_GET_VIRTUAL_WIDTH_HEIGHT   = 0x00040004,
-+	VCMSG_TST_VIRTUAL_WIDTH_HEIGHT   = 0x00044004,
-+	VCMSG_SET_VIRTUAL_WIDTH_HEIGHT   = 0x00048004,
-+	VCMSG_GET_DEPTH                  = 0x00040005,
-+	VCMSG_TST_DEPTH                  = 0x00044005,
-+	VCMSG_SET_DEPTH                  = 0x00048005,
-+	VCMSG_GET_PIXEL_ORDER            = 0x00040006,
-+	VCMSG_TST_PIXEL_ORDER            = 0x00044006,
-+	VCMSG_SET_PIXEL_ORDER            = 0x00048006,
-+	VCMSG_GET_ALPHA_MODE             = 0x00040007,
-+	VCMSG_TST_ALPHA_MODE             = 0x00044007,
-+	VCMSG_SET_ALPHA_MODE             = 0x00048007,
-+	VCMSG_GET_PITCH                  = 0x00040008,
-+	VCMSG_TST_PITCH                  = 0x00044008,
-+	VCMSG_SET_PITCH                  = 0x00048008,
-+	VCMSG_GET_VIRTUAL_OFFSET         = 0x00040009,
-+	VCMSG_TST_VIRTUAL_OFFSET         = 0x00044009,
-+	VCMSG_SET_VIRTUAL_OFFSET         = 0x00048009,
-+	VCMSG_GET_OVERSCAN               = 0x0004000a,
-+	VCMSG_TST_OVERSCAN               = 0x0004400a,
-+	VCMSG_SET_OVERSCAN               = 0x0004800a,
-+	VCMSG_GET_PALETTE                = 0x0004000b,
-+	VCMSG_TST_PALETTE                = 0x0004400b,
-+	VCMSG_SET_PALETTE                = 0x0004800b,
-+	VCMSG_GET_LAYER                  = 0x0004000c,
-+	VCMSG_TST_LAYER                  = 0x0004400c,
-+	VCMSG_SET_LAYER                  = 0x0004800c,
-+	VCMSG_GET_TRANSFORM              = 0x0004000d,
-+	VCMSG_TST_TRANSFORM              = 0x0004400d,
-+	VCMSG_SET_TRANSFORM              = 0x0004800d,
-+	VCMSG_TST_VSYNC                  = 0x0004400e,
-+	VCMSG_SET_VSYNC                  = 0x0004800e,
-+	VCMSG_SET_CURSOR_INFO            = 0x00008010,
-+	VCMSG_SET_CURSOR_STATE           = 0x00008011,
-+};
-+
-+int bcm_mailbox_read(unsigned chan, uint32_t *data28);
-+int bcm_mailbox_write(unsigned chan, uint32_t data28);
-+int bcm_mailbox_property(void *data, int size);
-+
-+#endif
diff --git a/target/linux/brcm2708/patches-4.1/0004-Add-dwc_otg-driver.patch b/target/linux/brcm2708/patches-4.1/0004-Add-dwc_otg-driver.patch
deleted file mode 100644
index 86bce44..0000000
--- a/target/linux/brcm2708/patches-4.1/0004-Add-dwc_otg-driver.patch
+++ /dev/null
@@ -1,61067 +0,0 @@
-From 1426af053026f1ad7f7beec0bf05212f7a135a2f Mon Sep 17 00:00:00 2001
-From: popcornmix <popcornmix at gmail.com>
-Date: Wed, 1 May 2013 19:46:17 +0100
-Subject: [PATCH 004/222] Add dwc_otg driver
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: popcornmix <popcornmix at gmail.com>
-
-usb: dwc: fix lockdep false positive
-
-Signed-off-by: Kari Suvanto <karis79 at gmail.com>
-
-usb: dwc: fix inconsistent lock state
-
-Signed-off-by: Kari Suvanto <karis79 at gmail.com>
-
-Add FIQ patch to dwc_otg driver. Enable with dwc_otg.fiq_fix_enable=1. Should give about 10% more ARM performance.
-Thanks to Gordon and Costas
-
-Avoid dynamic memory allocation for channel lock in USB driver. Thanks ddv2005.
-
-Add NAK holdoff scheme. Enabled by default, disable with dwc_otg.nak_holdoff_enable=0. Thanks gsh
-
-Make sure we wait for the reset to finish
-
-dwc_otg: fix bug in dwc_otg_hcd.c resulting in silent kernel
-	 memory corruption, escalating to OOPS under high USB load.
-
-dwc_otg: Fix unsafe access of QTD during URB enqueue
-
-In dwc_otg_hcd_urb_enqueue during qtd creation, it was possible that the
-transaction could complete almost immediately after the qtd was assigned
-to a host channel during URB enqueue, which meant the qtd pointer was no
-longer valid having been completed and removed. Usually, this resulted in
-an OOPS during URB submission. By predetermining whether transactions
-need to be queued or not, this unsafe pointer access is avoided.
-
-This bug was only evident on the Pi model A where a device was attached
-that had no periodic endpoints (e.g. USB pendrive or some wlan devices).
-
-dwc_otg: Fix incorrect URB allocation error handling
-
-If the memory allocation for a dwc_otg_urb failed, the kernel would OOPS
-because for some reason a member of the *unallocated* struct was set to
-zero. Error handling changed to fail correctly.
-
-dwc_otg: fix potential use-after-free case in interrupt handler
-
-If a transaction had previously aborted, certain interrupts are
-enabled to track error counts and reset where necessary. On IN
-endpoints the host generates an ACK interrupt near-simultaneously
-with completion of transfer. In the case where this transfer had
-previously had an error, this results in a use-after-free on
-the QTD memory space with a 1-byte length being overwritten to
-0x00.
-
-dwc_otg: add handling of SPLIT transaction data toggle errors
-
-Previously a data toggle error on packets from a USB1.1 device behind
-a TT would result in the Pi locking up as the driver never handled
-the associated interrupt. Patch adds basic retry mechanism and
-interrupt acknowledgement to cater for either a chance toggle error or
-for devices that have a broken initial toggle state (FT8U232/FT232BM).
-
-dwc_otg: implement tasklet for returning URBs to usbcore hcd layer
-
-The dwc_otg driver interrupt handler for transfer completion will spend
-a very long time with interrupts disabled when a URB is completed -
-this is because usb_hcd_giveback_urb is called from within the handler
-which for a USB device driver with complicated processing (e.g. webcam)
-will take an exorbitant amount of time to complete. This results in
-missed completion interrupts for other USB packets which lead to them
-being dropped due to microframe overruns.
-
-This patch splits returning the URB to the usb hcd layer into a
-high-priority tasklet. This will have most benefit for isochronous IN
-transfers but will also have incidental benefit where multiple periodic
-devices are active at once.
-
-dwc_otg: fix NAK holdoff and allow on split transactions only
-
-This corrects a bug where if a single active non-periodic endpoint
-had at least one transaction in its qh, on frnum == MAX_FRNUM the qh
-would get skipped and never get queued again. This would result in
-a silent device until error detection (automatic or otherwise) would
-either reset the device or flush and requeue the URBs.
-
-Additionally the NAK holdoff was enabled for all transactions - this
-would potentially stall a HS endpoint for 1ms if a previous error state
-enabled this interrupt and the next response was a NAK. Fix so that
-only split transactions get held off.
-
-dwc_otg: Call usb_hcd_unlink_urb_from_ep with lock held in completion handler
-
-usb_hcd_unlink_urb_from_ep must be called with the HCD lock held.  Calling it
-asynchronously in the tasklet was not safe (regression in
-c4564d4a1a0a9b10d4419e48239f5d99e88d2667).
-
-This change unlinks it from the endpoint prior to queueing it for handling in
-the tasklet, and also adds a check to ensure the urb is OK to be unlinked
-before doing so.
-
-NULL pointer dereference kernel oopses had been observed in usb_hcd_giveback_urb
-when a USB device was unplugged/replugged during data transfer.  This effect
-was reproduced using automated USB port power control, hundreds of replug
-events were performed during active transfers to confirm that the problem was
-eliminated.
-
-USB fix using a FIQ to implement split transactions
-
-This commit adds a FIQ implementaion that schedules
-the split transactions using a FIQ so we don't get
-held off by the interrupt latency of Linux
-
-dwc_otg: fix device attributes and avoid kernel warnings on boot
-
-dcw_otg: avoid logging function that can cause panics
-
-See: https://github.com/raspberrypi/firmware/issues/21
-Thanks to cleverca22 for fix
-
-dwc_otg: mask correct interrupts after transaction error recovery
-
-The dwc_otg driver will unmask certain interrupts on a transaction
-that previously halted in the error state in order to reset the
-QTD error count. The various fine-grained interrupt handlers do not
-consider that other interrupts besides themselves were unmasked.
-
-By disabling the two other interrupts only ever enabled in DMA mode
-for this purpose, we can avoid unnecessary function calls in the
-IRQ handler. This will also prevent an unneccesary FIQ interrupt
-from being generated if the FIQ is enabled.
-
-dwc_otg: fiq: prevent FIQ thrash and incorrect state passing to IRQ
-
-In the case of a transaction to a device that had previously aborted
-due to an error, several interrupts are enabled to reset the error
-count when a device responds. This has the side-effect of making the
-FIQ thrash because the hardware will generate multiple instances of
-a NAK on an IN bulk/interrupt endpoint and multiple instances of ACK
-on an OUT bulk/interrupt endpoint. Make the FIQ mask and clear the
-associated interrupts.
-
-Additionally, on non-split transactions make sure that only unmasked
-interrupts are cleared. This caused a hard-to-trigger but serious
-race condition when you had the combination of an endpoint awaiting
-error recovery and a transaction completed on an endpoint - due to
-the sequencing and timing of interrupts generated by the dwc_otg core,
-it was possible to confuse the IRQ handler.
-
-Fix function tracing
-
-dwc_otg: whitespace cleanup in dwc_otg_urb_enqueue
-
-dwc_otg: prevent OOPSes during device disconnects
-
-The dwc_otg_urb_enqueue function is thread-unsafe. In particular the
-access of urb->hcpriv, usb_hcd_link_urb_to_ep, dwc_otg_urb->qtd and
-friends does not occur within a critical section and so if a device
-was unplugged during activity there was a high chance that the
-usbcore hub_thread would try to disable the endpoint with partially-
-formed entries in the URB queue. This would result in BUG() or null
-pointer dereferences.
-
-Fix so that access of urb->hcpriv, enqueuing to the hardware and
-adding to usbcore endpoint URB lists is contained within a single
-critical section.
-
-dwc_otg: prevent BUG() in TT allocation if hub address is > 16
-
-A fixed-size array is used to track TT allocation. This was
-previously set to 16 which caused a crash because
-dwc_otg_hcd_allocate_port would read past the end of the array.
-
-This was hit if a hub was plugged in which enumerated as addr > 16,
-due to previous device resets or unplugs.
-
-Also add #ifdef FIQ_DEBUG around hcd->hub_port_alloc[], which grows
-to a large size if 128 hub addresses are supported. This field is
-for debug only for tracking which frame an allocate happened in.
-
-dwc_otg: make channel halts with unknown state less damaging
-
-If the IRQ received a channel halt interrupt through the FIQ
-with no other bits set, the IRQ would not release the host
-channel and never complete the URB.
-
-Add catchall handling to treat as a transaction error and retry.
-
-dwc_otg: fiq_split: use TTs with more granularity
-
-This fixes certain issues with split transaction scheduling.
-
-- Isochronous multi-packet OUT transactions now hog the TT until
-  they are completed - this prevents hubs aborting transactions
-  if they get a periodic start-split out-of-order
-- Don't perform TT allocation on non-periodic endpoints - this
-  allows simultaneous use of the TT's bulk/control and periodic
-  transaction buffers
-
-This commit will mainly affect USB audio playback.
-
-dwc_otg: fix potential sleep while atomic during urb enqueue
-
-Fixes a regression introduced with eb1b482a. Kmalloc called from
-dwc_otg_hcd_qtd_add / dwc_otg_hcd_qtd_create did not always have
-the GPF_ATOMIC flag set. Force this flag when inside the larger
-critical section.
-
-dwc_otg: make fiq_split_enable imply fiq_fix_enable
-
-Failing to set up the FIQ correctly would result in
-"IRQ 32: nobody cared" errors in dmesg.
-
-dwc_otg: prevent crashes on host port disconnects
-
-Fix several issues resulting in crashes or inconsistent state
-if a Model A root port was disconnected.
-
-- Clean up queue heads properly in kill_urbs_in_qh_list by
-  removing the empty QHs from the schedule lists
-- Set the halt status properly to prevent IRQ handlers from
-  using freed memory
-- Add fiq_split related cleanup for saved registers
-- Make microframe scheduling reclaim host channels if
-  active during a disconnect
-- Abort URBs with -ESHUTDOWN status response, informing
-  device drivers so they respond in a more correct fashion
-  and don't try to resubmit URBs
-- Prevent IRQ handlers from attempting to handle channel
-  interrupts if the associated URB was dequeued (and the
-  driver state was cleared)
-
-dwc_otg: prevent leaking URBs during enqueue
-
-A dwc_otg_urb would get leaked if the HCD enqueue function
-failed for any reason. Free the URB at the appropriate points.
-
-dwc_otg: Enable NAK holdoff for control split transactions
-
-Certain low-speed devices take a very long time to complete a
-data or status stage of a control transaction, producing NAK
-responses until they complete internal processing - the USB2.0
-spec limit is up to 500mS. This causes the same type of interrupt
-storm as seen with USB-serial dongles prior to c8edb238.
-
-In certain circumstances, usually while booting, this interrupt
-storm could cause SD card timeouts.
-
-dwc_otg: Fix for occasional lockup on boot when doing a USB reset
-
-dwc_otg: Don't issue traffic to LS devices in FS mode
-
-Issuing low-speed packets when the root port is in full-speed mode
-causes the root port to stop responding. Explicitly fail when
-enqueuing URBs to a LS endpoint on a FS bus.
-
-Fix ARM architecture issue with local_irq_restore()
-
-If local_fiq_enable() is called before a local_irq_restore(flags) where
-the flags variable has the F bit set, the FIQ will be erroneously disabled.
-
-Fixup arch_local_irq_restore to avoid trampling the F bit in CPSR.
-
-Also fix some of the hacks previously implemented for previous dwc_otg
-incarnations.
-
-dwc_otg: fiq_fsm: Base commit for driver rewrite
-
-This commit removes the previous FIQ fixes entirely and adds fiq_fsm.
-
-This rewrite features much more complete support for split transactions
-and takes into account several OTG hardware bugs. High-speed
-isochronous transactions are also capable of being performed by fiq_fsm.
-
-All driver options have been removed and replaced with:
-  - dwc_otg.fiq_enable (bool)
-  - dwc_otg.fiq_fsm_enable (bool)
-  - dwc_otg.fiq_fsm_mask (bitmask)
-  - dwc_otg.nak_holdoff (unsigned int)
-
-Defaults are specified such that fiq_fsm behaves similarly to the
-previously implemented FIQ fixes.
-
-fiq_fsm: Push error recovery into the FIQ when fiq_fsm is used
-
-If the transfer associated with a QTD failed due to a bus error, the HCD
-would retry the transfer up to 3 times (implementing the USB2.0
-three-strikes retry in software).
-
-Due to the masking mechanism used by fiq_fsm, it is only possible to pass
-a single interrupt through to the HCD per-transfer.
-
-In this instance host channels would fall off the radar because the error
-reset would function, but the subsequent channel halt would be lost.
-
-Push the error count reset into the FIQ handler.
-
-fiq_fsm: Implement timeout mechanism
-
-For full-speed endpoints with a large packet size, interrupt latency
-runs the risk of the FIQ starting a transaction too late in a full-speed
-frame. If the device is still transmitting data when EOF2 for the
-downstream frame occurs, the hub will disable the port. This change is
-not reflected in the hub status endpoint and the device becomes
-unresponsive.
-
-Prevent high-bandwidth transactions from being started too late in a
-frame. The mechanism is not guaranteed: a combination of bit stuffing
-and hub latency may still result in a device overrunning.
-
-fiq_fsm: fix bounce buffer utilisation for Isochronous OUT
-
-Multi-packet isochronous OUT transactions were subject to a few bounday
-bugs. Fix them.
-
-Audio playback is now much more robust: however, an issue stands with
-devices that have adaptive sinks - ALSA plays samples too fast.
-
-dwc_otg: Return full-speed frame numbers in HS mode
-
-The frame counter increments on every *microframe* in high-speed mode.
-Most device drivers expect this number to be in full-speed frames - this
-caused considerable confusion to e.g. snd_usb_audio which uses the
-frame counter to estimate the number of samples played.
-
-fiq_fsm: save PID on completion of interrupt OUT transfers
-
-Also add edge case handling for interrupt transports.
-
-Note that for periodic split IN, data toggles are unimplemented in the
-OTG host hardware - it unconditionally accepts any PID.
-
-fiq_fsm: add missing case for fiq_fsm_tt_in_use()
-
-Certain combinations of bitrate and endpoint activity could
-result in a periodic transaction erroneously getting started
-while the previous Isochronous OUT was still active.
-
-fiq_fsm: clear hcintmsk for aborted transactions
-
-Prevents the FIQ from erroneously handling interrupts
-on a timed out channel.
-
-fiq_fsm: enable by default
-
-fiq_fsm: fix dequeues for non-periodic split transactions
-
-If a dequeue happened between the SSPLIT and CSPLIT phases of the
-transaction, the HCD would never receive an interrupt.
-
-fiq_fsm: Disable by default
-
-fiq_fsm: Handle HC babble errors
-
-The HCTSIZ transfer size field raises a babble interrupt if
-the counter wraps. Handle the resulting interrupt in this case.
-
-dwc_otg: fix interrupt registration for fiq_enable=0
-
-Additionally make the module parameter conditional for wherever
-hcd->fiq_state is touched.
-
-fiq_fsm: Enable by default
-
-dwc_otg: Fix various issues with root port and transaction errors
-
-Process the host port interrupts correctly (and don't trample them).
-Root port hotplug now functional again.
-
-Fix a few thinkos with the transaction error passthrough for fiq_fsm.
-
-fiq_fsm: Implement hack for Split Interrupt transactions
-
-Hubs aren't too picky about which endpoint we send Control type split
-transactions to. By treating Interrupt transfers as Control, it is
-possible to use the non-periodic queue in the OTG core as well as the
-non-periodic FIFOs in the hub itself. This massively reduces the
-microframe exclusivity/contention that periodic split transactions
-otherwise have to enforce.
-
-It goes without saying that this is a fairly egregious USB specification
-violation, but it works.
-
-Original idea by Hans Petter Selasky @ FreeBSD.org.
-
-dwc_otg: FIQ support on SMP. Set up FIQ stack and handler on Core 0 only.
-
-dwc_otg: introduce fiq_fsm_spin(un|)lock()
-
-SMP safety for the FIQ relies on register read-modify write cycles being
-completed in the correct order. Several places in the DWC code modify
-registers also touched by the FIQ. Protect these by a bare-bones lock
-mechanism.
-
-This also makes it possible to run the FIQ and IRQ handlers on different
-cores.
-
-fiq_fsm: fix build on bcm2708 and bcm2709 platforms
-
-dwc_otg: put some barriers back where they should be for UP
-
-bcm2709/dwc_otg: Setup FIQ on core 1 if >1 core active
-
-dwc_otg: fixup read-modify-write in critical paths
-
-Be more careful about read-modify-write on registers that the FIQ
-also touches.
-
-Guard fiq_fsm_spin_lock with fiq_enable check
-
-fiq_fsm: Falling out of the state machine isn't fatal
-
-This edge case can be hit if the port is disabled while the FIQ is
-in the middle of a transaction. Make the effects less severe.
-
-Also get rid of the useless return value.
-
-squash: dwc_otg: Allow to build without SMP
-
-usb: core: make overcurrent messages more prominent
-
-Hub overcurrent messages are more serious than "debug". Increase loglevel.
-
-usb: dwc_otg: Don't use dma_to_virt()
-
-Commit 6ce0d20 changes dma_to_virt() which breaks this driver.
-Open code the old dma_to_virt() implementation to work around this.
-
-Limit the use of __bus_to_virt() to cases where transfer_buffer_length
-is set and transfer_buffer is not set. This is done to increase the
-chance that this driver will also work on ARCH_BCM2835.
-
-transfer_buffer should not be NULL if the length is set, but the
-comment in the code indicates that there are situations where this
-might happen. drivers/usb/isp1760/isp1760-hcd.c also has a similar
-comment pointing to a possible: 'usb storage / SCSI bug'.
-
-Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
-
-dwc_otg: Fix crash when fiq_enable=0
----
- arch/arm/include/asm/irqflags.h                    |   16 +-
- arch/arm/kernel/fiqasm.S                           |    4 +
- arch/arm/mach-bcm2708/armctrl.c                    |   19 +-
- arch/arm/mach-bcm2708/bcm2708.c                    |   11 +
- arch/arm/mach-bcm2708/include/mach/irqs.h          |  153 +-
- arch/arm/mach-bcm2709/armctrl.c                    |   10 +-
- drivers/usb/Makefile                               |    1 +
- drivers/usb/core/generic.c                         |    1 +
- drivers/usb/core/hub.c                             |    2 +-
- drivers/usb/core/message.c                         |   79 +
- drivers/usb/core/otg_whitelist.h                   |  114 +-
- drivers/usb/gadget/file_storage.c                  | 3676 ++++++++++
- drivers/usb/host/Kconfig                           |   13 +
- drivers/usb/host/Makefile                          |    2 +
- drivers/usb/host/dwc_common_port/Makefile          |   58 +
- drivers/usb/host/dwc_common_port/Makefile.fbsd     |   17 +
- drivers/usb/host/dwc_common_port/Makefile.linux    |   49 +
- drivers/usb/host/dwc_common_port/changes.txt       |  174 +
- drivers/usb/host/dwc_common_port/doc/doxygen.cfg   |  270 +
- drivers/usb/host/dwc_common_port/dwc_cc.c          |  532 ++
- drivers/usb/host/dwc_common_port/dwc_cc.h          |  224 +
- drivers/usb/host/dwc_common_port/dwc_common_fbsd.c | 1308 ++++
- .../usb/host/dwc_common_port/dwc_common_linux.c    | 1434 ++++
- drivers/usb/host/dwc_common_port/dwc_common_nbsd.c | 1275 ++++
- drivers/usb/host/dwc_common_port/dwc_crypto.c      |  308 +
- drivers/usb/host/dwc_common_port/dwc_crypto.h      |  111 +
- drivers/usb/host/dwc_common_port/dwc_dh.c          |  291 +
- drivers/usb/host/dwc_common_port/dwc_dh.h          |  106 +
- drivers/usb/host/dwc_common_port/dwc_list.h        |  594 ++
- drivers/usb/host/dwc_common_port/dwc_mem.c         |  245 +
- drivers/usb/host/dwc_common_port/dwc_modpow.c      |  636 ++
- drivers/usb/host/dwc_common_port/dwc_modpow.h      |   34 +
- drivers/usb/host/dwc_common_port/dwc_notifier.c    |  319 +
- drivers/usb/host/dwc_common_port/dwc_notifier.h    |  122 +
- drivers/usb/host/dwc_common_port/dwc_os.h          | 1276 ++++
- drivers/usb/host/dwc_common_port/usb.h             |  946 +++
- drivers/usb/host/dwc_otg/Makefile                  |   82 +
- drivers/usb/host/dwc_otg/doc/doxygen.cfg           |  224 +
- drivers/usb/host/dwc_otg/dummy_audio.c             | 1575 +++++
- drivers/usb/host/dwc_otg/dwc_cfi_common.h          |  142 +
- drivers/usb/host/dwc_otg/dwc_otg_adp.c             |  854 +++
- drivers/usb/host/dwc_otg/dwc_otg_adp.h             |   80 +
- drivers/usb/host/dwc_otg/dwc_otg_attr.c            | 1210 ++++
- drivers/usb/host/dwc_otg/dwc_otg_attr.h            |   89 +
- drivers/usb/host/dwc_otg/dwc_otg_cfi.c             | 1876 +++++
- drivers/usb/host/dwc_otg/dwc_otg_cfi.h             |  320 +
- drivers/usb/host/dwc_otg/dwc_otg_cil.c             | 7141 ++++++++++++++++++++
- drivers/usb/host/dwc_otg/dwc_otg_cil.h             | 1464 ++++
- drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c        | 1594 +++++
- drivers/usb/host/dwc_otg/dwc_otg_core_if.h         |  705 ++
- drivers/usb/host/dwc_otg/dwc_otg_dbg.h             |  117 +
- drivers/usb/host/dwc_otg/dwc_otg_driver.c          | 1756 +++++
- drivers/usb/host/dwc_otg/dwc_otg_driver.h          |   86 +
- drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c         | 1346 ++++
- drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h         |  367 +
- drivers/usb/host/dwc_otg/dwc_otg_fiq_stub.S        |   80 +
- drivers/usb/host/dwc_otg/dwc_otg_hcd.c             | 4252 ++++++++++++
- drivers/usb/host/dwc_otg/dwc_otg_hcd.h             |  862 +++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c        | 1132 ++++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h          |  417 ++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c        | 2713 ++++++++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c       |  995 +++
- drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c       |  957 +++
- drivers/usb/host/dwc_otg/dwc_otg_os_dep.h          |  188 +
- drivers/usb/host/dwc_otg/dwc_otg_pcd.c             | 2712 ++++++++
- drivers/usb/host/dwc_otg/dwc_otg_pcd.h             |  266 +
- drivers/usb/host/dwc_otg/dwc_otg_pcd_if.h          |  360 +
- drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c        | 5147 ++++++++++++++
- drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c       | 1360 ++++
- drivers/usb/host/dwc_otg/dwc_otg_regs.h            | 2550 +++++++
- drivers/usb/host/dwc_otg/test/Makefile             |   16 +
- drivers/usb/host/dwc_otg/test/dwc_otg_test.pm      |  337 +
- drivers/usb/host/dwc_otg/test/test_mod_param.pl    |  133 +
- drivers/usb/host/dwc_otg/test/test_sysfs.pl        |  193 +
- 74 files changed, 60032 insertions(+), 96 deletions(-)
- create mode 100644 drivers/usb/gadget/file_storage.c
- create mode 100644 drivers/usb/host/dwc_common_port/Makefile
- create mode 100644 drivers/usb/host/dwc_common_port/Makefile.fbsd
- create mode 100644 drivers/usb/host/dwc_common_port/Makefile.linux
- create mode 100644 drivers/usb/host/dwc_common_port/changes.txt
- create mode 100644 drivers/usb/host/dwc_common_port/doc/doxygen.cfg
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_cc.c
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_cc.h
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_common_fbsd.c
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_common_linux.c
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_common_nbsd.c
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_crypto.c
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_crypto.h
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_dh.c
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_dh.h
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_list.h
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_mem.c
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_modpow.c
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_modpow.h
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_notifier.c
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_notifier.h
- create mode 100644 drivers/usb/host/dwc_common_port/dwc_os.h
- create mode 100644 drivers/usb/host/dwc_common_port/usb.h
- create mode 100644 drivers/usb/host/dwc_otg/Makefile
- create mode 100644 drivers/usb/host/dwc_otg/doc/doxygen.cfg
- create mode 100644 drivers/usb/host/dwc_otg/dummy_audio.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_cfi_common.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_adp.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_adp.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_attr.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_attr.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cfi.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cfi.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cil.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cil.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_core_if.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_dbg.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_driver.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_driver.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_fiq_stub.S
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_os_dep.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_pcd.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_pcd.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_pcd_if.h
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_pcd_intr.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_pcd_linux.c
- create mode 100644 drivers/usb/host/dwc_otg/dwc_otg_regs.h
- create mode 100644 drivers/usb/host/dwc_otg/test/Makefile
- create mode 100644 drivers/usb/host/dwc_otg/test/dwc_otg_test.pm
- create mode 100644 drivers/usb/host/dwc_otg/test/test_mod_param.pl
- create mode 100644 drivers/usb/host/dwc_otg/test/test_sysfs.pl
-
---- a/arch/arm/include/asm/irqflags.h
-+++ b/arch/arm/include/asm/irqflags.h
-@@ -145,12 +145,22 @@ static inline unsigned long arch_local_s
- }
- 
- /*
-- * restore saved IRQ & FIQ state
-+ * restore saved IRQ state
-  */
- static inline void arch_local_irq_restore(unsigned long flags)
- {
--	asm volatile(
--		"	msr	" IRQMASK_REG_NAME_W ", %0	@ local_irq_restore"
-+	unsigned long temp = 0;
-+	flags &= ~(1 << 6);
-+	asm volatile (
-+		" mrs %0, cpsr"
-+		: "=r" (temp)
-+		:
-+		: "memory", "cc");
-+		/* Preserve FIQ bit */
-+		temp &= (1 << 6);
-+		flags = flags | temp;
-+	asm volatile (
-+		"    msr    cpsr_c, %0    @ local_irq_restore"
- 		:
- 		: "r" (flags)
- 		: "memory", "cc");
---- a/arch/arm/kernel/fiqasm.S
-+++ b/arch/arm/kernel/fiqasm.S
-@@ -47,3 +47,7 @@ ENTRY(__get_fiq_regs)
- 	mov	r0, r0		@ avoid hazard prior to ARMv4
- 	ret	lr
- ENDPROC(__get_fiq_regs)
-+
-+ENTRY(__FIQ_Branch)
-+	mov pc, r8
-+ENDPROC(__FIQ_Branch)
---- a/arch/arm/mach-bcm2708/armctrl.c
-+++ b/arch/arm/mach-bcm2708/armctrl.c
-@@ -54,8 +54,12 @@ static void armctrl_mask_irq(struct irq_
- 		0
- 	};
- 
--	unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
--	writel(1 << (data & 0x1f), __io_address(disables[(data >> 5) & 0x3]));
-+	if (d->irq >= FIQ_START) {
-+		writel(0, __io_address(ARM_IRQ_FAST));
-+	} else {
-+		unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
-+		writel(1 << (data & 0x1f), __io_address(disables[(data >> 5) & 0x3]));
-+	}
- }
- 
- static void armctrl_unmask_irq(struct irq_data *d)
-@@ -67,8 +71,14 @@ static void armctrl_unmask_irq(struct ir
- 		0
- 	};
- 
--	unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
--	writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3]));
-+	if (d->irq >= FIQ_START) {
-+		unsigned int data =
-+		    (unsigned int)irq_get_chip_data(d->irq) - FIQ_START;
-+		writel(0x80 | data, __io_address(ARM_IRQ_FAST));
-+	} else {
-+		unsigned int data = (unsigned int)irq_get_chip_data(d->irq);
-+		writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3]));
-+	}
- }
- 
- #ifdef CONFIG_OF
-@@ -299,6 +309,7 @@ int __init armctrl_init(void __iomem * b
- 	}
- 
- 	armctrl_pm_register(base, irq_start, resume_sources);
-+	init_FIQ(FIQ_START);
- 	armctrl_dt_init();
- 	return 0;
- }
---- a/arch/arm/mach-bcm2708/bcm2708.c
-+++ b/arch/arm/mach-bcm2708/bcm2708.c
-@@ -254,12 +254,23 @@ static struct resource bcm2708_usb_resou
- 		.flags = IORESOURCE_MEM,
- 		},
- 	[1] = {
-+		.start = MPHI_BASE,
-+		.end = MPHI_BASE + SZ_4K - 1,
-+		.flags = IORESOURCE_MEM,
-+		},
-+	[2] = {
-+		.start = IRQ_HOSTPORT,
-+		.end = IRQ_HOSTPORT,
-+		.flags = IORESOURCE_IRQ,
-+		},
-+	[3] = {
- 		.start = IRQ_USB,
- 		.end = IRQ_USB,
- 		.flags = IORESOURCE_IRQ,
- 		},
- };
- 
-+
- static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON);
- 
- static struct platform_device bcm2708_usb_device = {
---- a/arch/arm/mach-bcm2708/include/mach/irqs.h
-+++ b/arch/arm/mach-bcm2708/include/mach/irqs.h
-@@ -106,87 +106,90 @@
- #define IRQ_PENDING1          (IRQ_ARMCTRL_START + INTERRUPT_PENDING1)
- #define IRQ_PENDING2          (IRQ_ARMCTRL_START + INTERRUPT_PENDING2)
- 
-+#define FIQ_START             HARD_IRQS
-+
- /*
-  *  FIQ interrupts definitions are the same as the INT definitions.
-  */
--#define FIQ_TIMER0            INT_TIMER0
--#define FIQ_TIMER1            INT_TIMER1
--#define FIQ_TIMER2            INT_TIMER2
--#define FIQ_TIMER3            INT_TIMER3
--#define FIQ_CODEC0            INT_CODEC0
--#define FIQ_CODEC1            INT_CODEC1
--#define FIQ_CODEC2            INT_CODEC2
--#define FIQ_JPEG              INT_JPEG
--#define FIQ_ISP               INT_ISP
--#define FIQ_USB               INT_USB
--#define FIQ_3D                INT_3D
--#define FIQ_TRANSPOSER        INT_TRANSPOSER
--#define FIQ_MULTICORESYNC0    INT_MULTICORESYNC0
--#define FIQ_MULTICORESYNC1    INT_MULTICORESYNC1
--#define FIQ_MULTICORESYNC2    INT_MULTICORESYNC2
--#define FIQ_MULTICORESYNC3    INT_MULTICORESYNC3
--#define FIQ_DMA0              INT_DMA0
--#define FIQ_DMA1              INT_DMA1
--#define FIQ_DMA2              INT_DMA2
--#define FIQ_DMA3              INT_DMA3
--#define FIQ_DMA4              INT_DMA4
--#define FIQ_DMA5              INT_DMA5
--#define FIQ_DMA6              INT_DMA6
--#define FIQ_DMA7              INT_DMA7
--#define FIQ_DMA8              INT_DMA8
--#define FIQ_DMA9              INT_DMA9
--#define FIQ_DMA10             INT_DMA10
--#define FIQ_DMA11             INT_DMA11
--#define FIQ_DMA12             INT_DMA12
--#define FIQ_AUX               INT_AUX
--#define FIQ_ARM               INT_ARM
--#define FIQ_VPUDMA            INT_VPUDMA
--#define FIQ_HOSTPORT          INT_HOSTPORT
--#define FIQ_VIDEOSCALER       INT_VIDEOSCALER
--#define FIQ_CCP2TX            INT_CCP2TX
--#define FIQ_SDC               INT_SDC
--#define FIQ_DSI0              INT_DSI0
--#define FIQ_AVE               INT_AVE
--#define FIQ_CAM0              INT_CAM0
--#define FIQ_CAM1              INT_CAM1
--#define FIQ_HDMI0             INT_HDMI0
--#define FIQ_HDMI1             INT_HDMI1
--#define FIQ_PIXELVALVE1       INT_PIXELVALVE1
--#define FIQ_I2CSPISLV         INT_I2CSPISLV
--#define FIQ_DSI1              INT_DSI1
--#define FIQ_PWA0              INT_PWA0
--#define FIQ_PWA1              INT_PWA1
--#define FIQ_CPR               INT_CPR
--#define FIQ_SMI               INT_SMI
--#define FIQ_GPIO0             INT_GPIO0
--#define FIQ_GPIO1             INT_GPIO1
--#define FIQ_GPIO2             INT_GPIO2
--#define FIQ_GPIO3             INT_GPIO3
--#define FIQ_I2C               INT_I2C
--#define FIQ_SPI               INT_SPI
--#define FIQ_I2SPCM            INT_I2SPCM
--#define FIQ_SDIO              INT_SDIO
--#define FIQ_UART              INT_UART
--#define FIQ_SLIMBUS           INT_SLIMBUS
--#define FIQ_VEC               INT_VEC
--#define FIQ_CPG               INT_CPG
--#define FIQ_RNG               INT_RNG
--#define FIQ_ARASANSDIO        INT_ARASANSDIO
--#define FIQ_AVSPMON           INT_AVSPMON
-+#define FIQ_TIMER0            (FIQ_START+INTERRUPT_TIMER0)
-+#define FIQ_TIMER1            (FIQ_START+INTERRUPT_TIMER1)
-+#define FIQ_TIMER2            (FIQ_START+INTERRUPT_TIMER2)
-+#define FIQ_TIMER3            (FIQ_START+INTERRUPT_TIMER3)
-+#define FIQ_CODEC0            (FIQ_START+INTERRUPT_CODEC0)
-+#define FIQ_CODEC1            (FIQ_START+INTERRUPT_CODEC1)
-+#define FIQ_CODEC2            (FIQ_START+INTERRUPT_CODEC2)
-+#define FIQ_JPEG              (FIQ_START+INTERRUPT_JPEG)
-+#define FIQ_ISP               (FIQ_START+INTERRUPT_ISP)
-+#define FIQ_USB               (FIQ_START+INTERRUPT_USB)
-+#define FIQ_3D                (FIQ_START+INTERRUPT_3D)
-+#define FIQ_TRANSPOSER        (FIQ_START+INTERRUPT_TRANSPOSER)
-+#define FIQ_MULTICORESYNC0    (FIQ_START+INTERRUPT_MULTICORESYNC0)
-+#define FIQ_MULTICORESYNC1    (FIQ_START+INTERRUPT_MULTICORESYNC1)
-+#define FIQ_MULTICORESYNC2    (FIQ_START+INTERRUPT_MULTICORESYNC2)
-+#define FIQ_MULTICORESYNC3    (FIQ_START+INTERRUPT_MULTICORESYNC3)
-+#define FIQ_DMA0              (FIQ_START+INTERRUPT_DMA0)
-+#define FIQ_DMA1              (FIQ_START+INTERRUPT_DMA1)
-+#define FIQ_DMA2              (FIQ_START+INTERRUPT_DMA2)
-+#define FIQ_DMA3              (FIQ_START+INTERRUPT_DMA3)
-+#define FIQ_DMA4              (FIQ_START+INTERRUPT_DMA4)
-+#define FIQ_DMA5              (FIQ_START+INTERRUPT_DMA5)
-+#define FIQ_DMA6              (FIQ_START+INTERRUPT_DMA6)
-+#define FIQ_DMA7              (FIQ_START+INTERRUPT_DMA7)
-+#define FIQ_DMA8              (FIQ_START+INTERRUPT_DMA8)
-+#define FIQ_DMA9              (FIQ_START+INTERRUPT_DMA9)
-+#define FIQ_DMA10             (FIQ_START+INTERRUPT_DMA10)
-+#define FIQ_DMA11             (FIQ_START+INTERRUPT_DMA11)
-+#define FIQ_DMA12             (FIQ_START+INTERRUPT_DMA12)
-+#define FIQ_AUX               (FIQ_START+INTERRUPT_AUX)
-+#define FIQ_ARM               (FIQ_START+INTERRUPT_ARM)
-+#define FIQ_VPUDMA            (FIQ_START+INTERRUPT_VPUDMA)
-+#define FIQ_HOSTPORT          (FIQ_START+INTERRUPT_HOSTPORT)
-+#define FIQ_VIDEOSCALER       (FIQ_START+INTERRUPT_VIDEOSCALER)
-+#define FIQ_CCP2TX            (FIQ_START+INTERRUPT_CCP2TX)
-+#define FIQ_SDC               (FIQ_START+INTERRUPT_SDC)
-+#define FIQ_DSI0              (FIQ_START+INTERRUPT_DSI0)
-+#define FIQ_AVE               (FIQ_START+INTERRUPT_AVE)
-+#define FIQ_CAM0              (FIQ_START+INTERRUPT_CAM0)
-+#define FIQ_CAM1              (FIQ_START+INTERRUPT_CAM1)
-+#define FIQ_HDMI0             (FIQ_START+INTERRUPT_HDMI0)
-+#define FIQ_HDMI1             (FIQ_START+INTERRUPT_HDMI1)
-+#define FIQ_PIXELVALVE1       (FIQ_START+INTERRUPT_PIXELVALVE1)
-+#define FIQ_I2CSPISLV         (FIQ_START+INTERRUPT_I2CSPISLV)
-+#define FIQ_DSI1              (FIQ_START+INTERRUPT_DSI1)
-+#define FIQ_PWA0              (FIQ_START+INTERRUPT_PWA0)
-+#define FIQ_PWA1              (FIQ_START+INTERRUPT_PWA1)
-+#define FIQ_CPR               (FIQ_START+INTERRUPT_CPR)
-+#define FIQ_SMI               (FIQ_START+INTERRUPT_SMI)
-+#define FIQ_GPIO0             (FIQ_START+INTERRUPT_GPIO0)
-+#define FIQ_GPIO1             (FIQ_START+INTERRUPT_GPIO1)
-+#define FIQ_GPIO2             (FIQ_START+INTERRUPT_GPIO2)
-+#define FIQ_GPIO3             (FIQ_START+INTERRUPT_GPIO3)
-+#define FIQ_I2C               (FIQ_START+INTERRUPT_I2C)
-+#define FIQ_SPI               (FIQ_START+INTERRUPT_SPI)
-+#define FIQ_I2SPCM            (FIQ_START+INTERRUPT_I2SPCM)
-+#define FIQ_SDIO              (FIQ_START+INTERRUPT_SDIO)
-+#define FIQ_UART              (FIQ_START+INTERRUPT_UART)
-+#define FIQ_SLIMBUS           (FIQ_START+INTERRUPT_SLIMBUS)
-+#define FIQ_VEC               (FIQ_START+INTERRUPT_VEC)
-+#define FIQ_CPG               (FIQ_START+INTERRUPT_CPG)
-+#define FIQ_RNG               (FIQ_START+INTERRUPT_RNG)
-+#define FIQ_ARASANSDIO        (FIQ_START+INTERRUPT_ARASANSDIO)
-+#define FIQ_AVSPMON           (FIQ_START+INTERRUPT_AVSPMON)
- 
--#define FIQ_ARM_TIMER         INT_ARM_TIMER
--#define FIQ_ARM_MAILBOX       INT_ARM_MAILBOX
--#define FIQ_ARM_DOORBELL_0    INT_ARM_DOORBELL_0
--#define FIQ_ARM_DOORBELL_1    INT_ARM_DOORBELL_1
--#define FIQ_VPU0_HALTED       INT_VPU0_HALTED
--#define FIQ_VPU1_HALTED       INT_VPU1_HALTED
--#define FIQ_ILLEGAL_TYPE0     INT_ILLEGAL_TYPE0
--#define FIQ_ILLEGAL_TYPE1     INT_ILLEGAL_TYPE1
--#define FIQ_PENDING1          INT_PENDING1
--#define FIQ_PENDING2          INT_PENDING2
-+#define FIQ_ARM_TIMER         (FIQ_START+INTERRUPT_ARM_TIMER)
-+#define FIQ_ARM_MAILBOX       (FIQ_START+INTERRUPT_ARM_MAILBOX)
-+#define FIQ_ARM_DOORBELL_0    (FIQ_START+INTERRUPT_ARM_DOORBELL_0)
-+#define FIQ_ARM_DOORBELL_1    (FIQ_START+INTERRUPT_ARM_DOORBELL_1)
-+#define FIQ_VPU0_HALTED       (FIQ_START+INTERRUPT_VPU0_HALTED)
-+#define FIQ_VPU1_HALTED       (FIQ_START+INTERRUPT_VPU1_HALTED)
-+#define FIQ_ILLEGAL_TYPE0     (FIQ_START+INTERRUPT_ILLEGAL_TYPE0)
-+#define FIQ_ILLEGAL_TYPE1     (FIQ_START+INTERRUPT_ILLEGAL_TYPE1)
-+#define FIQ_PENDING1          (FIQ_START+INTERRUPT_PENDING1)
-+#define FIQ_PENDING2          (FIQ_START+INTERRUPT_PENDING2)
- 
- #define HARD_IRQS	      (64 + 21)
--#define GPIO_IRQ_START  (HARD_IRQS)
-+#define FIQ_IRQS        (64 + 21)
-+#define GPIO_IRQ_START  (HARD_IRQS + FIQ_IRQS)
- #define GPIO_IRQS	      (32*5)
- #define SPARE_ALLOC_IRQS      64
- #define BCM2708_ALLOC_IRQS    (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS)
---- a/arch/arm/mach-bcm2709/armctrl.c
-+++ b/arch/arm/mach-bcm2709/armctrl.c
-@@ -91,7 +91,15 @@ static void armctrl_unmask_irq(struct ir
- 	};
- 	int i;
- 	if (d->irq >= FIQ_START) {
--		unsigned int data = (unsigned int)irq_get_chip_data(d->irq) - FIQ_START;
-+		unsigned int data;
-+		if (num_online_cpus() > 1) {
-+			data = readl(__io_address(ARM_LOCAL_GPU_INT_ROUTING));
-+			data &= ~0xc;
-+			data |= (1 << 2);
-+			writel(data, __io_address(ARM_LOCAL_GPU_INT_ROUTING));
-+		}
-+		/* Unmask in ARMCTRL block after routing it properly */
-+		data = (unsigned int)irq_get_chip_data(d->irq) - FIQ_START;
- 		writel(0x80 | data, __io_address(ARM_IRQ_FAST));
- 	} else if (d->irq >= IRQ_ARM_LOCAL_CNTPSIRQ && d->irq < IRQ_ARM_LOCAL_CNTPSIRQ + 4) {
- #if 1
---- a/drivers/usb/Makefile
-+++ b/drivers/usb/Makefile
-@@ -7,6 +7,7 @@
- obj-$(CONFIG_USB)		+= core/
- obj-$(CONFIG_USB_SUPPORT)	+= phy/
- 
-+obj-$(CONFIG_USB_DWCOTG)	+= host/
- obj-$(CONFIG_USB_DWC3)		+= dwc3/
- obj-$(CONFIG_USB_DWC2)		+= dwc2/
- obj-$(CONFIG_USB_ISP1760)	+= isp1760/
---- a/drivers/usb/core/generic.c
-+++ b/drivers/usb/core/generic.c
-@@ -152,6 +152,7 @@ int usb_choose_configuration(struct usb_
- 		dev_warn(&udev->dev,
- 			"no configuration chosen from %d choice%s\n",
- 			num_configs, plural(num_configs));
-+		dev_warn(&udev->dev, "No support over %dmA\n", udev->bus_mA);
- 	}
- 	return i;
- }
---- a/drivers/usb/core/hub.c
-+++ b/drivers/usb/core/hub.c
-@@ -4911,7 +4911,7 @@ static void port_event(struct usb_hub *h
- 	if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
- 		u16 status = 0, unused;
- 
--		dev_dbg(&port_dev->dev, "over-current change\n");
-+		dev_notice(&port_dev->dev, "over-current change\n");
- 		usb_clear_port_feature(hdev, port1,
- 				USB_PORT_FEAT_C_OVER_CURRENT);
- 		msleep(100);	/* Cool down */
---- a/drivers/usb/core/message.c
-+++ b/drivers/usb/core/message.c
-@@ -1872,6 +1872,85 @@ free_interfaces:
- 	if (cp->string == NULL &&
- 			!(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS))
- 		cp->string = usb_cache_string(dev, cp->desc.iConfiguration);
-+/* Uncomment this define to enable the HS Electrical Test support */
-+#define DWC_HS_ELECT_TST 1
-+#ifdef DWC_HS_ELECT_TST
-+		/* Here we implement the HS Electrical Test support. The
-+		 * tester uses a vendor ID of 0x1A0A to indicate we should
-+		 * run a special test sequence. The product ID tells us
-+		 * which sequence to run. We invoke the test sequence by
-+		 * sending a non-standard SetFeature command to our root
-+		 * hub port. Our dwc_otg_hcd_hub_control() routine will
-+		 * recognize the command and perform the desired test
-+		 * sequence.
-+		 */
-+		if (dev->descriptor.idVendor == 0x1A0A) {
-+			/* HSOTG Electrical Test */
-+			dev_warn(&dev->dev, "VID from HSOTG Electrical Test Fixture\n");
-+
-+			if (dev->bus && dev->bus->root_hub) {
-+				struct usb_device *hdev = dev->bus->root_hub;
-+				dev_warn(&dev->dev, "Got PID 0x%x\n", dev->descriptor.idProduct);
-+
-+				switch (dev->descriptor.idProduct) {
-+				case 0x0101:	/* TEST_SE0_NAK */
-+					dev_warn(&dev->dev, "TEST_SE0_NAK\n");
-+					usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-+							USB_REQ_SET_FEATURE, USB_RT_PORT,
-+							USB_PORT_FEAT_TEST, 0x300, NULL, 0, HZ);
-+					break;
-+
-+				case 0x0102:	/* TEST_J */
-+					dev_warn(&dev->dev, "TEST_J\n");
-+					usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-+							USB_REQ_SET_FEATURE, USB_RT_PORT,
-+							USB_PORT_FEAT_TEST, 0x100, NULL, 0, HZ);
-+					break;
-+
-+				case 0x0103:	/* TEST_K */
-+					dev_warn(&dev->dev, "TEST_K\n");
-+					usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-+							USB_REQ_SET_FEATURE, USB_RT_PORT,
-+							USB_PORT_FEAT_TEST, 0x200, NULL, 0, HZ);
-+					break;
-+
-+				case 0x0104:	/* TEST_PACKET */
-+					dev_warn(&dev->dev, "TEST_PACKET\n");
-+					usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-+							USB_REQ_SET_FEATURE, USB_RT_PORT,
-+							USB_PORT_FEAT_TEST, 0x400, NULL, 0, HZ);
-+					break;
-+
-+				case 0x0105:	/* TEST_FORCE_ENABLE */
-+					dev_warn(&dev->dev, "TEST_FORCE_ENABLE\n");
-+					usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-+							USB_REQ_SET_FEATURE, USB_RT_PORT,
-+							USB_PORT_FEAT_TEST, 0x500, NULL, 0, HZ);
-+					break;
-+
-+				case 0x0106:	/* HS_HOST_PORT_SUSPEND_RESUME */
-+					dev_warn(&dev->dev, "HS_HOST_PORT_SUSPEND_RESUME\n");
-+					usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-+							USB_REQ_SET_FEATURE, USB_RT_PORT,
-+							USB_PORT_FEAT_TEST, 0x600, NULL, 0, 40 * HZ);
-+					break;
-+
-+				case 0x0107:	/* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
-+					dev_warn(&dev->dev, "SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup\n");
-+					usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-+							USB_REQ_SET_FEATURE, USB_RT_PORT,
-+							USB_PORT_FEAT_TEST, 0x700, NULL, 0, 40 * HZ);
-+					break;
-+
-+				case 0x0108:	/* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
-+					dev_warn(&dev->dev, "SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute\n");
-+					usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
-+							USB_REQ_SET_FEATURE, USB_RT_PORT,
-+							USB_PORT_FEAT_TEST, 0x800, NULL, 0, 40 * HZ);
-+				}
-+			}
-+		}
-+#endif /* DWC_HS_ELECT_TST */
- 
- 	/* Now that the interfaces are installed, re-enable LPM. */
- 	usb_unlocked_enable_lpm(dev);
---- a/drivers/usb/core/otg_whitelist.h
-+++ b/drivers/usb/core/otg_whitelist.h
-@@ -19,33 +19,82 @@
- static struct usb_device_id whitelist_table [] = {
- 
- /* hubs are optional in OTG, but very handy ... */
-+#define CERT_WITHOUT_HUBS
-+#if defined(CERT_WITHOUT_HUBS)
-+{ USB_DEVICE( 0x0000, 0x0000 ), }, /* Root HUB Only*/
-+#else
- { USB_DEVICE_INFO(USB_CLASS_HUB, 0, 0), },
- { USB_DEVICE_INFO(USB_CLASS_HUB, 0, 1), },
-+{ USB_DEVICE_INFO(USB_CLASS_HUB, 0, 2), },
-+#endif
- 
- #ifdef	CONFIG_USB_PRINTER		/* ignoring nonstatic linkage! */
- /* FIXME actually, printers are NOT supposed to use device classes;
-  * they're supposed to use interface classes...
-  */
--{ USB_DEVICE_INFO(7, 1, 1) },
--{ USB_DEVICE_INFO(7, 1, 2) },
--{ USB_DEVICE_INFO(7, 1, 3) },
-+//{ USB_DEVICE_INFO(7, 1, 1) },
-+//{ USB_DEVICE_INFO(7, 1, 2) },
-+//{ USB_DEVICE_INFO(7, 1, 3) },
- #endif
- 
- #ifdef	CONFIG_USB_NET_CDCETHER
- /* Linux-USB CDC Ethernet gadget */
--{ USB_DEVICE(0x0525, 0xa4a1), },
-+//{ USB_DEVICE(0x0525, 0xa4a1), },
- /* Linux-USB CDC Ethernet + RNDIS gadget */
--{ USB_DEVICE(0x0525, 0xa4a2), },
-+//{ USB_DEVICE(0x0525, 0xa4a2), },
- #endif
- 
- #if	defined(CONFIG_USB_TEST) || defined(CONFIG_USB_TEST_MODULE)
- /* gadget zero, for testing */
--{ USB_DEVICE(0x0525, 0xa4a0), },
-+//{ USB_DEVICE(0x0525, 0xa4a0), },
- #endif
- 
-+/* OPT Tester */
-+{ USB_DEVICE( 0x1a0a, 0x0101 ), }, /* TEST_SE0_NAK */
-+{ USB_DEVICE( 0x1a0a, 0x0102 ), }, /* Test_J */
-+{ USB_DEVICE( 0x1a0a, 0x0103 ), }, /* Test_K */
-+{ USB_DEVICE( 0x1a0a, 0x0104 ), }, /* Test_PACKET */
-+{ USB_DEVICE( 0x1a0a, 0x0105 ), }, /* Test_FORCE_ENABLE */
-+{ USB_DEVICE( 0x1a0a, 0x0106 ), }, /* HS_PORT_SUSPEND_RESUME  */
-+{ USB_DEVICE( 0x1a0a, 0x0107 ), }, /* SINGLE_STEP_GET_DESCRIPTOR setup */
-+{ USB_DEVICE( 0x1a0a, 0x0108 ), }, /* SINGLE_STEP_GET_DESCRIPTOR execute */
-+
-+/* Sony cameras */
-+{ USB_DEVICE_VER(0x054c,0x0010,0x0410, 0x0500), },
-+
-+/* Memory Devices */
-+//{ USB_DEVICE( 0x0781, 0x5150 ), }, /* SanDisk */
-+//{ USB_DEVICE( 0x05DC, 0x0080 ), }, /* Lexar */
-+//{ USB_DEVICE( 0x4146, 0x9281 ), }, /* IOMEGA */
-+//{ USB_DEVICE( 0x067b, 0x2507 ), }, /* Hammer 20GB External HD  */
-+{ USB_DEVICE( 0x0EA0, 0x2168 ), }, /* Ours Technology Inc. (BUFFALO ClipDrive)*/
-+//{ USB_DEVICE( 0x0457, 0x0150 ), }, /* Silicon Integrated Systems Corp. */
-+
-+/* HP Printers */
-+//{ USB_DEVICE( 0x03F0, 0x1102 ), }, /* HP Photosmart 245 */
-+//{ USB_DEVICE( 0x03F0, 0x1302 ), }, /* HP Photosmart 370 Series */
-+
-+/* Speakers */
-+//{ USB_DEVICE( 0x0499, 0x3002 ), }, /* YAMAHA YST-MS35D USB Speakers */
-+//{ USB_DEVICE( 0x0672, 0x1041 ), }, /* Labtec USB Headset */
-+
- { }	/* Terminating entry */
- };
- 
-+static inline void report_errors(struct usb_device *dev)
-+{
-+	/* OTG MESSAGE: report errors here, customize to match your product */
-+	dev_info(&dev->dev, "device Vendor:%04x Product:%04x is not supported\n",
-+		 le16_to_cpu(dev->descriptor.idVendor),
-+		 le16_to_cpu(dev->descriptor.idProduct));
-+        if (USB_CLASS_HUB == dev->descriptor.bDeviceClass){
-+                dev_printk(KERN_CRIT, &dev->dev, "Unsupported Hub Topology\n");
-+        } else {
-+                dev_printk(KERN_CRIT, &dev->dev, "Attached Device is not Supported\n");
-+        }
-+}
-+
-+
- static int is_targeted(struct usb_device *dev)
- {
- 	struct usb_device_id	*id = whitelist_table;
-@@ -95,16 +144,57 @@ static int is_targeted(struct usb_device
- 			continue;
- 
- 		return 1;
--	}
-+		/* NOTE: can't use usb_match_id() since interface caches
-+		 * aren't set up yet. this is cut/paste from that code.
-+		 */
-+		for (id = whitelist_table; id->match_flags; id++) {
-+#ifdef DEBUG
-+			dev_dbg(&dev->dev,
-+				"ID: V:%04x P:%04x DC:%04x SC:%04x PR:%04x \n",
-+				id->idVendor,
-+				id->idProduct,
-+				id->bDeviceClass,
-+				id->bDeviceSubClass,
-+				id->bDeviceProtocol);
-+#endif
- 
--	/* add other match criteria here ... */
-+			if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
-+			    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
-+				continue;
-+
-+			if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
-+			    id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
-+				continue;
-+
-+			/* No need to test id->bcdDevice_lo != 0, since 0 is never
-+			   greater than any unsigned number. */
-+			if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
-+			    (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
-+				continue;
-+
-+			if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
-+			    (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
-+				continue;
-+
-+			if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
-+			    (id->bDeviceClass != dev->descriptor.bDeviceClass))
-+				continue;
-+
-+			if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
-+			    (id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))
-+				continue;
-+
-+			if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
-+			    (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
-+				continue;
- 
-+			return 1;
-+		}
-+	}
- 
--	/* OTG MESSAGE: report errors here, customize to match your product */
--	dev_err(&dev->dev, "device v%04x p%04x is not supported\n",
--		le16_to_cpu(dev->descriptor.idVendor),
--		le16_to_cpu(dev->descriptor.idProduct));
-+	/* add other match criteria here ... */
- 
-+	report_errors(dev);
- 	return 0;
- }
- 
---- /dev/null
-+++ b/drivers/usb/gadget/file_storage.c
-@@ -0,0 +1,3676 @@
-+/*
-+ * file_storage.c -- File-backed USB Storage Gadget, for USB development
-+ *
-+ * Copyright (C) 2003-2008 Alan Stern
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions, and the following disclaimer,
-+ *    without modification.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. The names of the above-listed copyright holders may not be used
-+ *    to endorse or promote products derived from this software without
-+ *    specific prior written permission.
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+
-+/*
-+ * The File-backed Storage Gadget acts as a USB Mass Storage device,
-+ * appearing to the host as a disk drive or as a CD-ROM drive.  In addition
-+ * to providing an example of a genuinely useful gadget driver for a USB
-+ * device, it also illustrates a technique of double-buffering for increased
-+ * throughput.  Last but not least, it gives an easy way to probe the
-+ * behavior of the Mass Storage drivers in a USB host.
-+ *
-+ * Backing storage is provided by a regular file or a block device, specified
-+ * by the "file" module parameter.  Access can be limited to read-only by
-+ * setting the optional "ro" module parameter.  (For CD-ROM emulation,
-+ * access is always read-only.)  The gadget will indicate that it has
-+ * removable media if the optional "removable" module parameter is set.
-+ *
-+ * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI),
-+ * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected
-+ * by the optional "transport" module parameter.  It also supports the
-+ * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03),
-+ * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by
-+ * the optional "protocol" module parameter.  In addition, the default
-+ * Vendor ID, Product ID, release number and serial number can be overridden.
-+ *
-+ * There is support for multiple logical units (LUNs), each of which has
-+ * its own backing file.  The number of LUNs can be set using the optional
-+ * "luns" module parameter (anywhere from 1 to 8), and the corresponding
-+ * files are specified using comma-separated lists for "file" and "ro".
-+ * The default number of LUNs is taken from the number of "file" elements;
-+ * it is 1 if "file" is not given.  If "removable" is not set then a backing
-+ * file must be specified for each LUN.  If it is set, then an unspecified
-+ * or empty backing filename means the LUN's medium is not loaded.  Ideally
-+ * each LUN would be settable independently as a disk drive or a CD-ROM
-+ * drive, but currently all LUNs have to be the same type.  The CD-ROM
-+ * emulation includes a single data track and no audio tracks; hence there
-+ * need be only one backing file per LUN.
-+ *
-+ * Requirements are modest; only a bulk-in and a bulk-out endpoint are
-+ * needed (an interrupt-out endpoint is also needed for CBI).  The memory
-+ * requirement amounts to two 16K buffers, size configurable by a parameter.
-+ * Support is included for both full-speed and high-speed operation.
-+ *
-+ * Note that the driver is slightly non-portable in that it assumes a
-+ * single memory/DMA buffer will be useable for bulk-in, bulk-out, and
-+ * interrupt-in endpoints.  With most device controllers this isn't an
-+ * issue, but there may be some with hardware restrictions that prevent
-+ * a buffer from being used by more than one endpoint.
-+ *
-+ * Module options:
-+ *
-+ *	file=filename[,filename...]
-+ *				Required if "removable" is not set, names of
-+ *					the files or block devices used for
-+ *					backing storage
-+ *	serial=HHHH...		Required serial number (string of hex chars)
-+ *	ro=b[,b...]		Default false, booleans for read-only access
-+ *	removable		Default false, boolean for removable media
-+ *	luns=N			Default N = number of filenames, number of
-+ *					LUNs to support
-+ *	nofua=b[,b...]		Default false, booleans for ignore FUA flag
-+ *					in SCSI WRITE(10,12) commands
-+ *	stall			Default determined according to the type of
-+ *					USB device controller (usually true),
-+ *					boolean to permit the driver to halt
-+ *					bulk endpoints
-+ *	cdrom			Default false, boolean for whether to emulate
-+ *					a CD-ROM drive
-+ *	transport=XXX		Default BBB, transport name (CB, CBI, or BBB)
-+ *	protocol=YYY		Default SCSI, protocol name (RBC, 8020 or
-+ *					ATAPI, QIC, UFI, 8070, or SCSI;
-+ *					also 1 - 6)
-+ *	vendor=0xVVVV		Default 0x0525 (NetChip), USB Vendor ID
-+ *	product=0xPPPP		Default 0xa4a5 (FSG), USB Product ID
-+ *	release=0xRRRR		Override the USB release number (bcdDevice)
-+ *	buflen=N		Default N=16384, buffer size used (will be
-+ *					rounded down to a multiple of
-+ *					PAGE_CACHE_SIZE)
-+ *
-+ * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "serial", "ro",
-+ * "removable", "luns", "nofua", "stall", and "cdrom" options are available;
-+ * default values are used for everything else.
-+ *
-+ * The pathnames of the backing files and the ro settings are available in
-+ * the attribute files "file", "nofua", and "ro" in the lun<n> subdirectory of
-+ * the gadget's sysfs directory.  If the "removable" option is set, writing to
-+ * these files will simulate ejecting/loading the medium (writing an empty
-+ * line means eject) and adjusting a write-enable tab.  Changes to the ro
-+ * setting are not allowed when the medium is loaded or if CD-ROM emulation
-+ * is being used.
-+ *
-+ * This gadget driver is heavily based on "Gadget Zero" by David Brownell.
-+ * The driver's SCSI command interface was based on the "Information
-+ * technology - Small Computer System Interface - 2" document from
-+ * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at
-+ * <http://www.t10.org/ftp/t10/drafts/s2/s2-r10l.pdf>.  The single exception
-+ * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the
-+ * "Universal Serial Bus Mass Storage Class UFI Command Specification"
-+ * document, Revision 1.0, December 14, 1998, available at
-+ * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>.
-+ */
-+
-+
-+/*
-+ *				Driver Design
-+ *
-+ * The FSG driver is fairly straightforward.  There is a main kernel
-+ * thread that handles most of the work.  Interrupt routines field
-+ * callbacks from the controller driver: bulk- and interrupt-request
-+ * completion notifications, endpoint-0 events, and disconnect events.
-+ * Completion events are passed to the main thread by wakeup calls.  Many
-+ * ep0 requests are handled at interrupt time, but SetInterface,
-+ * SetConfiguration, and device reset requests are forwarded to the
-+ * thread in the form of "exceptions" using SIGUSR1 signals (since they
-+ * should interrupt any ongoing file I/O operations).
-+ *
-+ * The thread's main routine implements the standard command/data/status
-+ * parts of a SCSI interaction.  It and its subroutines are full of tests
-+ * for pending signals/exceptions -- all this polling is necessary since
-+ * the kernel has no setjmp/longjmp equivalents.  (Maybe this is an
-+ * indication that the driver really wants to be running in userspace.)
-+ * An important point is that so long as the thread is alive it keeps an
-+ * open reference to the backing file.  This will prevent unmounting
-+ * the backing file's underlying filesystem and could cause problems
-+ * during system shutdown, for example.  To prevent such problems, the
-+ * thread catches INT, TERM, and KILL signals and converts them into
-+ * an EXIT exception.
-+ *
-+ * In normal operation the main thread is started during the gadget's
-+ * fsg_bind() callback and stopped during fsg_unbind().  But it can also
-+ * exit when it receives a signal, and there's no point leaving the
-+ * gadget running when the thread is dead.  So just before the thread
-+ * exits, it deregisters the gadget driver.  This makes things a little
-+ * tricky: The driver is deregistered at two places, and the exiting
-+ * thread can indirectly call fsg_unbind() which in turn can tell the
-+ * thread to exit.  The first problem is resolved through the use of the
-+ * REGISTERED atomic bitflag; the driver will only be deregistered once.
-+ * The second problem is resolved by having fsg_unbind() check
-+ * fsg->state; it won't try to stop the thread if the state is already
-+ * FSG_STATE_TERMINATED.
-+ *
-+ * To provide maximum throughput, the driver uses a circular pipeline of
-+ * buffer heads (struct fsg_buffhd).  In principle the pipeline can be
-+ * arbitrarily long; in practice the benefits don't justify having more
-+ * than 2 stages (i.e., double buffering).  But it helps to think of the
-+ * pipeline as being a long one.  Each buffer head contains a bulk-in and
-+ * a bulk-out request pointer (since the buffer can be used for both
-+ * output and input -- directions always are given from the host's
-+ * point of view) as well as a pointer to the buffer and various state
-+ * variables.
-+ *
-+ * Use of the pipeline follows a simple protocol.  There is a variable
-+ * (fsg->next_buffhd_to_fill) that points to the next buffer head to use.
-+ * At any time that buffer head may still be in use from an earlier
-+ * request, so each buffer head has a state variable indicating whether
-+ * it is EMPTY, FULL, or BUSY.  Typical use involves waiting for the
-+ * buffer head to be EMPTY, filling the buffer either by file I/O or by
-+ * USB I/O (during which the buffer head is BUSY), and marking the buffer
-+ * head FULL when the I/O is complete.  Then the buffer will be emptied
-+ * (again possibly by USB I/O, during which it is marked BUSY) and
-+ * finally marked EMPTY again (possibly by a completion routine).
-+ *
-+ * A module parameter tells the driver to avoid stalling the bulk
-+ * endpoints wherever the transport specification allows.  This is
-+ * necessary for some UDCs like the SuperH, which cannot reliably clear a
-+ * halt on a bulk endpoint.  However, under certain circumstances the
-+ * Bulk-only specification requires a stall.  In such cases the driver
-+ * will halt the endpoint and set a flag indicating that it should clear
-+ * the halt in software during the next device reset.  Hopefully this
-+ * will permit everything to work correctly.  Furthermore, although the
-+ * specification allows the bulk-out endpoint to halt when the host sends
-+ * too much data, implementing this would cause an unavoidable race.
-+ * The driver will always use the "no-stall" approach for OUT transfers.
-+ *
-+ * One subtle point concerns sending status-stage responses for ep0
-+ * requests.  Some of these requests, such as device reset, can involve
-+ * interrupting an ongoing file I/O operation, which might take an
-+ * arbitrarily long time.  During that delay the host might give up on
-+ * the original ep0 request and issue a new one.  When that happens the
-+ * driver should not notify the host about completion of the original
-+ * request, as the host will no longer be waiting for it.  So the driver
-+ * assigns to each ep0 request a unique tag, and it keeps track of the
-+ * tag value of the request associated with a long-running exception
-+ * (device-reset, interface-change, or configuration-change).  When the
-+ * exception handler is finished, the status-stage response is submitted
-+ * only if the current ep0 request tag is equal to the exception request
-+ * tag.  Thus only the most recently received ep0 request will get a
-+ * status-stage response.
-+ *
-+ * Warning: This driver source file is too long.  It ought to be split up
-+ * into a header file plus about 3 separate .c files, to handle the details
-+ * of the Gadget, USB Mass Storage, and SCSI protocols.
-+ */
-+
-+
-+/* #define VERBOSE_DEBUG */
-+/* #define DUMP_MSGS */
-+
-+
-+#include <linux/blkdev.h>
-+#include <linux/completion.h>
-+#include <linux/dcache.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/fcntl.h>
-+#include <linux/file.h>
-+#include <linux/fs.h>
-+#include <linux/kref.h>
-+#include <linux/kthread.h>
-+#include <linux/limits.h>
-+#include <linux/module.h>
-+#include <linux/rwsem.h>
-+#include <linux/slab.h>
-+#include <linux/spinlock.h>
-+#include <linux/string.h>
-+#include <linux/freezer.h>
-+#include <linux/utsname.h>
-+
-+#include <linux/usb/ch9.h>
-+#include <linux/usb/gadget.h>
-+
-+#include "gadget_chips.h"
-+
-+
-+
-+/*
-+ * Kbuild is not very cooperative with respect to linking separately
-+ * compiled library objects into one module.  So for now we won't use
-+ * separate compilation ... ensuring init/exit sections work to shrink
-+ * the runtime footprint, and giving us at least some parts of what
-+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
-+ */
-+#include "usbstring.c"
-+#include "config.c"
-+#include "epautoconf.c"
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#define DRIVER_DESC		"File-backed Storage Gadget"
-+#define DRIVER_NAME		"g_file_storage"
-+#define DRIVER_VERSION		"1 September 2010"
-+
-+static       char fsg_string_manufacturer[64];
-+static const char fsg_string_product[] = DRIVER_DESC;
-+static const char fsg_string_config[] = "Self-powered";
-+static const char fsg_string_interface[] = "Mass Storage";
-+
-+
-+#include "storage_common.c"
-+
-+
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+MODULE_AUTHOR("Alan Stern");
-+MODULE_LICENSE("Dual BSD/GPL");
-+
-+/*
-+ * This driver assumes self-powered hardware and has no way for users to
-+ * trigger remote wakeup.  It uses autoconfiguration to select endpoints
-+ * and endpoint addresses.
-+ */
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+
-+/* Encapsulate the module parameter settings */
-+
-+static struct {
-+	char		*file[FSG_MAX_LUNS];
-+	char		*serial;
-+	bool		ro[FSG_MAX_LUNS];
-+	bool		nofua[FSG_MAX_LUNS];
-+	unsigned int	num_filenames;
-+	unsigned int	num_ros;
-+	unsigned int	num_nofuas;
-+	unsigned int	nluns;
-+
-+	bool		removable;
-+	bool		can_stall;
-+	bool		cdrom;
-+
-+	char		*transport_parm;
-+	char		*protocol_parm;
-+	unsigned short	vendor;
-+	unsigned short	product;
-+	unsigned short	release;
-+	unsigned int	buflen;
-+
-+	int		transport_type;
-+	char		*transport_name;
-+	int		protocol_type;
-+	char		*protocol_name;
-+
-+} mod_data = {					// Default values
-+	.transport_parm		= "BBB",
-+	.protocol_parm		= "SCSI",
-+	.removable		= 0,
-+	.can_stall		= 1,
-+	.cdrom			= 0,
-+	.vendor			= FSG_VENDOR_ID,
-+	.product		= FSG_PRODUCT_ID,
-+	.release		= 0xffff,	// Use controller chip type
-+	.buflen			= 16384,
-+	};
-+
-+
-+module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames,
-+		S_IRUGO);
-+MODULE_PARM_DESC(file, "names of backing files or devices");
-+
-+module_param_named(serial, mod_data.serial, charp, S_IRUGO);
-+MODULE_PARM_DESC(serial, "USB serial number");
-+
-+module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO);
-+MODULE_PARM_DESC(ro, "true to force read-only");
-+
-+module_param_array_named(nofua, mod_data.nofua, bool, &mod_data.num_nofuas,
-+		S_IRUGO);
-+MODULE_PARM_DESC(nofua, "true to ignore SCSI WRITE(10,12) FUA bit");
-+
-+module_param_named(luns, mod_data.nluns, uint, S_IRUGO);
-+MODULE_PARM_DESC(luns, "number of LUNs");
-+
-+module_param_named(removable, mod_data.removable, bool, S_IRUGO);
-+MODULE_PARM_DESC(removable, "true to simulate removable media");
-+
-+module_param_named(stall, mod_data.can_stall, bool, S_IRUGO);
-+MODULE_PARM_DESC(stall, "false to prevent bulk stalls");
-+
-+module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO);
-+MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk");
-+
-+/* In the non-TEST version, only the module parameters listed above
-+ * are available. */
-+#ifdef CONFIG_USB_FILE_STORAGE_TEST
-+
-+module_param_named(transport, mod_data.transport_parm, charp, S_IRUGO);
-+MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)");
-+
-+module_param_named(protocol, mod_data.protocol_parm, charp, S_IRUGO);
-+MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, "
-+		"8070, or SCSI)");
-+
-+module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO);
-+MODULE_PARM_DESC(vendor, "USB Vendor ID");
-+
-+module_param_named(product, mod_data.product, ushort, S_IRUGO);
-+MODULE_PARM_DESC(product, "USB Product ID");
-+
-+module_param_named(release, mod_data.release, ushort, S_IRUGO);
-+MODULE_PARM_DESC(release, "USB release number");
-+
-+module_param_named(buflen, mod_data.buflen, uint, S_IRUGO);
-+MODULE_PARM_DESC(buflen, "I/O buffer size");
-+
-+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-+
-+
-+/*
-+ * These definitions will permit the compiler to avoid generating code for
-+ * parts of the driver that aren't used in the non-TEST version.  Even gcc
-+ * can recognize when a test of a constant expression yields a dead code
-+ * path.
-+ */
-+
-+#ifdef CONFIG_USB_FILE_STORAGE_TEST
-+
-+#define transport_is_bbb()	(mod_data.transport_type == USB_PR_BULK)
-+#define transport_is_cbi()	(mod_data.transport_type == USB_PR_CBI)
-+#define protocol_is_scsi()	(mod_data.protocol_type == USB_SC_SCSI)
-+
-+#else
-+
-+#define transport_is_bbb()	1
-+#define transport_is_cbi()	0
-+#define protocol_is_scsi()	1
-+
-+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+
-+struct fsg_dev {
-+	/* lock protects: state, all the req_busy's, and cbbuf_cmnd */
-+	spinlock_t		lock;
-+	struct usb_gadget	*gadget;
-+
-+	/* filesem protects: backing files in use */
-+	struct rw_semaphore	filesem;
-+
-+	/* reference counting: wait until all LUNs are released */
-+	struct kref		ref;
-+
-+	struct usb_ep		*ep0;		// Handy copy of gadget->ep0
-+	struct usb_request	*ep0req;	// For control responses
-+	unsigned int		ep0_req_tag;
-+	const char		*ep0req_name;
-+
-+	struct usb_request	*intreq;	// For interrupt responses
-+	int			intreq_busy;
-+	struct fsg_buffhd	*intr_buffhd;
-+
-+	unsigned int		bulk_out_maxpacket;
-+	enum fsg_state		state;		// For exception handling
-+	unsigned int		exception_req_tag;
-+
-+	u8			config, new_config;
-+
-+	unsigned int		running : 1;
-+	unsigned int		bulk_in_enabled : 1;
-+	unsigned int		bulk_out_enabled : 1;
-+	unsigned int		intr_in_enabled : 1;
-+	unsigned int		phase_error : 1;
-+	unsigned int		short_packet_received : 1;
-+	unsigned int		bad_lun_okay : 1;
-+
-+	unsigned long		atomic_bitflags;
-+#define REGISTERED		0
-+#define IGNORE_BULK_OUT		1
-+#define SUSPENDED		2
-+
-+	struct usb_ep		*bulk_in;
-+	struct usb_ep		*bulk_out;
-+	struct usb_ep		*intr_in;
-+
-+	struct fsg_buffhd	*next_buffhd_to_fill;
-+	struct fsg_buffhd	*next_buffhd_to_drain;
-+
-+	int			thread_wakeup_needed;
-+	struct completion	thread_notifier;
-+	struct task_struct	*thread_task;
-+
-+	int			cmnd_size;
-+	u8			cmnd[MAX_COMMAND_SIZE];
-+	enum data_direction	data_dir;
-+	u32			data_size;
-+	u32			data_size_from_cmnd;
-+	u32			tag;
-+	unsigned int		lun;
-+	u32			residue;
-+	u32			usb_amount_left;
-+
-+	/* The CB protocol offers no way for a host to know when a command
-+	 * has completed.  As a result the next command may arrive early,
-+	 * and we will still have to handle it.  For that reason we need
-+	 * a buffer to store new commands when using CB (or CBI, which
-+	 * does not oblige a host to wait for command completion either). */
-+	int			cbbuf_cmnd_size;
-+	u8			cbbuf_cmnd[MAX_COMMAND_SIZE];
-+
-+	unsigned int		nluns;
-+	struct fsg_lun		*luns;
-+	struct fsg_lun		*curlun;
-+	/* Must be the last entry */
-+	struct fsg_buffhd	buffhds[];
-+};
-+
-+typedef void (*fsg_routine_t)(struct fsg_dev *);
-+
-+static int exception_in_progress(struct fsg_dev *fsg)
-+{
-+	return (fsg->state > FSG_STATE_IDLE);
-+}
-+
-+/* Make bulk-out requests be divisible by the maxpacket size */
-+static void set_bulk_out_req_length(struct fsg_dev *fsg,
-+		struct fsg_buffhd *bh, unsigned int length)
-+{
-+	unsigned int	rem;
-+
-+	bh->bulk_out_intended_length = length;
-+	rem = length % fsg->bulk_out_maxpacket;
-+	if (rem > 0)
-+		length += fsg->bulk_out_maxpacket - rem;
-+	bh->outreq->length = length;
-+}
-+
-+static struct fsg_dev			*the_fsg;
-+static struct usb_gadget_driver		fsg_driver;
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
-+{
-+	const char	*name;
-+
-+	if (ep == fsg->bulk_in)
-+		name = "bulk-in";
-+	else if (ep == fsg->bulk_out)
-+		name = "bulk-out";
-+	else
-+		name = ep->name;
-+	DBG(fsg, "%s set halt\n", name);
-+	return usb_ep_set_halt(ep);
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * DESCRIPTORS ... most are static, but strings and (full) configuration
-+ * descriptors are built on demand.  Also the (static) config and interface
-+ * descriptors are adjusted during fsg_bind().
-+ */
-+
-+/* There is only one configuration. */
-+#define	CONFIG_VALUE		1
-+
-+static struct usb_device_descriptor
-+device_desc = {
-+	.bLength =		sizeof device_desc,
-+	.bDescriptorType =	USB_DT_DEVICE,
-+
-+	.bcdUSB =		cpu_to_le16(0x0200),
-+	.bDeviceClass =		USB_CLASS_PER_INTERFACE,
-+
-+	/* The next three values can be overridden by module parameters */
-+	.idVendor =		cpu_to_le16(FSG_VENDOR_ID),
-+	.idProduct =		cpu_to_le16(FSG_PRODUCT_ID),
-+	.bcdDevice =		cpu_to_le16(0xffff),
-+
-+	.iManufacturer =	FSG_STRING_MANUFACTURER,
-+	.iProduct =		FSG_STRING_PRODUCT,
-+	.iSerialNumber =	FSG_STRING_SERIAL,
-+	.bNumConfigurations =	1,
-+};
-+
-+static struct usb_config_descriptor
-+config_desc = {
-+	.bLength =		sizeof config_desc,
-+	.bDescriptorType =	USB_DT_CONFIG,
-+
-+	/* wTotalLength computed by usb_gadget_config_buf() */
-+	.bNumInterfaces =	1,
-+	.bConfigurationValue =	CONFIG_VALUE,
-+	.iConfiguration =	FSG_STRING_CONFIG,
-+	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-+	.bMaxPower =		CONFIG_USB_GADGET_VBUS_DRAW / 2,
-+};
-+
-+
-+static struct usb_qualifier_descriptor
-+dev_qualifier = {
-+	.bLength =		sizeof dev_qualifier,
-+	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
-+
-+	.bcdUSB =		cpu_to_le16(0x0200),
-+	.bDeviceClass =		USB_CLASS_PER_INTERFACE,
-+
-+	.bNumConfigurations =	1,
-+};
-+
-+static int populate_bos(struct fsg_dev *fsg, u8 *buf)
-+{
-+	memcpy(buf, &fsg_bos_desc, USB_DT_BOS_SIZE);
-+	buf += USB_DT_BOS_SIZE;
-+
-+	memcpy(buf, &fsg_ext_cap_desc, USB_DT_USB_EXT_CAP_SIZE);
-+	buf += USB_DT_USB_EXT_CAP_SIZE;
-+
-+	memcpy(buf, &fsg_ss_cap_desc, USB_DT_USB_SS_CAP_SIZE);
-+
-+	return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE
-+		+ USB_DT_USB_EXT_CAP_SIZE;
-+}
-+
-+/*
-+ * Config descriptors must agree with the code that sets configurations
-+ * and with code managing interfaces and their altsettings.  They must
-+ * also handle different speeds and other-speed requests.
-+ */
-+static int populate_config_buf(struct usb_gadget *gadget,
-+		u8 *buf, u8 type, unsigned index)
-+{
-+	enum usb_device_speed			speed = gadget->speed;
-+	int					len;
-+	const struct usb_descriptor_header	**function;
-+
-+	if (index > 0)
-+		return -EINVAL;
-+
-+	if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG)
-+		speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed;
-+	function = gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH
-+		? (const struct usb_descriptor_header **)fsg_hs_function
-+		: (const struct usb_descriptor_header **)fsg_fs_function;
-+
-+	/* for now, don't advertise srp-only devices */
-+	if (!gadget_is_otg(gadget))
-+		function++;
-+
-+	len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function);
-+	((struct usb_config_descriptor *) buf)->bDescriptorType = type;
-+	return len;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* These routines may be called in process context or in_irq */
-+
-+/* Caller must hold fsg->lock */
-+static void wakeup_thread(struct fsg_dev *fsg)
-+{
-+	/* Tell the main thread that something has happened */
-+	fsg->thread_wakeup_needed = 1;
-+	if (fsg->thread_task)
-+		wake_up_process(fsg->thread_task);
-+}
-+
-+
-+static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state)
-+{
-+	unsigned long		flags;
-+
-+	/* Do nothing if a higher-priority exception is already in progress.
-+	 * If a lower-or-equal priority exception is in progress, preempt it
-+	 * and notify the main thread by sending it a signal. */
-+	spin_lock_irqsave(&fsg->lock, flags);
-+	if (fsg->state <= new_state) {
-+		fsg->exception_req_tag = fsg->ep0_req_tag;
-+		fsg->state = new_state;
-+		if (fsg->thread_task)
-+			send_sig_info(SIGUSR1, SEND_SIG_FORCED,
-+					fsg->thread_task);
-+	}
-+	spin_unlock_irqrestore(&fsg->lock, flags);
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* The disconnect callback and ep0 routines.  These always run in_irq,
-+ * except that ep0_queue() is called in the main thread to acknowledge
-+ * completion of various requests: set config, set interface, and
-+ * Bulk-only device reset. */
-+
-+static void fsg_disconnect(struct usb_gadget *gadget)
-+{
-+	struct fsg_dev		*fsg = get_gadget_data(gadget);
-+
-+	DBG(fsg, "disconnect or port reset\n");
-+	raise_exception(fsg, FSG_STATE_DISCONNECT);
-+}
-+
-+
-+static int ep0_queue(struct fsg_dev *fsg)
-+{
-+	int	rc;
-+
-+	rc = usb_ep_queue(fsg->ep0, fsg->ep0req, GFP_ATOMIC);
-+	if (rc != 0 && rc != -ESHUTDOWN) {
-+
-+		/* We can't do much more than wait for a reset */
-+		WARNING(fsg, "error in submission: %s --> %d\n",
-+				fsg->ep0->name, rc);
-+	}
-+	return rc;
-+}
-+
-+static void ep0_complete(struct usb_ep *ep, struct usb_request *req)
-+{
-+	struct fsg_dev		*fsg = ep->driver_data;
-+
-+	if (req->actual > 0)
-+		dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual);
-+	if (req->status || req->actual != req->length)
-+		DBG(fsg, "%s --> %d, %u/%u\n", __func__,
-+				req->status, req->actual, req->length);
-+	if (req->status == -ECONNRESET)		// Request was cancelled
-+		usb_ep_fifo_flush(ep);
-+
-+	if (req->status == 0 && req->context)
-+		((fsg_routine_t) (req->context))(fsg);
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Bulk and interrupt endpoint completion handlers.
-+ * These always run in_irq. */
-+
-+static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
-+{
-+	struct fsg_dev		*fsg = ep->driver_data;
-+	struct fsg_buffhd	*bh = req->context;
-+
-+	if (req->status || req->actual != req->length)
-+		DBG(fsg, "%s --> %d, %u/%u\n", __func__,
-+				req->status, req->actual, req->length);
-+	if (req->status == -ECONNRESET)		// Request was cancelled
-+		usb_ep_fifo_flush(ep);
-+
-+	/* Hold the lock while we update the request and buffer states */
-+	smp_wmb();
-+	spin_lock(&fsg->lock);
-+	bh->inreq_busy = 0;
-+	bh->state = BUF_STATE_EMPTY;
-+	wakeup_thread(fsg);
-+	spin_unlock(&fsg->lock);
-+}
-+
-+static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
-+{
-+	struct fsg_dev		*fsg = ep->driver_data;
-+	struct fsg_buffhd	*bh = req->context;
-+
-+	dump_msg(fsg, "bulk-out", req->buf, req->actual);
-+	if (req->status || req->actual != bh->bulk_out_intended_length)
-+		DBG(fsg, "%s --> %d, %u/%u\n", __func__,
-+				req->status, req->actual,
-+				bh->bulk_out_intended_length);
-+	if (req->status == -ECONNRESET)		// Request was cancelled
-+		usb_ep_fifo_flush(ep);
-+
-+	/* Hold the lock while we update the request and buffer states */
-+	smp_wmb();
-+	spin_lock(&fsg->lock);
-+	bh->outreq_busy = 0;
-+	bh->state = BUF_STATE_FULL;
-+	wakeup_thread(fsg);
-+	spin_unlock(&fsg->lock);
-+}
-+
-+
-+#ifdef CONFIG_USB_FILE_STORAGE_TEST
-+static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
-+{
-+	struct fsg_dev		*fsg = ep->driver_data;
-+	struct fsg_buffhd	*bh = req->context;
-+
-+	if (req->status || req->actual != req->length)
-+		DBG(fsg, "%s --> %d, %u/%u\n", __func__,
-+				req->status, req->actual, req->length);
-+	if (req->status == -ECONNRESET)		// Request was cancelled
-+		usb_ep_fifo_flush(ep);
-+
-+	/* Hold the lock while we update the request and buffer states */
-+	smp_wmb();
-+	spin_lock(&fsg->lock);
-+	fsg->intreq_busy = 0;
-+	bh->state = BUF_STATE_EMPTY;
-+	wakeup_thread(fsg);
-+	spin_unlock(&fsg->lock);
-+}
-+
-+#else
-+static void intr_in_complete(struct usb_ep *ep, struct usb_request *req)
-+{}
-+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Ep0 class-specific handlers.  These always run in_irq. */
-+
-+#ifdef CONFIG_USB_FILE_STORAGE_TEST
-+static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{
-+	struct usb_request	*req = fsg->ep0req;
-+	static u8		cbi_reset_cmnd[6] = {
-+			SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff};
-+
-+	/* Error in command transfer? */
-+	if (req->status || req->length != req->actual ||
-+			req->actual < 6 || req->actual > MAX_COMMAND_SIZE) {
-+
-+		/* Not all controllers allow a protocol stall after
-+		 * receiving control-out data, but we'll try anyway. */
-+		fsg_set_halt(fsg, fsg->ep0);
-+		return;			// Wait for reset
-+	}
-+
-+	/* Is it the special reset command? */
-+	if (req->actual >= sizeof cbi_reset_cmnd &&
-+			memcmp(req->buf, cbi_reset_cmnd,
-+				sizeof cbi_reset_cmnd) == 0) {
-+
-+		/* Raise an exception to stop the current operation
-+		 * and reinitialize our state. */
-+		DBG(fsg, "cbi reset request\n");
-+		raise_exception(fsg, FSG_STATE_RESET);
-+		return;
-+	}
-+
-+	VDBG(fsg, "CB[I] accept device-specific command\n");
-+	spin_lock(&fsg->lock);
-+
-+	/* Save the command for later */
-+	if (fsg->cbbuf_cmnd_size)
-+		WARNING(fsg, "CB[I] overwriting previous command\n");
-+	fsg->cbbuf_cmnd_size = req->actual;
-+	memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
-+
-+	wakeup_thread(fsg);
-+	spin_unlock(&fsg->lock);
-+}
-+
-+#else
-+static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{}
-+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-+
-+
-+static int class_setup_req(struct fsg_dev *fsg,
-+		const struct usb_ctrlrequest *ctrl)
-+{
-+	struct usb_request	*req = fsg->ep0req;
-+	int			value = -EOPNOTSUPP;
-+	u16			w_index = le16_to_cpu(ctrl->wIndex);
-+	u16                     w_value = le16_to_cpu(ctrl->wValue);
-+	u16			w_length = le16_to_cpu(ctrl->wLength);
-+
-+	if (!fsg->config)
-+		return value;
-+
-+	/* Handle Bulk-only class-specific requests */
-+	if (transport_is_bbb()) {
-+		switch (ctrl->bRequest) {
-+
-+		case US_BULK_RESET_REQUEST:
-+			if (ctrl->bRequestType != (USB_DIR_OUT |
-+					USB_TYPE_CLASS | USB_RECIP_INTERFACE))
-+				break;
-+			if (w_index != 0 || w_value != 0 || w_length != 0) {
-+				value = -EDOM;
-+				break;
-+			}
-+
-+			/* Raise an exception to stop the current operation
-+			 * and reinitialize our state. */
-+			DBG(fsg, "bulk reset request\n");
-+			raise_exception(fsg, FSG_STATE_RESET);
-+			value = DELAYED_STATUS;
-+			break;
-+
-+		case US_BULK_GET_MAX_LUN:
-+			if (ctrl->bRequestType != (USB_DIR_IN |
-+					USB_TYPE_CLASS | USB_RECIP_INTERFACE))
-+				break;
-+			if (w_index != 0 || w_value != 0 || w_length != 1) {
-+				value = -EDOM;
-+				break;
-+			}
-+			VDBG(fsg, "get max LUN\n");
-+			*(u8 *) req->buf = fsg->nluns - 1;
-+			value = 1;
-+			break;
-+		}
-+	}
-+
-+	/* Handle CBI class-specific requests */
-+	else {
-+		switch (ctrl->bRequest) {
-+
-+		case USB_CBI_ADSC_REQUEST:
-+			if (ctrl->bRequestType != (USB_DIR_OUT |
-+					USB_TYPE_CLASS | USB_RECIP_INTERFACE))
-+				break;
-+			if (w_index != 0 || w_value != 0) {
-+				value = -EDOM;
-+				break;
-+			}
-+			if (w_length > MAX_COMMAND_SIZE) {
-+				value = -EOVERFLOW;
-+				break;
-+			}
-+			value = w_length;
-+			fsg->ep0req->context = received_cbi_adsc;
-+			break;
-+		}
-+	}
-+
-+	if (value == -EOPNOTSUPP)
-+		VDBG(fsg,
-+			"unknown class-specific control req "
-+			"%02x.%02x v%04x i%04x l%u\n",
-+			ctrl->bRequestType, ctrl->bRequest,
-+			le16_to_cpu(ctrl->wValue), w_index, w_length);
-+	return value;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Ep0 standard request handlers.  These always run in_irq. */
-+
-+static int standard_setup_req(struct fsg_dev *fsg,
-+		const struct usb_ctrlrequest *ctrl)
-+{
-+	struct usb_request	*req = fsg->ep0req;
-+	int			value = -EOPNOTSUPP;
-+	u16			w_index = le16_to_cpu(ctrl->wIndex);
-+	u16			w_value = le16_to_cpu(ctrl->wValue);
-+
-+	/* Usually this just stores reply data in the pre-allocated ep0 buffer,
-+	 * but config change events will also reconfigure hardware. */
-+	switch (ctrl->bRequest) {
-+
-+	case USB_REQ_GET_DESCRIPTOR:
-+		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
-+				USB_RECIP_DEVICE))
-+			break;
-+		switch (w_value >> 8) {
-+
-+		case USB_DT_DEVICE:
-+			VDBG(fsg, "get device descriptor\n");
-+			device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket;
-+			value = sizeof device_desc;
-+			memcpy(req->buf, &device_desc, value);
-+			break;
-+		case USB_DT_DEVICE_QUALIFIER:
-+			VDBG(fsg, "get device qualifier\n");
-+			if (!gadget_is_dualspeed(fsg->gadget) ||
-+					fsg->gadget->speed == USB_SPEED_SUPER)
-+				break;
-+			/*
-+			 * Assume ep0 uses the same maxpacket value for both
-+			 * speeds
-+			 */
-+			dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket;
-+			value = sizeof dev_qualifier;
-+			memcpy(req->buf, &dev_qualifier, value);
-+			break;
-+
-+		case USB_DT_OTHER_SPEED_CONFIG:
-+			VDBG(fsg, "get other-speed config descriptor\n");
-+			if (!gadget_is_dualspeed(fsg->gadget) ||
-+					fsg->gadget->speed == USB_SPEED_SUPER)
-+				break;
-+			goto get_config;
-+		case USB_DT_CONFIG:
-+			VDBG(fsg, "get configuration descriptor\n");
-+get_config:
-+			value = populate_config_buf(fsg->gadget,
-+					req->buf,
-+					w_value >> 8,
-+					w_value & 0xff);
-+			break;
-+
-+		case USB_DT_STRING:
-+			VDBG(fsg, "get string descriptor\n");
-+
-+			/* wIndex == language code */
-+			value = usb_gadget_get_string(&fsg_stringtab,
-+					w_value & 0xff, req->buf);
-+			break;
-+
-+		case USB_DT_BOS:
-+			VDBG(fsg, "get bos descriptor\n");
-+
-+			if (gadget_is_superspeed(fsg->gadget))
-+				value = populate_bos(fsg, req->buf);
-+			break;
-+		}
-+
-+		break;
-+
-+	/* One config, two speeds */
-+	case USB_REQ_SET_CONFIGURATION:
-+		if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
-+				USB_RECIP_DEVICE))
-+			break;
-+		VDBG(fsg, "set configuration\n");
-+		if (w_value == CONFIG_VALUE || w_value == 0) {
-+			fsg->new_config = w_value;
-+
-+			/* Raise an exception to wipe out previous transaction
-+			 * state (queued bufs, etc) and set the new config. */
-+			raise_exception(fsg, FSG_STATE_CONFIG_CHANGE);
-+			value = DELAYED_STATUS;
-+		}
-+		break;
-+	case USB_REQ_GET_CONFIGURATION:
-+		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
-+				USB_RECIP_DEVICE))
-+			break;
-+		VDBG(fsg, "get configuration\n");
-+		*(u8 *) req->buf = fsg->config;
-+		value = 1;
-+		break;
-+
-+	case USB_REQ_SET_INTERFACE:
-+		if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD |
-+				USB_RECIP_INTERFACE))
-+			break;
-+		if (fsg->config && w_index == 0) {
-+
-+			/* Raise an exception to wipe out previous transaction
-+			 * state (queued bufs, etc) and install the new
-+			 * interface altsetting. */
-+			raise_exception(fsg, FSG_STATE_INTERFACE_CHANGE);
-+			value = DELAYED_STATUS;
-+		}
-+		break;
-+	case USB_REQ_GET_INTERFACE:
-+		if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD |
-+				USB_RECIP_INTERFACE))
-+			break;
-+		if (!fsg->config)
-+			break;
-+		if (w_index != 0) {
-+			value = -EDOM;
-+			break;
-+		}
-+		VDBG(fsg, "get interface\n");
-+		*(u8 *) req->buf = 0;
-+		value = 1;
-+		break;
-+
-+	default:
-+		VDBG(fsg,
-+			"unknown control req %02x.%02x v%04x i%04x l%u\n",
-+			ctrl->bRequestType, ctrl->bRequest,
-+			w_value, w_index, le16_to_cpu(ctrl->wLength));
-+	}
-+
-+	return value;
-+}
-+
-+
-+static int fsg_setup(struct usb_gadget *gadget,
-+		const struct usb_ctrlrequest *ctrl)
-+{
-+	struct fsg_dev		*fsg = get_gadget_data(gadget);
-+	int			rc;
-+	int			w_length = le16_to_cpu(ctrl->wLength);
-+
-+	++fsg->ep0_req_tag;		// Record arrival of a new request
-+	fsg->ep0req->context = NULL;
-+	fsg->ep0req->length = 0;
-+	dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl));
-+
-+	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
-+		rc = class_setup_req(fsg, ctrl);
-+	else
-+		rc = standard_setup_req(fsg, ctrl);
-+
-+	/* Respond with data/status or defer until later? */
-+	if (rc >= 0 && rc != DELAYED_STATUS) {
-+		rc = min(rc, w_length);
-+		fsg->ep0req->length = rc;
-+		fsg->ep0req->zero = rc < w_length;
-+		fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ?
-+				"ep0-in" : "ep0-out");
-+		rc = ep0_queue(fsg);
-+	}
-+
-+	/* Device either stalls (rc < 0) or reports success */
-+	return rc;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* All the following routines run in process context */
-+
-+
-+/* Use this for bulk or interrupt transfers, not ep0 */
-+static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
-+		struct usb_request *req, int *pbusy,
-+		enum fsg_buffer_state *state)
-+{
-+	int	rc;
-+
-+	if (ep == fsg->bulk_in)
-+		dump_msg(fsg, "bulk-in", req->buf, req->length);
-+	else if (ep == fsg->intr_in)
-+		dump_msg(fsg, "intr-in", req->buf, req->length);
-+
-+	spin_lock_irq(&fsg->lock);
-+	*pbusy = 1;
-+	*state = BUF_STATE_BUSY;
-+	spin_unlock_irq(&fsg->lock);
-+	rc = usb_ep_queue(ep, req, GFP_KERNEL);
-+	if (rc != 0) {
-+		*pbusy = 0;
-+		*state = BUF_STATE_EMPTY;
-+
-+		/* We can't do much more than wait for a reset */
-+
-+		/* Note: currently the net2280 driver fails zero-length
-+		 * submissions if DMA is enabled. */
-+		if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP &&
-+						req->length == 0))
-+			WARNING(fsg, "error in submission: %s --> %d\n",
-+					ep->name, rc);
-+	}
-+}
-+
-+
-+static int sleep_thread(struct fsg_dev *fsg)
-+{
-+	int	rc = 0;
-+
-+	/* Wait until a signal arrives or we are woken up */
-+	for (;;) {
-+		try_to_freeze();
-+		set_current_state(TASK_INTERRUPTIBLE);
-+		if (signal_pending(current)) {
-+			rc = -EINTR;
-+			break;
-+		}
-+		if (fsg->thread_wakeup_needed)
-+			break;
-+		schedule();
-+	}
-+	__set_current_state(TASK_RUNNING);
-+	fsg->thread_wakeup_needed = 0;
-+	return rc;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int do_read(struct fsg_dev *fsg)
-+{
-+	struct fsg_lun		*curlun = fsg->curlun;
-+	u32			lba;
-+	struct fsg_buffhd	*bh;
-+	int			rc;
-+	u32			amount_left;
-+	loff_t			file_offset, file_offset_tmp;
-+	unsigned int		amount;
-+	ssize_t			nread;
-+
-+	/* Get the starting Logical Block Address and check that it's
-+	 * not too big */
-+	if (fsg->cmnd[0] == READ_6)
-+		lba = get_unaligned_be24(&fsg->cmnd[1]);
-+	else {
-+		lba = get_unaligned_be32(&fsg->cmnd[2]);
-+
-+		/* We allow DPO (Disable Page Out = don't save data in the
-+		 * cache) and FUA (Force Unit Access = don't read from the
-+		 * cache), but we don't implement them. */
-+		if ((fsg->cmnd[1] & ~0x18) != 0) {
-+			curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+			return -EINVAL;
-+		}
-+	}
-+	if (lba >= curlun->num_sectors) {
-+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-+		return -EINVAL;
-+	}
-+	file_offset = ((loff_t) lba) << curlun->blkbits;
-+
-+	/* Carry out the file reads */
-+	amount_left = fsg->data_size_from_cmnd;
-+	if (unlikely(amount_left == 0))
-+		return -EIO;		// No default reply
-+
-+	for (;;) {
-+
-+		/* Figure out how much we need to read:
-+		 * Try to read the remaining amount.
-+		 * But don't read more than the buffer size.
-+		 * And don't try to read past the end of the file.
-+		 */
-+		amount = min((unsigned int) amount_left, mod_data.buflen);
-+		amount = min((loff_t) amount,
-+				curlun->file_length - file_offset);
-+
-+		/* Wait for the next buffer to become available */
-+		bh = fsg->next_buffhd_to_fill;
-+		while (bh->state != BUF_STATE_EMPTY) {
-+			rc = sleep_thread(fsg);
-+			if (rc)
-+				return rc;
-+		}
-+
-+		/* If we were asked to read past the end of file,
-+		 * end with an empty buffer. */
-+		if (amount == 0) {
-+			curlun->sense_data =
-+					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-+			curlun->sense_data_info = file_offset >> curlun->blkbits;
-+			curlun->info_valid = 1;
-+			bh->inreq->length = 0;
-+			bh->state = BUF_STATE_FULL;
-+			break;
-+		}
-+
-+		/* Perform the read */
-+		file_offset_tmp = file_offset;
-+		nread = vfs_read(curlun->filp,
-+				(char __user *) bh->buf,
-+				amount, &file_offset_tmp);
-+		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
-+				(unsigned long long) file_offset,
-+				(int) nread);
-+		if (signal_pending(current))
-+			return -EINTR;
-+
-+		if (nread < 0) {
-+			LDBG(curlun, "error in file read: %d\n",
-+					(int) nread);
-+			nread = 0;
-+		} else if (nread < amount) {
-+			LDBG(curlun, "partial file read: %d/%u\n",
-+					(int) nread, amount);
-+			nread = round_down(nread, curlun->blksize);
-+		}
-+		file_offset  += nread;
-+		amount_left  -= nread;
-+		fsg->residue -= nread;
-+
-+		/* Except at the end of the transfer, nread will be
-+		 * equal to the buffer size, which is divisible by the
-+		 * bulk-in maxpacket size.
-+		 */
-+		bh->inreq->length = nread;
-+		bh->state = BUF_STATE_FULL;
-+
-+		/* If an error occurred, report it and its position */
-+		if (nread < amount) {
-+			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
-+			curlun->sense_data_info = file_offset >> curlun->blkbits;
-+			curlun->info_valid = 1;
-+			break;
-+		}
-+
-+		if (amount_left == 0)
-+			break;		// No more left to read
-+
-+		/* Send this buffer and go read some more */
-+		bh->inreq->zero = 0;
-+		start_transfer(fsg, fsg->bulk_in, bh->inreq,
-+				&bh->inreq_busy, &bh->state);
-+		fsg->next_buffhd_to_fill = bh->next;
-+	}
-+
-+	return -EIO;		// No default reply
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int do_write(struct fsg_dev *fsg)
-+{
-+	struct fsg_lun		*curlun = fsg->curlun;
-+	u32			lba;
-+	struct fsg_buffhd	*bh;
-+	int			get_some_more;
-+	u32			amount_left_to_req, amount_left_to_write;
-+	loff_t			usb_offset, file_offset, file_offset_tmp;
-+	unsigned int		amount;
-+	ssize_t			nwritten;
-+	int			rc;
-+
-+	if (curlun->ro) {
-+		curlun->sense_data = SS_WRITE_PROTECTED;
-+		return -EINVAL;
-+	}
-+	spin_lock(&curlun->filp->f_lock);
-+	curlun->filp->f_flags &= ~O_SYNC;	// Default is not to wait
-+	spin_unlock(&curlun->filp->f_lock);
-+
-+	/* Get the starting Logical Block Address and check that it's
-+	 * not too big */
-+	if (fsg->cmnd[0] == WRITE_6)
-+		lba = get_unaligned_be24(&fsg->cmnd[1]);
-+	else {
-+		lba = get_unaligned_be32(&fsg->cmnd[2]);
-+
-+		/* We allow DPO (Disable Page Out = don't save data in the
-+		 * cache) and FUA (Force Unit Access = write directly to the
-+		 * medium).  We don't implement DPO; we implement FUA by
-+		 * performing synchronous output. */
-+		if ((fsg->cmnd[1] & ~0x18) != 0) {
-+			curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+			return -EINVAL;
-+		}
-+		/* FUA */
-+		if (!curlun->nofua && (fsg->cmnd[1] & 0x08)) {
-+			spin_lock(&curlun->filp->f_lock);
-+			curlun->filp->f_flags |= O_DSYNC;
-+			spin_unlock(&curlun->filp->f_lock);
-+		}
-+	}
-+	if (lba >= curlun->num_sectors) {
-+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-+		return -EINVAL;
-+	}
-+
-+	/* Carry out the file writes */
-+	get_some_more = 1;
-+	file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits;
-+	amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd;
-+
-+	while (amount_left_to_write > 0) {
-+
-+		/* Queue a request for more data from the host */
-+		bh = fsg->next_buffhd_to_fill;
-+		if (bh->state == BUF_STATE_EMPTY && get_some_more) {
-+
-+			/* Figure out how much we want to get:
-+			 * Try to get the remaining amount,
-+			 * but not more than the buffer size.
-+			 */
-+			amount = min(amount_left_to_req, mod_data.buflen);
-+
-+			/* Beyond the end of the backing file? */
-+			if (usb_offset >= curlun->file_length) {
-+				get_some_more = 0;
-+				curlun->sense_data =
-+					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-+				curlun->sense_data_info = usb_offset >> curlun->blkbits;
-+				curlun->info_valid = 1;
-+				continue;
-+			}
-+
-+			/* Get the next buffer */
-+			usb_offset += amount;
-+			fsg->usb_amount_left -= amount;
-+			amount_left_to_req -= amount;
-+			if (amount_left_to_req == 0)
-+				get_some_more = 0;
-+
-+			/* Except at the end of the transfer, amount will be
-+			 * equal to the buffer size, which is divisible by
-+			 * the bulk-out maxpacket size.
-+			 */
-+			set_bulk_out_req_length(fsg, bh, amount);
-+			start_transfer(fsg, fsg->bulk_out, bh->outreq,
-+					&bh->outreq_busy, &bh->state);
-+			fsg->next_buffhd_to_fill = bh->next;
-+			continue;
-+		}
-+
-+		/* Write the received data to the backing file */
-+		bh = fsg->next_buffhd_to_drain;
-+		if (bh->state == BUF_STATE_EMPTY && !get_some_more)
-+			break;			// We stopped early
-+		if (bh->state == BUF_STATE_FULL) {
-+			smp_rmb();
-+			fsg->next_buffhd_to_drain = bh->next;
-+			bh->state = BUF_STATE_EMPTY;
-+
-+			/* Did something go wrong with the transfer? */
-+			if (bh->outreq->status != 0) {
-+				curlun->sense_data = SS_COMMUNICATION_FAILURE;
-+				curlun->sense_data_info = file_offset >> curlun->blkbits;
-+				curlun->info_valid = 1;
-+				break;
-+			}
-+
-+			amount = bh->outreq->actual;
-+			if (curlun->file_length - file_offset < amount) {
-+				LERROR(curlun,
-+	"write %u @ %llu beyond end %llu\n",
-+	amount, (unsigned long long) file_offset,
-+	(unsigned long long) curlun->file_length);
-+				amount = curlun->file_length - file_offset;
-+			}
-+
-+			/* Don't accept excess data.  The spec doesn't say
-+			 * what to do in this case.  We'll ignore the error.
-+			 */
-+			amount = min(amount, bh->bulk_out_intended_length);
-+
-+			/* Don't write a partial block */
-+			amount = round_down(amount, curlun->blksize);
-+			if (amount == 0)
-+				goto empty_write;
-+
-+			/* Perform the write */
-+			file_offset_tmp = file_offset;
-+			nwritten = vfs_write(curlun->filp,
-+					(char __user *) bh->buf,
-+					amount, &file_offset_tmp);
-+			VLDBG(curlun, "file write %u @ %llu -> %d\n", amount,
-+					(unsigned long long) file_offset,
-+					(int) nwritten);
-+			if (signal_pending(current))
-+				return -EINTR;		// Interrupted!
-+
-+			if (nwritten < 0) {
-+				LDBG(curlun, "error in file write: %d\n",
-+						(int) nwritten);
-+				nwritten = 0;
-+			} else if (nwritten < amount) {
-+				LDBG(curlun, "partial file write: %d/%u\n",
-+						(int) nwritten, amount);
-+				nwritten = round_down(nwritten, curlun->blksize);
-+			}
-+			file_offset += nwritten;
-+			amount_left_to_write -= nwritten;
-+			fsg->residue -= nwritten;
-+
-+			/* If an error occurred, report it and its position */
-+			if (nwritten < amount) {
-+				curlun->sense_data = SS_WRITE_ERROR;
-+				curlun->sense_data_info = file_offset >> curlun->blkbits;
-+				curlun->info_valid = 1;
-+				break;
-+			}
-+
-+ empty_write:
-+			/* Did the host decide to stop early? */
-+			if (bh->outreq->actual < bh->bulk_out_intended_length) {
-+				fsg->short_packet_received = 1;
-+				break;
-+			}
-+			continue;
-+		}
-+
-+		/* Wait for something to happen */
-+		rc = sleep_thread(fsg);
-+		if (rc)
-+			return rc;
-+	}
-+
-+	return -EIO;		// No default reply
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int do_synchronize_cache(struct fsg_dev *fsg)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+	int		rc;
-+
-+	/* We ignore the requested LBA and write out all file's
-+	 * dirty data buffers. */
-+	rc = fsg_lun_fsync_sub(curlun);
-+	if (rc)
-+		curlun->sense_data = SS_WRITE_ERROR;
-+	return 0;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void invalidate_sub(struct fsg_lun *curlun)
-+{
-+	struct file	*filp = curlun->filp;
-+	struct inode	*inode = filp->f_path.dentry->d_inode;
-+	unsigned long	rc;
-+
-+	rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
-+	VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc);
-+}
-+
-+static int do_verify(struct fsg_dev *fsg)
-+{
-+	struct fsg_lun		*curlun = fsg->curlun;
-+	u32			lba;
-+	u32			verification_length;
-+	struct fsg_buffhd	*bh = fsg->next_buffhd_to_fill;
-+	loff_t			file_offset, file_offset_tmp;
-+	u32			amount_left;
-+	unsigned int		amount;
-+	ssize_t			nread;
-+
-+	/* Get the starting Logical Block Address and check that it's
-+	 * not too big */
-+	lba = get_unaligned_be32(&fsg->cmnd[2]);
-+	if (lba >= curlun->num_sectors) {
-+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-+		return -EINVAL;
-+	}
-+
-+	/* We allow DPO (Disable Page Out = don't save data in the
-+	 * cache) but we don't implement it. */
-+	if ((fsg->cmnd[1] & ~0x10) != 0) {
-+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+		return -EINVAL;
-+	}
-+
-+	verification_length = get_unaligned_be16(&fsg->cmnd[7]);
-+	if (unlikely(verification_length == 0))
-+		return -EIO;		// No default reply
-+
-+	/* Prepare to carry out the file verify */
-+	amount_left = verification_length << curlun->blkbits;
-+	file_offset = ((loff_t) lba) << curlun->blkbits;
-+
-+	/* Write out all the dirty buffers before invalidating them */
-+	fsg_lun_fsync_sub(curlun);
-+	if (signal_pending(current))
-+		return -EINTR;
-+
-+	invalidate_sub(curlun);
-+	if (signal_pending(current))
-+		return -EINTR;
-+
-+	/* Just try to read the requested blocks */
-+	while (amount_left > 0) {
-+
-+		/* Figure out how much we need to read:
-+		 * Try to read the remaining amount, but not more than
-+		 * the buffer size.
-+		 * And don't try to read past the end of the file.
-+		 */
-+		amount = min((unsigned int) amount_left, mod_data.buflen);
-+		amount = min((loff_t) amount,
-+				curlun->file_length - file_offset);
-+		if (amount == 0) {
-+			curlun->sense_data =
-+					SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-+			curlun->sense_data_info = file_offset >> curlun->blkbits;
-+			curlun->info_valid = 1;
-+			break;
-+		}
-+
-+		/* Perform the read */
-+		file_offset_tmp = file_offset;
-+		nread = vfs_read(curlun->filp,
-+				(char __user *) bh->buf,
-+				amount, &file_offset_tmp);
-+		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
-+				(unsigned long long) file_offset,
-+				(int) nread);
-+		if (signal_pending(current))
-+			return -EINTR;
-+
-+		if (nread < 0) {
-+			LDBG(curlun, "error in file verify: %d\n",
-+					(int) nread);
-+			nread = 0;
-+		} else if (nread < amount) {
-+			LDBG(curlun, "partial file verify: %d/%u\n",
-+					(int) nread, amount);
-+			nread = round_down(nread, curlun->blksize);
-+		}
-+		if (nread == 0) {
-+			curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
-+			curlun->sense_data_info = file_offset >> curlun->blkbits;
-+			curlun->info_valid = 1;
-+			break;
-+		}
-+		file_offset += nread;
-+		amount_left -= nread;
-+	}
-+	return 0;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{
-+	u8	*buf = (u8 *) bh->buf;
-+
-+	static char vendor_id[] = "Linux   ";
-+	static char product_disk_id[] = "File-Stor Gadget";
-+	static char product_cdrom_id[] = "File-CD Gadget  ";
-+
-+	if (!fsg->curlun) {		// Unsupported LUNs are okay
-+		fsg->bad_lun_okay = 1;
-+		memset(buf, 0, 36);
-+		buf[0] = 0x7f;		// Unsupported, no device-type
-+		buf[4] = 31;		// Additional length
-+		return 36;
-+	}
-+
-+	memset(buf, 0, 8);
-+	buf[0] = (mod_data.cdrom ? TYPE_ROM : TYPE_DISK);
-+	if (mod_data.removable)
-+		buf[1] = 0x80;
-+	buf[2] = 2;		// ANSI SCSI level 2
-+	buf[3] = 2;		// SCSI-2 INQUIRY data format
-+	buf[4] = 31;		// Additional length
-+				// No special options
-+	sprintf(buf + 8, "%-8s%-16s%04x", vendor_id,
-+			(mod_data.cdrom ? product_cdrom_id :
-+				product_disk_id),
-+			mod_data.release);
-+	return 36;
-+}
-+
-+
-+static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+	u8		*buf = (u8 *) bh->buf;
-+	u32		sd, sdinfo;
-+	int		valid;
-+
-+	/*
-+	 * From the SCSI-2 spec., section 7.9 (Unit attention condition):
-+	 *
-+	 * If a REQUEST SENSE command is received from an initiator
-+	 * with a pending unit attention condition (before the target
-+	 * generates the contingent allegiance condition), then the
-+	 * target shall either:
-+	 *   a) report any pending sense data and preserve the unit
-+	 *	attention condition on the logical unit, or,
-+	 *   b) report the unit attention condition, may discard any
-+	 *	pending sense data, and clear the unit attention
-+	 *	condition on the logical unit for that initiator.
-+	 *
-+	 * FSG normally uses option a); enable this code to use option b).
-+	 */
-+#if 0
-+	if (curlun && curlun->unit_attention_data != SS_NO_SENSE) {
-+		curlun->sense_data = curlun->unit_attention_data;
-+		curlun->unit_attention_data = SS_NO_SENSE;
-+	}
-+#endif
-+
-+	if (!curlun) {		// Unsupported LUNs are okay
-+		fsg->bad_lun_okay = 1;
-+		sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
-+		sdinfo = 0;
-+		valid = 0;
-+	} else {
-+		sd = curlun->sense_data;
-+		sdinfo = curlun->sense_data_info;
-+		valid = curlun->info_valid << 7;
-+		curlun->sense_data = SS_NO_SENSE;
-+		curlun->sense_data_info = 0;
-+		curlun->info_valid = 0;
-+	}
-+
-+	memset(buf, 0, 18);
-+	buf[0] = valid | 0x70;			// Valid, current error
-+	buf[2] = SK(sd);
-+	put_unaligned_be32(sdinfo, &buf[3]);	/* Sense information */
-+	buf[7] = 18 - 8;			// Additional sense length
-+	buf[12] = ASC(sd);
-+	buf[13] = ASCQ(sd);
-+	return 18;
-+}
-+
-+
-+static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+	u32		lba = get_unaligned_be32(&fsg->cmnd[2]);
-+	int		pmi = fsg->cmnd[8];
-+	u8		*buf = (u8 *) bh->buf;
-+
-+	/* Check the PMI and LBA fields */
-+	if (pmi > 1 || (pmi == 0 && lba != 0)) {
-+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+		return -EINVAL;
-+	}
-+
-+	put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
-+						/* Max logical block */
-+	put_unaligned_be32(curlun->blksize, &buf[4]);	/* Block length */
-+	return 8;
-+}
-+
-+
-+static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+	int		msf = fsg->cmnd[1] & 0x02;
-+	u32		lba = get_unaligned_be32(&fsg->cmnd[2]);
-+	u8		*buf = (u8 *) bh->buf;
-+
-+	if ((fsg->cmnd[1] & ~0x02) != 0) {		/* Mask away MSF */
-+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+		return -EINVAL;
-+	}
-+	if (lba >= curlun->num_sectors) {
-+		curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
-+		return -EINVAL;
-+	}
-+
-+	memset(buf, 0, 8);
-+	buf[0] = 0x01;		/* 2048 bytes of user data, rest is EC */
-+	store_cdrom_address(&buf[4], msf, lba);
-+	return 8;
-+}
-+
-+
-+static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+	int		msf = fsg->cmnd[1] & 0x02;
-+	int		start_track = fsg->cmnd[6];
-+	u8		*buf = (u8 *) bh->buf;
-+
-+	if ((fsg->cmnd[1] & ~0x02) != 0 ||		/* Mask away MSF */
-+			start_track > 1) {
-+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+		return -EINVAL;
-+	}
-+
-+	memset(buf, 0, 20);
-+	buf[1] = (20-2);		/* TOC data length */
-+	buf[2] = 1;			/* First track number */
-+	buf[3] = 1;			/* Last track number */
-+	buf[5] = 0x16;			/* Data track, copying allowed */
-+	buf[6] = 0x01;			/* Only track is number 1 */
-+	store_cdrom_address(&buf[8], msf, 0);
-+
-+	buf[13] = 0x16;			/* Lead-out track is data */
-+	buf[14] = 0xAA;			/* Lead-out track number */
-+	store_cdrom_address(&buf[16], msf, curlun->num_sectors);
-+	return 20;
-+}
-+
-+
-+static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+	int		mscmnd = fsg->cmnd[0];
-+	u8		*buf = (u8 *) bh->buf;
-+	u8		*buf0 = buf;
-+	int		pc, page_code;
-+	int		changeable_values, all_pages;
-+	int		valid_page = 0;
-+	int		len, limit;
-+
-+	if ((fsg->cmnd[1] & ~0x08) != 0) {		// Mask away DBD
-+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+		return -EINVAL;
-+	}
-+	pc = fsg->cmnd[2] >> 6;
-+	page_code = fsg->cmnd[2] & 0x3f;
-+	if (pc == 3) {
-+		curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED;
-+		return -EINVAL;
-+	}
-+	changeable_values = (pc == 1);
-+	all_pages = (page_code == 0x3f);
-+
-+	/* Write the mode parameter header.  Fixed values are: default
-+	 * medium type, no cache control (DPOFUA), and no block descriptors.
-+	 * The only variable value is the WriteProtect bit.  We will fill in
-+	 * the mode data length later. */
-+	memset(buf, 0, 8);
-+	if (mscmnd == MODE_SENSE) {
-+		buf[2] = (curlun->ro ? 0x80 : 0x00);		// WP, DPOFUA
-+		buf += 4;
-+		limit = 255;
-+	} else {			// MODE_SENSE_10
-+		buf[3] = (curlun->ro ? 0x80 : 0x00);		// WP, DPOFUA
-+		buf += 8;
-+		limit = 65535;		// Should really be mod_data.buflen
-+	}
-+
-+	/* No block descriptors */
-+
-+	/* The mode pages, in numerical order.  The only page we support
-+	 * is the Caching page. */
-+	if (page_code == 0x08 || all_pages) {
-+		valid_page = 1;
-+		buf[0] = 0x08;		// Page code
-+		buf[1] = 10;		// Page length
-+		memset(buf+2, 0, 10);	// None of the fields are changeable
-+
-+		if (!changeable_values) {
-+			buf[2] = 0x04;	// Write cache enable,
-+					// Read cache not disabled
-+					// No cache retention priorities
-+			put_unaligned_be16(0xffff, &buf[4]);
-+					/* Don't disable prefetch */
-+					/* Minimum prefetch = 0 */
-+			put_unaligned_be16(0xffff, &buf[8]);
-+					/* Maximum prefetch */
-+			put_unaligned_be16(0xffff, &buf[10]);
-+					/* Maximum prefetch ceiling */
-+		}
-+		buf += 12;
-+	}
-+
-+	/* Check that a valid page was requested and the mode data length
-+	 * isn't too long. */
-+	len = buf - buf0;
-+	if (!valid_page || len > limit) {
-+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+		return -EINVAL;
-+	}
-+
-+	/*  Store the mode data length */
-+	if (mscmnd == MODE_SENSE)
-+		buf0[0] = len - 1;
-+	else
-+		put_unaligned_be16(len - 2, buf0);
-+	return len;
-+}
-+
-+
-+static int do_start_stop(struct fsg_dev *fsg)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+	int		loej, start;
-+
-+	if (!mod_data.removable) {
-+		curlun->sense_data = SS_INVALID_COMMAND;
-+		return -EINVAL;
-+	}
-+
-+	// int immed = fsg->cmnd[1] & 0x01;
-+	loej = fsg->cmnd[4] & 0x02;
-+	start = fsg->cmnd[4] & 0x01;
-+
-+#ifdef CONFIG_USB_FILE_STORAGE_TEST
-+	if ((fsg->cmnd[1] & ~0x01) != 0 ||		// Mask away Immed
-+			(fsg->cmnd[4] & ~0x03) != 0) {	// Mask LoEj, Start
-+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+		return -EINVAL;
-+	}
-+
-+	if (!start) {
-+
-+		/* Are we allowed to unload the media? */
-+		if (curlun->prevent_medium_removal) {
-+			LDBG(curlun, "unload attempt prevented\n");
-+			curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED;
-+			return -EINVAL;
-+		}
-+		if (loej) {		// Simulate an unload/eject
-+			up_read(&fsg->filesem);
-+			down_write(&fsg->filesem);
-+			fsg_lun_close(curlun);
-+			up_write(&fsg->filesem);
-+			down_read(&fsg->filesem);
-+		}
-+	} else {
-+
-+		/* Our emulation doesn't support mounting; the medium is
-+		 * available for use as soon as it is loaded. */
-+		if (!fsg_lun_is_open(curlun)) {
-+			curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
-+			return -EINVAL;
-+		}
-+	}
-+#endif
-+	return 0;
-+}
-+
-+
-+static int do_prevent_allow(struct fsg_dev *fsg)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+	int		prevent;
-+
-+	if (!mod_data.removable) {
-+		curlun->sense_data = SS_INVALID_COMMAND;
-+		return -EINVAL;
-+	}
-+
-+	prevent = fsg->cmnd[4] & 0x01;
-+	if ((fsg->cmnd[4] & ~0x01) != 0) {		// Mask away Prevent
-+		curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+		return -EINVAL;
-+	}
-+
-+	if (curlun->prevent_medium_removal && !prevent)
-+		fsg_lun_fsync_sub(curlun);
-+	curlun->prevent_medium_removal = prevent;
-+	return 0;
-+}
-+
-+
-+static int do_read_format_capacities(struct fsg_dev *fsg,
-+			struct fsg_buffhd *bh)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+	u8		*buf = (u8 *) bh->buf;
-+
-+	buf[0] = buf[1] = buf[2] = 0;
-+	buf[3] = 8;		// Only the Current/Maximum Capacity Descriptor
-+	buf += 4;
-+
-+	put_unaligned_be32(curlun->num_sectors, &buf[0]);
-+						/* Number of blocks */
-+	put_unaligned_be32(curlun->blksize, &buf[4]);	/* Block length */
-+	buf[4] = 0x02;				/* Current capacity */
-+	return 12;
-+}
-+
-+
-+static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{
-+	struct fsg_lun	*curlun = fsg->curlun;
-+
-+	/* We don't support MODE SELECT */
-+	curlun->sense_data = SS_INVALID_COMMAND;
-+	return -EINVAL;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
-+{
-+	int	rc;
-+
-+	rc = fsg_set_halt(fsg, fsg->bulk_in);
-+	if (rc == -EAGAIN)
-+		VDBG(fsg, "delayed bulk-in endpoint halt\n");
-+	while (rc != 0) {
-+		if (rc != -EAGAIN) {
-+			WARNING(fsg, "usb_ep_set_halt -> %d\n", rc);
-+			rc = 0;
-+			break;
-+		}
-+
-+		/* Wait for a short time and then try again */
-+		if (msleep_interruptible(100) != 0)
-+			return -EINTR;
-+		rc = usb_ep_set_halt(fsg->bulk_in);
-+	}
-+	return rc;
-+}
-+
-+static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
-+{
-+	int	rc;
-+
-+	DBG(fsg, "bulk-in set wedge\n");
-+	rc = usb_ep_set_wedge(fsg->bulk_in);
-+	if (rc == -EAGAIN)
-+		VDBG(fsg, "delayed bulk-in endpoint wedge\n");
-+	while (rc != 0) {
-+		if (rc != -EAGAIN) {
-+			WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc);
-+			rc = 0;
-+			break;
-+		}
-+
-+		/* Wait for a short time and then try again */
-+		if (msleep_interruptible(100) != 0)
-+			return -EINTR;
-+		rc = usb_ep_set_wedge(fsg->bulk_in);
-+	}
-+	return rc;
-+}
-+
-+static int throw_away_data(struct fsg_dev *fsg)
-+{
-+	struct fsg_buffhd	*bh;
-+	u32			amount;
-+	int			rc;
-+
-+	while ((bh = fsg->next_buffhd_to_drain)->state != BUF_STATE_EMPTY ||
-+			fsg->usb_amount_left > 0) {
-+
-+		/* Throw away the data in a filled buffer */
-+		if (bh->state == BUF_STATE_FULL) {
-+			smp_rmb();
-+			bh->state = BUF_STATE_EMPTY;
-+			fsg->next_buffhd_to_drain = bh->next;
-+
-+			/* A short packet or an error ends everything */
-+			if (bh->outreq->actual < bh->bulk_out_intended_length ||
-+					bh->outreq->status != 0) {
-+				raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
-+				return -EINTR;
-+			}
-+			continue;
-+		}
-+
-+		/* Try to submit another request if we need one */
-+		bh = fsg->next_buffhd_to_fill;
-+		if (bh->state == BUF_STATE_EMPTY && fsg->usb_amount_left > 0) {
-+			amount = min(fsg->usb_amount_left,
-+					(u32) mod_data.buflen);
-+
-+			/* Except at the end of the transfer, amount will be
-+			 * equal to the buffer size, which is divisible by
-+			 * the bulk-out maxpacket size.
-+			 */
-+			set_bulk_out_req_length(fsg, bh, amount);
-+			start_transfer(fsg, fsg->bulk_out, bh->outreq,
-+					&bh->outreq_busy, &bh->state);
-+			fsg->next_buffhd_to_fill = bh->next;
-+			fsg->usb_amount_left -= amount;
-+			continue;
-+		}
-+
-+		/* Otherwise wait for something to happen */
-+		rc = sleep_thread(fsg);
-+		if (rc)
-+			return rc;
-+	}
-+	return 0;
-+}
-+
-+
-+static int finish_reply(struct fsg_dev *fsg)
-+{
-+	struct fsg_buffhd	*bh = fsg->next_buffhd_to_fill;
-+	int			rc = 0;
-+
-+	switch (fsg->data_dir) {
-+	case DATA_DIR_NONE:
-+		break;			// Nothing to send
-+
-+	/* If we don't know whether the host wants to read or write,
-+	 * this must be CB or CBI with an unknown command.  We mustn't
-+	 * try to send or receive any data.  So stall both bulk pipes
-+	 * if we can and wait for a reset. */
-+	case DATA_DIR_UNKNOWN:
-+		if (mod_data.can_stall) {
-+			fsg_set_halt(fsg, fsg->bulk_out);
-+			rc = halt_bulk_in_endpoint(fsg);
-+		}
-+		break;
-+
-+	/* All but the last buffer of data must have already been sent */
-+	case DATA_DIR_TO_HOST:
-+		if (fsg->data_size == 0)
-+			;		// Nothing to send
-+
-+		/* If there's no residue, simply send the last buffer */
-+		else if (fsg->residue == 0) {
-+			bh->inreq->zero = 0;
-+			start_transfer(fsg, fsg->bulk_in, bh->inreq,
-+					&bh->inreq_busy, &bh->state);
-+			fsg->next_buffhd_to_fill = bh->next;
-+		}
-+
-+		/* There is a residue.  For CB and CBI, simply mark the end
-+		 * of the data with a short packet.  However, if we are
-+		 * allowed to stall, there was no data at all (residue ==
-+		 * data_size), and the command failed (invalid LUN or
-+		 * sense data is set), then halt the bulk-in endpoint
-+		 * instead. */
-+		else if (!transport_is_bbb()) {
-+			if (mod_data.can_stall &&
-+					fsg->residue == fsg->data_size &&
-+	(!fsg->curlun || fsg->curlun->sense_data != SS_NO_SENSE)) {
-+				bh->state = BUF_STATE_EMPTY;
-+				rc = halt_bulk_in_endpoint(fsg);
-+			} else {
-+				bh->inreq->zero = 1;
-+				start_transfer(fsg, fsg->bulk_in, bh->inreq,
-+						&bh->inreq_busy, &bh->state);
-+				fsg->next_buffhd_to_fill = bh->next;
-+			}
-+		}
-+
-+		/*
-+		 * For Bulk-only, mark the end of the data with a short
-+		 * packet.  If we are allowed to stall, halt the bulk-in
-+		 * endpoint.  (Note: This violates the Bulk-Only Transport
-+		 * specification, which requires us to pad the data if we
-+		 * don't halt the endpoint.  Presumably nobody will mind.)
-+		 */
-+		else {
-+			bh->inreq->zero = 1;
-+			start_transfer(fsg, fsg->bulk_in, bh->inreq,
-+					&bh->inreq_busy, &bh->state);
-+			fsg->next_buffhd_to_fill = bh->next;
-+			if (mod_data.can_stall)
-+				rc = halt_bulk_in_endpoint(fsg);
-+		}
-+		break;
-+
-+	/* We have processed all we want from the data the host has sent.
-+	 * There may still be outstanding bulk-out requests. */
-+	case DATA_DIR_FROM_HOST:
-+		if (fsg->residue == 0)
-+			;		// Nothing to receive
-+
-+		/* Did the host stop sending unexpectedly early? */
-+		else if (fsg->short_packet_received) {
-+			raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
-+			rc = -EINTR;
-+		}
-+
-+		/* We haven't processed all the incoming data.  Even though
-+		 * we may be allowed to stall, doing so would cause a race.
-+		 * The controller may already have ACK'ed all the remaining
-+		 * bulk-out packets, in which case the host wouldn't see a
-+		 * STALL.  Not realizing the endpoint was halted, it wouldn't
-+		 * clear the halt -- leading to problems later on. */
-+#if 0
-+		else if (mod_data.can_stall) {
-+			fsg_set_halt(fsg, fsg->bulk_out);
-+			raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT);
-+			rc = -EINTR;
-+		}
-+#endif
-+
-+		/* We can't stall.  Read in the excess data and throw it
-+		 * all away. */
-+		else
-+			rc = throw_away_data(fsg);
-+		break;
-+	}
-+	return rc;
-+}
-+
-+
-+static int send_status(struct fsg_dev *fsg)
-+{
-+	struct fsg_lun		*curlun = fsg->curlun;
-+	struct fsg_buffhd	*bh;
-+	int			rc;
-+	u8			status = US_BULK_STAT_OK;
-+	u32			sd, sdinfo = 0;
-+
-+	/* Wait for the next buffer to become available */
-+	bh = fsg->next_buffhd_to_fill;
-+	while (bh->state != BUF_STATE_EMPTY) {
-+		rc = sleep_thread(fsg);
-+		if (rc)
-+			return rc;
-+	}
-+
-+	if (curlun) {
-+		sd = curlun->sense_data;
-+		sdinfo = curlun->sense_data_info;
-+	} else if (fsg->bad_lun_okay)
-+		sd = SS_NO_SENSE;
-+	else
-+		sd = SS_LOGICAL_UNIT_NOT_SUPPORTED;
-+
-+	if (fsg->phase_error) {
-+		DBG(fsg, "sending phase-error status\n");
-+		status = US_BULK_STAT_PHASE;
-+		sd = SS_INVALID_COMMAND;
-+	} else if (sd != SS_NO_SENSE) {
-+		DBG(fsg, "sending command-failure status\n");
-+		status = US_BULK_STAT_FAIL;
-+		VDBG(fsg, "  sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
-+				"  info x%x\n",
-+				SK(sd), ASC(sd), ASCQ(sd), sdinfo);
-+	}
-+
-+	if (transport_is_bbb()) {
-+		struct bulk_cs_wrap	*csw = bh->buf;
-+
-+		/* Store and send the Bulk-only CSW */
-+		csw->Signature = cpu_to_le32(US_BULK_CS_SIGN);
-+		csw->Tag = fsg->tag;
-+		csw->Residue = cpu_to_le32(fsg->residue);
-+		csw->Status = status;
-+
-+		bh->inreq->length = US_BULK_CS_WRAP_LEN;
-+		bh->inreq->zero = 0;
-+		start_transfer(fsg, fsg->bulk_in, bh->inreq,
-+				&bh->inreq_busy, &bh->state);
-+
-+	} else if (mod_data.transport_type == USB_PR_CB) {
-+
-+		/* Control-Bulk transport has no status phase! */
-+		return 0;
-+
-+	} else {			// USB_PR_CBI
-+		struct interrupt_data	*buf = bh->buf;
-+
-+		/* Store and send the Interrupt data.  UFI sends the ASC
-+		 * and ASCQ bytes.  Everything else sends a Type (which
-+		 * is always 0) and the status Value. */
-+		if (mod_data.protocol_type == USB_SC_UFI) {
-+			buf->bType = ASC(sd);
-+			buf->bValue = ASCQ(sd);
-+		} else {
-+			buf->bType = 0;
-+			buf->bValue = status;
-+		}
-+		fsg->intreq->length = CBI_INTERRUPT_DATA_LEN;
-+
-+		fsg->intr_buffhd = bh;		// Point to the right buffhd
-+		fsg->intreq->buf = bh->inreq->buf;
-+		fsg->intreq->context = bh;
-+		start_transfer(fsg, fsg->intr_in, fsg->intreq,
-+				&fsg->intreq_busy, &bh->state);
-+	}
-+
-+	fsg->next_buffhd_to_fill = bh->next;
-+	return 0;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Check whether the command is properly formed and whether its data size
-+ * and direction agree with the values we already have. */
-+static int check_command(struct fsg_dev *fsg, int cmnd_size,
-+		enum data_direction data_dir, unsigned int mask,
-+		int needs_medium, const char *name)
-+{
-+	int			i;
-+	int			lun = fsg->cmnd[1] >> 5;
-+	static const char	dirletter[4] = {'u', 'o', 'i', 'n'};
-+	char			hdlen[20];
-+	struct fsg_lun		*curlun;
-+
-+	/* Adjust the expected cmnd_size for protocol encapsulation padding.
-+	 * Transparent SCSI doesn't pad. */
-+	if (protocol_is_scsi())
-+		;
-+
-+	/* There's some disagreement as to whether RBC pads commands or not.
-+	 * We'll play it safe and accept either form. */
-+	else if (mod_data.protocol_type == USB_SC_RBC) {
-+		if (fsg->cmnd_size == 12)
-+			cmnd_size = 12;
-+
-+	/* All the other protocols pad to 12 bytes */
-+	} else
-+		cmnd_size = 12;
-+
-+	hdlen[0] = 0;
-+	if (fsg->data_dir != DATA_DIR_UNKNOWN)
-+		sprintf(hdlen, ", H%c=%u", dirletter[(int) fsg->data_dir],
-+				fsg->data_size);
-+	VDBG(fsg, "SCSI command: %s;  Dc=%d, D%c=%u;  Hc=%d%s\n",
-+			name, cmnd_size, dirletter[(int) data_dir],
-+			fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen);
-+
-+	/* We can't reply at all until we know the correct data direction
-+	 * and size. */
-+	if (fsg->data_size_from_cmnd == 0)
-+		data_dir = DATA_DIR_NONE;
-+	if (fsg->data_dir == DATA_DIR_UNKNOWN) {	// CB or CBI
-+		fsg->data_dir = data_dir;
-+		fsg->data_size = fsg->data_size_from_cmnd;
-+
-+	} else {					// Bulk-only
-+		if (fsg->data_size < fsg->data_size_from_cmnd) {
-+
-+			/* Host data size < Device data size is a phase error.
-+			 * Carry out the command, but only transfer as much
-+			 * as we are allowed. */
-+			fsg->data_size_from_cmnd = fsg->data_size;
-+			fsg->phase_error = 1;
-+		}
-+	}
-+	fsg->residue = fsg->usb_amount_left = fsg->data_size;
-+
-+	/* Conflicting data directions is a phase error */
-+	if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) {
-+		fsg->phase_error = 1;
-+		return -EINVAL;
-+	}
-+
-+	/* Verify the length of the command itself */
-+	if (cmnd_size != fsg->cmnd_size) {
-+
-+		/* Special case workaround: There are plenty of buggy SCSI
-+		 * implementations. Many have issues with cbw->Length
-+		 * field passing a wrong command size. For those cases we
-+		 * always try to work around the problem by using the length
-+		 * sent by the host side provided it is at least as large
-+		 * as the correct command length.
-+		 * Examples of such cases would be MS-Windows, which issues
-+		 * REQUEST SENSE with cbw->Length == 12 where it should
-+		 * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and
-+		 * REQUEST SENSE with cbw->Length == 10 where it should
-+		 * be 6 as well.
-+		 */
-+		if (cmnd_size <= fsg->cmnd_size) {
-+			DBG(fsg, "%s is buggy! Expected length %d "
-+					"but we got %d\n", name,
-+					cmnd_size, fsg->cmnd_size);
-+			cmnd_size = fsg->cmnd_size;
-+		} else {
-+			fsg->phase_error = 1;
-+			return -EINVAL;
-+		}
-+	}
-+
-+	/* Check that the LUN values are consistent */
-+	if (transport_is_bbb()) {
-+		if (fsg->lun != lun)
-+			DBG(fsg, "using LUN %d from CBW, "
-+					"not LUN %d from CDB\n",
-+					fsg->lun, lun);
-+	}
-+
-+	/* Check the LUN */
-+	curlun = fsg->curlun;
-+	if (curlun) {
-+		if (fsg->cmnd[0] != REQUEST_SENSE) {
-+			curlun->sense_data = SS_NO_SENSE;
-+			curlun->sense_data_info = 0;
-+			curlun->info_valid = 0;
-+		}
-+	} else {
-+		fsg->bad_lun_okay = 0;
-+
-+		/* INQUIRY and REQUEST SENSE commands are explicitly allowed
-+		 * to use unsupported LUNs; all others may not. */
-+		if (fsg->cmnd[0] != INQUIRY &&
-+				fsg->cmnd[0] != REQUEST_SENSE) {
-+			DBG(fsg, "unsupported LUN %d\n", fsg->lun);
-+			return -EINVAL;
-+		}
-+	}
-+
-+	/* If a unit attention condition exists, only INQUIRY and
-+	 * REQUEST SENSE commands are allowed; anything else must fail. */
-+	if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
-+			fsg->cmnd[0] != INQUIRY &&
-+			fsg->cmnd[0] != REQUEST_SENSE) {
-+		curlun->sense_data = curlun->unit_attention_data;
-+		curlun->unit_attention_data = SS_NO_SENSE;
-+		return -EINVAL;
-+	}
-+
-+	/* Check that only command bytes listed in the mask are non-zero */
-+	fsg->cmnd[1] &= 0x1f;			// Mask away the LUN
-+	for (i = 1; i < cmnd_size; ++i) {
-+		if (fsg->cmnd[i] && !(mask & (1 << i))) {
-+			if (curlun)
-+				curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
-+			return -EINVAL;
-+		}
-+	}
-+
-+	/* If the medium isn't mounted and the command needs to access
-+	 * it, return an error. */
-+	if (curlun && !fsg_lun_is_open(curlun) && needs_medium) {
-+		curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
-+		return -EINVAL;
-+	}
-+
-+	return 0;
-+}
-+
-+/* wrapper of check_command for data size in blocks handling */
-+static int check_command_size_in_blocks(struct fsg_dev *fsg, int cmnd_size,
-+		enum data_direction data_dir, unsigned int mask,
-+		int needs_medium, const char *name)
-+{
-+	if (fsg->curlun)
-+		fsg->data_size_from_cmnd <<= fsg->curlun->blkbits;
-+	return check_command(fsg, cmnd_size, data_dir,
-+			mask, needs_medium, name);
-+}
-+
-+static int do_scsi_command(struct fsg_dev *fsg)
-+{
-+	struct fsg_buffhd	*bh;
-+	int			rc;
-+	int			reply = -EINVAL;
-+	int			i;
-+	static char		unknown[16];
-+
-+	dump_cdb(fsg);
-+
-+	/* Wait for the next buffer to become available for data or status */
-+	bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill;
-+	while (bh->state != BUF_STATE_EMPTY) {
-+		rc = sleep_thread(fsg);
-+		if (rc)
-+			return rc;
-+	}
-+	fsg->phase_error = 0;
-+	fsg->short_packet_received = 0;
-+
-+	down_read(&fsg->filesem);	// We're using the backing file
-+	switch (fsg->cmnd[0]) {
-+
-+	case INQUIRY:
-+		fsg->data_size_from_cmnd = fsg->cmnd[4];
-+		if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
-+				(1<<4), 0,
-+				"INQUIRY")) == 0)
-+			reply = do_inquiry(fsg, bh);
-+		break;
-+
-+	case MODE_SELECT:
-+		fsg->data_size_from_cmnd = fsg->cmnd[4];
-+		if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST,
-+				(1<<1) | (1<<4), 0,
-+				"MODE SELECT(6)")) == 0)
-+			reply = do_mode_select(fsg, bh);
-+		break;
-+
-+	case MODE_SELECT_10:
-+		fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
-+		if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST,
-+				(1<<1) | (3<<7), 0,
-+				"MODE SELECT(10)")) == 0)
-+			reply = do_mode_select(fsg, bh);
-+		break;
-+
-+	case MODE_SENSE:
-+		fsg->data_size_from_cmnd = fsg->cmnd[4];
-+		if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
-+				(1<<1) | (1<<2) | (1<<4), 0,
-+				"MODE SENSE(6)")) == 0)
-+			reply = do_mode_sense(fsg, bh);
-+		break;
-+
-+	case MODE_SENSE_10:
-+		fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
-+		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
-+				(1<<1) | (1<<2) | (3<<7), 0,
-+				"MODE SENSE(10)")) == 0)
-+			reply = do_mode_sense(fsg, bh);
-+		break;
-+
-+	case ALLOW_MEDIUM_REMOVAL:
-+		fsg->data_size_from_cmnd = 0;
-+		if ((reply = check_command(fsg, 6, DATA_DIR_NONE,
-+				(1<<4), 0,
-+				"PREVENT-ALLOW MEDIUM REMOVAL")) == 0)
-+			reply = do_prevent_allow(fsg);
-+		break;
-+
-+	case READ_6:
-+		i = fsg->cmnd[4];
-+		fsg->data_size_from_cmnd = (i == 0) ? 256 : i;
-+		if ((reply = check_command_size_in_blocks(fsg, 6,
-+				DATA_DIR_TO_HOST,
-+				(7<<1) | (1<<4), 1,
-+				"READ(6)")) == 0)
-+			reply = do_read(fsg);
-+		break;
-+
-+	case READ_10:
-+		fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
-+		if ((reply = check_command_size_in_blocks(fsg, 10,
-+				DATA_DIR_TO_HOST,
-+				(1<<1) | (0xf<<2) | (3<<7), 1,
-+				"READ(10)")) == 0)
-+			reply = do_read(fsg);
-+		break;
-+
-+	case READ_12:
-+		fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]);
-+		if ((reply = check_command_size_in_blocks(fsg, 12,
-+				DATA_DIR_TO_HOST,
-+				(1<<1) | (0xf<<2) | (0xf<<6), 1,
-+				"READ(12)")) == 0)
-+			reply = do_read(fsg);
-+		break;
-+
-+	case READ_CAPACITY:
-+		fsg->data_size_from_cmnd = 8;
-+		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
-+				(0xf<<2) | (1<<8), 1,
-+				"READ CAPACITY")) == 0)
-+			reply = do_read_capacity(fsg, bh);
-+		break;
-+
-+	case READ_HEADER:
-+		if (!mod_data.cdrom)
-+			goto unknown_cmnd;
-+		fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
-+		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
-+				(3<<7) | (0x1f<<1), 1,
-+				"READ HEADER")) == 0)
-+			reply = do_read_header(fsg, bh);
-+		break;
-+
-+	case READ_TOC:
-+		if (!mod_data.cdrom)
-+			goto unknown_cmnd;
-+		fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
-+		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
-+				(7<<6) | (1<<1), 1,
-+				"READ TOC")) == 0)
-+			reply = do_read_toc(fsg, bh);
-+		break;
-+
-+	case READ_FORMAT_CAPACITIES:
-+		fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
-+		if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST,
-+				(3<<7), 1,
-+				"READ FORMAT CAPACITIES")) == 0)
-+			reply = do_read_format_capacities(fsg, bh);
-+		break;
-+
-+	case REQUEST_SENSE:
-+		fsg->data_size_from_cmnd = fsg->cmnd[4];
-+		if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST,
-+				(1<<4), 0,
-+				"REQUEST SENSE")) == 0)
-+			reply = do_request_sense(fsg, bh);
-+		break;
-+
-+	case START_STOP:
-+		fsg->data_size_from_cmnd = 0;
-+		if ((reply = check_command(fsg, 6, DATA_DIR_NONE,
-+				(1<<1) | (1<<4), 0,
-+				"START-STOP UNIT")) == 0)
-+			reply = do_start_stop(fsg);
-+		break;
-+
-+	case SYNCHRONIZE_CACHE:
-+		fsg->data_size_from_cmnd = 0;
-+		if ((reply = check_command(fsg, 10, DATA_DIR_NONE,
-+				(0xf<<2) | (3<<7), 1,
-+				"SYNCHRONIZE CACHE")) == 0)
-+			reply = do_synchronize_cache(fsg);
-+		break;
-+
-+	case TEST_UNIT_READY:
-+		fsg->data_size_from_cmnd = 0;
-+		reply = check_command(fsg, 6, DATA_DIR_NONE,
-+				0, 1,
-+				"TEST UNIT READY");
-+		break;
-+
-+	/* Although optional, this command is used by MS-Windows.  We
-+	 * support a minimal version: BytChk must be 0. */
-+	case VERIFY:
-+		fsg->data_size_from_cmnd = 0;
-+		if ((reply = check_command(fsg, 10, DATA_DIR_NONE,
-+				(1<<1) | (0xf<<2) | (3<<7), 1,
-+				"VERIFY")) == 0)
-+			reply = do_verify(fsg);
-+		break;
-+
-+	case WRITE_6:
-+		i = fsg->cmnd[4];
-+		fsg->data_size_from_cmnd = (i == 0) ? 256 : i;
-+		if ((reply = check_command_size_in_blocks(fsg, 6,
-+				DATA_DIR_FROM_HOST,
-+				(7<<1) | (1<<4), 1,
-+				"WRITE(6)")) == 0)
-+			reply = do_write(fsg);
-+		break;
-+
-+	case WRITE_10:
-+		fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]);
-+		if ((reply = check_command_size_in_blocks(fsg, 10,
-+				DATA_DIR_FROM_HOST,
-+				(1<<1) | (0xf<<2) | (3<<7), 1,
-+				"WRITE(10)")) == 0)
-+			reply = do_write(fsg);
-+		break;
-+
-+	case WRITE_12:
-+		fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]);
-+		if ((reply = check_command_size_in_blocks(fsg, 12,
-+				DATA_DIR_FROM_HOST,
-+				(1<<1) | (0xf<<2) | (0xf<<6), 1,
-+				"WRITE(12)")) == 0)
-+			reply = do_write(fsg);
-+		break;
-+
-+	/* Some mandatory commands that we recognize but don't implement.
-+	 * They don't mean much in this setting.  It's left as an exercise
-+	 * for anyone interested to implement RESERVE and RELEASE in terms
-+	 * of Posix locks. */
-+	case FORMAT_UNIT:
-+	case RELEASE:
-+	case RESERVE:
-+	case SEND_DIAGNOSTIC:
-+		// Fall through
-+
-+	default:
-+ unknown_cmnd:
-+		fsg->data_size_from_cmnd = 0;
-+		sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);
-+		if ((reply = check_command(fsg, fsg->cmnd_size,
-+				DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) {
-+			fsg->curlun->sense_data = SS_INVALID_COMMAND;
-+			reply = -EINVAL;
-+		}
-+		break;
-+	}
-+	up_read(&fsg->filesem);
-+
-+	if (reply == -EINTR || signal_pending(current))
-+		return -EINTR;
-+
-+	/* Set up the single reply buffer for finish_reply() */
-+	if (reply == -EINVAL)
-+		reply = 0;		// Error reply length
-+	if (reply >= 0 && fsg->data_dir == DATA_DIR_TO_HOST) {
-+		reply = min((u32) reply, fsg->data_size_from_cmnd);
-+		bh->inreq->length = reply;
-+		bh->state = BUF_STATE_FULL;
-+		fsg->residue -= reply;
-+	}				// Otherwise it's already set
-+
-+	return 0;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
-+{
-+	struct usb_request		*req = bh->outreq;
-+	struct bulk_cb_wrap	*cbw = req->buf;
-+
-+	/* Was this a real packet?  Should it be ignored? */
-+	if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
-+		return -EINVAL;
-+
-+	/* Is the CBW valid? */
-+	if (req->actual != US_BULK_CB_WRAP_LEN ||
-+			cbw->Signature != cpu_to_le32(
-+				US_BULK_CB_SIGN)) {
-+		DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
-+				req->actual,
-+				le32_to_cpu(cbw->Signature));
-+
-+		/* The Bulk-only spec says we MUST stall the IN endpoint
-+		 * (6.6.1), so it's unavoidable.  It also says we must
-+		 * retain this state until the next reset, but there's
-+		 * no way to tell the controller driver it should ignore
-+		 * Clear-Feature(HALT) requests.
-+		 *
-+		 * We aren't required to halt the OUT endpoint; instead
-+		 * we can simply accept and discard any data received
-+		 * until the next reset. */
-+		wedge_bulk_in_endpoint(fsg);
-+		set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
-+		return -EINVAL;
-+	}
-+
-+	/* Is the CBW meaningful? */
-+	if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN ||
-+			cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
-+		DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
-+				"cmdlen %u\n",
-+				cbw->Lun, cbw->Flags, cbw->Length);
-+
-+		/* We can do anything we want here, so let's stall the
-+		 * bulk pipes if we are allowed to. */
-+		if (mod_data.can_stall) {
-+			fsg_set_halt(fsg, fsg->bulk_out);
-+			halt_bulk_in_endpoint(fsg);
-+		}
-+		return -EINVAL;
-+	}
-+
-+	/* Save the command for later */
-+	fsg->cmnd_size = cbw->Length;
-+	memcpy(fsg->cmnd, cbw->CDB, fsg->cmnd_size);
-+	if (cbw->Flags & US_BULK_FLAG_IN)
-+		fsg->data_dir = DATA_DIR_TO_HOST;
-+	else
-+		fsg->data_dir = DATA_DIR_FROM_HOST;
-+	fsg->data_size = le32_to_cpu(cbw->DataTransferLength);
-+	if (fsg->data_size == 0)
-+		fsg->data_dir = DATA_DIR_NONE;
-+	fsg->lun = cbw->Lun;
-+	fsg->tag = cbw->Tag;
-+	return 0;
-+}
-+
-+
-+static int get_next_command(struct fsg_dev *fsg)
-+{
-+	struct fsg_buffhd	*bh;
-+	int			rc = 0;
-+
-+	if (transport_is_bbb()) {
-+
-+		/* Wait for the next buffer to become available */
-+		bh = fsg->next_buffhd_to_fill;
-+		while (bh->state != BUF_STATE_EMPTY) {
-+			rc = sleep_thread(fsg);
-+			if (rc)
-+				return rc;
-+		}
-+
-+		/* Queue a request to read a Bulk-only CBW */
-+		set_bulk_out_req_length(fsg, bh, US_BULK_CB_WRAP_LEN);
-+		start_transfer(fsg, fsg->bulk_out, bh->outreq,
-+				&bh->outreq_busy, &bh->state);
-+
-+		/* We will drain the buffer in software, which means we
-+		 * can reuse it for the next filling.  No need to advance
-+		 * next_buffhd_to_fill. */
-+
-+		/* Wait for the CBW to arrive */
-+		while (bh->state != BUF_STATE_FULL) {
-+			rc = sleep_thread(fsg);
-+			if (rc)
-+				return rc;
-+		}
-+		smp_rmb();
-+		rc = received_cbw(fsg, bh);
-+		bh->state = BUF_STATE_EMPTY;
-+
-+	} else {		// USB_PR_CB or USB_PR_CBI
-+
-+		/* Wait for the next command to arrive */
-+		while (fsg->cbbuf_cmnd_size == 0) {
-+			rc = sleep_thread(fsg);
-+			if (rc)
-+				return rc;
-+		}
-+
-+		/* Is the previous status interrupt request still busy?
-+		 * The host is allowed to skip reading the status,
-+		 * so we must cancel it. */
-+		if (fsg->intreq_busy)
-+			usb_ep_dequeue(fsg->intr_in, fsg->intreq);
-+
-+		/* Copy the command and mark the buffer empty */
-+		fsg->data_dir = DATA_DIR_UNKNOWN;
-+		spin_lock_irq(&fsg->lock);
-+		fsg->cmnd_size = fsg->cbbuf_cmnd_size;
-+		memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size);
-+		fsg->cbbuf_cmnd_size = 0;
-+		spin_unlock_irq(&fsg->lock);
-+
-+		/* Use LUN from the command */
-+		fsg->lun = fsg->cmnd[1] >> 5;
-+	}
-+
-+	/* Update current lun */
-+	if (fsg->lun >= 0 && fsg->lun < fsg->nluns)
-+		fsg->curlun = &fsg->luns[fsg->lun];
-+	else
-+		fsg->curlun = NULL;
-+
-+	return rc;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int enable_endpoint(struct fsg_dev *fsg, struct usb_ep *ep,
-+		const struct usb_endpoint_descriptor *d)
-+{
-+	int	rc;
-+
-+	ep->driver_data = fsg;
-+	ep->desc = d;
-+	rc = usb_ep_enable(ep);
-+	if (rc)
-+		ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc);
-+	return rc;
-+}
-+
-+static int alloc_request(struct fsg_dev *fsg, struct usb_ep *ep,
-+		struct usb_request **preq)
-+{
-+	*preq = usb_ep_alloc_request(ep, GFP_ATOMIC);
-+	if (*preq)
-+		return 0;
-+	ERROR(fsg, "can't allocate request for %s\n", ep->name);
-+	return -ENOMEM;
-+}
-+
-+/*
-+ * Reset interface setting and re-init endpoint state (toggle etc).
-+ * Call with altsetting < 0 to disable the interface.  The only other
-+ * available altsetting is 0, which enables the interface.
-+ */
-+static int do_set_interface(struct fsg_dev *fsg, int altsetting)
-+{
-+	int	rc = 0;
-+	int	i;
-+	const struct usb_endpoint_descriptor	*d;
-+
-+	if (fsg->running)
-+		DBG(fsg, "reset interface\n");
-+
-+reset:
-+	/* Deallocate the requests */
-+	for (i = 0; i < fsg_num_buffers; ++i) {
-+		struct fsg_buffhd *bh = &fsg->buffhds[i];
-+
-+		if (bh->inreq) {
-+			usb_ep_free_request(fsg->bulk_in, bh->inreq);
-+			bh->inreq = NULL;
-+		}
-+		if (bh->outreq) {
-+			usb_ep_free_request(fsg->bulk_out, bh->outreq);
-+			bh->outreq = NULL;
-+		}
-+	}
-+	if (fsg->intreq) {
-+		usb_ep_free_request(fsg->intr_in, fsg->intreq);
-+		fsg->intreq = NULL;
-+	}
-+
-+	/* Disable the endpoints */
-+	if (fsg->bulk_in_enabled) {
-+		usb_ep_disable(fsg->bulk_in);
-+		fsg->bulk_in_enabled = 0;
-+	}
-+	if (fsg->bulk_out_enabled) {
-+		usb_ep_disable(fsg->bulk_out);
-+		fsg->bulk_out_enabled = 0;
-+	}
-+	if (fsg->intr_in_enabled) {
-+		usb_ep_disable(fsg->intr_in);
-+		fsg->intr_in_enabled = 0;
-+	}
-+
-+	fsg->running = 0;
-+	if (altsetting < 0 || rc != 0)
-+		return rc;
-+
-+	DBG(fsg, "set interface %d\n", altsetting);
-+
-+	/* Enable the endpoints */
-+	d = fsg_ep_desc(fsg->gadget,
-+			&fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc,
-+			&fsg_ss_bulk_in_desc);
-+	if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0)
-+		goto reset;
-+	fsg->bulk_in_enabled = 1;
-+
-+	d = fsg_ep_desc(fsg->gadget,
-+			&fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc,
-+			&fsg_ss_bulk_out_desc);
-+	if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0)
-+		goto reset;
-+	fsg->bulk_out_enabled = 1;
-+	fsg->bulk_out_maxpacket = usb_endpoint_maxp(d);
-+	clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags);
-+
-+	if (transport_is_cbi()) {
-+		d = fsg_ep_desc(fsg->gadget,
-+				&fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc,
-+				&fsg_ss_intr_in_desc);
-+		if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0)
-+			goto reset;
-+		fsg->intr_in_enabled = 1;
-+	}
-+
-+	/* Allocate the requests */
-+	for (i = 0; i < fsg_num_buffers; ++i) {
-+		struct fsg_buffhd	*bh = &fsg->buffhds[i];
-+
-+		if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0)
-+			goto reset;
-+		if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0)
-+			goto reset;
-+		bh->inreq->buf = bh->outreq->buf = bh->buf;
-+		bh->inreq->context = bh->outreq->context = bh;
-+		bh->inreq->complete = bulk_in_complete;
-+		bh->outreq->complete = bulk_out_complete;
-+	}
-+	if (transport_is_cbi()) {
-+		if ((rc = alloc_request(fsg, fsg->intr_in, &fsg->intreq)) != 0)
-+			goto reset;
-+		fsg->intreq->complete = intr_in_complete;
-+	}
-+
-+	fsg->running = 1;
-+	for (i = 0; i < fsg->nluns; ++i)
-+		fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED;
-+	return rc;
-+}
-+
-+
-+/*
-+ * Change our operational configuration.  This code must agree with the code
-+ * that returns config descriptors, and with interface altsetting code.
-+ *
-+ * It's also responsible for power management interactions.  Some
-+ * configurations might not work with our current power sources.
-+ * For now we just assume the gadget is always self-powered.
-+ */
-+static int do_set_config(struct fsg_dev *fsg, u8 new_config)
-+{
-+	int	rc = 0;
-+
-+	/* Disable the single interface */
-+	if (fsg->config != 0) {
-+		DBG(fsg, "reset config\n");
-+		fsg->config = 0;
-+		rc = do_set_interface(fsg, -1);
-+	}
-+
-+	/* Enable the interface */
-+	if (new_config != 0) {
-+		fsg->config = new_config;
-+		if ((rc = do_set_interface(fsg, 0)) != 0)
-+			fsg->config = 0;	// Reset on errors
-+		else
-+			INFO(fsg, "%s config #%d\n",
-+			     usb_speed_string(fsg->gadget->speed),
-+			     fsg->config);
-+	}
-+	return rc;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void handle_exception(struct fsg_dev *fsg)
-+{
-+	siginfo_t		info;
-+	int			sig;
-+	int			i;
-+	int			num_active;
-+	struct fsg_buffhd	*bh;
-+	enum fsg_state		old_state;
-+	u8			new_config;
-+	struct fsg_lun		*curlun;
-+	unsigned int		exception_req_tag;
-+	int			rc;
-+
-+	/* Clear the existing signals.  Anything but SIGUSR1 is converted
-+	 * into a high-priority EXIT exception. */
-+	for (;;) {
-+		sig = dequeue_signal_lock(current, &current->blocked, &info);
-+		if (!sig)
-+			break;
-+		if (sig != SIGUSR1) {
-+			if (fsg->state < FSG_STATE_EXIT)
-+				DBG(fsg, "Main thread exiting on signal\n");
-+			raise_exception(fsg, FSG_STATE_EXIT);
-+		}
-+	}
-+
-+	/* Cancel all the pending transfers */
-+	if (fsg->intreq_busy)
-+		usb_ep_dequeue(fsg->intr_in, fsg->intreq);
-+	for (i = 0; i < fsg_num_buffers; ++i) {
-+		bh = &fsg->buffhds[i];
-+		if (bh->inreq_busy)
-+			usb_ep_dequeue(fsg->bulk_in, bh->inreq);
-+		if (bh->outreq_busy)
-+			usb_ep_dequeue(fsg->bulk_out, bh->outreq);
-+	}
-+
-+	/* Wait until everything is idle */
-+	for (;;) {
-+		num_active = fsg->intreq_busy;
-+		for (i = 0; i < fsg_num_buffers; ++i) {
-+			bh = &fsg->buffhds[i];
-+			num_active += bh->inreq_busy + bh->outreq_busy;
-+		}
-+		if (num_active == 0)
-+			break;
-+		if (sleep_thread(fsg))
-+			return;
-+	}
-+
-+	/* Clear out the controller's fifos */
-+	if (fsg->bulk_in_enabled)
-+		usb_ep_fifo_flush(fsg->bulk_in);
-+	if (fsg->bulk_out_enabled)
-+		usb_ep_fifo_flush(fsg->bulk_out);
-+	if (fsg->intr_in_enabled)
-+		usb_ep_fifo_flush(fsg->intr_in);
-+
-+	/* Reset the I/O buffer states and pointers, the SCSI
-+	 * state, and the exception.  Then invoke the handler. */
-+	spin_lock_irq(&fsg->lock);
-+
-+	for (i = 0; i < fsg_num_buffers; ++i) {
-+		bh = &fsg->buffhds[i];
-+		bh->state = BUF_STATE_EMPTY;
-+	}
-+	fsg->next_buffhd_to_fill = fsg->next_buffhd_to_drain =
-+			&fsg->buffhds[0];
-+
-+	exception_req_tag = fsg->exception_req_tag;
-+	new_config = fsg->new_config;
-+	old_state = fsg->state;
-+
-+	if (old_state == FSG_STATE_ABORT_BULK_OUT)
-+		fsg->state = FSG_STATE_STATUS_PHASE;
-+	else {
-+		for (i = 0; i < fsg->nluns; ++i) {
-+			curlun = &fsg->luns[i];
-+			curlun->prevent_medium_removal = 0;
-+			curlun->sense_data = curlun->unit_attention_data =
-+					SS_NO_SENSE;
-+			curlun->sense_data_info = 0;
-+			curlun->info_valid = 0;
-+		}
-+		fsg->state = FSG_STATE_IDLE;
-+	}
-+	spin_unlock_irq(&fsg->lock);
-+
-+	/* Carry out any extra actions required for the exception */
-+	switch (old_state) {
-+	default:
-+		break;
-+
-+	case FSG_STATE_ABORT_BULK_OUT:
-+		send_status(fsg);
-+		spin_lock_irq(&fsg->lock);
-+		if (fsg->state == FSG_STATE_STATUS_PHASE)
-+			fsg->state = FSG_STATE_IDLE;
-+		spin_unlock_irq(&fsg->lock);
-+		break;
-+
-+	case FSG_STATE_RESET:
-+		/* In case we were forced against our will to halt a
-+		 * bulk endpoint, clear the halt now.  (The SuperH UDC
-+		 * requires this.) */
-+		if (test_and_clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
-+			usb_ep_clear_halt(fsg->bulk_in);
-+
-+		if (transport_is_bbb()) {
-+			if (fsg->ep0_req_tag == exception_req_tag)
-+				ep0_queue(fsg);	// Complete the status stage
-+
-+		} else if (transport_is_cbi())
-+			send_status(fsg);	// Status by interrupt pipe
-+
-+		/* Technically this should go here, but it would only be
-+		 * a waste of time.  Ditto for the INTERFACE_CHANGE and
-+		 * CONFIG_CHANGE cases. */
-+		// for (i = 0; i < fsg->nluns; ++i)
-+		//	fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED;
-+		break;
-+
-+	case FSG_STATE_INTERFACE_CHANGE:
-+		rc = do_set_interface(fsg, 0);
-+		if (fsg->ep0_req_tag != exception_req_tag)
-+			break;
-+		if (rc != 0)			// STALL on errors
-+			fsg_set_halt(fsg, fsg->ep0);
-+		else				// Complete the status stage
-+			ep0_queue(fsg);
-+		break;
-+
-+	case FSG_STATE_CONFIG_CHANGE:
-+		rc = do_set_config(fsg, new_config);
-+		if (fsg->ep0_req_tag != exception_req_tag)
-+			break;
-+		if (rc != 0)			// STALL on errors
-+			fsg_set_halt(fsg, fsg->ep0);
-+		else				// Complete the status stage
-+			ep0_queue(fsg);
-+		break;
-+
-+	case FSG_STATE_DISCONNECT:
-+		for (i = 0; i < fsg->nluns; ++i)
-+			fsg_lun_fsync_sub(fsg->luns + i);
-+		do_set_config(fsg, 0);		// Unconfigured state
-+		break;
-+
-+	case FSG_STATE_EXIT:
-+	case FSG_STATE_TERMINATED:
-+		do_set_config(fsg, 0);			// Free resources
-+		spin_lock_irq(&fsg->lock);
-+		fsg->state = FSG_STATE_TERMINATED;	// Stop the thread
-+		spin_unlock_irq(&fsg->lock);
-+		break;
-+	}
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int fsg_main_thread(void *fsg_)
-+{
-+	struct fsg_dev		*fsg = fsg_;
-+
-+	/* Allow the thread to be killed by a signal, but set the signal mask
-+	 * to block everything but INT, TERM, KILL, and USR1. */
-+	allow_signal(SIGINT);
-+	allow_signal(SIGTERM);
-+	allow_signal(SIGKILL);
-+	allow_signal(SIGUSR1);
-+
-+	/* Allow the thread to be frozen */
-+	set_freezable();
-+
-+	/* Arrange for userspace references to be interpreted as kernel
-+	 * pointers.  That way we can pass a kernel pointer to a routine
-+	 * that expects a __user pointer and it will work okay. */
-+	set_fs(get_ds());
-+
-+	/* The main loop */
-+	while (fsg->state != FSG_STATE_TERMINATED) {
-+		if (exception_in_progress(fsg) || signal_pending(current)) {
-+			handle_exception(fsg);
-+			continue;
-+		}
-+
-+		if (!fsg->running) {
-+			sleep_thread(fsg);
-+			continue;
-+		}
-+
-+		if (get_next_command(fsg))
-+			continue;
-+
-+		spin_lock_irq(&fsg->lock);
-+		if (!exception_in_progress(fsg))
-+			fsg->state = FSG_STATE_DATA_PHASE;
-+		spin_unlock_irq(&fsg->lock);
-+
-+		if (do_scsi_command(fsg) || finish_reply(fsg))
-+			continue;
-+
-+		spin_lock_irq(&fsg->lock);
-+		if (!exception_in_progress(fsg))
-+			fsg->state = FSG_STATE_STATUS_PHASE;
-+		spin_unlock_irq(&fsg->lock);
-+
-+		if (send_status(fsg))
-+			continue;
-+
-+		spin_lock_irq(&fsg->lock);
-+		if (!exception_in_progress(fsg))
-+			fsg->state = FSG_STATE_IDLE;
-+		spin_unlock_irq(&fsg->lock);
-+		}
-+
-+	spin_lock_irq(&fsg->lock);
-+	fsg->thread_task = NULL;
-+	spin_unlock_irq(&fsg->lock);
-+
-+	/* If we are exiting because of a signal, unregister the
-+	 * gadget driver. */
-+	if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
-+		usb_gadget_unregister_driver(&fsg_driver);
-+
-+	/* Let the unbind and cleanup routines know the thread has exited */
-+	complete_and_exit(&fsg->thread_notifier, 0);
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+
-+/* The write permissions and store_xxx pointers are set in fsg_bind() */
-+static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL);
-+static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, NULL);
-+static DEVICE_ATTR(file, 0444, fsg_show_file, NULL);
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void fsg_release(struct kref *ref)
-+{
-+	struct fsg_dev	*fsg = container_of(ref, struct fsg_dev, ref);
-+
-+	kfree(fsg->luns);
-+	kfree(fsg);
-+}
-+
-+static void lun_release(struct device *dev)
-+{
-+	struct rw_semaphore	*filesem = dev_get_drvdata(dev);
-+	struct fsg_dev		*fsg =
-+		container_of(filesem, struct fsg_dev, filesem);
-+
-+	kref_put(&fsg->ref, fsg_release);
-+}
-+
-+static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
-+{
-+	struct fsg_dev		*fsg = get_gadget_data(gadget);
-+	int			i;
-+	struct fsg_lun		*curlun;
-+	struct usb_request	*req = fsg->ep0req;
-+
-+	DBG(fsg, "unbind\n");
-+	clear_bit(REGISTERED, &fsg->atomic_bitflags);
-+
-+	/* If the thread isn't already dead, tell it to exit now */
-+	if (fsg->state != FSG_STATE_TERMINATED) {
-+		raise_exception(fsg, FSG_STATE_EXIT);
-+		wait_for_completion(&fsg->thread_notifier);
-+
-+		/* The cleanup routine waits for this completion also */
-+		complete(&fsg->thread_notifier);
-+	}
-+
-+	/* Unregister the sysfs attribute files and the LUNs */
-+	for (i = 0; i < fsg->nluns; ++i) {
-+		curlun = &fsg->luns[i];
-+		if (curlun->registered) {
-+			device_remove_file(&curlun->dev, &dev_attr_nofua);
-+			device_remove_file(&curlun->dev, &dev_attr_ro);
-+			device_remove_file(&curlun->dev, &dev_attr_file);
-+			fsg_lun_close(curlun);
-+			device_unregister(&curlun->dev);
-+			curlun->registered = 0;
-+		}
-+	}
-+
-+	/* Free the data buffers */
-+	for (i = 0; i < fsg_num_buffers; ++i)
-+		kfree(fsg->buffhds[i].buf);
-+
-+	/* Free the request and buffer for endpoint 0 */
-+	if (req) {
-+		kfree(req->buf);
-+		usb_ep_free_request(fsg->ep0, req);
-+	}
-+
-+	set_gadget_data(gadget, NULL);
-+}
-+
-+
-+static int __init check_parameters(struct fsg_dev *fsg)
-+{
-+	int	prot;
-+	int	gcnum;
-+
-+	/* Store the default values */
-+	mod_data.transport_type = USB_PR_BULK;
-+	mod_data.transport_name = "Bulk-only";
-+	mod_data.protocol_type = USB_SC_SCSI;
-+	mod_data.protocol_name = "Transparent SCSI";
-+
-+	/* Some peripheral controllers are known not to be able to
-+	 * halt bulk endpoints correctly.  If one of them is present,
-+	 * disable stalls.
-+	 */
-+	if (gadget_is_at91(fsg->gadget))
-+		mod_data.can_stall = 0;
-+
-+	if (mod_data.release == 0xffff) {	// Parameter wasn't set
-+		gcnum = usb_gadget_controller_number(fsg->gadget);
-+		if (gcnum >= 0)
-+			mod_data.release = 0x0300 + gcnum;
-+		else {
-+			WARNING(fsg, "controller '%s' not recognized\n",
-+				fsg->gadget->name);
-+			mod_data.release = 0x0399;
-+		}
-+	}
-+
-+	prot = simple_strtol(mod_data.protocol_parm, NULL, 0);
-+
-+#ifdef CONFIG_USB_FILE_STORAGE_TEST
-+	if (strnicmp(mod_data.transport_parm, "BBB", 10) == 0) {
-+		;		// Use default setting
-+	} else if (strnicmp(mod_data.transport_parm, "CB", 10) == 0) {
-+		mod_data.transport_type = USB_PR_CB;
-+		mod_data.transport_name = "Control-Bulk";
-+	} else if (strnicmp(mod_data.transport_parm, "CBI", 10) == 0) {
-+		mod_data.transport_type = USB_PR_CBI;
-+		mod_data.transport_name = "Control-Bulk-Interrupt";
-+	} else {
-+		ERROR(fsg, "invalid transport: %s\n", mod_data.transport_parm);
-+		return -EINVAL;
-+	}
-+
-+	if (strnicmp(mod_data.protocol_parm, "SCSI", 10) == 0 ||
-+			prot == USB_SC_SCSI) {
-+		;		// Use default setting
-+	} else if (strnicmp(mod_data.protocol_parm, "RBC", 10) == 0 ||
-+			prot == USB_SC_RBC) {
-+		mod_data.protocol_type = USB_SC_RBC;
-+		mod_data.protocol_name = "RBC";
-+	} else if (strnicmp(mod_data.protocol_parm, "8020", 4) == 0 ||
-+			strnicmp(mod_data.protocol_parm, "ATAPI", 10) == 0 ||
-+			prot == USB_SC_8020) {
-+		mod_data.protocol_type = USB_SC_8020;
-+		mod_data.protocol_name = "8020i (ATAPI)";
-+	} else if (strnicmp(mod_data.protocol_parm, "QIC", 3) == 0 ||
-+			prot == USB_SC_QIC) {
-+		mod_data.protocol_type = USB_SC_QIC;
-+		mod_data.protocol_name = "QIC-157";
-+	} else if (strnicmp(mod_data.protocol_parm, "UFI", 10) == 0 ||
-+			prot == USB_SC_UFI) {
-+		mod_data.protocol_type = USB_SC_UFI;
-+		mod_data.protocol_name = "UFI";
-+	} else if (strnicmp(mod_data.protocol_parm, "8070", 4) == 0 ||
-+			prot == USB_SC_8070) {
-+		mod_data.protocol_type = USB_SC_8070;
-+		mod_data.protocol_name = "8070i";
-+	} else {
-+		ERROR(fsg, "invalid protocol: %s\n", mod_data.protocol_parm);
-+		return -EINVAL;
-+	}
-+
-+	mod_data.buflen &= PAGE_CACHE_MASK;
-+	if (mod_data.buflen <= 0) {
-+		ERROR(fsg, "invalid buflen\n");
-+		return -ETOOSMALL;
-+	}
-+
-+#endif /* CONFIG_USB_FILE_STORAGE_TEST */
-+
-+	/* Serial string handling.
-+	 * On a real device, the serial string would be loaded
-+	 * from permanent storage. */
-+	if (mod_data.serial) {
-+		const char *ch;
-+		unsigned len = 0;
-+
-+		/* Sanity check :
-+		 * The CB[I] specification limits the serial string to
-+		 * 12 uppercase hexadecimal characters.
-+		 * BBB need at least 12 uppercase hexadecimal characters,
-+		 * with a maximum of 126. */
-+		for (ch = mod_data.serial; *ch; ++ch) {
-+			++len;
-+			if ((*ch < '0' || *ch > '9') &&
-+			    (*ch < 'A' || *ch > 'F')) { /* not uppercase hex */
-+				WARNING(fsg,
-+					"Invalid serial string character: %c\n",
-+					*ch);
-+				goto no_serial;
-+			}
-+		}
-+		if (len > 126 ||
-+		    (mod_data.transport_type == USB_PR_BULK && len < 12) ||
-+		    (mod_data.transport_type != USB_PR_BULK && len > 12)) {
-+			WARNING(fsg, "Invalid serial string length!\n");
-+			goto no_serial;
-+		}
-+		fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial;
-+	} else {
-+		WARNING(fsg, "No serial-number string provided!\n");
-+ no_serial:
-+		device_desc.iSerialNumber = 0;
-+	}
-+
-+	return 0;
-+}
-+
-+
-+static int __init fsg_bind(struct usb_gadget *gadget)
-+{
-+	struct fsg_dev		*fsg = the_fsg;
-+	int			rc;
-+	int			i;
-+	struct fsg_lun		*curlun;
-+	struct usb_ep		*ep;
-+	struct usb_request	*req;
-+	char			*pathbuf, *p;
-+
-+	fsg->gadget = gadget;
-+	set_gadget_data(gadget, fsg);
-+	fsg->ep0 = gadget->ep0;
-+	fsg->ep0->driver_data = fsg;
-+
-+	if ((rc = check_parameters(fsg)) != 0)
-+		goto out;
-+
-+	if (mod_data.removable) {	// Enable the store_xxx attributes
-+		dev_attr_file.attr.mode = 0644;
-+		dev_attr_file.store = fsg_store_file;
-+		if (!mod_data.cdrom) {
-+			dev_attr_ro.attr.mode = 0644;
-+			dev_attr_ro.store = fsg_store_ro;
-+		}
-+	}
-+
-+	/* Only for removable media? */
-+	dev_attr_nofua.attr.mode = 0644;
-+	dev_attr_nofua.store = fsg_store_nofua;
-+
-+	/* Find out how many LUNs there should be */
-+	i = mod_data.nluns;
-+	if (i == 0)
-+		i = max(mod_data.num_filenames, 1u);
-+	if (i > FSG_MAX_LUNS) {
-+		ERROR(fsg, "invalid number of LUNs: %d\n", i);
-+		rc = -EINVAL;
-+		goto out;
-+	}
-+
-+	/* Create the LUNs, open their backing files, and register the
-+	 * LUN devices in sysfs. */
-+	fsg->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL);
-+	if (!fsg->luns) {
-+		rc = -ENOMEM;
-+		goto out;
-+	}
-+	fsg->nluns = i;
-+
-+	for (i = 0; i < fsg->nluns; ++i) {
-+		curlun = &fsg->luns[i];
-+		curlun->cdrom = !!mod_data.cdrom;
-+		curlun->ro = mod_data.cdrom || mod_data.ro[i];
-+		curlun->initially_ro = curlun->ro;
-+		curlun->removable = mod_data.removable;
-+		curlun->nofua = mod_data.nofua[i];
-+		curlun->dev.release = lun_release;
-+		curlun->dev.parent = &gadget->dev;
-+		curlun->dev.driver = &fsg_driver.driver;
-+		dev_set_drvdata(&curlun->dev, &fsg->filesem);
-+		dev_set_name(&curlun->dev,"%s-lun%d",
-+			     dev_name(&gadget->dev), i);
-+
-+		kref_get(&fsg->ref);
-+		rc = device_register(&curlun->dev);
-+		if (rc) {
-+			INFO(fsg, "failed to register LUN%d: %d\n", i, rc);
-+			put_device(&curlun->dev);
-+			goto out;
-+		}
-+		curlun->registered = 1;
-+
-+		rc = device_create_file(&curlun->dev, &dev_attr_ro);
-+		if (rc)
-+			goto out;
-+		rc = device_create_file(&curlun->dev, &dev_attr_nofua);
-+		if (rc)
-+			goto out;
-+		rc = device_create_file(&curlun->dev, &dev_attr_file);
-+		if (rc)
-+			goto out;
-+
-+		if (mod_data.file[i] && *mod_data.file[i]) {
-+			rc = fsg_lun_open(curlun, mod_data.file[i]);
-+			if (rc)
-+				goto out;
-+		} else if (!mod_data.removable) {
-+			ERROR(fsg, "no file given for LUN%d\n", i);
-+			rc = -EINVAL;
-+			goto out;
-+		}
-+	}
-+
-+	/* Find all the endpoints we will use */
-+	usb_ep_autoconfig_reset(gadget);
-+	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc);
-+	if (!ep)
-+		goto autoconf_fail;
-+	ep->driver_data = fsg;		// claim the endpoint
-+	fsg->bulk_in = ep;
-+
-+	ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc);
-+	if (!ep)
-+		goto autoconf_fail;
-+	ep->driver_data = fsg;		// claim the endpoint
-+	fsg->bulk_out = ep;
-+
-+	if (transport_is_cbi()) {
-+		ep = usb_ep_autoconfig(gadget, &fsg_fs_intr_in_desc);
-+		if (!ep)
-+			goto autoconf_fail;
-+		ep->driver_data = fsg;		// claim the endpoint
-+		fsg->intr_in = ep;
-+	}
-+
-+	/* Fix up the descriptors */
-+	device_desc.idVendor = cpu_to_le16(mod_data.vendor);
-+	device_desc.idProduct = cpu_to_le16(mod_data.product);
-+	device_desc.bcdDevice = cpu_to_le16(mod_data.release);
-+
-+	i = (transport_is_cbi() ? 3 : 2);	// Number of endpoints
-+	fsg_intf_desc.bNumEndpoints = i;
-+	fsg_intf_desc.bInterfaceSubClass = mod_data.protocol_type;
-+	fsg_intf_desc.bInterfaceProtocol = mod_data.transport_type;
-+	fsg_fs_function[i + FSG_FS_FUNCTION_PRE_EP_ENTRIES] = NULL;
-+
-+	if (gadget_is_dualspeed(gadget)) {
-+		fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL;
-+
-+		/* Assume endpoint addresses are the same for both speeds */
-+		fsg_hs_bulk_in_desc.bEndpointAddress =
-+			fsg_fs_bulk_in_desc.bEndpointAddress;
-+		fsg_hs_bulk_out_desc.bEndpointAddress =
-+			fsg_fs_bulk_out_desc.bEndpointAddress;
-+		fsg_hs_intr_in_desc.bEndpointAddress =
-+			fsg_fs_intr_in_desc.bEndpointAddress;
-+	}
-+
-+	if (gadget_is_superspeed(gadget)) {
-+		unsigned		max_burst;
-+
-+		fsg_ss_function[i + FSG_SS_FUNCTION_PRE_EP_ENTRIES] = NULL;
-+
-+		/* Calculate bMaxBurst, we know packet size is 1024 */
-+		max_burst = min_t(unsigned, mod_data.buflen / 1024, 15);
-+
-+		/* Assume endpoint addresses are the same for both speeds */
-+		fsg_ss_bulk_in_desc.bEndpointAddress =
-+			fsg_fs_bulk_in_desc.bEndpointAddress;
-+		fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
-+
-+		fsg_ss_bulk_out_desc.bEndpointAddress =
-+			fsg_fs_bulk_out_desc.bEndpointAddress;
-+		fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
-+	}
-+
-+	if (gadget_is_otg(gadget))
-+		fsg_otg_desc.bmAttributes |= USB_OTG_HNP;
-+
-+	rc = -ENOMEM;
-+
-+	/* Allocate the request and buffer for endpoint 0 */
-+	fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL);
-+	if (!req)
-+		goto out;
-+	req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL);
-+	if (!req->buf)
-+		goto out;
-+	req->complete = ep0_complete;
-+
-+	/* Allocate the data buffers */
-+	for (i = 0; i < fsg_num_buffers; ++i) {
-+		struct fsg_buffhd	*bh = &fsg->buffhds[i];
-+
-+		/* Allocate for the bulk-in endpoint.  We assume that
-+		 * the buffer will also work with the bulk-out (and
-+		 * interrupt-in) endpoint. */
-+		bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL);
-+		if (!bh->buf)
-+			goto out;
-+		bh->next = bh + 1;
-+	}
-+	fsg->buffhds[fsg_num_buffers - 1].next = &fsg->buffhds[0];
-+
-+	/* This should reflect the actual gadget power source */
-+	usb_gadget_set_selfpowered(gadget);
-+
-+	snprintf(fsg_string_manufacturer, sizeof fsg_string_manufacturer,
-+			"%s %s with %s",
-+			init_utsname()->sysname, init_utsname()->release,
-+			gadget->name);
-+
-+	fsg->thread_task = kthread_create(fsg_main_thread, fsg,
-+			"file-storage-gadget");
-+	if (IS_ERR(fsg->thread_task)) {
-+		rc = PTR_ERR(fsg->thread_task);
-+		goto out;
-+	}
-+
-+	INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n");
-+	INFO(fsg, "NOTE: This driver is deprecated.  "
-+			"Consider using g_mass_storage instead.\n");
-+	INFO(fsg, "Number of LUNs=%d\n", fsg->nluns);
-+
-+	pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
-+	for (i = 0; i < fsg->nluns; ++i) {
-+		curlun = &fsg->luns[i];
-+		if (fsg_lun_is_open(curlun)) {
-+			p = NULL;
-+			if (pathbuf) {
-+				p = d_path(&curlun->filp->f_path,
-+					   pathbuf, PATH_MAX);
-+				if (IS_ERR(p))
-+					p = NULL;
-+			}
-+			LINFO(curlun, "ro=%d, nofua=%d, file: %s\n",
-+			      curlun->ro, curlun->nofua, (p ? p : "(error)"));
-+		}
-+	}
-+	kfree(pathbuf);
-+
-+	DBG(fsg, "transport=%s (x%02x)\n",
-+			mod_data.transport_name, mod_data.transport_type);
-+	DBG(fsg, "protocol=%s (x%02x)\n",
-+			mod_data.protocol_name, mod_data.protocol_type);
-+	DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n",
-+			mod_data.vendor, mod_data.product, mod_data.release);
-+	DBG(fsg, "removable=%d, stall=%d, cdrom=%d, buflen=%u\n",
-+			mod_data.removable, mod_data.can_stall,
-+			mod_data.cdrom, mod_data.buflen);
-+	DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task));
-+
-+	set_bit(REGISTERED, &fsg->atomic_bitflags);
-+
-+	/* Tell the thread to start working */
-+	wake_up_process(fsg->thread_task);
-+	return 0;
-+
-+autoconf_fail:
-+	ERROR(fsg, "unable to autoconfigure all endpoints\n");
-+	rc = -ENOTSUPP;
-+
-+out:
-+	fsg->state = FSG_STATE_TERMINATED;	// The thread is dead
-+	fsg_unbind(gadget);
-+	complete(&fsg->thread_notifier);
-+	return rc;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void fsg_suspend(struct usb_gadget *gadget)
-+{
-+	struct fsg_dev		*fsg = get_gadget_data(gadget);
-+
-+	DBG(fsg, "suspend\n");
-+	set_bit(SUSPENDED, &fsg->atomic_bitflags);
-+}
-+
-+static void fsg_resume(struct usb_gadget *gadget)
-+{
-+	struct fsg_dev		*fsg = get_gadget_data(gadget);
-+
-+	DBG(fsg, "resume\n");
-+	clear_bit(SUSPENDED, &fsg->atomic_bitflags);
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static struct usb_gadget_driver		fsg_driver = {
-+	.max_speed	= USB_SPEED_SUPER,
-+	.function	= (char *) fsg_string_product,
-+	.unbind		= fsg_unbind,
-+	.disconnect	= fsg_disconnect,
-+	.setup		= fsg_setup,
-+	.suspend	= fsg_suspend,
-+	.resume		= fsg_resume,
-+
-+	.driver		= {
-+		.name		= DRIVER_NAME,
-+		.owner		= THIS_MODULE,
-+		// .release = ...
-+		// .suspend = ...
-+		// .resume = ...
-+	},
-+};
-+
-+
-+static int __init fsg_alloc(void)
-+{
-+	struct fsg_dev		*fsg;
-+
-+	fsg = kzalloc(sizeof *fsg +
-+		      fsg_num_buffers * sizeof *(fsg->buffhds), GFP_KERNEL);
-+
-+	if (!fsg)
-+		return -ENOMEM;
-+	spin_lock_init(&fsg->lock);
-+	init_rwsem(&fsg->filesem);
-+	kref_init(&fsg->ref);
-+	init_completion(&fsg->thread_notifier);
-+
-+	the_fsg = fsg;
-+	return 0;
-+}
-+
-+
-+static int __init fsg_init(void)
-+{
-+	int		rc;
-+	struct fsg_dev	*fsg;
-+
-+	rc = fsg_num_buffers_validate();
-+	if (rc != 0)
-+		return rc;
-+
-+	if ((rc = fsg_alloc()) != 0)
-+		return rc;
-+	fsg = the_fsg;
-+	if ((rc = usb_gadget_probe_driver(&fsg_driver, fsg_bind)) != 0)
-+		kref_put(&fsg->ref, fsg_release);
-+	return rc;
-+}
-+module_init(fsg_init);
-+
-+
-+static void __exit fsg_cleanup(void)
-+{
-+	struct fsg_dev	*fsg = the_fsg;
-+
-+	/* Unregister the driver iff the thread hasn't already done so */
-+	if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags))
-+		usb_gadget_unregister_driver(&fsg_driver);
-+
-+	/* Wait for the thread to finish up */
-+	wait_for_completion(&fsg->thread_notifier);
-+
-+	kref_put(&fsg->ref, fsg_release);
-+}
-+module_exit(fsg_cleanup);
---- a/drivers/usb/host/Kconfig
-+++ b/drivers/usb/host/Kconfig
-@@ -745,6 +745,19 @@ config USB_HWA_HCD
- 	  To compile this driver a module, choose M here: the module
- 	  will be called "hwa-hc".
- 
-+config USB_DWCOTG
-+	tristate "Synopsis DWC host support"
-+	depends on USB
-+	help
-+	  The Synopsis DWC controller is a dual-role
-+	  host/peripheral/OTG ("On The Go") USB controllers.
-+
-+	  Enable this option to support this IP in host controller mode.
-+	  If unsure, say N.
-+
-+	  To compile this driver as a module, choose M here: the
-+	  modules built will be called dwc_otg and dwc_common_port.
-+
- config USB_IMX21_HCD
-        tristate "i.MX21 HCD support"
-        depends on ARM && ARCH_MXC
---- a/drivers/usb/host/Makefile
-+++ b/drivers/usb/host/Makefile
-@@ -68,6 +68,8 @@ obj-$(CONFIG_USB_SL811_CS)	+= sl811_cs.o
- obj-$(CONFIG_USB_U132_HCD)	+= u132-hcd.o
- obj-$(CONFIG_USB_R8A66597_HCD)	+= r8a66597-hcd.o
- obj-$(CONFIG_USB_HWA_HCD)	+= hwa-hc.o
-+
-+obj-$(CONFIG_USB_DWCOTG)        += dwc_otg/ dwc_common_port/
- obj-$(CONFIG_USB_IMX21_HCD)	+= imx21-hcd.o
- obj-$(CONFIG_USB_FSL_MPH_DR_OF)	+= fsl-mph-dr-of.o
- obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/Makefile
-@@ -0,0 +1,58 @@
-+#
-+# Makefile for DWC_common library
-+#
-+
-+ifneq ($(KERNELRELEASE),)
-+
-+ccflags-y	+= -DDWC_LINUX
-+#ccflags-y	+= -DDEBUG
-+#ccflags-y	+= -DDWC_DEBUG_REGS
-+#ccflags-y	+= -DDWC_DEBUG_MEMORY
-+
-+ccflags-y	+= -DDWC_LIBMODULE
-+ccflags-y	+= -DDWC_CCLIB
-+#ccflags-y	+= -DDWC_CRYPTOLIB
-+ccflags-y	+= -DDWC_NOTIFYLIB
-+ccflags-y	+= -DDWC_UTFLIB
-+
-+obj-$(CONFIG_USB_DWCOTG)	+= dwc_common_port_lib.o
-+dwc_common_port_lib-objs := dwc_cc.o dwc_modpow.o dwc_dh.o \
-+			    dwc_crypto.o dwc_notifier.o \
-+			    dwc_common_linux.o dwc_mem.o
-+
-+kernrelwd := $(subst ., ,$(KERNELRELEASE))
-+kernrel3 := $(word 1,$(kernrelwd)).$(word 2,$(kernrelwd)).$(word 3,$(kernrelwd))
-+
-+ifneq ($(kernrel3),2.6.20)
-+# grayg - I only know that we use ccflags-y in 2.6.31 actually
-+ccflags-y += $(CPPFLAGS)
-+endif
-+
-+else
-+
-+#ifeq ($(KDIR),)
-+#$(error Must give "KDIR=/path/to/kernel/source" on command line or in environment)
-+#endif
-+
-+ifeq ($(ARCH),)
-+$(error Must give "ARCH=<arch>" on command line or in environment. Also, if \
-+ cross-compiling, must give "CROSS_COMPILE=/path/to/compiler/plus/tool-prefix-")
-+endif
-+
-+ifeq ($(DOXYGEN),)
-+DOXYGEN		:= doxygen
-+endif
-+
-+default:
-+	$(MAKE) -C$(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
-+
-+docs:	$(wildcard *.[hc]) doc/doxygen.cfg
-+	$(DOXYGEN) doc/doxygen.cfg
-+
-+tags:	$(wildcard *.[hc])
-+	$(CTAGS) -e $(wildcard *.[hc]) $(wildcard linux/*.[hc]) $(wildcard $(KDIR)/include/linux/usb*.h)
-+
-+endif
-+
-+clean:
-+	rm -rf *.o *.ko .*.cmd *.mod.c .*.o.d .*.o.tmp modules.order Module.markers Module.symvers .tmp_versions/
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/Makefile.fbsd
-@@ -0,0 +1,17 @@
-+CFLAGS	+= -I/sys/i386/compile/GENERIC -I/sys/i386/include -I/usr/include
-+CFLAGS	+= -DDWC_FREEBSD
-+CFLAGS	+= -DDEBUG
-+#CFLAGS	+= -DDWC_DEBUG_REGS
-+#CFLAGS	+= -DDWC_DEBUG_MEMORY
-+
-+#CFLAGS	+= -DDWC_LIBMODULE
-+#CFLAGS	+= -DDWC_CCLIB
-+#CFLAGS	+= -DDWC_CRYPTOLIB
-+#CFLAGS	+= -DDWC_NOTIFYLIB
-+#CFLAGS	+= -DDWC_UTFLIB
-+
-+KMOD = dwc_common_port_lib
-+SRCS = dwc_cc.c dwc_modpow.c dwc_dh.c dwc_crypto.c dwc_notifier.c \
-+       dwc_common_fbsd.c dwc_mem.c
-+
-+.include <bsd.kmod.mk>
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/Makefile.linux
-@@ -0,0 +1,49 @@
-+#
-+# Makefile for DWC_common library
-+#
-+ifneq ($(KERNELRELEASE),)
-+
-+ccflags-y	+= -DDWC_LINUX
-+#ccflags-y	+= -DDEBUG
-+#ccflags-y	+= -DDWC_DEBUG_REGS
-+#ccflags-y	+= -DDWC_DEBUG_MEMORY
-+
-+ccflags-y	+= -DDWC_LIBMODULE
-+ccflags-y	+= -DDWC_CCLIB
-+ccflags-y	+= -DDWC_CRYPTOLIB
-+ccflags-y	+= -DDWC_NOTIFYLIB
-+ccflags-y	+= -DDWC_UTFLIB
-+
-+obj-m			 := dwc_common_port_lib.o
-+dwc_common_port_lib-objs := dwc_cc.o dwc_modpow.o dwc_dh.o \
-+			    dwc_crypto.o dwc_notifier.o \
-+			    dwc_common_linux.o dwc_mem.o
-+
-+else
-+
-+ifeq ($(KDIR),)
-+$(error Must give "KDIR=/path/to/kernel/source" on command line or in environment)
-+endif
-+
-+ifeq ($(ARCH),)
-+$(error Must give "ARCH=<arch>" on command line or in environment. Also, if \
-+ cross-compiling, must give "CROSS_COMPILE=/path/to/compiler/plus/tool-prefix-")
-+endif
-+
-+ifeq ($(DOXYGEN),)
-+DOXYGEN		:= doxygen
-+endif
-+
-+default:
-+	$(MAKE) -C$(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
-+
-+docs:	$(wildcard *.[hc]) doc/doxygen.cfg
-+	$(DOXYGEN) doc/doxygen.cfg
-+
-+tags:	$(wildcard *.[hc])
-+	$(CTAGS) -e $(wildcard *.[hc]) $(wildcard linux/*.[hc]) $(wildcard $(KDIR)/include/linux/usb*.h)
-+
-+endif
-+
-+clean:
-+	rm -rf *.o *.ko .*.cmd *.mod.c .*.o.d .*.o.tmp modules.order Module.markers Module.symvers .tmp_versions/
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/changes.txt
-@@ -0,0 +1,174 @@
-+
-+dwc_read_reg32() and friends now take an additional parameter, a pointer to an
-+IO context struct. The IO context struct should live in an os-dependent struct
-+in your driver. As an example, the dwc_usb3 driver has an os-dependent struct
-+named 'os_dep' embedded in the main device struct. So there these calls look
-+like this:
-+
-+	dwc_read_reg32(&usb3_dev->os_dep.ioctx, &pcd->dev_global_regs->dcfg);
-+
-+	dwc_write_reg32(&usb3_dev->os_dep.ioctx,
-+			&pcd->dev_global_regs->dcfg, 0);
-+
-+Note that for the existing Linux driver ports, it is not necessary to actually
-+define the 'ioctx' member in the os-dependent struct. Since Linux does not
-+require an IO context, its macros for dwc_read_reg32() and friends do not
-+use the context pointer, so it is optimized away by the compiler. But it is
-+necessary to add the pointer parameter to all of the call sites, to be ready
-+for any future ports (such as FreeBSD) which do require an IO context.
-+
-+
-+Similarly, dwc_alloc(), dwc_alloc_atomic(), dwc_strdup(), and dwc_free() now
-+take an additional parameter, a pointer to a memory context. Examples:
-+
-+	addr = dwc_alloc(&usb3_dev->os_dep.memctx, size);
-+
-+	dwc_free(&usb3_dev->os_dep.memctx, addr);
-+
-+Again, for the Linux ports, it is not necessary to actually define the memctx
-+member, but it is necessary to add the pointer parameter to all of the call
-+sites.
-+
-+
-+Same for dwc_dma_alloc() and dwc_dma_free(). Examples:
-+
-+	virt_addr = dwc_dma_alloc(&usb3_dev->os_dep.dmactx, size, &phys_addr);
-+
-+	dwc_dma_free(&usb3_dev->os_dep.dmactx, size, virt_addr, phys_addr);
-+
-+
-+Same for dwc_mutex_alloc() and dwc_mutex_free(). Examples:
-+
-+	mutex = dwc_mutex_alloc(&usb3_dev->os_dep.mtxctx);
-+
-+	dwc_mutex_free(&usb3_dev->os_dep.mtxctx, mutex);
-+
-+
-+Same for dwc_spinlock_alloc() and dwc_spinlock_free(). Examples:
-+
-+	lock = dwc_spinlock_alloc(&usb3_dev->osdep.splctx);
-+
-+	dwc_spinlock_free(&usb3_dev->osdep.splctx, lock);
-+
-+
-+Same for dwc_timer_alloc(). Example:
-+
-+	timer = dwc_timer_alloc(&usb3_dev->os_dep.tmrctx, "dwc_usb3_tmr1",
-+				cb_func, cb_data);
-+
-+
-+Same for dwc_waitq_alloc(). Example:
-+
-+	waitq = dwc_waitq_alloc(&usb3_dev->os_dep.wtqctx);
-+
-+
-+Same for dwc_thread_run(). Example:
-+
-+	thread = dwc_thread_run(&usb3_dev->os_dep.thdctx, func,
-+				"dwc_usb3_thd1", data);
-+
-+
-+Same for dwc_workq_alloc(). Example:
-+
-+	workq = dwc_workq_alloc(&usb3_dev->osdep.wkqctx, "dwc_usb3_wkq1");
-+
-+
-+Same for dwc_task_alloc(). Example:
-+
-+	task = dwc_task_alloc(&usb3_dev->os_dep.tskctx, "dwc_usb3_tsk1",
-+			      cb_func, cb_data);
-+
-+
-+In addition to the context pointer additions, a few core functions have had
-+other changes made to their parameters:
-+
-+The 'flags' parameter to dwc_spinlock_irqsave() and dwc_spinunlock_irqrestore()
-+has been changed from a uint64_t to a dwc_irqflags_t.
-+
-+dwc_thread_should_stop() now takes a 'dwc_thread_t *' parameter, because the
-+FreeBSD equivalent of that function requires it.
-+
-+And, in addition to the context pointer, dwc_task_alloc() also adds a
-+'char *name' parameter, to be consistent with dwc_thread_run() and
-+dwc_workq_alloc(), and because the FreeBSD equivalent of that function
-+requires a unique name.
-+
-+
-+Here is a complete list of the core functions that now take a pointer to a
-+context as their first parameter:
-+
-+	dwc_read_reg32
-+	dwc_read_reg64
-+	dwc_write_reg32
-+	dwc_write_reg64
-+	dwc_modify_reg32
-+	dwc_modify_reg64
-+	dwc_alloc
-+	dwc_alloc_atomic
-+	dwc_strdup
-+	dwc_free
-+	dwc_dma_alloc
-+	dwc_dma_free
-+	dwc_mutex_alloc
-+	dwc_mutex_free
-+	dwc_spinlock_alloc
-+	dwc_spinlock_free
-+	dwc_timer_alloc
-+	dwc_waitq_alloc
-+	dwc_thread_run
-+	dwc_workq_alloc
-+	dwc_task_alloc     Also adds a 'char *name' as its 2nd parameter
-+
-+And here are the core functions that have other changes to their parameters:
-+
-+	dwc_spinlock_irqsave      'flags' param is now a 'dwc_irqflags_t *'
-+	dwc_spinunlock_irqrestore 'flags' param is now a 'dwc_irqflags_t'
-+	dwc_thread_should_stop    Adds a 'dwc_thread_t *' parameter
-+
-+
-+
-+The changes to the core functions also require some of the other library
-+functions to change:
-+
-+	dwc_cc_if_alloc() and dwc_cc_if_free() now take a 'void *memctx'
-+	(for memory allocation) as the 1st param and a 'void *mtxctx'
-+	(for mutex allocation) as the 2nd param.
-+
-+	dwc_cc_clear(), dwc_cc_add(), dwc_cc_change(), dwc_cc_remove(),
-+	dwc_cc_data_for_save(), and dwc_cc_restore_from_data() now take a
-+	'void *memctx' as the 1st param.
-+
-+	dwc_dh_modpow(), dwc_dh_pk(), and dwc_dh_derive_keys() now take a
-+	'void *memctx' as the 1st param.
-+
-+	dwc_modpow() now takes a 'void *memctx' as the 1st param.
-+
-+	dwc_alloc_notification_manager() now takes a 'void *memctx' as the
-+	1st param and a 'void *wkqctx' (for work queue allocation) as the 2nd
-+	param, and also now returns an integer value that is non-zero if
-+	allocation of its data structures or work queue fails.
-+
-+	dwc_register_notifier() now takes a 'void *memctx' as the 1st param.
-+
-+	dwc_memory_debug_start() now takes a 'void *mem_ctx' as the first
-+	param, and also now returns an integer value that is non-zero if
-+	allocation of its data structures fails.
-+
-+
-+
-+Other miscellaneous changes:
-+
-+The DEBUG_MEMORY and DEBUG_REGS #define's have been renamed to
-+DWC_DEBUG_MEMORY and DWC_DEBUG_REGS.
-+
-+The following #define's have been added to allow selectively compiling library
-+features:
-+
-+	DWC_CCLIB
-+	DWC_CRYPTOLIB
-+	DWC_NOTIFYLIB
-+	DWC_UTFLIB
-+
-+A DWC_LIBMODULE #define has also been added. If this is not defined, then the
-+module code in dwc_common_linux.c is not compiled in. This allows linking the
-+library code directly into a driver module, instead of as a standalone module.
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/doc/doxygen.cfg
-@@ -0,0 +1,270 @@
-+# Doxyfile 1.4.5
-+
-+#---------------------------------------------------------------------------
-+# Project related configuration options
-+#---------------------------------------------------------------------------
-+PROJECT_NAME           = "Synopsys DWC Portability and Common Library for UWB"
-+PROJECT_NUMBER         =
-+OUTPUT_DIRECTORY       = doc
-+CREATE_SUBDIRS         = NO
-+OUTPUT_LANGUAGE        = English
-+BRIEF_MEMBER_DESC      = YES
-+REPEAT_BRIEF           = YES
-+ABBREVIATE_BRIEF       = "The $name class" \
-+                         "The $name widget" \
-+                         "The $name file" \
-+                         is \
-+                         provides \
-+                         specifies \
-+                         contains \
-+                         represents \
-+                         a \
-+                         an \
-+                         the
-+ALWAYS_DETAILED_SEC    = YES
-+INLINE_INHERITED_MEMB  = NO
-+FULL_PATH_NAMES        = NO
-+STRIP_FROM_PATH        = ..
-+STRIP_FROM_INC_PATH    =
-+SHORT_NAMES            = NO
-+JAVADOC_AUTOBRIEF      = YES
-+MULTILINE_CPP_IS_BRIEF = NO
-+DETAILS_AT_TOP         = YES
-+INHERIT_DOCS           = YES
-+SEPARATE_MEMBER_PAGES  = NO
-+TAB_SIZE               = 8
-+ALIASES                =
-+OPTIMIZE_OUTPUT_FOR_C  = YES
-+OPTIMIZE_OUTPUT_JAVA   = NO
-+BUILTIN_STL_SUPPORT    = NO
-+DISTRIBUTE_GROUP_DOC   = NO
-+SUBGROUPING            = NO
-+#---------------------------------------------------------------------------
-+# Build related configuration options
-+#---------------------------------------------------------------------------
-+EXTRACT_ALL            = NO
-+EXTRACT_PRIVATE        = NO
-+EXTRACT_STATIC         = YES
-+EXTRACT_LOCAL_CLASSES  = NO
-+EXTRACT_LOCAL_METHODS  = NO
-+HIDE_UNDOC_MEMBERS     = NO
-+HIDE_UNDOC_CLASSES     = NO
-+HIDE_FRIEND_COMPOUNDS  = NO
-+HIDE_IN_BODY_DOCS      = NO
-+INTERNAL_DOCS          = NO
-+CASE_SENSE_NAMES       = YES
-+HIDE_SCOPE_NAMES       = NO
-+SHOW_INCLUDE_FILES     = NO
-+INLINE_INFO            = YES
-+SORT_MEMBER_DOCS       = NO
-+SORT_BRIEF_DOCS        = NO
-+SORT_BY_SCOPE_NAME     = NO
-+GENERATE_TODOLIST      = YES
-+GENERATE_TESTLIST      = YES
-+GENERATE_BUGLIST       = YES
-+GENERATE_DEPRECATEDLIST= YES
-+ENABLED_SECTIONS       =
-+MAX_INITIALIZER_LINES  = 30
-+SHOW_USED_FILES        = YES
-+SHOW_DIRECTORIES       = YES
-+FILE_VERSION_FILTER    =
-+#---------------------------------------------------------------------------
-+# configuration options related to warning and progress messages
-+#---------------------------------------------------------------------------
-+QUIET                  = YES
-+WARNINGS               = YES
-+WARN_IF_UNDOCUMENTED   = NO
-+WARN_IF_DOC_ERROR      = YES
-+WARN_NO_PARAMDOC       = YES
-+WARN_FORMAT            = "$file:$line: $text"
-+WARN_LOGFILE           =
-+#---------------------------------------------------------------------------
-+# configuration options related to the input files
-+#---------------------------------------------------------------------------
-+INPUT                  = .
-+FILE_PATTERNS          = *.c \
-+                         *.cc \
-+                         *.cxx \
-+                         *.cpp \
-+                         *.c++ \
-+                         *.d \
-+                         *.java \
-+                         *.ii \
-+                         *.ixx \
-+                         *.ipp \
-+                         *.i++ \
-+                         *.inl \
-+                         *.h \
-+                         *.hh \
-+                         *.hxx \
-+                         *.hpp \
-+                         *.h++ \
-+                         *.idl \
-+                         *.odl \
-+                         *.cs \
-+                         *.php \
-+                         *.php3 \
-+                         *.inc \
-+                         *.m \
-+                         *.mm \
-+                         *.dox \
-+                         *.py \
-+                         *.C \
-+                         *.CC \
-+                         *.C++ \
-+                         *.II \
-+                         *.I++ \
-+                         *.H \
-+                         *.HH \
-+                         *.H++ \
-+                         *.CS \
-+                         *.PHP \
-+                         *.PHP3 \
-+                         *.M \
-+                         *.MM \
-+                         *.PY
-+RECURSIVE              = NO
-+EXCLUDE                =
-+EXCLUDE_SYMLINKS       = NO
-+EXCLUDE_PATTERNS       =
-+EXAMPLE_PATH           =
-+EXAMPLE_PATTERNS       = *
-+EXAMPLE_RECURSIVE      = NO
-+IMAGE_PATH             =
-+INPUT_FILTER           =
-+FILTER_PATTERNS        =
-+FILTER_SOURCE_FILES    = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to source browsing
-+#---------------------------------------------------------------------------
-+SOURCE_BROWSER         = NO
-+INLINE_SOURCES         = NO
-+STRIP_CODE_COMMENTS    = YES
-+REFERENCED_BY_RELATION = YES
-+REFERENCES_RELATION    = YES
-+USE_HTAGS              = NO
-+VERBATIM_HEADERS       = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to the alphabetical class index
-+#---------------------------------------------------------------------------
-+ALPHABETICAL_INDEX     = NO
-+COLS_IN_ALPHA_INDEX    = 5
-+IGNORE_PREFIX          =
-+#---------------------------------------------------------------------------
-+# configuration options related to the HTML output
-+#---------------------------------------------------------------------------
-+GENERATE_HTML          = YES
-+HTML_OUTPUT            = html
-+HTML_FILE_EXTENSION    = .html
-+HTML_HEADER            =
-+HTML_FOOTER            =
-+HTML_STYLESHEET        =
-+HTML_ALIGN_MEMBERS     = YES
-+GENERATE_HTMLHELP      = NO
-+CHM_FILE               =
-+HHC_LOCATION           =
-+GENERATE_CHI           = NO
-+BINARY_TOC             = NO
-+TOC_EXPAND             = NO
-+DISABLE_INDEX          = NO
-+ENUM_VALUES_PER_LINE   = 4
-+GENERATE_TREEVIEW      = YES
-+TREEVIEW_WIDTH         = 250
-+#---------------------------------------------------------------------------
-+# configuration options related to the LaTeX output
-+#---------------------------------------------------------------------------
-+GENERATE_LATEX         = NO
-+LATEX_OUTPUT           = latex
-+LATEX_CMD_NAME         = latex
-+MAKEINDEX_CMD_NAME     = makeindex
-+COMPACT_LATEX          = NO
-+PAPER_TYPE             = a4wide
-+EXTRA_PACKAGES         =
-+LATEX_HEADER           =
-+PDF_HYPERLINKS         = NO
-+USE_PDFLATEX           = NO
-+LATEX_BATCHMODE        = NO
-+LATEX_HIDE_INDICES     = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to the RTF output
-+#---------------------------------------------------------------------------
-+GENERATE_RTF           = NO
-+RTF_OUTPUT             = rtf
-+COMPACT_RTF            = NO
-+RTF_HYPERLINKS         = NO
-+RTF_STYLESHEET_FILE    =
-+RTF_EXTENSIONS_FILE    =
-+#---------------------------------------------------------------------------
-+# configuration options related to the man page output
-+#---------------------------------------------------------------------------
-+GENERATE_MAN           = NO
-+MAN_OUTPUT             = man
-+MAN_EXTENSION          = .3
-+MAN_LINKS              = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to the XML output
-+#---------------------------------------------------------------------------
-+GENERATE_XML           = NO
-+XML_OUTPUT             = xml
-+XML_SCHEMA             =
-+XML_DTD                =
-+XML_PROGRAMLISTING     = YES
-+#---------------------------------------------------------------------------
-+# configuration options for the AutoGen Definitions output
-+#---------------------------------------------------------------------------
-+GENERATE_AUTOGEN_DEF   = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to the Perl module output
-+#---------------------------------------------------------------------------
-+GENERATE_PERLMOD       = NO
-+PERLMOD_LATEX          = NO
-+PERLMOD_PRETTY         = YES
-+PERLMOD_MAKEVAR_PREFIX =
-+#---------------------------------------------------------------------------
-+# Configuration options related to the preprocessor
-+#---------------------------------------------------------------------------
-+ENABLE_PREPROCESSING   = YES
-+MACRO_EXPANSION        = NO
-+EXPAND_ONLY_PREDEF     = NO
-+SEARCH_INCLUDES        = YES
-+INCLUDE_PATH           =
-+INCLUDE_FILE_PATTERNS  =
-+PREDEFINED             = DEBUG DEBUG_MEMORY
-+EXPAND_AS_DEFINED      =
-+SKIP_FUNCTION_MACROS   = YES
-+#---------------------------------------------------------------------------
-+# Configuration::additions related to external references
-+#---------------------------------------------------------------------------
-+TAGFILES               =
-+GENERATE_TAGFILE       =
-+ALLEXTERNALS           = NO
-+EXTERNAL_GROUPS        = YES
-+PERL_PATH              = /usr/bin/perl
-+#---------------------------------------------------------------------------
-+# Configuration options related to the dot tool
-+#---------------------------------------------------------------------------
-+CLASS_DIAGRAMS         = YES
-+HIDE_UNDOC_RELATIONS   = YES
-+HAVE_DOT               = NO
-+CLASS_GRAPH            = YES
-+COLLABORATION_GRAPH    = YES
-+GROUP_GRAPHS           = YES
-+UML_LOOK               = NO
-+TEMPLATE_RELATIONS     = NO
-+INCLUDE_GRAPH          = NO
-+INCLUDED_BY_GRAPH      = YES
-+CALL_GRAPH             = NO
-+GRAPHICAL_HIERARCHY    = YES
-+DIRECTORY_GRAPH        = YES
-+DOT_IMAGE_FORMAT       = png
-+DOT_PATH               =
-+DOTFILE_DIRS           =
-+MAX_DOT_GRAPH_DEPTH    = 1000
-+DOT_TRANSPARENT        = NO
-+DOT_MULTI_TARGETS      = NO
-+GENERATE_LEGEND        = YES
-+DOT_CLEANUP            = YES
-+#---------------------------------------------------------------------------
-+# Configuration::additions related to the search engine
-+#---------------------------------------------------------------------------
-+SEARCHENGINE           = NO
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_cc.c
-@@ -0,0 +1,532 @@
-+/* =========================================================================
-+ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_cc.c $
-+ * $Revision: #4 $
-+ * $Date: 2010/11/04 $
-+ * $Change: 1621692 $
-+ *
-+ * Synopsys Portability Library Software and documentation
-+ * (hereinafter, "Software") is an Unsupported proprietary work of
-+ * Synopsys, Inc. unless otherwise expressly agreed to in writing
-+ * between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for
-+ * Licensed Product with Synopsys or any supplement thereto. You are
-+ * permitted to use and redistribute this Software in source and binary
-+ * forms, with or without modification, provided that redistributions
-+ * of source code must retain this notice. You may not view, use,
-+ * disclose, copy or distribute this file or any information contained
-+ * herein except pursuant to this license grant from Synopsys. If you
-+ * do not agree with this notice, including the disclaimer below, then
-+ * you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
-+ * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================= */
-+#ifdef DWC_CCLIB
-+
-+#include "dwc_cc.h"
-+
-+typedef struct dwc_cc
-+{
-+	uint32_t uid;
-+	uint8_t chid[16];
-+	uint8_t cdid[16];
-+	uint8_t ck[16];
-+	uint8_t *name;
-+	uint8_t length;
-+        DWC_CIRCLEQ_ENTRY(dwc_cc) list_entry;
-+} dwc_cc_t;
-+
-+DWC_CIRCLEQ_HEAD(context_list, dwc_cc);
-+
-+/** The main structure for CC management.  */
-+struct dwc_cc_if
-+{
-+	dwc_mutex_t *mutex;
-+	char *filename;
-+
-+	unsigned is_host:1;
-+
-+	dwc_notifier_t *notifier;
-+
-+	struct context_list list;
-+};
-+
-+#ifdef DEBUG
-+static inline void dump_bytes(char *name, uint8_t *bytes, int len)
-+{
-+	int i;
-+	DWC_PRINTF("%s: ", name);
-+	for (i=0; i<len; i++) {
-+		DWC_PRINTF("%02x ", bytes[i]);
-+	}
-+	DWC_PRINTF("\n");
-+}
-+#else
-+#define dump_bytes(x...)
-+#endif
-+
-+static dwc_cc_t *alloc_cc(void *mem_ctx, uint8_t *name, uint32_t length)
-+{
-+	dwc_cc_t *cc = dwc_alloc(mem_ctx, sizeof(dwc_cc_t));
-+	if (!cc) {
-+		return NULL;
-+	}
-+	DWC_MEMSET(cc, 0, sizeof(dwc_cc_t));
-+
-+	if (name) {
-+		cc->length = length;
-+		cc->name = dwc_alloc(mem_ctx, length);
-+		if (!cc->name) {
-+			dwc_free(mem_ctx, cc);
-+			return NULL;
-+		}
-+
-+		DWC_MEMCPY(cc->name, name, length);
-+	}
-+
-+	return cc;
-+}
-+
-+static void free_cc(void *mem_ctx, dwc_cc_t *cc)
-+{
-+	if (cc->name) {
-+		dwc_free(mem_ctx, cc->name);
-+	}
-+	dwc_free(mem_ctx, cc);
-+}
-+
-+static uint32_t next_uid(dwc_cc_if_t *cc_if)
-+{
-+	uint32_t uid = 0;
-+	dwc_cc_t *cc;
-+	DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) {
-+		if (cc->uid > uid) {
-+			uid = cc->uid;
-+		}
-+	}
-+
-+	if (uid == 0) {
-+		uid = 255;
-+	}
-+
-+	return uid + 1;
-+}
-+
-+static dwc_cc_t *cc_find(dwc_cc_if_t *cc_if, uint32_t uid)
-+{
-+	dwc_cc_t *cc;
-+	DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) {
-+		if (cc->uid == uid) {
-+			return cc;
-+		}
-+	}
-+	return NULL;
-+}
-+
-+static unsigned int cc_data_size(dwc_cc_if_t *cc_if)
-+{
-+	unsigned int size = 0;
-+	dwc_cc_t *cc;
-+	DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) {
-+		size += (48 + 1);
-+		if (cc->name) {
-+			size += cc->length;
-+		}
-+	}
-+	return size;
-+}
-+
-+static uint32_t cc_match_chid(dwc_cc_if_t *cc_if, uint8_t *chid)
-+{
-+	uint32_t uid = 0;
-+	dwc_cc_t *cc;
-+
-+	DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) {
-+		if (DWC_MEMCMP(cc->chid, chid, 16) == 0) {
-+			uid = cc->uid;
-+			break;
-+		}
-+	}
-+	return uid;
-+}
-+static uint32_t cc_match_cdid(dwc_cc_if_t *cc_if, uint8_t *cdid)
-+{
-+	uint32_t uid = 0;
-+	dwc_cc_t *cc;
-+
-+	DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) {
-+		if (DWC_MEMCMP(cc->cdid, cdid, 16) == 0) {
-+			uid = cc->uid;
-+			break;
-+		}
-+	}
-+	return uid;
-+}
-+
-+/* Internal cc_add */
-+static int32_t cc_add(void *mem_ctx, dwc_cc_if_t *cc_if, uint8_t *chid,
-+		      uint8_t *cdid, uint8_t *ck, uint8_t *name, uint8_t length)
-+{
-+	dwc_cc_t *cc;
-+	uint32_t uid;
-+
-+	if (cc_if->is_host) {
-+		uid = cc_match_cdid(cc_if, cdid);
-+	}
-+	else {
-+		uid = cc_match_chid(cc_if, chid);
-+	}
-+
-+	if (uid) {
-+		DWC_DEBUGC("Replacing previous connection context id=%d name=%p name_len=%d", uid, name, length);
-+		cc = cc_find(cc_if, uid);
-+	}
-+	else {
-+		cc = alloc_cc(mem_ctx, name, length);
-+		cc->uid = next_uid(cc_if);
-+		DWC_CIRCLEQ_INSERT_TAIL(&cc_if->list, cc, list_entry);
-+	}
-+
-+	DWC_MEMCPY(&(cc->chid[0]), chid, 16);
-+	DWC_MEMCPY(&(cc->cdid[0]), cdid, 16);
-+	DWC_MEMCPY(&(cc->ck[0]), ck, 16);
-+
-+	DWC_DEBUGC("Added connection context id=%d name=%p name_len=%d", cc->uid, name, length);
-+	dump_bytes("CHID", cc->chid, 16);
-+	dump_bytes("CDID", cc->cdid, 16);
-+	dump_bytes("CK", cc->ck, 16);
-+	return cc->uid;
-+}
-+
-+/* Internal cc_clear */
-+static void cc_clear(void *mem_ctx, dwc_cc_if_t *cc_if)
-+{
-+	while (!DWC_CIRCLEQ_EMPTY(&cc_if->list)) {
-+		dwc_cc_t *cc = DWC_CIRCLEQ_FIRST(&cc_if->list);
-+		DWC_CIRCLEQ_REMOVE_INIT(&cc_if->list, cc, list_entry);
-+		free_cc(mem_ctx, cc);
-+	}
-+}
-+
-+dwc_cc_if_t *dwc_cc_if_alloc(void *mem_ctx, void *mtx_ctx,
-+			     dwc_notifier_t *notifier, unsigned is_host)
-+{
-+	dwc_cc_if_t *cc_if = NULL;
-+
-+	/* Allocate a common_cc_if structure */
-+	cc_if = dwc_alloc(mem_ctx, sizeof(dwc_cc_if_t));
-+
-+	if (!cc_if)
-+		return NULL;
-+
-+#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES))
-+	DWC_MUTEX_ALLOC_LINUX_DEBUG(cc_if->mutex);
-+#else
-+	cc_if->mutex = dwc_mutex_alloc(mtx_ctx);
-+#endif
-+	if (!cc_if->mutex) {
-+		dwc_free(mem_ctx, cc_if);
-+		return NULL;
-+	}
-+
-+	DWC_CIRCLEQ_INIT(&cc_if->list);
-+	cc_if->is_host = is_host;
-+	cc_if->notifier = notifier;
-+	return cc_if;
-+}
-+
-+void dwc_cc_if_free(void *mem_ctx, void *mtx_ctx, dwc_cc_if_t *cc_if)
-+{
-+#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES))
-+	DWC_MUTEX_FREE(cc_if->mutex);
-+#else
-+	dwc_mutex_free(mtx_ctx, cc_if->mutex);
-+#endif
-+	cc_clear(mem_ctx, cc_if);
-+	dwc_free(mem_ctx, cc_if);
-+}
-+
-+static void cc_changed(dwc_cc_if_t *cc_if)
-+{
-+	if (cc_if->notifier) {
-+		dwc_notify(cc_if->notifier, DWC_CC_LIST_CHANGED_NOTIFICATION, cc_if);
-+	}
-+}
-+
-+void dwc_cc_clear(void *mem_ctx, dwc_cc_if_t *cc_if)
-+{
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	cc_clear(mem_ctx, cc_if);
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+	cc_changed(cc_if);
-+}
-+
-+int32_t dwc_cc_add(void *mem_ctx, dwc_cc_if_t *cc_if, uint8_t *chid,
-+		   uint8_t *cdid, uint8_t *ck, uint8_t *name, uint8_t length)
-+{
-+	uint32_t uid;
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	uid = cc_add(mem_ctx, cc_if, chid, cdid, ck, name, length);
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+	cc_changed(cc_if);
-+
-+	return uid;
-+}
-+
-+void dwc_cc_change(void *mem_ctx, dwc_cc_if_t *cc_if, int32_t id, uint8_t *chid,
-+		   uint8_t *cdid, uint8_t *ck, uint8_t *name, uint8_t length)
-+{
-+	dwc_cc_t* cc;
-+
-+	DWC_DEBUGC("Change connection context %d", id);
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	cc = cc_find(cc_if, id);
-+	if (!cc) {
-+		DWC_ERROR("Uid %d not found in cc list\n", id);
-+		DWC_MUTEX_UNLOCK(cc_if->mutex);
-+		return;
-+	}
-+
-+	if (chid) {
-+		DWC_MEMCPY(&(cc->chid[0]), chid, 16);
-+	}
-+	if (cdid) {
-+		DWC_MEMCPY(&(cc->cdid[0]), cdid, 16);
-+	}
-+	if (ck) {
-+		DWC_MEMCPY(&(cc->ck[0]), ck, 16);
-+	}
-+
-+	if (name) {
-+		if (cc->name) {
-+			dwc_free(mem_ctx, cc->name);
-+		}
-+		cc->name = dwc_alloc(mem_ctx, length);
-+		if (!cc->name) {
-+			DWC_ERROR("Out of memory in dwc_cc_change()\n");
-+			DWC_MUTEX_UNLOCK(cc_if->mutex);
-+			return;
-+		}
-+		cc->length = length;
-+		DWC_MEMCPY(cc->name, name, length);
-+	}
-+
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+
-+	cc_changed(cc_if);
-+
-+	DWC_DEBUGC("Changed connection context id=%d\n", id);
-+	dump_bytes("New CHID", cc->chid, 16);
-+	dump_bytes("New CDID", cc->cdid, 16);
-+	dump_bytes("New CK", cc->ck, 16);
-+}
-+
-+void dwc_cc_remove(void *mem_ctx, dwc_cc_if_t *cc_if, int32_t id)
-+{
-+	dwc_cc_t *cc;
-+
-+	DWC_DEBUGC("Removing connection context %d", id);
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	cc = cc_find(cc_if, id);
-+	if (!cc) {
-+		DWC_ERROR("Uid %d not found in cc list\n", id);
-+		DWC_MUTEX_UNLOCK(cc_if->mutex);
-+		return;
-+	}
-+
-+	DWC_CIRCLEQ_REMOVE_INIT(&cc_if->list, cc, list_entry);
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+	free_cc(mem_ctx, cc);
-+
-+	cc_changed(cc_if);
-+}
-+
-+uint8_t *dwc_cc_data_for_save(void *mem_ctx, dwc_cc_if_t *cc_if, unsigned int *length)
-+{
-+	uint8_t *buf, *x;
-+	uint8_t zero = 0;
-+	dwc_cc_t *cc;
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	*length = cc_data_size(cc_if);
-+	if (!(*length)) {
-+		DWC_MUTEX_UNLOCK(cc_if->mutex);
-+		return NULL;
-+	}
-+
-+	DWC_DEBUGC("Creating data for saving (length=%d)", *length);
-+
-+	buf = dwc_alloc(mem_ctx, *length);
-+	if (!buf) {
-+		*length = 0;
-+		DWC_MUTEX_UNLOCK(cc_if->mutex);
-+		return NULL;
-+	}
-+
-+	x = buf;
-+	DWC_CIRCLEQ_FOREACH(cc, &cc_if->list, list_entry) {
-+		DWC_MEMCPY(x, cc->chid, 16);
-+		x += 16;
-+		DWC_MEMCPY(x, cc->cdid, 16);
-+		x += 16;
-+		DWC_MEMCPY(x, cc->ck, 16);
-+		x += 16;
-+		if (cc->name) {
-+			DWC_MEMCPY(x, &cc->length, 1);
-+			x += 1;
-+			DWC_MEMCPY(x, cc->name, cc->length);
-+			x += cc->length;
-+		}
-+		else {
-+			DWC_MEMCPY(x, &zero, 1);
-+			x += 1;
-+		}
-+	}
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+
-+	return buf;
-+}
-+
-+void dwc_cc_restore_from_data(void *mem_ctx, dwc_cc_if_t *cc_if, uint8_t *data, uint32_t length)
-+{
-+	uint8_t name_length;
-+	uint8_t *name;
-+	uint8_t *chid;
-+	uint8_t *cdid;
-+	uint8_t *ck;
-+	uint32_t i = 0;
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	cc_clear(mem_ctx, cc_if);
-+
-+	while (i < length) {
-+		chid = &data[i];
-+		i += 16;
-+		cdid = &data[i];
-+		i += 16;
-+		ck = &data[i];
-+		i += 16;
-+
-+		name_length = data[i];
-+		i ++;
-+
-+		if (name_length) {
-+			name = &data[i];
-+			i += name_length;
-+		}
-+		else {
-+			name = NULL;
-+		}
-+
-+		/* check to see if we haven't overflown the buffer */
-+		if (i > length) {
-+			DWC_ERROR("Data format error while attempting to load CCs "
-+				  "(nlen=%d, iter=%d, buflen=%d).\n", name_length, i, length);
-+			break;
-+		}
-+
-+		cc_add(mem_ctx, cc_if, chid, cdid, ck, name, name_length);
-+	}
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+
-+	cc_changed(cc_if);
-+}
-+
-+uint32_t dwc_cc_match_chid(dwc_cc_if_t *cc_if, uint8_t *chid)
-+{
-+	uint32_t uid = 0;
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	uid = cc_match_chid(cc_if, chid);
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+	return uid;
-+}
-+uint32_t dwc_cc_match_cdid(dwc_cc_if_t *cc_if, uint8_t *cdid)
-+{
-+	uint32_t uid = 0;
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	uid = cc_match_cdid(cc_if, cdid);
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+	return uid;
-+}
-+
-+uint8_t *dwc_cc_ck(dwc_cc_if_t *cc_if, int32_t id)
-+{
-+	uint8_t *ck = NULL;
-+	dwc_cc_t *cc;
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	cc = cc_find(cc_if, id);
-+	if (cc) {
-+		ck = cc->ck;
-+	}
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+
-+	return ck;
-+
-+}
-+
-+uint8_t *dwc_cc_chid(dwc_cc_if_t *cc_if, int32_t id)
-+{
-+	uint8_t *retval = NULL;
-+	dwc_cc_t *cc;
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	cc = cc_find(cc_if, id);
-+	if (cc) {
-+		retval = cc->chid;
-+	}
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+
-+	return retval;
-+}
-+
-+uint8_t *dwc_cc_cdid(dwc_cc_if_t *cc_if, int32_t id)
-+{
-+	uint8_t *retval = NULL;
-+	dwc_cc_t *cc;
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	cc = cc_find(cc_if, id);
-+	if (cc) {
-+		retval = cc->cdid;
-+	}
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+
-+	return retval;
-+}
-+
-+uint8_t *dwc_cc_name(dwc_cc_if_t *cc_if, int32_t id, uint8_t *length)
-+{
-+	uint8_t *retval = NULL;
-+	dwc_cc_t *cc;
-+
-+	DWC_MUTEX_LOCK(cc_if->mutex);
-+	*length = 0;
-+	cc = cc_find(cc_if, id);
-+	if (cc) {
-+		*length = cc->length;
-+		retval = cc->name;
-+	}
-+	DWC_MUTEX_UNLOCK(cc_if->mutex);
-+
-+	return retval;
-+}
-+
-+#endif	/* DWC_CCLIB */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_cc.h
-@@ -0,0 +1,224 @@
-+/* =========================================================================
-+ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_cc.h $
-+ * $Revision: #4 $
-+ * $Date: 2010/09/28 $
-+ * $Change: 1596182 $
-+ *
-+ * Synopsys Portability Library Software and documentation
-+ * (hereinafter, "Software") is an Unsupported proprietary work of
-+ * Synopsys, Inc. unless otherwise expressly agreed to in writing
-+ * between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for
-+ * Licensed Product with Synopsys or any supplement thereto. You are
-+ * permitted to use and redistribute this Software in source and binary
-+ * forms, with or without modification, provided that redistributions
-+ * of source code must retain this notice. You may not view, use,
-+ * disclose, copy or distribute this file or any information contained
-+ * herein except pursuant to this license grant from Synopsys. If you
-+ * do not agree with this notice, including the disclaimer below, then
-+ * you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
-+ * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================= */
-+#ifndef _DWC_CC_H_
-+#define _DWC_CC_H_
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/** @file
-+ *
-+ * This file defines the Context Context library.
-+ *
-+ * The main data structure is dwc_cc_if_t which is returned by either the
-+ * dwc_cc_if_alloc function or returned by the module to the user via a provided
-+ * function. The data structure is opaque and should only be manipulated via the
-+ * functions provied in this API.
-+ *
-+ * It manages a list of connection contexts and operations can be performed to
-+ * add, remove, query, search, and change, those contexts.  Additionally,
-+ * a dwc_notifier_t object can be requested from the manager so that
-+ * the user can be notified whenever the context list has changed.
-+ */
-+
-+#include "dwc_os.h"
-+#include "dwc_list.h"
-+#include "dwc_notifier.h"
-+
-+
-+/* Notifications */
-+#define DWC_CC_LIST_CHANGED_NOTIFICATION "DWC_CC_LIST_CHANGED_NOTIFICATION"
-+
-+struct dwc_cc_if;
-+typedef struct dwc_cc_if dwc_cc_if_t;
-+
-+
-+/** @name Connection Context Operations */
-+/** @{ */
-+
-+/** This function allocates memory for a dwc_cc_if_t structure, initializes
-+ * fields to default values, and returns a pointer to the structure or NULL on
-+ * error. */
-+extern dwc_cc_if_t *dwc_cc_if_alloc(void *mem_ctx, void *mtx_ctx,
-+				    dwc_notifier_t *notifier, unsigned is_host);
-+
-+/** Frees the memory for the specified CC structure allocated from
-+ * dwc_cc_if_alloc(). */
-+extern void dwc_cc_if_free(void *mem_ctx, void *mtx_ctx, dwc_cc_if_t *cc_if);
-+
-+/** Removes all contexts from the connection context list */
-+extern void dwc_cc_clear(void *mem_ctx, dwc_cc_if_t *cc_if);
-+
-+/** Adds a connection context (CHID, CK, CDID, Name) to the connection context list.
-+ * If a CHID already exists, the CK and name are overwritten.  Statistics are
-+ * not overwritten.
-+ *
-+ * @param cc_if The cc_if structure.
-+ * @param chid A pointer to the 16-byte CHID.  This value will be copied.
-+ * @param ck A pointer to the 16-byte CK.  This value will be copied.
-+ * @param cdid A pointer to the 16-byte CDID.  This value will be copied.
-+ * @param name An optional host friendly name as defined in the association model
-+ * spec.  Must be a UTF16-LE unicode string.  Can be NULL to indicated no name.
-+ * @param length The length othe unicode string.
-+ * @return A unique identifier used to refer to this context that is valid for
-+ * as long as this context is still in the list. */
-+extern int32_t dwc_cc_add(void *mem_ctx, dwc_cc_if_t *cc_if, uint8_t *chid,
-+			  uint8_t *cdid, uint8_t *ck, uint8_t *name,
-+			  uint8_t length);
-+
-+/** Changes the CHID, CK, CDID, or Name values of a connection context in the
-+ * list, preserving any accumulated statistics.  This would typically be called
-+ * if the host decideds to change the context with a SET_CONNECTION request.
-+ *
-+ * @param cc_if The cc_if structure.
-+ * @param id The identifier of the connection context.
-+ * @param chid A pointer to the 16-byte CHID.  This value will be copied.  NULL
-+ * indicates no change.
-+ * @param cdid A pointer to the 16-byte CDID.  This value will be copied.  NULL
-+ * indicates no change.
-+ * @param ck A pointer to the 16-byte CK.  This value will be copied.  NULL
-+ * indicates no change.
-+ * @param name Host friendly name UTF16-LE.  NULL indicates no change.
-+ * @param length Length of name. */
-+extern void dwc_cc_change(void *mem_ctx, dwc_cc_if_t *cc_if, int32_t id,
-+			  uint8_t *chid, uint8_t *cdid, uint8_t *ck,
-+			  uint8_t *name, uint8_t length);
-+
-+/** Remove the specified connection context.
-+ * @param cc_if The cc_if structure.
-+ * @param id The identifier of the connection context to remove. */
-+extern void dwc_cc_remove(void *mem_ctx, dwc_cc_if_t *cc_if, int32_t id);
-+
-+/** Get a binary block of data for the connection context list and attributes.
-+ * This data can be used by the OS specific driver to save the connection
-+ * context list into non-volatile memory.
-+ *
-+ * @param cc_if The cc_if structure.
-+ * @param length Return the length of the data buffer.
-+ * @return A pointer to the data buffer.  The memory for this buffer should be
-+ * freed with DWC_FREE() after use. */
-+extern uint8_t *dwc_cc_data_for_save(void *mem_ctx, dwc_cc_if_t *cc_if,
-+				     unsigned int *length);
-+
-+/** Restore the connection context list from the binary data that was previously
-+ * returned from a call to dwc_cc_data_for_save.  This can be used by the OS specific
-+ * driver to load a connection context list from non-volatile memory.
-+ *
-+ * @param cc_if The cc_if structure.
-+ * @param data The data bytes as returned from dwc_cc_data_for_save.
-+ * @param length The length of the data. */
-+extern void dwc_cc_restore_from_data(void *mem_ctx, dwc_cc_if_t *cc_if,
-+				     uint8_t *data, unsigned int length);
-+
-+/** Find the connection context from the specified CHID.
-+ *
-+ * @param cc_if The cc_if structure.
-+ * @param chid A pointer to the CHID data.
-+ * @return A non-zero identifier of the connection context if the CHID matches.
-+ * Otherwise returns 0. */
-+extern uint32_t dwc_cc_match_chid(dwc_cc_if_t *cc_if, uint8_t *chid);
-+
-+/** Find the connection context from the specified CDID.
-+ *
-+ * @param cc_if The cc_if structure.
-+ * @param cdid A pointer to the CDID data.
-+ * @return A non-zero identifier of the connection context if the CHID matches.
-+ * Otherwise returns 0. */
-+extern uint32_t dwc_cc_match_cdid(dwc_cc_if_t *cc_if, uint8_t *cdid);
-+
-+/** Retrieve the CK from the specified connection context.
-+ *
-+ * @param cc_if The cc_if structure.
-+ * @param id The identifier of the connection context.
-+ * @return A pointer to the CK data.  The memory does not need to be freed. */
-+extern uint8_t *dwc_cc_ck(dwc_cc_if_t *cc_if, int32_t id);
-+
-+/** Retrieve the CHID from the specified connection context.
-+ *
-+ * @param cc_if The cc_if structure.
-+ * @param id The identifier of the connection context.
-+ * @return A pointer to the CHID data.  The memory does not need to be freed. */
-+extern uint8_t *dwc_cc_chid(dwc_cc_if_t *cc_if, int32_t id);
-+
-+/** Retrieve the CDID from the specified connection context.
-+ *
-+ * @param cc_if The cc_if structure.
-+ * @param id The identifier of the connection context.
-+ * @return A pointer to the CDID data.  The memory does not need to be freed. */
-+extern uint8_t *dwc_cc_cdid(dwc_cc_if_t *cc_if, int32_t id);
-+
-+extern uint8_t *dwc_cc_name(dwc_cc_if_t *cc_if, int32_t id, uint8_t *length);
-+
-+/** Checks a buffer for non-zero.
-+ * @param id A pointer to a 16 byte buffer.
-+ * @return true if the 16 byte value is non-zero. */
-+static inline unsigned dwc_assoc_is_not_zero_id(uint8_t *id) {
-+	int i;
-+	for (i=0; i<16; i++) {
-+		if (id[i]) return 1;
-+	}
-+	return 0;
-+}
-+
-+/** Checks a buffer for zero.
-+ * @param id A pointer to a 16 byte buffer.
-+ * @return true if the 16 byte value is zero. */
-+static inline unsigned dwc_assoc_is_zero_id(uint8_t *id) {
-+	return !dwc_assoc_is_not_zero_id(id);
-+}
-+
-+/** Prints an ASCII representation for the 16-byte chid, cdid, or ck, into
-+ * buffer. */
-+static inline int dwc_print_id_string(char *buffer, uint8_t *id) {
-+	char *ptr = buffer;
-+	int i;
-+	for (i=0; i<16; i++) {
-+		ptr += DWC_SPRINTF(ptr, "%02x", id[i]);
-+		if (i < 15) {
-+			ptr += DWC_SPRINTF(ptr, " ");
-+		}
-+	}
-+	return ptr - buffer;
-+}
-+
-+/** @} */
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _DWC_CC_H_ */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_common_fbsd.c
-@@ -0,0 +1,1308 @@
-+#include "dwc_os.h"
-+#include "dwc_list.h"
-+
-+#ifdef DWC_CCLIB
-+# include "dwc_cc.h"
-+#endif
-+
-+#ifdef DWC_CRYPTOLIB
-+# include "dwc_modpow.h"
-+# include "dwc_dh.h"
-+# include "dwc_crypto.h"
-+#endif
-+
-+#ifdef DWC_NOTIFYLIB
-+# include "dwc_notifier.h"
-+#endif
-+
-+/* OS-Level Implementations */
-+
-+/* This is the FreeBSD 7.0 kernel implementation of the DWC platform library. */
-+
-+
-+/* MISC */
-+
-+void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size)
-+{
-+	return memset(dest, byte, size);
-+}
-+
-+void *DWC_MEMCPY(void *dest, void const *src, uint32_t size)
-+{
-+	return memcpy(dest, src, size);
-+}
-+
-+void *DWC_MEMMOVE(void *dest, void *src, uint32_t size)
-+{
-+	bcopy(src, dest, size);
-+	return dest;
-+}
-+
-+int DWC_MEMCMP(void *m1, void *m2, uint32_t size)
-+{
-+	return memcmp(m1, m2, size);
-+}
-+
-+int DWC_STRNCMP(void *s1, void *s2, uint32_t size)
-+{
-+	return strncmp(s1, s2, size);
-+}
-+
-+int DWC_STRCMP(void *s1, void *s2)
-+{
-+	return strcmp(s1, s2);
-+}
-+
-+int DWC_STRLEN(char const *str)
-+{
-+	return strlen(str);
-+}
-+
-+char *DWC_STRCPY(char *to, char const *from)
-+{
-+	return strcpy(to, from);
-+}
-+
-+char *DWC_STRDUP(char const *str)
-+{
-+	int len = DWC_STRLEN(str) + 1;
-+	char *new = DWC_ALLOC_ATOMIC(len);
-+
-+	if (!new) {
-+		return NULL;
-+	}
-+
-+	DWC_MEMCPY(new, str, len);
-+	return new;
-+}
-+
-+int DWC_ATOI(char *str, int32_t *value)
-+{
-+	char *end = NULL;
-+
-+	*value = strtol(str, &end, 0);
-+	if (*end == '\0') {
-+		return 0;
-+	}
-+
-+	return -1;
-+}
-+
-+int DWC_ATOUI(char *str, uint32_t *value)
-+{
-+	char *end = NULL;
-+
-+	*value = strtoul(str, &end, 0);
-+	if (*end == '\0') {
-+		return 0;
-+	}
-+
-+	return -1;
-+}
-+
-+
-+#ifdef DWC_UTFLIB
-+/* From usbstring.c */
-+
-+int DWC_UTF8_TO_UTF16LE(uint8_t const *s, uint16_t *cp, unsigned len)
-+{
-+	int	count = 0;
-+	u8	c;
-+	u16	uchar;
-+
-+	/* this insists on correct encodings, though not minimal ones.
-+	 * BUT it currently rejects legit 4-byte UTF-8 code points,
-+	 * which need surrogate pairs.  (Unicode 3.1 can use them.)
-+	 */
-+	while (len != 0 && (c = (u8) *s++) != 0) {
-+		if (unlikely(c & 0x80)) {
-+			// 2-byte sequence:
-+			// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
-+			if ((c & 0xe0) == 0xc0) {
-+				uchar = (c & 0x1f) << 6;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c;
-+
-+			// 3-byte sequence (most CJKV characters):
-+			// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
-+			} else if ((c & 0xf0) == 0xe0) {
-+				uchar = (c & 0x0f) << 12;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c << 6;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c;
-+
-+				/* no bogus surrogates */
-+				if (0xd800 <= uchar && uchar <= 0xdfff)
-+					goto fail;
-+
-+			// 4-byte sequence (surrogate pairs, currently rare):
-+			// 11101110wwwwzzzzyy + 110111yyyyxxxxxx
-+			//     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-+			// (uuuuu = wwww + 1)
-+			// FIXME accept the surrogate code points (only)
-+			} else
-+				goto fail;
-+		} else
-+			uchar = c;
-+		put_unaligned (cpu_to_le16 (uchar), cp++);
-+		count++;
-+		len--;
-+	}
-+	return count;
-+fail:
-+	return -1;
-+}
-+
-+#endif	/* DWC_UTFLIB */
-+
-+
-+/* dwc_debug.h */
-+
-+dwc_bool_t DWC_IN_IRQ(void)
-+{
-+//	return in_irq();
-+	return 0;
-+}
-+
-+dwc_bool_t DWC_IN_BH(void)
-+{
-+//	return in_softirq();
-+	return 0;
-+}
-+
-+void DWC_VPRINTF(char *format, va_list args)
-+{
-+	vprintf(format, args);
-+}
-+
-+int DWC_VSNPRINTF(char *str, int size, char *format, va_list args)
-+{
-+	return vsnprintf(str, size, format, args);
-+}
-+
-+void DWC_PRINTF(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+
-+int DWC_SPRINTF(char *buffer, char *format, ...)
-+{
-+	int retval;
-+	va_list args;
-+
-+	va_start(args, format);
-+	retval = vsprintf(buffer, format, args);
-+	va_end(args);
-+	return retval;
-+}
-+
-+int DWC_SNPRINTF(char *buffer, int size, char *format, ...)
-+{
-+	int retval;
-+	va_list args;
-+
-+	va_start(args, format);
-+	retval = vsnprintf(buffer, size, format, args);
-+	va_end(args);
-+	return retval;
-+}
-+
-+void __DWC_WARN(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+
-+void __DWC_ERROR(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+
-+void DWC_EXCEPTION(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+//	BUG_ON(1);	???
-+}
-+
-+#ifdef DEBUG
-+void __DWC_DEBUG(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+#endif
-+
-+
-+/* dwc_mem.h */
-+
-+#if 0
-+dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size,
-+				uint32_t align,
-+				uint32_t alloc)
-+{
-+	struct dma_pool *pool = dma_pool_create("Pool", NULL,
-+						size, align, alloc);
-+	return (dwc_pool_t *)pool;
-+}
-+
-+void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool)
-+{
-+	dma_pool_destroy((struct dma_pool *)pool);
-+}
-+
-+void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
-+{
-+//	return dma_pool_alloc((struct dma_pool *)pool, GFP_KERNEL, dma_addr);
-+	return dma_pool_alloc((struct dma_pool *)pool, M_WAITOK, dma_addr);
-+}
-+
-+void *DWC_DMA_POOL_ZALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
-+{
-+	void *vaddr = DWC_DMA_POOL_ALLOC(pool, dma_addr);
-+	memset(..);
-+}
-+
-+void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr)
-+{
-+	dma_pool_free(pool, vaddr, daddr);
-+}
-+#endif
-+
-+static void dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
-+{
-+	if (error)
-+		return;
-+	*(bus_addr_t *)arg = segs[0].ds_addr;
-+}
-+
-+void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
-+{
-+	dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx;
-+	int error;
-+
-+	error = bus_dma_tag_create(
-+#if __FreeBSD_version >= 700000
-+			bus_get_dma_tag(dma->dev),	/* parent */
-+#else
-+			NULL,				/* parent */
-+#endif
-+			4, 0,				/* alignment, bounds */
-+			BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
-+			BUS_SPACE_MAXADDR,		/* highaddr */
-+			NULL, NULL,			/* filter, filterarg */
-+			size,				/* maxsize */
-+			1,				/* nsegments */
-+			size,				/* maxsegsize */
-+			0,				/* flags */
-+			NULL,				/* lockfunc */
-+			NULL,				/* lockarg */
-+			&dma->dma_tag);
-+	if (error) {
-+		device_printf(dma->dev, "%s: bus_dma_tag_create failed: %d\n",
-+			      __func__, error);
-+		goto fail_0;
-+	}
-+
-+	error = bus_dmamem_alloc(dma->dma_tag, &dma->dma_vaddr,
-+				 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dma->dma_map);
-+	if (error) {
-+		device_printf(dma->dev, "%s: bus_dmamem_alloc(%ju) failed: %d\n",
-+			      __func__, (uintmax_t)size, error);
-+		goto fail_1;
-+	}
-+
-+	dma->dma_paddr = 0;
-+	error = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr, size,
-+				dmamap_cb, &dma->dma_paddr, BUS_DMA_NOWAIT);
-+	if (error || dma->dma_paddr == 0) {
-+		device_printf(dma->dev, "%s: bus_dmamap_load failed: %d\n",
-+			      __func__, error);
-+		goto fail_2;
-+	}
-+
-+	*dma_addr = dma->dma_paddr;
-+	return dma->dma_vaddr;
-+
-+fail_2:
-+	bus_dmamap_unload(dma->dma_tag, dma->dma_map);
-+fail_1:
-+	bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
-+	bus_dma_tag_destroy(dma->dma_tag);
-+fail_0:
-+	dma->dma_map = NULL;
-+	dma->dma_tag = NULL;
-+
-+	return NULL;
-+}
-+
-+void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr)
-+{
-+	dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx;
-+
-+	if (dma->dma_tag == NULL)
-+		return;
-+	if (dma->dma_map != NULL) {
-+		bus_dmamap_sync(dma->dma_tag, dma->dma_map,
-+				BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-+		bus_dmamap_unload(dma->dma_tag, dma->dma_map);
-+		bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
-+		dma->dma_map = NULL;
-+	}
-+
-+	bus_dma_tag_destroy(dma->dma_tag);
-+	dma->dma_tag = NULL;
-+}
-+
-+void *__DWC_ALLOC(void *mem_ctx, uint32_t size)
-+{
-+	return malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
-+}
-+
-+void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size)
-+{
-+	return malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
-+}
-+
-+void __DWC_FREE(void *mem_ctx, void *addr)
-+{
-+	free(addr, M_DEVBUF);
-+}
-+
-+
-+#ifdef DWC_CRYPTOLIB
-+/* dwc_crypto.h */
-+
-+void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length)
-+{
-+	get_random_bytes(buffer, length);
-+}
-+
-+int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out)
-+{
-+	struct crypto_blkcipher *tfm;
-+	struct blkcipher_desc desc;
-+	struct scatterlist sgd;
-+	struct scatterlist sgs;
-+
-+	tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
-+	if (tfm == NULL) {
-+		printk("failed to load transform for aes CBC\n");
-+		return -1;
-+	}
-+
-+	crypto_blkcipher_setkey(tfm, key, keylen);
-+	crypto_blkcipher_set_iv(tfm, iv, 16);
-+
-+	sg_init_one(&sgd, out, messagelen);
-+	sg_init_one(&sgs, message, messagelen);
-+
-+	desc.tfm = tfm;
-+	desc.flags = 0;
-+
-+	if (crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) {
-+		crypto_free_blkcipher(tfm);
-+		DWC_ERROR("AES CBC encryption failed");
-+		return -1;
-+	}
-+
-+	crypto_free_blkcipher(tfm);
-+	return 0;
-+}
-+
-+int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out)
-+{
-+	struct crypto_hash *tfm;
-+	struct hash_desc desc;
-+	struct scatterlist sg;
-+
-+	tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
-+	if (IS_ERR(tfm)) {
-+		DWC_ERROR("Failed to load transform for sha256: %ld", PTR_ERR(tfm));
-+		return 0;
-+	}
-+	desc.tfm = tfm;
-+	desc.flags = 0;
-+
-+	sg_init_one(&sg, message, len);
-+	crypto_hash_digest(&desc, &sg, len, out);
-+	crypto_free_hash(tfm);
-+
-+	return 1;
-+}
-+
-+int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen,
-+		    uint8_t *key, uint32_t keylen, uint8_t *out)
-+{
-+	struct crypto_hash *tfm;
-+	struct hash_desc desc;
-+	struct scatterlist sg;
-+
-+	tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC);
-+	if (IS_ERR(tfm)) {
-+		DWC_ERROR("Failed to load transform for hmac(sha256): %ld", PTR_ERR(tfm));
-+		return 0;
-+	}
-+	desc.tfm = tfm;
-+	desc.flags = 0;
-+
-+	sg_init_one(&sg, message, messagelen);
-+	crypto_hash_setkey(tfm, key, keylen);
-+	crypto_hash_digest(&desc, &sg, messagelen, out);
-+	crypto_free_hash(tfm);
-+
-+	return 1;
-+}
-+
-+#endif	/* DWC_CRYPTOLIB */
-+
-+
-+/* Byte Ordering Conversions */
-+
-+uint32_t DWC_CPU_TO_LE32(uint32_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint32_t DWC_CPU_TO_BE32(uint32_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint32_t DWC_LE32_TO_CPU(uint32_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint32_t DWC_BE32_TO_CPU(uint32_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint16_t DWC_CPU_TO_LE16(uint16_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+uint16_t DWC_CPU_TO_BE16(uint16_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+uint16_t DWC_LE16_TO_CPU(uint16_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+uint16_t DWC_BE16_TO_CPU(uint16_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+
-+/* Registers */
-+
-+uint32_t DWC_READ_REG32(void *io_ctx, uint32_t volatile *reg)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	return bus_space_read_4(io->iot, io->ioh, ior);
-+}
-+
-+#if 0
-+uint64_t DWC_READ_REG64(void *io_ctx, uint64_t volatile *reg)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	return bus_space_read_8(io->iot, io->ioh, ior);
-+}
-+#endif
-+
-+void DWC_WRITE_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t value)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	bus_space_write_4(io->iot, io->ioh, ior, value);
-+}
-+
-+#if 0
-+void DWC_WRITE_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t value)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	bus_space_write_8(io->iot, io->ioh, ior, value);
-+}
-+#endif
-+
-+void DWC_MODIFY_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t clear_mask,
-+		      uint32_t set_mask)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	bus_space_write_4(io->iot, io->ioh, ior,
-+			  (bus_space_read_4(io->iot, io->ioh, ior) &
-+			   ~clear_mask) | set_mask);
-+}
-+
-+#if 0
-+void DWC_MODIFY_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t clear_mask,
-+		      uint64_t set_mask)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	bus_space_write_8(io->iot, io->ioh, ior,
-+			  (bus_space_read_8(io->iot, io->ioh, ior) &
-+			   ~clear_mask) | set_mask);
-+}
-+#endif
-+
-+
-+/* Locking */
-+
-+dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void)
-+{
-+	struct mtx *sl = DWC_ALLOC(sizeof(*sl));
-+
-+	if (!sl) {
-+		DWC_ERROR("Cannot allocate memory for spinlock");
-+		return NULL;
-+	}
-+
-+	mtx_init(sl, "dw3spn", NULL, MTX_SPIN);
-+	return (dwc_spinlock_t *)sl;
-+}
-+
-+void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock)
-+{
-+	struct mtx *sl = (struct mtx *)lock;
-+
-+	mtx_destroy(sl);
-+	DWC_FREE(sl);
-+}
-+
-+void DWC_SPINLOCK(dwc_spinlock_t *lock)
-+{
-+	mtx_lock_spin((struct mtx *)lock);	// ???
-+}
-+
-+void DWC_SPINUNLOCK(dwc_spinlock_t *lock)
-+{
-+	mtx_unlock_spin((struct mtx *)lock);	// ???
-+}
-+
-+void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags)
-+{
-+	mtx_lock_spin((struct mtx *)lock);
-+}
-+
-+void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags)
-+{
-+	mtx_unlock_spin((struct mtx *)lock);
-+}
-+
-+dwc_mutex_t *DWC_MUTEX_ALLOC(void)
-+{
-+	struct mtx *m;
-+	dwc_mutex_t *mutex = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mtx));
-+
-+	if (!mutex) {
-+		DWC_ERROR("Cannot allocate memory for mutex");
-+		return NULL;
-+	}
-+
-+	m = (struct mtx *)mutex;
-+	mtx_init(m, "dw3mtx", NULL, MTX_DEF);
-+	return mutex;
-+}
-+
-+#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES))
-+#else
-+void DWC_MUTEX_FREE(dwc_mutex_t *mutex)
-+{
-+	mtx_destroy((struct mtx *)mutex);
-+	DWC_FREE(mutex);
-+}
-+#endif
-+
-+void DWC_MUTEX_LOCK(dwc_mutex_t *mutex)
-+{
-+	struct mtx *m = (struct mtx *)mutex;
-+
-+	mtx_lock(m);
-+}
-+
-+int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex)
-+{
-+	struct mtx *m = (struct mtx *)mutex;
-+
-+	return mtx_trylock(m);
-+}
-+
-+void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex)
-+{
-+	struct mtx *m = (struct mtx *)mutex;
-+
-+	mtx_unlock(m);
-+}
-+
-+
-+/* Timing */
-+
-+void DWC_UDELAY(uint32_t usecs)
-+{
-+	DELAY(usecs);
-+}
-+
-+void DWC_MDELAY(uint32_t msecs)
-+{
-+	do {
-+		DELAY(1000);
-+	} while (--msecs);
-+}
-+
-+void DWC_MSLEEP(uint32_t msecs)
-+{
-+	struct timeval tv;
-+
-+	tv.tv_sec = msecs / 1000;
-+	tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000;
-+	pause("dw3slp", tvtohz(&tv));
-+}
-+
-+uint32_t DWC_TIME(void)
-+{
-+	struct timeval tv;
-+
-+	microuptime(&tv);	// or getmicrouptime? (less precise, but faster)
-+	return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-+}
-+
-+
-+/* Timers */
-+
-+struct dwc_timer {
-+	struct callout t;
-+	char *name;
-+	dwc_spinlock_t *lock;
-+	dwc_timer_callback_t cb;
-+	void *data;
-+};
-+
-+dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data)
-+{
-+	dwc_timer_t *t = DWC_ALLOC(sizeof(*t));
-+
-+	if (!t) {
-+		DWC_ERROR("Cannot allocate memory for timer");
-+		return NULL;
-+	}
-+
-+	callout_init(&t->t, 1);
-+
-+	t->name = DWC_STRDUP(name);
-+	if (!t->name) {
-+		DWC_ERROR("Cannot allocate memory for timer->name");
-+		goto no_name;
-+	}
-+
-+	t->lock = DWC_SPINLOCK_ALLOC();
-+	if (!t->lock) {
-+		DWC_ERROR("Cannot allocate memory for lock");
-+		goto no_lock;
-+	}
-+
-+	t->cb = cb;
-+	t->data = data;
-+
-+	return t;
-+
-+ no_lock:
-+	DWC_FREE(t->name);
-+ no_name:
-+	DWC_FREE(t);
-+
-+	return NULL;
-+}
-+
-+void DWC_TIMER_FREE(dwc_timer_t *timer)
-+{
-+	callout_stop(&timer->t);
-+	DWC_SPINLOCK_FREE(timer->lock);
-+	DWC_FREE(timer->name);
-+	DWC_FREE(timer);
-+}
-+
-+void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time)
-+{
-+	struct timeval tv;
-+
-+	tv.tv_sec = time / 1000;
-+	tv.tv_usec = (time - tv.tv_sec * 1000) * 1000;
-+	callout_reset(&timer->t, tvtohz(&tv), timer->cb, timer->data);
-+}
-+
-+void DWC_TIMER_CANCEL(dwc_timer_t *timer)
-+{
-+	callout_stop(&timer->t);
-+}
-+
-+
-+/* Wait Queues */
-+
-+struct dwc_waitq {
-+	struct mtx lock;
-+	int abort;
-+};
-+
-+dwc_waitq_t *DWC_WAITQ_ALLOC(void)
-+{
-+	dwc_waitq_t *wq = DWC_ALLOC(sizeof(*wq));
-+
-+	if (!wq) {
-+		DWC_ERROR("Cannot allocate memory for waitqueue");
-+		return NULL;
-+	}
-+
-+	mtx_init(&wq->lock, "dw3wtq", NULL, MTX_DEF);
-+	wq->abort = 0;
-+
-+	return wq;
-+}
-+
-+void DWC_WAITQ_FREE(dwc_waitq_t *wq)
-+{
-+	mtx_destroy(&wq->lock);
-+	DWC_FREE(wq);
-+}
-+
-+int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data)
-+{
-+//	intrmask_t ipl;
-+	int result = 0;
-+
-+	mtx_lock(&wq->lock);
-+//	ipl = splbio();
-+
-+	/* Skip the sleep if already aborted or triggered */
-+	if (!wq->abort && !cond(data)) {
-+//		splx(ipl);
-+		result = msleep(wq, &wq->lock, PCATCH, "dw3wat", 0); // infinite timeout
-+//		ipl = splbio();
-+	}
-+
-+	if (result == ERESTART) {	// signaled - restart
-+		result = -DWC_E_RESTART;
-+
-+	} else if (result == EINTR) {	// signaled - interrupt
-+		result = -DWC_E_ABORT;
-+
-+	} else if (wq->abort) {
-+		result = -DWC_E_ABORT;
-+
-+	} else {
-+		result = 0;
-+	}
-+
-+	wq->abort = 0;
-+//	splx(ipl);
-+	mtx_unlock(&wq->lock);
-+	return result;
-+}
-+
-+int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond,
-+			       void *data, int32_t msecs)
-+{
-+	struct timeval tv, tv1, tv2;
-+//	intrmask_t ipl;
-+	int result = 0;
-+
-+	tv.tv_sec = msecs / 1000;
-+	tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000;
-+
-+	mtx_lock(&wq->lock);
-+//	ipl = splbio();
-+
-+	/* Skip the sleep if already aborted or triggered */
-+	if (!wq->abort && !cond(data)) {
-+//		splx(ipl);
-+		getmicrouptime(&tv1);
-+		result = msleep(wq, &wq->lock, PCATCH, "dw3wto", tvtohz(&tv));
-+		getmicrouptime(&tv2);
-+//		ipl = splbio();
-+	}
-+
-+	if (result == 0) {			// awoken
-+		if (wq->abort) {
-+			result = -DWC_E_ABORT;
-+		} else {
-+			tv2.tv_usec -= tv1.tv_usec;
-+			if (tv2.tv_usec < 0) {
-+				tv2.tv_usec += 1000000;
-+				tv2.tv_sec--;
-+			}
-+
-+			tv2.tv_sec -= tv1.tv_sec;
-+			result = tv2.tv_sec * 1000 + tv2.tv_usec / 1000;
-+			result = msecs - result;
-+			if (result <= 0)
-+				result = 1;
-+		}
-+	} else if (result == ERESTART) {	// signaled - restart
-+		result = -DWC_E_RESTART;
-+
-+	} else if (result == EINTR) {		// signaled - interrupt
-+		result = -DWC_E_ABORT;
-+
-+	} else {				// timed out
-+		result = -DWC_E_TIMEOUT;
-+	}
-+
-+	wq->abort = 0;
-+//	splx(ipl);
-+	mtx_unlock(&wq->lock);
-+	return result;
-+}
-+
-+void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq)
-+{
-+	wakeup(wq);
-+}
-+
-+void DWC_WAITQ_ABORT(dwc_waitq_t *wq)
-+{
-+//	intrmask_t ipl;
-+
-+	mtx_lock(&wq->lock);
-+//	ipl = splbio();
-+	wq->abort = 1;
-+	wakeup(wq);
-+//	splx(ipl);
-+	mtx_unlock(&wq->lock);
-+}
-+
-+
-+/* Threading */
-+
-+struct dwc_thread {
-+	struct proc *proc;
-+	int abort;
-+};
-+
-+dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data)
-+{
-+	int retval;
-+	dwc_thread_t *thread = DWC_ALLOC(sizeof(*thread));
-+
-+	if (!thread) {
-+		return NULL;
-+	}
-+
-+	thread->abort = 0;
-+	retval = kthread_create((void (*)(void *))func, data, &thread->proc,
-+				RFPROC | RFNOWAIT, 0, "%s", name);
-+	if (retval) {
-+		DWC_FREE(thread);
-+		return NULL;
-+	}
-+
-+	return thread;
-+}
-+
-+int DWC_THREAD_STOP(dwc_thread_t *thread)
-+{
-+	int retval;
-+
-+	thread->abort = 1;
-+	retval = tsleep(&thread->abort, 0, "dw3stp", 60 * hz);
-+
-+	if (retval == 0) {
-+		/* DWC_THREAD_EXIT() will free the thread struct */
-+		return 0;
-+	}
-+
-+	/* NOTE: We leak the thread struct if thread doesn't die */
-+
-+	if (retval == EWOULDBLOCK) {
-+		return -DWC_E_TIMEOUT;
-+	}
-+
-+	return -DWC_E_UNKNOWN;
-+}
-+
-+dwc_bool_t DWC_THREAD_SHOULD_STOP(dwc_thread_t *thread)
-+{
-+	return thread->abort;
-+}
-+
-+void DWC_THREAD_EXIT(dwc_thread_t *thread)
-+{
-+	wakeup(&thread->abort);
-+	DWC_FREE(thread);
-+	kthread_exit(0);
-+}
-+
-+
-+/* tasklets
-+ - Runs in interrupt context (cannot sleep)
-+ - Each tasklet runs on a single CPU [ How can we ensure this on FreeBSD? Does it matter? ]
-+ - Different tasklets can be running simultaneously on different CPUs [ shouldn't matter ]
-+ */
-+struct dwc_tasklet {
-+	struct task t;
-+	dwc_tasklet_callback_t cb;
-+	void *data;
-+};
-+
-+static void tasklet_callback(void *data, int pending)	// what to do with pending ???
-+{
-+	dwc_tasklet_t *task = (dwc_tasklet_t *)data;
-+
-+	task->cb(task->data);
-+}
-+
-+dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data)
-+{
-+	dwc_tasklet_t *task = DWC_ALLOC(sizeof(*task));
-+
-+	if (task) {
-+		task->cb = cb;
-+		task->data = data;
-+		TASK_INIT(&task->t, 0, tasklet_callback, task);
-+	} else {
-+		DWC_ERROR("Cannot allocate memory for tasklet");
-+	}
-+
-+	return task;
-+}
-+
-+void DWC_TASK_FREE(dwc_tasklet_t *task)
-+{
-+	taskqueue_drain(taskqueue_fast, &task->t);	// ???
-+	DWC_FREE(task);
-+}
-+
-+void DWC_TASK_SCHEDULE(dwc_tasklet_t *task)
-+{
-+	/* Uses predefined system queue */
-+	taskqueue_enqueue_fast(taskqueue_fast, &task->t);
-+}
-+
-+
-+/* workqueues
-+ - Runs in process context (can sleep)
-+ */
-+typedef struct work_container {
-+	dwc_work_callback_t cb;
-+	void *data;
-+	dwc_workq_t *wq;
-+	char *name;
-+	int hz;
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_ENTRY(work_container) entry;
-+#endif
-+	struct task task;
-+} work_container_t;
-+
-+#ifdef DEBUG
-+DWC_CIRCLEQ_HEAD(work_container_queue, work_container);
-+#endif
-+
-+struct dwc_workq {
-+	struct taskqueue *taskq;
-+	dwc_spinlock_t *lock;
-+	dwc_waitq_t *waitq;
-+	int pending;
-+
-+#ifdef DEBUG
-+	struct work_container_queue entries;
-+#endif
-+};
-+
-+static void do_work(void *data, int pending)	// what to do with pending ???
-+{
-+	work_container_t *container = (work_container_t *)data;
-+	dwc_workq_t *wq = container->wq;
-+	dwc_irqflags_t flags;
-+
-+	if (container->hz) {
-+		pause("dw3wrk", container->hz);
-+	}
-+
-+	container->cb(container->data);
-+	DWC_DEBUG("Work done: %s, container=%p", container->name, container);
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_REMOVE(&wq->entries, container, entry);
-+#endif
-+	if (container->name)
-+		DWC_FREE(container->name);
-+	DWC_FREE(container);
-+	wq->pending--;
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+	DWC_WAITQ_TRIGGER(wq->waitq);
-+}
-+
-+static int work_done(void *data)
-+{
-+	dwc_workq_t *workq = (dwc_workq_t *)data;
-+
-+	return workq->pending == 0;
-+}
-+
-+int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout)
-+{
-+	return DWC_WAITQ_WAIT_TIMEOUT(workq->waitq, work_done, workq, timeout);
-+}
-+
-+dwc_workq_t *DWC_WORKQ_ALLOC(char *name)
-+{
-+	dwc_workq_t *wq = DWC_ALLOC(sizeof(*wq));
-+
-+	if (!wq) {
-+		DWC_ERROR("Cannot allocate memory for workqueue");
-+		return NULL;
-+	}
-+
-+	wq->taskq = taskqueue_create(name, M_NOWAIT, taskqueue_thread_enqueue, &wq->taskq);
-+	if (!wq->taskq) {
-+		DWC_ERROR("Cannot allocate memory for taskqueue");
-+		goto no_taskq;
-+	}
-+
-+	wq->pending = 0;
-+
-+	wq->lock = DWC_SPINLOCK_ALLOC();
-+	if (!wq->lock) {
-+		DWC_ERROR("Cannot allocate memory for spinlock");
-+		goto no_lock;
-+	}
-+
-+	wq->waitq = DWC_WAITQ_ALLOC();
-+	if (!wq->waitq) {
-+		DWC_ERROR("Cannot allocate memory for waitqueue");
-+		goto no_waitq;
-+	}
-+
-+	taskqueue_start_threads(&wq->taskq, 1, PWAIT, "%s taskq", "dw3tsk");
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_INIT(&wq->entries);
-+#endif
-+	return wq;
-+
-+ no_waitq:
-+	DWC_SPINLOCK_FREE(wq->lock);
-+ no_lock:
-+	taskqueue_free(wq->taskq);
-+ no_taskq:
-+	DWC_FREE(wq);
-+
-+	return NULL;
-+}
-+
-+void DWC_WORKQ_FREE(dwc_workq_t *wq)
-+{
-+#ifdef DEBUG
-+	dwc_irqflags_t flags;
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+
-+	if (wq->pending != 0) {
-+		struct work_container *container;
-+
-+		DWC_ERROR("Destroying work queue with pending work");
-+
-+		DWC_CIRCLEQ_FOREACH(container, &wq->entries, entry) {
-+			DWC_ERROR("Work %s still pending", container->name);
-+		}
-+	}
-+
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+#endif
-+	DWC_WAITQ_FREE(wq->waitq);
-+	DWC_SPINLOCK_FREE(wq->lock);
-+	taskqueue_free(wq->taskq);
-+	DWC_FREE(wq);
-+}
-+
-+void DWC_WORKQ_SCHEDULE(dwc_workq_t *wq, dwc_work_callback_t cb, void *data,
-+			char *format, ...)
-+{
-+	dwc_irqflags_t flags;
-+	work_container_t *container;
-+	static char name[128];
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VSNPRINTF(name, 128, format, args);
-+	va_end(args);
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+	wq->pending++;
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+	DWC_WAITQ_TRIGGER(wq->waitq);
-+
-+	container = DWC_ALLOC_ATOMIC(sizeof(*container));
-+	if (!container) {
-+		DWC_ERROR("Cannot allocate memory for container");
-+		return;
-+	}
-+
-+	container->name = DWC_STRDUP(name);
-+	if (!container->name) {
-+		DWC_ERROR("Cannot allocate memory for container->name");
-+		DWC_FREE(container);
-+		return;
-+	}
-+
-+	container->cb = cb;
-+	container->data = data;
-+	container->wq = wq;
-+	container->hz = 0;
-+
-+	DWC_DEBUG("Queueing work: %s, container=%p", container->name, container);
-+
-+	TASK_INIT(&container->task, 0, do_work, container);
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry);
-+#endif
-+	taskqueue_enqueue_fast(wq->taskq, &container->task);
-+}
-+
-+void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *wq, dwc_work_callback_t cb,
-+				void *data, uint32_t time, char *format, ...)
-+{
-+	dwc_irqflags_t flags;
-+	work_container_t *container;
-+	static char name[128];
-+	struct timeval tv;
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VSNPRINTF(name, 128, format, args);
-+	va_end(args);
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+	wq->pending++;
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+	DWC_WAITQ_TRIGGER(wq->waitq);
-+
-+	container = DWC_ALLOC_ATOMIC(sizeof(*container));
-+	if (!container) {
-+		DWC_ERROR("Cannot allocate memory for container");
-+		return;
-+	}
-+
-+	container->name = DWC_STRDUP(name);
-+	if (!container->name) {
-+		DWC_ERROR("Cannot allocate memory for container->name");
-+		DWC_FREE(container);
-+		return;
-+	}
-+
-+	container->cb = cb;
-+	container->data = data;
-+	container->wq = wq;
-+
-+	tv.tv_sec = time / 1000;
-+	tv.tv_usec = (time - tv.tv_sec * 1000) * 1000;
-+	container->hz = tvtohz(&tv);
-+
-+	DWC_DEBUG("Queueing work: %s, container=%p", container->name, container);
-+
-+	TASK_INIT(&container->task, 0, do_work, container);
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry);
-+#endif
-+	taskqueue_enqueue_fast(wq->taskq, &container->task);
-+}
-+
-+int DWC_WORKQ_PENDING(dwc_workq_t *wq)
-+{
-+	return wq->pending;
-+}
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_common_linux.c
-@@ -0,0 +1,1434 @@
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kthread.h>
-+
-+#ifdef DWC_CCLIB
-+# include "dwc_cc.h"
-+#endif
-+
-+#ifdef DWC_CRYPTOLIB
-+# include "dwc_modpow.h"
-+# include "dwc_dh.h"
-+# include "dwc_crypto.h"
-+#endif
-+
-+#ifdef DWC_NOTIFYLIB
-+# include "dwc_notifier.h"
-+#endif
-+
-+/* OS-Level Implementations */
-+
-+/* This is the Linux kernel implementation of the DWC platform library. */
-+#include <linux/moduleparam.h>
-+#include <linux/ctype.h>
-+#include <linux/crypto.h>
-+#include <linux/delay.h>
-+#include <linux/device.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/cdev.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/jiffies.h>
-+#include <linux/list.h>
-+#include <linux/pci.h>
-+#include <linux/random.h>
-+#include <linux/scatterlist.h>
-+#include <linux/slab.h>
-+#include <linux/stat.h>
-+#include <linux/string.h>
-+#include <linux/timer.h>
-+#include <linux/usb.h>
-+
-+#include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-+# include <linux/usb/gadget.h>
-+#else
-+# include <linux/usb_gadget.h>
-+#endif
-+
-+#include <asm/io.h>
-+#include <asm/page.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include "dwc_os.h"
-+#include "dwc_list.h"
-+
-+
-+/* MISC */
-+
-+void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size)
-+{
-+	return memset(dest, byte, size);
-+}
-+
-+void *DWC_MEMCPY(void *dest, void const *src, uint32_t size)
-+{
-+	return memcpy(dest, src, size);
-+}
-+
-+void *DWC_MEMMOVE(void *dest, void *src, uint32_t size)
-+{
-+	return memmove(dest, src, size);
-+}
-+
-+int DWC_MEMCMP(void *m1, void *m2, uint32_t size)
-+{
-+	return memcmp(m1, m2, size);
-+}
-+
-+int DWC_STRNCMP(void *s1, void *s2, uint32_t size)
-+{
-+	return strncmp(s1, s2, size);
-+}
-+
-+int DWC_STRCMP(void *s1, void *s2)
-+{
-+	return strcmp(s1, s2);
-+}
-+
-+int DWC_STRLEN(char const *str)
-+{
-+	return strlen(str);
-+}
-+
-+char *DWC_STRCPY(char *to, char const *from)
-+{
-+	return strcpy(to, from);
-+}
-+
-+char *DWC_STRDUP(char const *str)
-+{
-+	int len = DWC_STRLEN(str) + 1;
-+	char *new = DWC_ALLOC_ATOMIC(len);
-+
-+	if (!new) {
-+		return NULL;
-+	}
-+
-+	DWC_MEMCPY(new, str, len);
-+	return new;
-+}
-+
-+int DWC_ATOI(const char *str, int32_t *value)
-+{
-+	char *end = NULL;
-+
-+	*value = simple_strtol(str, &end, 0);
-+	if (*end == '\0') {
-+		return 0;
-+	}
-+
-+	return -1;
-+}
-+
-+int DWC_ATOUI(const char *str, uint32_t *value)
-+{
-+	char *end = NULL;
-+
-+	*value = simple_strtoul(str, &end, 0);
-+	if (*end == '\0') {
-+		return 0;
-+	}
-+
-+	return -1;
-+}
-+
-+
-+#ifdef DWC_UTFLIB
-+/* From usbstring.c */
-+
-+int DWC_UTF8_TO_UTF16LE(uint8_t const *s, uint16_t *cp, unsigned len)
-+{
-+	int	count = 0;
-+	u8	c;
-+	u16	uchar;
-+
-+	/* this insists on correct encodings, though not minimal ones.
-+	 * BUT it currently rejects legit 4-byte UTF-8 code points,
-+	 * which need surrogate pairs.  (Unicode 3.1 can use them.)
-+	 */
-+	while (len != 0 && (c = (u8) *s++) != 0) {
-+		if (unlikely(c & 0x80)) {
-+			// 2-byte sequence:
-+			// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
-+			if ((c & 0xe0) == 0xc0) {
-+				uchar = (c & 0x1f) << 6;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c;
-+
-+			// 3-byte sequence (most CJKV characters):
-+			// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
-+			} else if ((c & 0xf0) == 0xe0) {
-+				uchar = (c & 0x0f) << 12;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c << 6;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c;
-+
-+				/* no bogus surrogates */
-+				if (0xd800 <= uchar && uchar <= 0xdfff)
-+					goto fail;
-+
-+			// 4-byte sequence (surrogate pairs, currently rare):
-+			// 11101110wwwwzzzzyy + 110111yyyyxxxxxx
-+			//     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-+			// (uuuuu = wwww + 1)
-+			// FIXME accept the surrogate code points (only)
-+			} else
-+				goto fail;
-+		} else
-+			uchar = c;
-+		put_unaligned (cpu_to_le16 (uchar), cp++);
-+		count++;
-+		len--;
-+	}
-+	return count;
-+fail:
-+	return -1;
-+}
-+#endif	/* DWC_UTFLIB */
-+
-+
-+/* dwc_debug.h */
-+
-+dwc_bool_t DWC_IN_IRQ(void)
-+{
-+	return in_irq();
-+}
-+
-+dwc_bool_t DWC_IN_BH(void)
-+{
-+	return in_softirq();
-+}
-+
-+void DWC_VPRINTF(char *format, va_list args)
-+{
-+	vprintk(format, args);
-+}
-+
-+int DWC_VSNPRINTF(char *str, int size, char *format, va_list args)
-+{
-+	return vsnprintf(str, size, format, args);
-+}
-+
-+void DWC_PRINTF(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+
-+int DWC_SPRINTF(char *buffer, char *format, ...)
-+{
-+	int retval;
-+	va_list args;
-+
-+	va_start(args, format);
-+	retval = vsprintf(buffer, format, args);
-+	va_end(args);
-+	return retval;
-+}
-+
-+int DWC_SNPRINTF(char *buffer, int size, char *format, ...)
-+{
-+	int retval;
-+	va_list args;
-+
-+	va_start(args, format);
-+	retval = vsnprintf(buffer, size, format, args);
-+	va_end(args);
-+	return retval;
-+}
-+
-+void __DWC_WARN(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_PRINTF(KERN_WARNING);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+
-+void __DWC_ERROR(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_PRINTF(KERN_ERR);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+
-+void DWC_EXCEPTION(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_PRINTF(KERN_ERR);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+	BUG_ON(1);
-+}
-+
-+#ifdef DEBUG
-+void __DWC_DEBUG(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_PRINTF(KERN_DEBUG);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+#endif
-+
-+
-+/* dwc_mem.h */
-+
-+#if 0
-+dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size,
-+				uint32_t align,
-+				uint32_t alloc)
-+{
-+	struct dma_pool *pool = dma_pool_create("Pool", NULL,
-+						size, align, alloc);
-+	return (dwc_pool_t *)pool;
-+}
-+
-+void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool)
-+{
-+	dma_pool_destroy((struct dma_pool *)pool);
-+}
-+
-+void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
-+{
-+	return dma_pool_alloc((struct dma_pool *)pool, GFP_KERNEL, dma_addr);
-+}
-+
-+void *DWC_DMA_POOL_ZALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
-+{
-+	void *vaddr = DWC_DMA_POOL_ALLOC(pool, dma_addr);
-+	memset(..);
-+}
-+
-+void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr)
-+{
-+	dma_pool_free(pool, vaddr, daddr);
-+}
-+#endif
-+
-+void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
-+{
-+#ifdef xxCOSIM /* Only works for 32-bit cosim */
-+	void *buf = dma_alloc_coherent(dma_ctx, (size_t)size, dma_addr, GFP_KERNEL);
-+#else
-+	void *buf = dma_alloc_coherent(dma_ctx, (size_t)size, dma_addr, GFP_KERNEL | GFP_DMA32);
-+#endif
-+	if (!buf) {
-+		return NULL;
-+	}
-+
-+	memset(buf, 0, (size_t)size);
-+	return buf;
-+}
-+
-+void *__DWC_DMA_ALLOC_ATOMIC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
-+{
-+	void *buf = dma_alloc_coherent(NULL, (size_t)size, dma_addr, GFP_ATOMIC);
-+	if (!buf) {
-+		return NULL;
-+	}
-+	memset(buf, 0, (size_t)size);
-+	return buf;
-+}
-+
-+void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr)
-+{
-+	dma_free_coherent(dma_ctx, size, virt_addr, dma_addr);
-+}
-+
-+void *__DWC_ALLOC(void *mem_ctx, uint32_t size)
-+{
-+	return kzalloc(size, GFP_KERNEL);
-+}
-+
-+void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size)
-+{
-+	return kzalloc(size, GFP_ATOMIC);
-+}
-+
-+void __DWC_FREE(void *mem_ctx, void *addr)
-+{
-+	kfree(addr);
-+}
-+
-+
-+#ifdef DWC_CRYPTOLIB
-+/* dwc_crypto.h */
-+
-+void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length)
-+{
-+	get_random_bytes(buffer, length);
-+}
-+
-+int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out)
-+{
-+	struct crypto_blkcipher *tfm;
-+	struct blkcipher_desc desc;
-+	struct scatterlist sgd;
-+	struct scatterlist sgs;
-+
-+	tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
-+	if (tfm == NULL) {
-+		printk("failed to load transform for aes CBC\n");
-+		return -1;
-+	}
-+
-+	crypto_blkcipher_setkey(tfm, key, keylen);
-+	crypto_blkcipher_set_iv(tfm, iv, 16);
-+
-+	sg_init_one(&sgd, out, messagelen);
-+	sg_init_one(&sgs, message, messagelen);
-+
-+	desc.tfm = tfm;
-+	desc.flags = 0;
-+
-+	if (crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) {
-+		crypto_free_blkcipher(tfm);
-+		DWC_ERROR("AES CBC encryption failed");
-+		return -1;
-+	}
-+
-+	crypto_free_blkcipher(tfm);
-+	return 0;
-+}
-+
-+int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out)
-+{
-+	struct crypto_hash *tfm;
-+	struct hash_desc desc;
-+	struct scatterlist sg;
-+
-+	tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
-+	if (IS_ERR(tfm)) {
-+		DWC_ERROR("Failed to load transform for sha256: %ld\n", PTR_ERR(tfm));
-+		return 0;
-+	}
-+	desc.tfm = tfm;
-+	desc.flags = 0;
-+
-+	sg_init_one(&sg, message, len);
-+	crypto_hash_digest(&desc, &sg, len, out);
-+	crypto_free_hash(tfm);
-+
-+	return 1;
-+}
-+
-+int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen,
-+		    uint8_t *key, uint32_t keylen, uint8_t *out)
-+{
-+	struct crypto_hash *tfm;
-+	struct hash_desc desc;
-+	struct scatterlist sg;
-+
-+	tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC);
-+	if (IS_ERR(tfm)) {
-+		DWC_ERROR("Failed to load transform for hmac(sha256): %ld\n", PTR_ERR(tfm));
-+		return 0;
-+	}
-+	desc.tfm = tfm;
-+	desc.flags = 0;
-+
-+	sg_init_one(&sg, message, messagelen);
-+	crypto_hash_setkey(tfm, key, keylen);
-+	crypto_hash_digest(&desc, &sg, messagelen, out);
-+	crypto_free_hash(tfm);
-+
-+	return 1;
-+}
-+#endif	/* DWC_CRYPTOLIB */
-+
-+
-+/* Byte Ordering Conversions */
-+
-+uint32_t DWC_CPU_TO_LE32(uint32_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint32_t DWC_CPU_TO_BE32(uint32_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint32_t DWC_LE32_TO_CPU(uint32_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint32_t DWC_BE32_TO_CPU(uint32_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint16_t DWC_CPU_TO_LE16(uint16_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+uint16_t DWC_CPU_TO_BE16(uint16_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+uint16_t DWC_LE16_TO_CPU(uint16_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+uint16_t DWC_BE16_TO_CPU(uint16_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+
-+/* Registers */
-+
-+uint32_t DWC_READ_REG32(uint32_t volatile *reg)
-+{
-+	return readl(reg);
-+}
-+
-+#if 0
-+uint64_t DWC_READ_REG64(uint64_t volatile *reg)
-+{
-+}
-+#endif
-+
-+void DWC_WRITE_REG32(uint32_t volatile *reg, uint32_t value)
-+{
-+	writel(value, reg);
-+}
-+
-+#if 0
-+void DWC_WRITE_REG64(uint64_t volatile *reg, uint64_t value)
-+{
-+}
-+#endif
-+
-+void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask)
-+{
-+	writel((readl(reg) & ~clear_mask) | set_mask, reg);
-+}
-+
-+#if 0
-+void DWC_MODIFY_REG64(uint64_t volatile *reg, uint64_t clear_mask, uint64_t set_mask)
-+{
-+}
-+#endif
-+
-+
-+/* Locking */
-+
-+dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void)
-+{
-+	spinlock_t *sl = (spinlock_t *)1;
-+
-+#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
-+	sl = DWC_ALLOC(sizeof(*sl));
-+	if (!sl) {
-+		DWC_ERROR("Cannot allocate memory for spinlock\n");
-+		return NULL;
-+	}
-+
-+	spin_lock_init(sl);
-+#endif
-+	return (dwc_spinlock_t *)sl;
-+}
-+
-+void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock)
-+{
-+#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
-+	DWC_FREE(lock);
-+#endif
-+}
-+
-+void DWC_SPINLOCK(dwc_spinlock_t *lock)
-+{
-+#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
-+	spin_lock((spinlock_t *)lock);
-+#endif
-+}
-+
-+void DWC_SPINUNLOCK(dwc_spinlock_t *lock)
-+{
-+#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
-+	spin_unlock((spinlock_t *)lock);
-+#endif
-+}
-+
-+void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags)
-+{
-+	dwc_irqflags_t f;
-+
-+#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
-+	spin_lock_irqsave((spinlock_t *)lock, f);
-+#else
-+	local_irq_save(f);
-+#endif
-+	*flags = f;
-+}
-+
-+void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags)
-+{
-+#if defined(CONFIG_PREEMPT) || defined(CONFIG_SMP)
-+	spin_unlock_irqrestore((spinlock_t *)lock, flags);
-+#else
-+	local_irq_restore(flags);
-+#endif
-+}
-+
-+dwc_mutex_t *DWC_MUTEX_ALLOC(void)
-+{
-+	struct mutex *m;
-+	dwc_mutex_t *mutex = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mutex));
-+
-+	if (!mutex) {
-+		DWC_ERROR("Cannot allocate memory for mutex\n");
-+		return NULL;
-+	}
-+
-+	m = (struct mutex *)mutex;
-+	mutex_init(m);
-+	return mutex;
-+}
-+
-+#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES))
-+#else
-+void DWC_MUTEX_FREE(dwc_mutex_t *mutex)
-+{
-+	mutex_destroy((struct mutex *)mutex);
-+	DWC_FREE(mutex);
-+}
-+#endif
-+
-+void DWC_MUTEX_LOCK(dwc_mutex_t *mutex)
-+{
-+	struct mutex *m = (struct mutex *)mutex;
-+	mutex_lock(m);
-+}
-+
-+int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex)
-+{
-+	struct mutex *m = (struct mutex *)mutex;
-+	return mutex_trylock(m);
-+}
-+
-+void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex)
-+{
-+	struct mutex *m = (struct mutex *)mutex;
-+	mutex_unlock(m);
-+}
-+
-+
-+/* Timing */
-+
-+void DWC_UDELAY(uint32_t usecs)
-+{
-+	udelay(usecs);
-+}
-+
-+void DWC_MDELAY(uint32_t msecs)
-+{
-+	mdelay(msecs);
-+}
-+
-+void DWC_MSLEEP(uint32_t msecs)
-+{
-+	msleep(msecs);
-+}
-+
-+uint32_t DWC_TIME(void)
-+{
-+	return jiffies_to_msecs(jiffies);
-+}
-+
-+
-+/* Timers */
-+
-+struct dwc_timer {
-+	struct timer_list *t;
-+	char *name;
-+	dwc_timer_callback_t cb;
-+	void *data;
-+	uint8_t scheduled;
-+	dwc_spinlock_t *lock;
-+};
-+
-+static void timer_callback(unsigned long data)
-+{
-+	dwc_timer_t *timer = (dwc_timer_t *)data;
-+	dwc_irqflags_t flags;
-+
-+	DWC_SPINLOCK_IRQSAVE(timer->lock, &flags);
-+	timer->scheduled = 0;
-+	DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags);
-+	DWC_DEBUGC("Timer %s callback", timer->name);
-+	timer->cb(timer->data);
-+}
-+
-+dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data)
-+{
-+	dwc_timer_t *t = DWC_ALLOC(sizeof(*t));
-+
-+	if (!t) {
-+		DWC_ERROR("Cannot allocate memory for timer");
-+		return NULL;
-+	}
-+
-+	t->t = DWC_ALLOC(sizeof(*t->t));
-+	if (!t->t) {
-+		DWC_ERROR("Cannot allocate memory for timer->t");
-+		goto no_timer;
-+	}
-+
-+	t->name = DWC_STRDUP(name);
-+	if (!t->name) {
-+		DWC_ERROR("Cannot allocate memory for timer->name");
-+		goto no_name;
-+	}
-+
-+#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK))
-+	DWC_SPINLOCK_ALLOC_LINUX_DEBUG(t->lock);
-+#else
-+	t->lock = DWC_SPINLOCK_ALLOC();
-+#endif
-+	if (!t->lock) {
-+		DWC_ERROR("Cannot allocate memory for lock");
-+		goto no_lock;
-+	}
-+
-+	t->scheduled = 0;
-+	t->t->base = &boot_tvec_bases;
-+	t->t->expires = jiffies;
-+	setup_timer(t->t, timer_callback, (unsigned long)t);
-+
-+	t->cb = cb;
-+	t->data = data;
-+
-+	return t;
-+
-+ no_lock:
-+	DWC_FREE(t->name);
-+ no_name:
-+	DWC_FREE(t->t);
-+ no_timer:
-+	DWC_FREE(t);
-+	return NULL;
-+}
-+
-+void DWC_TIMER_FREE(dwc_timer_t *timer)
-+{
-+	dwc_irqflags_t flags;
-+
-+	DWC_SPINLOCK_IRQSAVE(timer->lock, &flags);
-+
-+	if (timer->scheduled) {
-+		del_timer(timer->t);
-+		timer->scheduled = 0;
-+	}
-+
-+	DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags);
-+	DWC_SPINLOCK_FREE(timer->lock);
-+	DWC_FREE(timer->t);
-+	DWC_FREE(timer->name);
-+	DWC_FREE(timer);
-+}
-+
-+void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time)
-+{
-+	dwc_irqflags_t flags;
-+
-+	DWC_SPINLOCK_IRQSAVE(timer->lock, &flags);
-+
-+	if (!timer->scheduled) {
-+		timer->scheduled = 1;
-+		DWC_DEBUGC("Scheduling timer %s to expire in +%d msec", timer->name, time);
-+		timer->t->expires = jiffies + msecs_to_jiffies(time);
-+		add_timer(timer->t);
-+	} else {
-+		DWC_DEBUGC("Modifying timer %s to expire in +%d msec", timer->name, time);
-+		mod_timer(timer->t, jiffies + msecs_to_jiffies(time));
-+	}
-+
-+	DWC_SPINUNLOCK_IRQRESTORE(timer->lock, flags);
-+}
-+
-+void DWC_TIMER_CANCEL(dwc_timer_t *timer)
-+{
-+	del_timer(timer->t);
-+}
-+
-+
-+/* Wait Queues */
-+
-+struct dwc_waitq {
-+	wait_queue_head_t queue;
-+	int abort;
-+};
-+
-+dwc_waitq_t *DWC_WAITQ_ALLOC(void)
-+{
-+	dwc_waitq_t *wq = DWC_ALLOC(sizeof(*wq));
-+
-+	if (!wq) {
-+		DWC_ERROR("Cannot allocate memory for waitqueue\n");
-+		return NULL;
-+	}
-+
-+	init_waitqueue_head(&wq->queue);
-+	wq->abort = 0;
-+	return wq;
-+}
-+
-+void DWC_WAITQ_FREE(dwc_waitq_t *wq)
-+{
-+	DWC_FREE(wq);
-+}
-+
-+int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data)
-+{
-+	int result = wait_event_interruptible(wq->queue,
-+					      cond(data) || wq->abort);
-+	if (result == -ERESTARTSYS) {
-+		wq->abort = 0;
-+		return -DWC_E_RESTART;
-+	}
-+
-+	if (wq->abort == 1) {
-+		wq->abort = 0;
-+		return -DWC_E_ABORT;
-+	}
-+
-+	wq->abort = 0;
-+
-+	if (result == 0) {
-+		return 0;
-+	}
-+
-+	return -DWC_E_UNKNOWN;
-+}
-+
-+int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond,
-+			       void *data, int32_t msecs)
-+{
-+	int32_t tmsecs;
-+	int result = wait_event_interruptible_timeout(wq->queue,
-+						      cond(data) || wq->abort,
-+						      msecs_to_jiffies(msecs));
-+	if (result == -ERESTARTSYS) {
-+		wq->abort = 0;
-+		return -DWC_E_RESTART;
-+	}
-+
-+	if (wq->abort == 1) {
-+		wq->abort = 0;
-+		return -DWC_E_ABORT;
-+	}
-+
-+	wq->abort = 0;
-+
-+	if (result > 0) {
-+		tmsecs = jiffies_to_msecs(result);
-+		if (!tmsecs) {
-+			return 1;
-+		}
-+
-+		return tmsecs;
-+	}
-+
-+	if (result == 0) {
-+		return -DWC_E_TIMEOUT;
-+	}
-+
-+	return -DWC_E_UNKNOWN;
-+}
-+
-+void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq)
-+{
-+	wq->abort = 0;
-+	wake_up_interruptible(&wq->queue);
-+}
-+
-+void DWC_WAITQ_ABORT(dwc_waitq_t *wq)
-+{
-+	wq->abort = 1;
-+	wake_up_interruptible(&wq->queue);
-+}
-+
-+
-+/* Threading */
-+
-+dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data)
-+{
-+	struct task_struct *thread = kthread_run(func, data, name);
-+
-+	if (thread == ERR_PTR(-ENOMEM)) {
-+		return NULL;
-+	}
-+
-+	return (dwc_thread_t *)thread;
-+}
-+
-+int DWC_THREAD_STOP(dwc_thread_t *thread)
-+{
-+	return kthread_stop((struct task_struct *)thread);
-+}
-+
-+dwc_bool_t DWC_THREAD_SHOULD_STOP(void)
-+{
-+	return kthread_should_stop();
-+}
-+
-+
-+/* tasklets
-+ - run in interrupt context (cannot sleep)
-+ - each tasklet runs on a single CPU
-+ - different tasklets can be running simultaneously on different CPUs
-+ */
-+struct dwc_tasklet {
-+	struct tasklet_struct t;
-+	dwc_tasklet_callback_t cb;
-+	void *data;
-+};
-+
-+static void tasklet_callback(unsigned long data)
-+{
-+	dwc_tasklet_t *t = (dwc_tasklet_t *)data;
-+	t->cb(t->data);
-+}
-+
-+dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data)
-+{
-+	dwc_tasklet_t *t = DWC_ALLOC(sizeof(*t));
-+
-+	if (t) {
-+		t->cb = cb;
-+		t->data = data;
-+		tasklet_init(&t->t, tasklet_callback, (unsigned long)t);
-+	} else {
-+		DWC_ERROR("Cannot allocate memory for tasklet\n");
-+	}
-+
-+	return t;
-+}
-+
-+void DWC_TASK_FREE(dwc_tasklet_t *task)
-+{
-+	DWC_FREE(task);
-+}
-+
-+void DWC_TASK_SCHEDULE(dwc_tasklet_t *task)
-+{
-+	tasklet_schedule(&task->t);
-+}
-+
-+void DWC_TASK_HI_SCHEDULE(dwc_tasklet_t *task)
-+{
-+	tasklet_hi_schedule(&task->t);
-+}
-+
-+
-+/* workqueues
-+ - run in process context (can sleep)
-+ */
-+typedef struct work_container {
-+	dwc_work_callback_t cb;
-+	void *data;
-+	dwc_workq_t *wq;
-+	char *name;
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_ENTRY(work_container) entry;
-+#endif
-+	struct delayed_work work;
-+} work_container_t;
-+
-+#ifdef DEBUG
-+DWC_CIRCLEQ_HEAD(work_container_queue, work_container);
-+#endif
-+
-+struct dwc_workq {
-+	struct workqueue_struct *wq;
-+	dwc_spinlock_t *lock;
-+	dwc_waitq_t *waitq;
-+	int pending;
-+
-+#ifdef DEBUG
-+	struct work_container_queue entries;
-+#endif
-+};
-+
-+static void do_work(struct work_struct *work)
-+{
-+	dwc_irqflags_t flags;
-+	struct delayed_work *dw = container_of(work, struct delayed_work, work);
-+	work_container_t *container = container_of(dw, struct work_container, work);
-+	dwc_workq_t *wq = container->wq;
-+
-+	container->cb(container->data);
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_REMOVE(&wq->entries, container, entry);
-+#endif
-+	DWC_DEBUGC("Work done: %s, container=%p", container->name, container);
-+	if (container->name) {
-+		DWC_FREE(container->name);
-+	}
-+	DWC_FREE(container);
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+	wq->pending--;
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+	DWC_WAITQ_TRIGGER(wq->waitq);
-+}
-+
-+static int work_done(void *data)
-+{
-+	dwc_workq_t *workq = (dwc_workq_t *)data;
-+	return workq->pending == 0;
-+}
-+
-+int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout)
-+{
-+	return DWC_WAITQ_WAIT_TIMEOUT(workq->waitq, work_done, workq, timeout);
-+}
-+
-+dwc_workq_t *DWC_WORKQ_ALLOC(char *name)
-+{
-+	dwc_workq_t *wq = DWC_ALLOC(sizeof(*wq));
-+
-+	if (!wq) {
-+		return NULL;
-+	}
-+
-+	wq->wq = create_singlethread_workqueue(name);
-+	if (!wq->wq) {
-+		goto no_wq;
-+	}
-+
-+	wq->pending = 0;
-+
-+#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK))
-+	DWC_SPINLOCK_ALLOC_LINUX_DEBUG(wq->lock);
-+#else
-+	wq->lock = DWC_SPINLOCK_ALLOC();
-+#endif
-+	if (!wq->lock) {
-+		goto no_lock;
-+	}
-+
-+	wq->waitq = DWC_WAITQ_ALLOC();
-+	if (!wq->waitq) {
-+		goto no_waitq;
-+	}
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_INIT(&wq->entries);
-+#endif
-+	return wq;
-+
-+ no_waitq:
-+	DWC_SPINLOCK_FREE(wq->lock);
-+ no_lock:
-+	destroy_workqueue(wq->wq);
-+ no_wq:
-+	DWC_FREE(wq);
-+
-+	return NULL;
-+}
-+
-+void DWC_WORKQ_FREE(dwc_workq_t *wq)
-+{
-+#ifdef DEBUG
-+	if (wq->pending != 0) {
-+		struct work_container *wc;
-+		DWC_ERROR("Destroying work queue with pending work");
-+		DWC_CIRCLEQ_FOREACH(wc, &wq->entries, entry) {
-+			DWC_ERROR("Work %s still pending", wc->name);
-+		}
-+	}
-+#endif
-+	destroy_workqueue(wq->wq);
-+	DWC_SPINLOCK_FREE(wq->lock);
-+	DWC_WAITQ_FREE(wq->waitq);
-+	DWC_FREE(wq);
-+}
-+
-+void DWC_WORKQ_SCHEDULE(dwc_workq_t *wq, dwc_work_callback_t cb, void *data,
-+			char *format, ...)
-+{
-+	dwc_irqflags_t flags;
-+	work_container_t *container;
-+	static char name[128];
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VSNPRINTF(name, 128, format, args);
-+	va_end(args);
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+	wq->pending++;
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+	DWC_WAITQ_TRIGGER(wq->waitq);
-+
-+	container = DWC_ALLOC_ATOMIC(sizeof(*container));
-+	if (!container) {
-+		DWC_ERROR("Cannot allocate memory for container\n");
-+		return;
-+	}
-+
-+	container->name = DWC_STRDUP(name);
-+	if (!container->name) {
-+		DWC_ERROR("Cannot allocate memory for container->name\n");
-+		DWC_FREE(container);
-+		return;
-+	}
-+
-+	container->cb = cb;
-+	container->data = data;
-+	container->wq = wq;
-+	DWC_DEBUGC("Queueing work: %s, container=%p", container->name, container);
-+	INIT_WORK(&container->work.work, do_work);
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry);
-+#endif
-+	queue_work(wq->wq, &container->work.work);
-+}
-+
-+void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *wq, dwc_work_callback_t cb,
-+				void *data, uint32_t time, char *format, ...)
-+{
-+	dwc_irqflags_t flags;
-+	work_container_t *container;
-+	static char name[128];
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VSNPRINTF(name, 128, format, args);
-+	va_end(args);
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+	wq->pending++;
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+	DWC_WAITQ_TRIGGER(wq->waitq);
-+
-+	container = DWC_ALLOC_ATOMIC(sizeof(*container));
-+	if (!container) {
-+		DWC_ERROR("Cannot allocate memory for container\n");
-+		return;
-+	}
-+
-+	container->name = DWC_STRDUP(name);
-+	if (!container->name) {
-+		DWC_ERROR("Cannot allocate memory for container->name\n");
-+		DWC_FREE(container);
-+		return;
-+	}
-+
-+	container->cb = cb;
-+	container->data = data;
-+	container->wq = wq;
-+	DWC_DEBUGC("Queueing work: %s, container=%p", container->name, container);
-+	INIT_DELAYED_WORK(&container->work, do_work);
-+
-+#ifdef DEBUG
-+	DWC_CIRCLEQ_INSERT_TAIL(&wq->entries, container, entry);
-+#endif
-+	queue_delayed_work(wq->wq, &container->work, msecs_to_jiffies(time));
-+}
-+
-+int DWC_WORKQ_PENDING(dwc_workq_t *wq)
-+{
-+	return wq->pending;
-+}
-+
-+
-+#ifdef DWC_LIBMODULE
-+
-+#ifdef DWC_CCLIB
-+/* CC */
-+EXPORT_SYMBOL(dwc_cc_if_alloc);
-+EXPORT_SYMBOL(dwc_cc_if_free);
-+EXPORT_SYMBOL(dwc_cc_clear);
-+EXPORT_SYMBOL(dwc_cc_add);
-+EXPORT_SYMBOL(dwc_cc_remove);
-+EXPORT_SYMBOL(dwc_cc_change);
-+EXPORT_SYMBOL(dwc_cc_data_for_save);
-+EXPORT_SYMBOL(dwc_cc_restore_from_data);
-+EXPORT_SYMBOL(dwc_cc_match_chid);
-+EXPORT_SYMBOL(dwc_cc_match_cdid);
-+EXPORT_SYMBOL(dwc_cc_ck);
-+EXPORT_SYMBOL(dwc_cc_chid);
-+EXPORT_SYMBOL(dwc_cc_cdid);
-+EXPORT_SYMBOL(dwc_cc_name);
-+#endif	/* DWC_CCLIB */
-+
-+#ifdef DWC_CRYPTOLIB
-+# ifndef CONFIG_MACH_IPMATE
-+/* Modpow */
-+EXPORT_SYMBOL(dwc_modpow);
-+
-+/* DH */
-+EXPORT_SYMBOL(dwc_dh_modpow);
-+EXPORT_SYMBOL(dwc_dh_derive_keys);
-+EXPORT_SYMBOL(dwc_dh_pk);
-+# endif	/* CONFIG_MACH_IPMATE */
-+
-+/* Crypto */
-+EXPORT_SYMBOL(dwc_wusb_aes_encrypt);
-+EXPORT_SYMBOL(dwc_wusb_cmf);
-+EXPORT_SYMBOL(dwc_wusb_prf);
-+EXPORT_SYMBOL(dwc_wusb_fill_ccm_nonce);
-+EXPORT_SYMBOL(dwc_wusb_gen_nonce);
-+EXPORT_SYMBOL(dwc_wusb_gen_key);
-+EXPORT_SYMBOL(dwc_wusb_gen_mic);
-+#endif	/* DWC_CRYPTOLIB */
-+
-+/* Notification */
-+#ifdef DWC_NOTIFYLIB
-+EXPORT_SYMBOL(dwc_alloc_notification_manager);
-+EXPORT_SYMBOL(dwc_free_notification_manager);
-+EXPORT_SYMBOL(dwc_register_notifier);
-+EXPORT_SYMBOL(dwc_unregister_notifier);
-+EXPORT_SYMBOL(dwc_add_observer);
-+EXPORT_SYMBOL(dwc_remove_observer);
-+EXPORT_SYMBOL(dwc_notify);
-+#endif
-+
-+/* Memory Debugging Routines */
-+#ifdef DWC_DEBUG_MEMORY
-+EXPORT_SYMBOL(dwc_alloc_debug);
-+EXPORT_SYMBOL(dwc_alloc_atomic_debug);
-+EXPORT_SYMBOL(dwc_free_debug);
-+EXPORT_SYMBOL(dwc_dma_alloc_debug);
-+EXPORT_SYMBOL(dwc_dma_free_debug);
-+#endif
-+
-+EXPORT_SYMBOL(DWC_MEMSET);
-+EXPORT_SYMBOL(DWC_MEMCPY);
-+EXPORT_SYMBOL(DWC_MEMMOVE);
-+EXPORT_SYMBOL(DWC_MEMCMP);
-+EXPORT_SYMBOL(DWC_STRNCMP);
-+EXPORT_SYMBOL(DWC_STRCMP);
-+EXPORT_SYMBOL(DWC_STRLEN);
-+EXPORT_SYMBOL(DWC_STRCPY);
-+EXPORT_SYMBOL(DWC_STRDUP);
-+EXPORT_SYMBOL(DWC_ATOI);
-+EXPORT_SYMBOL(DWC_ATOUI);
-+
-+#ifdef DWC_UTFLIB
-+EXPORT_SYMBOL(DWC_UTF8_TO_UTF16LE);
-+#endif	/* DWC_UTFLIB */
-+
-+EXPORT_SYMBOL(DWC_IN_IRQ);
-+EXPORT_SYMBOL(DWC_IN_BH);
-+EXPORT_SYMBOL(DWC_VPRINTF);
-+EXPORT_SYMBOL(DWC_VSNPRINTF);
-+EXPORT_SYMBOL(DWC_PRINTF);
-+EXPORT_SYMBOL(DWC_SPRINTF);
-+EXPORT_SYMBOL(DWC_SNPRINTF);
-+EXPORT_SYMBOL(__DWC_WARN);
-+EXPORT_SYMBOL(__DWC_ERROR);
-+EXPORT_SYMBOL(DWC_EXCEPTION);
-+
-+#ifdef DEBUG
-+EXPORT_SYMBOL(__DWC_DEBUG);
-+#endif
-+
-+EXPORT_SYMBOL(__DWC_DMA_ALLOC);
-+EXPORT_SYMBOL(__DWC_DMA_ALLOC_ATOMIC);
-+EXPORT_SYMBOL(__DWC_DMA_FREE);
-+EXPORT_SYMBOL(__DWC_ALLOC);
-+EXPORT_SYMBOL(__DWC_ALLOC_ATOMIC);
-+EXPORT_SYMBOL(__DWC_FREE);
-+
-+#ifdef DWC_CRYPTOLIB
-+EXPORT_SYMBOL(DWC_RANDOM_BYTES);
-+EXPORT_SYMBOL(DWC_AES_CBC);
-+EXPORT_SYMBOL(DWC_SHA256);
-+EXPORT_SYMBOL(DWC_HMAC_SHA256);
-+#endif
-+
-+EXPORT_SYMBOL(DWC_CPU_TO_LE32);
-+EXPORT_SYMBOL(DWC_CPU_TO_BE32);
-+EXPORT_SYMBOL(DWC_LE32_TO_CPU);
-+EXPORT_SYMBOL(DWC_BE32_TO_CPU);
-+EXPORT_SYMBOL(DWC_CPU_TO_LE16);
-+EXPORT_SYMBOL(DWC_CPU_TO_BE16);
-+EXPORT_SYMBOL(DWC_LE16_TO_CPU);
-+EXPORT_SYMBOL(DWC_BE16_TO_CPU);
-+EXPORT_SYMBOL(DWC_READ_REG32);
-+EXPORT_SYMBOL(DWC_WRITE_REG32);
-+EXPORT_SYMBOL(DWC_MODIFY_REG32);
-+
-+#if 0
-+EXPORT_SYMBOL(DWC_READ_REG64);
-+EXPORT_SYMBOL(DWC_WRITE_REG64);
-+EXPORT_SYMBOL(DWC_MODIFY_REG64);
-+#endif
-+
-+EXPORT_SYMBOL(DWC_SPINLOCK_ALLOC);
-+EXPORT_SYMBOL(DWC_SPINLOCK_FREE);
-+EXPORT_SYMBOL(DWC_SPINLOCK);
-+EXPORT_SYMBOL(DWC_SPINUNLOCK);
-+EXPORT_SYMBOL(DWC_SPINLOCK_IRQSAVE);
-+EXPORT_SYMBOL(DWC_SPINUNLOCK_IRQRESTORE);
-+EXPORT_SYMBOL(DWC_MUTEX_ALLOC);
-+
-+#if (!defined(DWC_LINUX) || !defined(CONFIG_DEBUG_MUTEXES))
-+EXPORT_SYMBOL(DWC_MUTEX_FREE);
-+#endif
-+
-+EXPORT_SYMBOL(DWC_MUTEX_LOCK);
-+EXPORT_SYMBOL(DWC_MUTEX_TRYLOCK);
-+EXPORT_SYMBOL(DWC_MUTEX_UNLOCK);
-+EXPORT_SYMBOL(DWC_UDELAY);
-+EXPORT_SYMBOL(DWC_MDELAY);
-+EXPORT_SYMBOL(DWC_MSLEEP);
-+EXPORT_SYMBOL(DWC_TIME);
-+EXPORT_SYMBOL(DWC_TIMER_ALLOC);
-+EXPORT_SYMBOL(DWC_TIMER_FREE);
-+EXPORT_SYMBOL(DWC_TIMER_SCHEDULE);
-+EXPORT_SYMBOL(DWC_TIMER_CANCEL);
-+EXPORT_SYMBOL(DWC_WAITQ_ALLOC);
-+EXPORT_SYMBOL(DWC_WAITQ_FREE);
-+EXPORT_SYMBOL(DWC_WAITQ_WAIT);
-+EXPORT_SYMBOL(DWC_WAITQ_WAIT_TIMEOUT);
-+EXPORT_SYMBOL(DWC_WAITQ_TRIGGER);
-+EXPORT_SYMBOL(DWC_WAITQ_ABORT);
-+EXPORT_SYMBOL(DWC_THREAD_RUN);
-+EXPORT_SYMBOL(DWC_THREAD_STOP);
-+EXPORT_SYMBOL(DWC_THREAD_SHOULD_STOP);
-+EXPORT_SYMBOL(DWC_TASK_ALLOC);
-+EXPORT_SYMBOL(DWC_TASK_FREE);
-+EXPORT_SYMBOL(DWC_TASK_SCHEDULE);
-+EXPORT_SYMBOL(DWC_WORKQ_WAIT_WORK_DONE);
-+EXPORT_SYMBOL(DWC_WORKQ_ALLOC);
-+EXPORT_SYMBOL(DWC_WORKQ_FREE);
-+EXPORT_SYMBOL(DWC_WORKQ_SCHEDULE);
-+EXPORT_SYMBOL(DWC_WORKQ_SCHEDULE_DELAYED);
-+EXPORT_SYMBOL(DWC_WORKQ_PENDING);
-+
-+static int dwc_common_port_init_module(void)
-+{
-+	int result = 0;
-+
-+	printk(KERN_DEBUG "Module dwc_common_port init\n" );
-+
-+#ifdef DWC_DEBUG_MEMORY
-+	result = dwc_memory_debug_start(NULL);
-+	if (result) {
-+		printk(KERN_ERR
-+		       "dwc_memory_debug_start() failed with error %d\n",
-+		       result);
-+		return result;
-+	}
-+#endif
-+
-+#ifdef DWC_NOTIFYLIB
-+	result = dwc_alloc_notification_manager(NULL, NULL);
-+	if (result) {
-+		printk(KERN_ERR
-+		       "dwc_alloc_notification_manager() failed with error %d\n",
-+		       result);
-+		return result;
-+	}
-+#endif
-+	return result;
-+}
-+
-+static void dwc_common_port_exit_module(void)
-+{
-+	printk(KERN_DEBUG "Module dwc_common_port exit\n" );
-+
-+#ifdef DWC_NOTIFYLIB
-+	dwc_free_notification_manager();
-+#endif
-+
-+#ifdef DWC_DEBUG_MEMORY
-+	dwc_memory_debug_stop();
-+#endif
-+}
-+
-+module_init(dwc_common_port_init_module);
-+module_exit(dwc_common_port_exit_module);
-+
-+MODULE_DESCRIPTION("DWC Common Library - Portable version");
-+MODULE_AUTHOR("Synopsys Inc.");
-+MODULE_LICENSE ("GPL");
-+
-+#endif	/* DWC_LIBMODULE */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_common_nbsd.c
-@@ -0,0 +1,1275 @@
-+#include "dwc_os.h"
-+#include "dwc_list.h"
-+
-+#ifdef DWC_CCLIB
-+# include "dwc_cc.h"
-+#endif
-+
-+#ifdef DWC_CRYPTOLIB
-+# include "dwc_modpow.h"
-+# include "dwc_dh.h"
-+# include "dwc_crypto.h"
-+#endif
-+
-+#ifdef DWC_NOTIFYLIB
-+# include "dwc_notifier.h"
-+#endif
-+
-+/* OS-Level Implementations */
-+
-+/* This is the NetBSD 4.0.1 kernel implementation of the DWC platform library. */
-+
-+
-+/* MISC */
-+
-+void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size)
-+{
-+	return memset(dest, byte, size);
-+}
-+
-+void *DWC_MEMCPY(void *dest, void const *src, uint32_t size)
-+{
-+	return memcpy(dest, src, size);
-+}
-+
-+void *DWC_MEMMOVE(void *dest, void *src, uint32_t size)
-+{
-+	bcopy(src, dest, size);
-+	return dest;
-+}
-+
-+int DWC_MEMCMP(void *m1, void *m2, uint32_t size)
-+{
-+	return memcmp(m1, m2, size);
-+}
-+
-+int DWC_STRNCMP(void *s1, void *s2, uint32_t size)
-+{
-+	return strncmp(s1, s2, size);
-+}
-+
-+int DWC_STRCMP(void *s1, void *s2)
-+{
-+	return strcmp(s1, s2);
-+}
-+
-+int DWC_STRLEN(char const *str)
-+{
-+	return strlen(str);
-+}
-+
-+char *DWC_STRCPY(char *to, char const *from)
-+{
-+	return strcpy(to, from);
-+}
-+
-+char *DWC_STRDUP(char const *str)
-+{
-+	int len = DWC_STRLEN(str) + 1;
-+	char *new = DWC_ALLOC_ATOMIC(len);
-+
-+	if (!new) {
-+		return NULL;
-+	}
-+
-+	DWC_MEMCPY(new, str, len);
-+	return new;
-+}
-+
-+int DWC_ATOI(char *str, int32_t *value)
-+{
-+	char *end = NULL;
-+
-+	/* NetBSD doesn't have 'strtol' in the kernel, but 'strtoul'
-+	 * should be equivalent on 2's complement machines
-+	 */
-+	*value = strtoul(str, &end, 0);
-+	if (*end == '\0') {
-+		return 0;
-+	}
-+
-+	return -1;
-+}
-+
-+int DWC_ATOUI(char *str, uint32_t *value)
-+{
-+	char *end = NULL;
-+
-+	*value = strtoul(str, &end, 0);
-+	if (*end == '\0') {
-+		return 0;
-+	}
-+
-+	return -1;
-+}
-+
-+
-+#ifdef DWC_UTFLIB
-+/* From usbstring.c */
-+
-+int DWC_UTF8_TO_UTF16LE(uint8_t const *s, uint16_t *cp, unsigned len)
-+{
-+	int	count = 0;
-+	u8	c;
-+	u16	uchar;
-+
-+	/* this insists on correct encodings, though not minimal ones.
-+	 * BUT it currently rejects legit 4-byte UTF-8 code points,
-+	 * which need surrogate pairs.  (Unicode 3.1 can use them.)
-+	 */
-+	while (len != 0 && (c = (u8) *s++) != 0) {
-+		if (unlikely(c & 0x80)) {
-+			// 2-byte sequence:
-+			// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
-+			if ((c & 0xe0) == 0xc0) {
-+				uchar = (c & 0x1f) << 6;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c;
-+
-+			// 3-byte sequence (most CJKV characters):
-+			// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
-+			} else if ((c & 0xf0) == 0xe0) {
-+				uchar = (c & 0x0f) << 12;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c << 6;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c;
-+
-+				/* no bogus surrogates */
-+				if (0xd800 <= uchar && uchar <= 0xdfff)
-+					goto fail;
-+
-+			// 4-byte sequence (surrogate pairs, currently rare):
-+			// 11101110wwwwzzzzyy + 110111yyyyxxxxxx
-+			//     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-+			// (uuuuu = wwww + 1)
-+			// FIXME accept the surrogate code points (only)
-+			} else
-+				goto fail;
-+		} else
-+			uchar = c;
-+		put_unaligned (cpu_to_le16 (uchar), cp++);
-+		count++;
-+		len--;
-+	}
-+	return count;
-+fail:
-+	return -1;
-+}
-+
-+#endif	/* DWC_UTFLIB */
-+
-+
-+/* dwc_debug.h */
-+
-+dwc_bool_t DWC_IN_IRQ(void)
-+{
-+//	return in_irq();
-+	return 0;
-+}
-+
-+dwc_bool_t DWC_IN_BH(void)
-+{
-+//	return in_softirq();
-+	return 0;
-+}
-+
-+void DWC_VPRINTF(char *format, va_list args)
-+{
-+	vprintf(format, args);
-+}
-+
-+int DWC_VSNPRINTF(char *str, int size, char *format, va_list args)
-+{
-+	return vsnprintf(str, size, format, args);
-+}
-+
-+void DWC_PRINTF(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+
-+int DWC_SPRINTF(char *buffer, char *format, ...)
-+{
-+	int retval;
-+	va_list args;
-+
-+	va_start(args, format);
-+	retval = vsprintf(buffer, format, args);
-+	va_end(args);
-+	return retval;
-+}
-+
-+int DWC_SNPRINTF(char *buffer, int size, char *format, ...)
-+{
-+	int retval;
-+	va_list args;
-+
-+	va_start(args, format);
-+	retval = vsnprintf(buffer, size, format, args);
-+	va_end(args);
-+	return retval;
-+}
-+
-+void __DWC_WARN(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+
-+void __DWC_ERROR(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+
-+void DWC_EXCEPTION(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+//	BUG_ON(1);	???
-+}
-+
-+#ifdef DEBUG
-+void __DWC_DEBUG(char *format, ...)
-+{
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VPRINTF(format, args);
-+	va_end(args);
-+}
-+#endif
-+
-+
-+/* dwc_mem.h */
-+
-+#if 0
-+dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size,
-+				uint32_t align,
-+				uint32_t alloc)
-+{
-+	struct dma_pool *pool = dma_pool_create("Pool", NULL,
-+						size, align, alloc);
-+	return (dwc_pool_t *)pool;
-+}
-+
-+void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool)
-+{
-+	dma_pool_destroy((struct dma_pool *)pool);
-+}
-+
-+void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
-+{
-+//	return dma_pool_alloc((struct dma_pool *)pool, GFP_KERNEL, dma_addr);
-+	return dma_pool_alloc((struct dma_pool *)pool, M_WAITOK, dma_addr);
-+}
-+
-+void *DWC_DMA_POOL_ZALLOC(dwc_pool_t *pool, uint64_t *dma_addr)
-+{
-+	void *vaddr = DWC_DMA_POOL_ALLOC(pool, dma_addr);
-+	memset(..);
-+}
-+
-+void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr)
-+{
-+	dma_pool_free(pool, vaddr, daddr);
-+}
-+#endif
-+
-+void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr)
-+{
-+	dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx;
-+	int error;
-+
-+	error = bus_dmamem_alloc(dma->dma_tag, size, 1, size, dma->segs,
-+				 sizeof(dma->segs) / sizeof(dma->segs[0]),
-+				 &dma->nsegs, BUS_DMA_NOWAIT);
-+	if (error) {
-+		printf("%s: bus_dmamem_alloc(%ju) failed: %d\n", __func__,
-+		       (uintmax_t)size, error);
-+		goto fail_0;
-+	}
-+
-+	error = bus_dmamem_map(dma->dma_tag, dma->segs, dma->nsegs, size,
-+			       (caddr_t *)&dma->dma_vaddr,
-+			       BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
-+	if (error) {
-+		printf("%s: bus_dmamem_map failed: %d\n", __func__, error);
-+		goto fail_1;
-+	}
-+
-+	error = bus_dmamap_create(dma->dma_tag, size, 1, size, 0,
-+				  BUS_DMA_NOWAIT, &dma->dma_map);
-+	if (error) {
-+		printf("%s: bus_dmamap_create failed: %d\n", __func__, error);
-+		goto fail_2;
-+	}
-+
-+	error = bus_dmamap_load(dma->dma_tag, dma->dma_map, dma->dma_vaddr,
-+				size, NULL, BUS_DMA_NOWAIT);
-+	if (error) {
-+		printf("%s: bus_dmamap_load failed: %d\n", __func__, error);
-+		goto fail_3;
-+	}
-+
-+	dma->dma_paddr = (bus_addr_t)dma->segs[0].ds_addr;
-+	*dma_addr = dma->dma_paddr;
-+	return dma->dma_vaddr;
-+
-+fail_3:
-+	bus_dmamap_destroy(dma->dma_tag, dma->dma_map);
-+fail_2:
-+	bus_dmamem_unmap(dma->dma_tag, dma->dma_vaddr, size);
-+fail_1:
-+	bus_dmamem_free(dma->dma_tag, dma->segs, dma->nsegs);
-+fail_0:
-+	dma->dma_map = NULL;
-+	dma->dma_vaddr = NULL;
-+	dma->nsegs = 0;
-+
-+	return NULL;
-+}
-+
-+void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr)
-+{
-+	dwc_dmactx_t *dma = (dwc_dmactx_t *)dma_ctx;
-+
-+	if (dma->dma_map != NULL) {
-+		bus_dmamap_sync(dma->dma_tag, dma->dma_map, 0, size,
-+				BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
-+		bus_dmamap_unload(dma->dma_tag, dma->dma_map);
-+		bus_dmamap_destroy(dma->dma_tag, dma->dma_map);
-+		bus_dmamem_unmap(dma->dma_tag, dma->dma_vaddr, size);
-+		bus_dmamem_free(dma->dma_tag, dma->segs, dma->nsegs);
-+		dma->dma_paddr = 0;
-+		dma->dma_map = NULL;
-+		dma->dma_vaddr = NULL;
-+		dma->nsegs = 0;
-+	}
-+}
-+
-+void *__DWC_ALLOC(void *mem_ctx, uint32_t size)
-+{
-+	return malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
-+}
-+
-+void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size)
-+{
-+	return malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
-+}
-+
-+void __DWC_FREE(void *mem_ctx, void *addr)
-+{
-+	free(addr, M_DEVBUF);
-+}
-+
-+
-+#ifdef DWC_CRYPTOLIB
-+/* dwc_crypto.h */
-+
-+void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length)
-+{
-+	get_random_bytes(buffer, length);
-+}
-+
-+int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out)
-+{
-+	struct crypto_blkcipher *tfm;
-+	struct blkcipher_desc desc;
-+	struct scatterlist sgd;
-+	struct scatterlist sgs;
-+
-+	tfm = crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
-+	if (tfm == NULL) {
-+		printk("failed to load transform for aes CBC\n");
-+		return -1;
-+	}
-+
-+	crypto_blkcipher_setkey(tfm, key, keylen);
-+	crypto_blkcipher_set_iv(tfm, iv, 16);
-+
-+	sg_init_one(&sgd, out, messagelen);
-+	sg_init_one(&sgs, message, messagelen);
-+
-+	desc.tfm = tfm;
-+	desc.flags = 0;
-+
-+	if (crypto_blkcipher_encrypt(&desc, &sgd, &sgs, messagelen)) {
-+		crypto_free_blkcipher(tfm);
-+		DWC_ERROR("AES CBC encryption failed");
-+		return -1;
-+	}
-+
-+	crypto_free_blkcipher(tfm);
-+	return 0;
-+}
-+
-+int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out)
-+{
-+	struct crypto_hash *tfm;
-+	struct hash_desc desc;
-+	struct scatterlist sg;
-+
-+	tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
-+	if (IS_ERR(tfm)) {
-+		DWC_ERROR("Failed to load transform for sha256: %ld", PTR_ERR(tfm));
-+		return 0;
-+	}
-+	desc.tfm = tfm;
-+	desc.flags = 0;
-+
-+	sg_init_one(&sg, message, len);
-+	crypto_hash_digest(&desc, &sg, len, out);
-+	crypto_free_hash(tfm);
-+
-+	return 1;
-+}
-+
-+int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen,
-+		    uint8_t *key, uint32_t keylen, uint8_t *out)
-+{
-+	struct crypto_hash *tfm;
-+	struct hash_desc desc;
-+	struct scatterlist sg;
-+
-+	tfm = crypto_alloc_hash("hmac(sha256)", 0, CRYPTO_ALG_ASYNC);
-+	if (IS_ERR(tfm)) {
-+		DWC_ERROR("Failed to load transform for hmac(sha256): %ld", PTR_ERR(tfm));
-+		return 0;
-+	}
-+	desc.tfm = tfm;
-+	desc.flags = 0;
-+
-+	sg_init_one(&sg, message, messagelen);
-+	crypto_hash_setkey(tfm, key, keylen);
-+	crypto_hash_digest(&desc, &sg, messagelen, out);
-+	crypto_free_hash(tfm);
-+
-+	return 1;
-+}
-+
-+#endif	/* DWC_CRYPTOLIB */
-+
-+
-+/* Byte Ordering Conversions */
-+
-+uint32_t DWC_CPU_TO_LE32(uint32_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint32_t DWC_CPU_TO_BE32(uint32_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint32_t DWC_LE32_TO_CPU(uint32_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint32_t DWC_BE32_TO_CPU(uint32_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+
-+	return (u_p[3] | (u_p[2] << 8) | (u_p[1] << 16) | (u_p[0] << 24));
-+#endif
-+}
-+
-+uint16_t DWC_CPU_TO_LE16(uint16_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+uint16_t DWC_CPU_TO_BE16(uint16_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+uint16_t DWC_LE16_TO_CPU(uint16_t *p)
-+{
-+#ifdef __LITTLE_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+uint16_t DWC_BE16_TO_CPU(uint16_t *p)
-+{
-+#ifdef __BIG_ENDIAN
-+	return *p;
-+#else
-+	uint8_t *u_p = (uint8_t *)p;
-+	return (u_p[1] | (u_p[0] << 8));
-+#endif
-+}
-+
-+
-+/* Registers */
-+
-+uint32_t DWC_READ_REG32(void *io_ctx, uint32_t volatile *reg)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	return bus_space_read_4(io->iot, io->ioh, ior);
-+}
-+
-+#if 0
-+uint64_t DWC_READ_REG64(void *io_ctx, uint64_t volatile *reg)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	return bus_space_read_8(io->iot, io->ioh, ior);
-+}
-+#endif
-+
-+void DWC_WRITE_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t value)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	bus_space_write_4(io->iot, io->ioh, ior, value);
-+}
-+
-+#if 0
-+void DWC_WRITE_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t value)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	bus_space_write_8(io->iot, io->ioh, ior, value);
-+}
-+#endif
-+
-+void DWC_MODIFY_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t clear_mask,
-+		      uint32_t set_mask)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	bus_space_write_4(io->iot, io->ioh, ior,
-+			  (bus_space_read_4(io->iot, io->ioh, ior) &
-+			   ~clear_mask) | set_mask);
-+}
-+
-+#if 0
-+void DWC_MODIFY_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t clear_mask,
-+		      uint64_t set_mask)
-+{
-+	dwc_ioctx_t *io = (dwc_ioctx_t *)io_ctx;
-+	bus_size_t ior = (bus_size_t)reg;
-+
-+	bus_space_write_8(io->iot, io->ioh, ior,
-+			  (bus_space_read_8(io->iot, io->ioh, ior) &
-+			   ~clear_mask) | set_mask);
-+}
-+#endif
-+
-+
-+/* Locking */
-+
-+dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void)
-+{
-+	struct simplelock *sl = DWC_ALLOC(sizeof(*sl));
-+
-+	if (!sl) {
-+		DWC_ERROR("Cannot allocate memory for spinlock");
-+		return NULL;
-+	}
-+
-+	simple_lock_init(sl);
-+	return (dwc_spinlock_t *)sl;
-+}
-+
-+void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock)
-+{
-+	struct simplelock *sl = (struct simplelock *)lock;
-+
-+	DWC_FREE(sl);
-+}
-+
-+void DWC_SPINLOCK(dwc_spinlock_t *lock)
-+{
-+	simple_lock((struct simplelock *)lock);
-+}
-+
-+void DWC_SPINUNLOCK(dwc_spinlock_t *lock)
-+{
-+	simple_unlock((struct simplelock *)lock);
-+}
-+
-+void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags)
-+{
-+	simple_lock((struct simplelock *)lock);
-+	*flags = splbio();
-+}
-+
-+void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags)
-+{
-+	splx(flags);
-+	simple_unlock((struct simplelock *)lock);
-+}
-+
-+dwc_mutex_t *DWC_MUTEX_ALLOC(void)
-+{
-+	dwc_mutex_t *mutex = DWC_ALLOC(sizeof(struct lock));
-+
-+	if (!mutex) {
-+		DWC_ERROR("Cannot allocate memory for mutex");
-+		return NULL;
-+	}
-+
-+	lockinit((struct lock *)mutex, 0, "dw3mtx", 0, 0);
-+	return mutex;
-+}
-+
-+#if (defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES))
-+#else
-+void DWC_MUTEX_FREE(dwc_mutex_t *mutex)
-+{
-+	DWC_FREE(mutex);
-+}
-+#endif
-+
-+void DWC_MUTEX_LOCK(dwc_mutex_t *mutex)
-+{
-+	lockmgr((struct lock *)mutex, LK_EXCLUSIVE, NULL);
-+}
-+
-+int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex)
-+{
-+	int status;
-+
-+	status = lockmgr((struct lock *)mutex, LK_EXCLUSIVE | LK_NOWAIT, NULL);
-+	return status == 0;
-+}
-+
-+void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex)
-+{
-+	lockmgr((struct lock *)mutex, LK_RELEASE, NULL);
-+}
-+
-+
-+/* Timing */
-+
-+void DWC_UDELAY(uint32_t usecs)
-+{
-+	DELAY(usecs);
-+}
-+
-+void DWC_MDELAY(uint32_t msecs)
-+{
-+	do {
-+		DELAY(1000);
-+	} while (--msecs);
-+}
-+
-+void DWC_MSLEEP(uint32_t msecs)
-+{
-+	struct timeval tv;
-+
-+	tv.tv_sec = msecs / 1000;
-+	tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000;
-+	tsleep(&tv, 0, "dw3slp", tvtohz(&tv));
-+}
-+
-+uint32_t DWC_TIME(void)
-+{
-+	struct timeval tv;
-+
-+	microuptime(&tv);	// or getmicrouptime? (less precise, but faster)
-+	return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-+}
-+
-+
-+/* Timers */
-+
-+struct dwc_timer {
-+	struct callout t;
-+	char *name;
-+	dwc_spinlock_t *lock;
-+	dwc_timer_callback_t cb;
-+	void *data;
-+};
-+
-+dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data)
-+{
-+	dwc_timer_t *t = DWC_ALLOC(sizeof(*t));
-+
-+	if (!t) {
-+		DWC_ERROR("Cannot allocate memory for timer");
-+		return NULL;
-+	}
-+
-+	callout_init(&t->t);
-+
-+	t->name = DWC_STRDUP(name);
-+	if (!t->name) {
-+		DWC_ERROR("Cannot allocate memory for timer->name");
-+		goto no_name;
-+	}
-+
-+	t->lock = DWC_SPINLOCK_ALLOC();
-+	if (!t->lock) {
-+		DWC_ERROR("Cannot allocate memory for timer->lock");
-+		goto no_lock;
-+	}
-+
-+	t->cb = cb;
-+	t->data = data;
-+
-+	return t;
-+
-+ no_lock:
-+	DWC_FREE(t->name);
-+ no_name:
-+	DWC_FREE(t);
-+
-+	return NULL;
-+}
-+
-+void DWC_TIMER_FREE(dwc_timer_t *timer)
-+{
-+	callout_stop(&timer->t);
-+	DWC_SPINLOCK_FREE(timer->lock);
-+	DWC_FREE(timer->name);
-+	DWC_FREE(timer);
-+}
-+
-+void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time)
-+{
-+	struct timeval tv;
-+
-+	tv.tv_sec = time / 1000;
-+	tv.tv_usec = (time - tv.tv_sec * 1000) * 1000;
-+	callout_reset(&timer->t, tvtohz(&tv), timer->cb, timer->data);
-+}
-+
-+void DWC_TIMER_CANCEL(dwc_timer_t *timer)
-+{
-+	callout_stop(&timer->t);
-+}
-+
-+
-+/* Wait Queues */
-+
-+struct dwc_waitq {
-+	struct simplelock lock;
-+	int abort;
-+};
-+
-+dwc_waitq_t *DWC_WAITQ_ALLOC(void)
-+{
-+	dwc_waitq_t *wq = DWC_ALLOC(sizeof(*wq));
-+
-+	if (!wq) {
-+		DWC_ERROR("Cannot allocate memory for waitqueue");
-+		return NULL;
-+	}
-+
-+	simple_lock_init(&wq->lock);
-+	wq->abort = 0;
-+
-+	return wq;
-+}
-+
-+void DWC_WAITQ_FREE(dwc_waitq_t *wq)
-+{
-+	DWC_FREE(wq);
-+}
-+
-+int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data)
-+{
-+	int ipl;
-+	int result = 0;
-+
-+	simple_lock(&wq->lock);
-+	ipl = splbio();
-+
-+	/* Skip the sleep if already aborted or triggered */
-+	if (!wq->abort && !cond(data)) {
-+		splx(ipl);
-+		result = ltsleep(wq, PCATCH, "dw3wat", 0, &wq->lock); // infinite timeout
-+		ipl = splbio();
-+	}
-+
-+	if (result == 0) {			// awoken
-+		if (wq->abort) {
-+			wq->abort = 0;
-+			result = -DWC_E_ABORT;
-+		} else {
-+			result = 0;
-+		}
-+
-+		splx(ipl);
-+		simple_unlock(&wq->lock);
-+	} else {
-+		wq->abort = 0;
-+		splx(ipl);
-+		simple_unlock(&wq->lock);
-+
-+		if (result == ERESTART) {	// signaled - restart
-+			result = -DWC_E_RESTART;
-+		} else {			// signaled - must be EINTR
-+			result = -DWC_E_ABORT;
-+		}
-+	}
-+
-+	return result;
-+}
-+
-+int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond,
-+			       void *data, int32_t msecs)
-+{
-+	struct timeval tv, tv1, tv2;
-+	int ipl;
-+	int result = 0;
-+
-+	tv.tv_sec = msecs / 1000;
-+	tv.tv_usec = (msecs - tv.tv_sec * 1000) * 1000;
-+
-+	simple_lock(&wq->lock);
-+	ipl = splbio();
-+
-+	/* Skip the sleep if already aborted or triggered */
-+	if (!wq->abort && !cond(data)) {
-+		splx(ipl);
-+		getmicrouptime(&tv1);
-+		result = ltsleep(wq, PCATCH, "dw3wto", tvtohz(&tv), &wq->lock);
-+		getmicrouptime(&tv2);
-+		ipl = splbio();
-+	}
-+
-+	if (result == 0) {			// awoken
-+		if (wq->abort) {
-+			wq->abort = 0;
-+			splx(ipl);
-+			simple_unlock(&wq->lock);
-+			result = -DWC_E_ABORT;
-+		} else {
-+			splx(ipl);
-+			simple_unlock(&wq->lock);
-+
-+			tv2.tv_usec -= tv1.tv_usec;
-+			if (tv2.tv_usec < 0) {
-+				tv2.tv_usec += 1000000;
-+				tv2.tv_sec--;
-+			}
-+
-+			tv2.tv_sec -= tv1.tv_sec;
-+			result = tv2.tv_sec * 1000 + tv2.tv_usec / 1000;
-+			result = msecs - result;
-+			if (result <= 0)
-+				result = 1;
-+		}
-+	} else {
-+		wq->abort = 0;
-+		splx(ipl);
-+		simple_unlock(&wq->lock);
-+
-+		if (result == ERESTART) {	// signaled - restart
-+			result = -DWC_E_RESTART;
-+
-+		} else if (result == EINTR) {		// signaled - interrupt
-+			result = -DWC_E_ABORT;
-+
-+		} else {				// timed out
-+			result = -DWC_E_TIMEOUT;
-+		}
-+	}
-+
-+	return result;
-+}
-+
-+void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq)
-+{
-+	wakeup(wq);
-+}
-+
-+void DWC_WAITQ_ABORT(dwc_waitq_t *wq)
-+{
-+	int ipl;
-+
-+	simple_lock(&wq->lock);
-+	ipl = splbio();
-+	wq->abort = 1;
-+	wakeup(wq);
-+	splx(ipl);
-+	simple_unlock(&wq->lock);
-+}
-+
-+
-+/* Threading */
-+
-+struct dwc_thread {
-+	struct proc *proc;
-+	int abort;
-+};
-+
-+dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data)
-+{
-+	int retval;
-+	dwc_thread_t *thread = DWC_ALLOC(sizeof(*thread));
-+
-+	if (!thread) {
-+		return NULL;
-+	}
-+
-+	thread->abort = 0;
-+	retval = kthread_create1((void (*)(void *))func, data, &thread->proc,
-+				 "%s", name);
-+	if (retval) {
-+		DWC_FREE(thread);
-+		return NULL;
-+	}
-+
-+	return thread;
-+}
-+
-+int DWC_THREAD_STOP(dwc_thread_t *thread)
-+{
-+	int retval;
-+
-+	thread->abort = 1;
-+	retval = tsleep(&thread->abort, 0, "dw3stp", 60 * hz);
-+
-+	if (retval == 0) {
-+		/* DWC_THREAD_EXIT() will free the thread struct */
-+		return 0;
-+	}
-+
-+	/* NOTE: We leak the thread struct if thread doesn't die */
-+
-+	if (retval == EWOULDBLOCK) {
-+		return -DWC_E_TIMEOUT;
-+	}
-+
-+	return -DWC_E_UNKNOWN;
-+}
-+
-+dwc_bool_t DWC_THREAD_SHOULD_STOP(dwc_thread_t *thread)
-+{
-+	return thread->abort;
-+}
-+
-+void DWC_THREAD_EXIT(dwc_thread_t *thread)
-+{
-+	wakeup(&thread->abort);
-+	DWC_FREE(thread);
-+	kthread_exit(0);
-+}
-+
-+/* tasklets
-+ - Runs in interrupt context (cannot sleep)
-+ - Each tasklet runs on a single CPU
-+ - Different tasklets can be running simultaneously on different CPUs
-+ [ On NetBSD there is no corresponding mechanism, drivers don't have bottom-
-+   halves. So we just call the callback directly from DWC_TASK_SCHEDULE() ]
-+ */
-+struct dwc_tasklet {
-+	dwc_tasklet_callback_t cb;
-+	void *data;
-+};
-+
-+static void tasklet_callback(void *data)
-+{
-+	dwc_tasklet_t *task = (dwc_tasklet_t *)data;
-+
-+	task->cb(task->data);
-+}
-+
-+dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data)
-+{
-+	dwc_tasklet_t *task = DWC_ALLOC(sizeof(*task));
-+
-+	if (task) {
-+		task->cb = cb;
-+		task->data = data;
-+	} else {
-+		DWC_ERROR("Cannot allocate memory for tasklet");
-+	}
-+
-+	return task;
-+}
-+
-+void DWC_TASK_FREE(dwc_tasklet_t *task)
-+{
-+	DWC_FREE(task);
-+}
-+
-+void DWC_TASK_SCHEDULE(dwc_tasklet_t *task)
-+{
-+	tasklet_callback(task);
-+}
-+
-+
-+/* workqueues
-+ - Runs in process context (can sleep)
-+ */
-+typedef struct work_container {
-+	dwc_work_callback_t cb;
-+	void *data;
-+	dwc_workq_t *wq;
-+	char *name;
-+	int hz;
-+	struct work task;
-+} work_container_t;
-+
-+struct dwc_workq {
-+	struct workqueue *taskq;
-+	dwc_spinlock_t *lock;
-+	dwc_waitq_t *waitq;
-+	int pending;
-+	struct work_container *container;
-+};
-+
-+static void do_work(struct work *task, void *data)
-+{
-+	dwc_workq_t *wq = (dwc_workq_t *)data;
-+	work_container_t *container = wq->container;
-+	dwc_irqflags_t flags;
-+
-+	if (container->hz) {
-+		tsleep(container, 0, "dw3wrk", container->hz);
-+	}
-+
-+	container->cb(container->data);
-+	DWC_DEBUG("Work done: %s, container=%p", container->name, container);
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+	if (container->name)
-+		DWC_FREE(container->name);
-+	DWC_FREE(container);
-+	wq->pending--;
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+	DWC_WAITQ_TRIGGER(wq->waitq);
-+}
-+
-+static int work_done(void *data)
-+{
-+	dwc_workq_t *workq = (dwc_workq_t *)data;
-+
-+	return workq->pending == 0;
-+}
-+
-+int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout)
-+{
-+	return DWC_WAITQ_WAIT_TIMEOUT(workq->waitq, work_done, workq, timeout);
-+}
-+
-+dwc_workq_t *DWC_WORKQ_ALLOC(char *name)
-+{
-+	int result;
-+	dwc_workq_t *wq = DWC_ALLOC(sizeof(*wq));
-+
-+	if (!wq) {
-+		DWC_ERROR("Cannot allocate memory for workqueue");
-+		return NULL;
-+	}
-+
-+	result = workqueue_create(&wq->taskq, name, do_work, wq, 0 /*PWAIT*/,
-+				  IPL_BIO, 0);
-+	if (result) {
-+		DWC_ERROR("Cannot create workqueue");
-+		goto no_taskq;
-+	}
-+
-+	wq->pending = 0;
-+
-+	wq->lock = DWC_SPINLOCK_ALLOC();
-+	if (!wq->lock) {
-+		DWC_ERROR("Cannot allocate memory for spinlock");
-+		goto no_lock;
-+	}
-+
-+	wq->waitq = DWC_WAITQ_ALLOC();
-+	if (!wq->waitq) {
-+		DWC_ERROR("Cannot allocate memory for waitqueue");
-+		goto no_waitq;
-+	}
-+
-+	return wq;
-+
-+ no_waitq:
-+	DWC_SPINLOCK_FREE(wq->lock);
-+ no_lock:
-+	workqueue_destroy(wq->taskq);
-+ no_taskq:
-+	DWC_FREE(wq);
-+
-+	return NULL;
-+}
-+
-+void DWC_WORKQ_FREE(dwc_workq_t *wq)
-+{
-+#ifdef DEBUG
-+	dwc_irqflags_t flags;
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+
-+	if (wq->pending != 0) {
-+		struct work_container *container = wq->container;
-+
-+		DWC_ERROR("Destroying work queue with pending work");
-+
-+		if (container && container->name) {
-+			DWC_ERROR("Work %s still pending", container->name);
-+		}
-+	}
-+
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+#endif
-+	DWC_WAITQ_FREE(wq->waitq);
-+	DWC_SPINLOCK_FREE(wq->lock);
-+	workqueue_destroy(wq->taskq);
-+	DWC_FREE(wq);
-+}
-+
-+void DWC_WORKQ_SCHEDULE(dwc_workq_t *wq, dwc_work_callback_t cb, void *data,
-+			char *format, ...)
-+{
-+	dwc_irqflags_t flags;
-+	work_container_t *container;
-+	static char name[128];
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VSNPRINTF(name, 128, format, args);
-+	va_end(args);
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+	wq->pending++;
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+	DWC_WAITQ_TRIGGER(wq->waitq);
-+
-+	container = DWC_ALLOC_ATOMIC(sizeof(*container));
-+	if (!container) {
-+		DWC_ERROR("Cannot allocate memory for container");
-+		return;
-+	}
-+
-+	container->name = DWC_STRDUP(name);
-+	if (!container->name) {
-+		DWC_ERROR("Cannot allocate memory for container->name");
-+		DWC_FREE(container);
-+		return;
-+	}
-+
-+	container->cb = cb;
-+	container->data = data;
-+	container->wq = wq;
-+	container->hz = 0;
-+	wq->container = container;
-+
-+	DWC_DEBUG("Queueing work: %s, container=%p", container->name, container);
-+	workqueue_enqueue(wq->taskq, &container->task);
-+}
-+
-+void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *wq, dwc_work_callback_t cb,
-+				void *data, uint32_t time, char *format, ...)
-+{
-+	dwc_irqflags_t flags;
-+	work_container_t *container;
-+	static char name[128];
-+	struct timeval tv;
-+	va_list args;
-+
-+	va_start(args, format);
-+	DWC_VSNPRINTF(name, 128, format, args);
-+	va_end(args);
-+
-+	DWC_SPINLOCK_IRQSAVE(wq->lock, &flags);
-+	wq->pending++;
-+	DWC_SPINUNLOCK_IRQRESTORE(wq->lock, flags);
-+	DWC_WAITQ_TRIGGER(wq->waitq);
-+
-+	container = DWC_ALLOC_ATOMIC(sizeof(*container));
-+	if (!container) {
-+		DWC_ERROR("Cannot allocate memory for container");
-+		return;
-+	}
-+
-+	container->name = DWC_STRDUP(name);
-+	if (!container->name) {
-+		DWC_ERROR("Cannot allocate memory for container->name");
-+		DWC_FREE(container);
-+		return;
-+	}
-+
-+	container->cb = cb;
-+	container->data = data;
-+	container->wq = wq;
-+	tv.tv_sec = time / 1000;
-+	tv.tv_usec = (time - tv.tv_sec * 1000) * 1000;
-+	container->hz = tvtohz(&tv);
-+	wq->container = container;
-+
-+	DWC_DEBUG("Queueing work: %s, container=%p", container->name, container);
-+	workqueue_enqueue(wq->taskq, &container->task);
-+}
-+
-+int DWC_WORKQ_PENDING(dwc_workq_t *wq)
-+{
-+	return wq->pending;
-+}
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_crypto.c
-@@ -0,0 +1,308 @@
-+/* =========================================================================
-+ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_crypto.c $
-+ * $Revision: #5 $
-+ * $Date: 2010/09/28 $
-+ * $Change: 1596182 $
-+ *
-+ * Synopsys Portability Library Software and documentation
-+ * (hereinafter, "Software") is an Unsupported proprietary work of
-+ * Synopsys, Inc. unless otherwise expressly agreed to in writing
-+ * between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for
-+ * Licensed Product with Synopsys or any supplement thereto. You are
-+ * permitted to use and redistribute this Software in source and binary
-+ * forms, with or without modification, provided that redistributions
-+ * of source code must retain this notice. You may not view, use,
-+ * disclose, copy or distribute this file or any information contained
-+ * herein except pursuant to this license grant from Synopsys. If you
-+ * do not agree with this notice, including the disclaimer below, then
-+ * you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
-+ * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================= */
-+
-+/** @file
-+ * This file contains the WUSB cryptographic routines.
-+ */
-+
-+#ifdef DWC_CRYPTOLIB
-+
-+#include "dwc_crypto.h"
-+#include "usb.h"
-+
-+#ifdef DEBUG
-+static inline void dump_bytes(char *name, uint8_t *bytes, int len)
-+{
-+	int i;
-+	DWC_PRINTF("%s: ", name);
-+	for (i=0; i<len; i++) {
-+		DWC_PRINTF("%02x ", bytes[i]);
-+	}
-+	DWC_PRINTF("\n");
-+}
-+#else
-+#define dump_bytes(x...)
-+#endif
-+
-+/* Display a block */
-+void show_block(const u8 *blk, const char *prefix, const char *suffix, int a)
-+{
-+#ifdef DWC_DEBUG_CRYPTO
-+	int i, blksize = 16;
-+
-+	DWC_DEBUG("%s", prefix);
-+
-+	if (suffix == NULL) {
-+		suffix = "\n";
-+		blksize = a;
-+	}
-+
-+	for (i = 0; i < blksize; i++)
-+		DWC_PRINT("%02x%s", *blk++, ((i & 3) == 3) ? "  " : " ");
-+	DWC_PRINT(suffix);
-+#endif
-+}
-+
-+/**
-+ * Encrypts an array of bytes using the AES encryption engine.
-+ * If <code>dst</code> == <code>src</code>, then the bytes will be encrypted
-+ * in-place.
-+ *
-+ * @return  0 on success, negative error code on error.
-+ */
-+int dwc_wusb_aes_encrypt(u8 *src, u8 *key, u8 *dst)
-+{
-+	u8 block_t[16];
-+	DWC_MEMSET(block_t, 0, 16);
-+
-+	return DWC_AES_CBC(src, 16, key, 16, block_t, dst);
-+}
-+
-+/**
-+ * The CCM-MAC-FUNCTION described in section 6.5 of the WUSB spec.
-+ * This function takes a data string and returns the encrypted CBC
-+ * Counter-mode MIC.
-+ *
-+ * @param key     The 128-bit symmetric key.
-+ * @param nonce   The CCM nonce.
-+ * @param label   The unique 14-byte ASCII text label.
-+ * @param bytes   The byte array to be encrypted.
-+ * @param len     Length of the byte array.
-+ * @param result  Byte array to receive the 8-byte encrypted MIC.
-+ */
-+void dwc_wusb_cmf(u8 *key, u8 *nonce,
-+		  char *label, u8 *bytes, int len, u8 *result)
-+{
-+	u8 block_m[16];
-+	u8 block_x[16];
-+	u8 block_t[8];
-+	int idx, blkNum;
-+	u16 la = (u16)(len + 14);
-+
-+	/* Set the AES-128 key */
-+	//dwc_aes_setkey(tfm, key, 16);
-+
-+	/* Fill block B0 from flags = 0x59, N, and l(m) = 0 */
-+	block_m[0] = 0x59;
-+	for (idx = 0; idx < 13; idx++)
-+		block_m[idx + 1] = nonce[idx];
-+	block_m[14] = 0;
-+	block_m[15] = 0;
-+
-+	/* Produce the CBC IV */
-+	dwc_wusb_aes_encrypt(block_m, key, block_x);
-+	show_block(block_m, "CBC IV in: ", "\n", 0);
-+	show_block(block_x, "CBC IV out:", "\n", 0);
-+
-+	/* Fill block B1 from l(a) = Blen + 14, and A */
-+	block_x[0] ^= (u8)(la >> 8);
-+	block_x[1] ^= (u8)la;
-+	for (idx = 0; idx < 14; idx++)
-+		block_x[idx + 2] ^= label[idx];
-+	show_block(block_x, "After xor: ", "b1\n", 16);
-+
-+	dwc_wusb_aes_encrypt(block_x, key, block_x);
-+	show_block(block_x, "After AES: ", "b1\n", 16);
-+
-+	idx = 0;
-+	blkNum = 0;
-+
-+	/* Fill remaining blocks with B */
-+	while (len-- > 0) {
-+		block_x[idx] ^= *bytes++;
-+		if (++idx >= 16) {
-+			idx = 0;
-+			show_block(block_x, "After xor: ", "\n", blkNum);
-+			dwc_wusb_aes_encrypt(block_x, key, block_x);
-+			show_block(block_x, "After AES: ", "\n", blkNum);
-+			blkNum++;
-+		}
-+	}
-+
-+	/* Handle partial last block */
-+	if (idx > 0) {
-+		show_block(block_x, "After xor: ", "\n", blkNum);
-+		dwc_wusb_aes_encrypt(block_x, key, block_x);
-+		show_block(block_x, "After AES: ", "\n", blkNum);
-+	}
-+
-+	/* Save the MIC tag */
-+	DWC_MEMCPY(block_t, block_x, 8);
-+	show_block(block_t, "MIC tag  : ", NULL, 8);
-+
-+	/* Fill block A0 from flags = 0x01, N, and counter = 0 */
-+	block_m[0] = 0x01;
-+	block_m[14] = 0;
-+	block_m[15] = 0;
-+
-+	/* Encrypt the counter */
-+	dwc_wusb_aes_encrypt(block_m, key, block_x);
-+	show_block(block_x, "CTR[MIC] : ", NULL, 8);
-+
-+	/* XOR with MIC tag */
-+	for (idx = 0; idx < 8; idx++) {
-+		block_t[idx] ^= block_x[idx];
-+	}
-+
-+	/* Return result to caller */
-+	DWC_MEMCPY(result, block_t, 8);
-+	show_block(result, "CCM-MIC  : ", NULL, 8);
-+
-+}
-+
-+/**
-+ * The PRF function described in section 6.5 of the WUSB spec. This function
-+ * concatenates MIC values returned from dwc_cmf() to create a value of
-+ * the requested length.
-+ *
-+ * @param prf_len  Length of the PRF function in bits (64, 128, or 256).
-+ * @param key, nonce, label, bytes, len  Same as for dwc_cmf().
-+ * @param result   Byte array to receive the result.
-+ */
-+void dwc_wusb_prf(int prf_len, u8 *key,
-+		  u8 *nonce, char *label, u8 *bytes, int len, u8 *result)
-+{
-+	int i;
-+
-+	nonce[0] = 0;
-+	for (i = 0; i < prf_len >> 6; i++, nonce[0]++) {
-+		dwc_wusb_cmf(key, nonce, label, bytes, len, result);
-+		result += 8;
-+	}
-+}
-+
-+/**
-+ * Fills in CCM Nonce per the WUSB spec.
-+ *
-+ * @param[in] haddr Host address.
-+ * @param[in] daddr Device address.
-+ * @param[in] tkid Session Key(PTK) identifier.
-+ * @param[out] nonce Pointer to where the CCM Nonce output is to be written.
-+ */
-+void dwc_wusb_fill_ccm_nonce(uint16_t haddr, uint16_t daddr, uint8_t *tkid,
-+			     uint8_t *nonce)
-+{
-+
-+	DWC_DEBUG("%s %x %x\n", __func__, daddr, haddr);
-+
-+	DWC_MEMSET(&nonce[0], 0, 16);
-+
-+	DWC_MEMCPY(&nonce[6], tkid, 3);
-+	nonce[9] = daddr & 0xFF;
-+	nonce[10] = (daddr >> 8) & 0xFF;
-+	nonce[11] = haddr & 0xFF;
-+	nonce[12] = (haddr >> 8) & 0xFF;
-+
-+	dump_bytes("CCM nonce", nonce, 16);
-+}
-+
-+/**
-+ * Generates a 16-byte cryptographic-grade random number for the Host/Device
-+ * Nonce.
-+ */
-+void dwc_wusb_gen_nonce(uint16_t addr, uint8_t *nonce)
-+{
-+	uint8_t inonce[16];
-+	uint32_t temp[4];
-+
-+	/* Fill in the Nonce */
-+	DWC_MEMSET(&inonce[0], 0, sizeof(inonce));
-+	inonce[9] = addr & 0xFF;
-+	inonce[10] = (addr >> 8) & 0xFF;
-+	inonce[11] = inonce[9];
-+	inonce[12] = inonce[10];
-+
-+	/* Collect "randomness samples" */
-+	DWC_RANDOM_BYTES((uint8_t *)temp, 16);
-+
-+	dwc_wusb_prf_128((uint8_t *)temp, nonce,
-+			 "Random Numbers", (uint8_t *)temp, sizeof(temp),
-+			 nonce);
-+}
-+
-+/**
-+ * Generates the Session Key (PTK) and Key Confirmation Key (KCK) per the
-+ * WUSB spec.
-+ *
-+ * @param[in] ccm_nonce Pointer to CCM Nonce.
-+ * @param[in] mk Master Key to derive the session from
-+ * @param[in] hnonce Pointer to Host Nonce.
-+ * @param[in] dnonce Pointer to Device Nonce.
-+ * @param[out] kck Pointer to where the KCK output is to be written.
-+ * @param[out] ptk Pointer to where the PTK output is to be written.
-+ */
-+void dwc_wusb_gen_key(uint8_t *ccm_nonce, uint8_t *mk, uint8_t *hnonce,
-+		      uint8_t *dnonce, uint8_t *kck, uint8_t *ptk)
-+{
-+	uint8_t idata[32];
-+	uint8_t odata[32];
-+
-+	dump_bytes("ck", mk, 16);
-+	dump_bytes("hnonce", hnonce, 16);
-+	dump_bytes("dnonce", dnonce, 16);
-+
-+	/* The data is the HNonce and DNonce concatenated */
-+	DWC_MEMCPY(&idata[0], hnonce, 16);
-+	DWC_MEMCPY(&idata[16], dnonce, 16);
-+
-+	dwc_wusb_prf_256(mk, ccm_nonce, "Pair-wise keys", idata, 32, odata);
-+
-+	/* Low 16 bytes of the result is the KCK, high 16 is the PTK */
-+	DWC_MEMCPY(kck, &odata[0], 16);
-+	DWC_MEMCPY(ptk, &odata[16], 16);
-+
-+	dump_bytes("kck", kck, 16);
-+	dump_bytes("ptk", ptk, 16);
-+}
-+
-+/**
-+ * Generates the Message Integrity Code over the Handshake data per the
-+ * WUSB spec.
-+ *
-+ * @param ccm_nonce Pointer to CCM Nonce.
-+ * @param kck   Pointer to Key Confirmation Key.
-+ * @param data  Pointer to Handshake data to be checked.
-+ * @param mic   Pointer to where the MIC output is to be written.
-+ */
-+void dwc_wusb_gen_mic(uint8_t *ccm_nonce, uint8_t *kck,
-+		      uint8_t *data, uint8_t *mic)
-+{
-+
-+	dwc_wusb_prf_64(kck, ccm_nonce, "out-of-bandMIC",
-+			data, WUSB_HANDSHAKE_LEN_FOR_MIC, mic);
-+}
-+
-+#endif	/* DWC_CRYPTOLIB */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_crypto.h
-@@ -0,0 +1,111 @@
-+/* =========================================================================
-+ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_crypto.h $
-+ * $Revision: #3 $
-+ * $Date: 2010/09/28 $
-+ * $Change: 1596182 $
-+ *
-+ * Synopsys Portability Library Software and documentation
-+ * (hereinafter, "Software") is an Unsupported proprietary work of
-+ * Synopsys, Inc. unless otherwise expressly agreed to in writing
-+ * between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for
-+ * Licensed Product with Synopsys or any supplement thereto. You are
-+ * permitted to use and redistribute this Software in source and binary
-+ * forms, with or without modification, provided that redistributions
-+ * of source code must retain this notice. You may not view, use,
-+ * disclose, copy or distribute this file or any information contained
-+ * herein except pursuant to this license grant from Synopsys. If you
-+ * do not agree with this notice, including the disclaimer below, then
-+ * you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
-+ * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================= */
-+
-+#ifndef _DWC_CRYPTO_H_
-+#define _DWC_CRYPTO_H_
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/** @file
-+ *
-+ * This file contains declarations for the WUSB Cryptographic routines as
-+ * defined in the WUSB spec.  They are only to be used internally by the DWC UWB
-+ * modules.
-+ */
-+
-+#include "dwc_os.h"
-+
-+int dwc_wusb_aes_encrypt(u8 *src, u8 *key, u8 *dst);
-+
-+void dwc_wusb_cmf(u8 *key, u8 *nonce,
-+		  char *label, u8 *bytes, int len, u8 *result);
-+void dwc_wusb_prf(int prf_len, u8 *key,
-+		  u8 *nonce, char *label, u8 *bytes, int len, u8 *result);
-+
-+/**
-+ * The PRF-64 function described in section 6.5 of the WUSB spec.
-+ *
-+ * @param key, nonce, label, bytes, len, result  Same as for dwc_prf().
-+ */
-+static inline void dwc_wusb_prf_64(u8 *key, u8 *nonce,
-+				   char *label, u8 *bytes, int len, u8 *result)
-+{
-+	dwc_wusb_prf(64, key, nonce, label, bytes, len, result);
-+}
-+
-+/**
-+ * The PRF-128 function described in section 6.5 of the WUSB spec.
-+ *
-+ * @param key, nonce, label, bytes, len, result  Same as for dwc_prf().
-+ */
-+static inline void dwc_wusb_prf_128(u8 *key, u8 *nonce,
-+				    char *label, u8 *bytes, int len, u8 *result)
-+{
-+	dwc_wusb_prf(128, key, nonce, label, bytes, len, result);
-+}
-+
-+/**
-+ * The PRF-256 function described in section 6.5 of the WUSB spec.
-+ *
-+ * @param key, nonce, label, bytes, len, result  Same as for dwc_prf().
-+ */
-+static inline void dwc_wusb_prf_256(u8 *key, u8 *nonce,
-+				    char *label, u8 *bytes, int len, u8 *result)
-+{
-+	dwc_wusb_prf(256, key, nonce, label, bytes, len, result);
-+}
-+
-+
-+void dwc_wusb_fill_ccm_nonce(uint16_t haddr, uint16_t daddr, uint8_t *tkid,
-+			       uint8_t *nonce);
-+void dwc_wusb_gen_nonce(uint16_t addr,
-+			  uint8_t *nonce);
-+
-+void dwc_wusb_gen_key(uint8_t *ccm_nonce, uint8_t *mk,
-+			uint8_t *hnonce, uint8_t *dnonce,
-+			uint8_t *kck, uint8_t *ptk);
-+
-+
-+void dwc_wusb_gen_mic(uint8_t *ccm_nonce, uint8_t
-+			*kck, uint8_t *data, uint8_t *mic);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _DWC_CRYPTO_H_ */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_dh.c
-@@ -0,0 +1,291 @@
-+/* =========================================================================
-+ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_dh.c $
-+ * $Revision: #3 $
-+ * $Date: 2010/09/28 $
-+ * $Change: 1596182 $
-+ *
-+ * Synopsys Portability Library Software and documentation
-+ * (hereinafter, "Software") is an Unsupported proprietary work of
-+ * Synopsys, Inc. unless otherwise expressly agreed to in writing
-+ * between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for
-+ * Licensed Product with Synopsys or any supplement thereto. You are
-+ * permitted to use and redistribute this Software in source and binary
-+ * forms, with or without modification, provided that redistributions
-+ * of source code must retain this notice. You may not view, use,
-+ * disclose, copy or distribute this file or any information contained
-+ * herein except pursuant to this license grant from Synopsys. If you
-+ * do not agree with this notice, including the disclaimer below, then
-+ * you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
-+ * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================= */
-+#ifdef DWC_CRYPTOLIB
-+
-+#ifndef CONFIG_MACH_IPMATE
-+
-+#include "dwc_dh.h"
-+#include "dwc_modpow.h"
-+
-+#ifdef DEBUG
-+/* This function prints out a buffer in the format described in the Association
-+ * Model specification. */
-+static void dh_dump(char *str, void *_num, int len)
-+{
-+	uint8_t *num = _num;
-+	int i;
-+	DWC_PRINTF("%s\n", str);
-+	for (i = 0; i < len; i ++) {
-+		DWC_PRINTF("%02x", num[i]);
-+		if (((i + 1) % 2) == 0) DWC_PRINTF(" ");
-+		if (((i + 1) % 26) == 0) DWC_PRINTF("\n");
-+	}
-+
-+	DWC_PRINTF("\n");
-+}
-+#else
-+#define dh_dump(_x...) do {; } while(0)
-+#endif
-+
-+/* Constant g value */
-+static __u32 dh_g[] = {
-+	0x02000000,
-+};
-+
-+/* Constant p value */
-+static __u32 dh_p[] = {
-+	0xFFFFFFFF, 0xFFFFFFFF, 0xA2DA0FC9, 0x34C26821, 0x8B62C6C4, 0xD11CDC80, 0x084E0229, 0x74CC678A,
-+	0xA6BE0B02, 0x229B133B, 0x79084A51, 0xDD04348E, 0xB31995EF, 0x1B433ACD, 0x6D0A2B30, 0x37145FF2,
-+	0x6D35E14F, 0x45C2516D, 0x76B585E4, 0xC67E5E62, 0xE9424CF4, 0x6BED37A6, 0xB65CFF0B, 0xEDB706F4,
-+	0xFB6B38EE, 0xA59F895A, 0x11249FAE, 0xE61F4B7C, 0x51662849, 0x3D5BE4EC, 0xB87C00C2, 0x05BF63A1,
-+	0x3648DA98, 0x9AD3551C, 0xA83F1669, 0x5FCF24FD, 0x235D6583, 0x96ADA3DC, 0x56F3621C, 0xBB528520,
-+	0x0729D59E, 0x6D969670, 0x4E350C67, 0x0498BC4A, 0x086C74F1, 0x7C2118CA, 0x465E9032, 0x3BCE362E,
-+	0x2C779EE3, 0x03860E18, 0xA283279B, 0x8FA207EC, 0xF05DC5B5, 0xC9524C6F, 0xF6CB2BDE, 0x18175895,
-+	0x7C499539, 0xE56A95EA, 0x1826D215, 0x1005FA98, 0x5A8E7215, 0x2DC4AA8A, 0x0D1733AD, 0x337A5004,
-+	0xAB2155A8, 0x64BA1CDF, 0x0485FBEC, 0x0AEFDB58, 0x5771EA8A, 0x7D0C065D, 0x850F97B3, 0xC7E4E1A6,
-+	0x8CAEF5AB, 0xD73309DB, 0xE0948C1E, 0x9D61254A, 0x26D2E3CE, 0x6BEED21A, 0x06FA2FF1, 0x64088AD9,
-+	0x730276D8, 0x646AC83E, 0x182B1F52, 0x0C207B17, 0x5717E1BB, 0x6C5D617A, 0xC0880977, 0xE246D9BA,
-+	0xA04FE208, 0x31ABE574, 0xFC5BDB43, 0x8E10FDE0, 0x20D1824B, 0xCAD23AA9, 0xFFFFFFFF, 0xFFFFFFFF,
-+};
-+
-+static void dh_swap_bytes(void *_in, void *_out, uint32_t len)
-+{
-+	uint8_t *in = _in;
-+	uint8_t *out = _out;
-+	int i;
-+	for (i=0; i<len; i++) {
-+		out[i] = in[len-1-i];
-+	}
-+}
-+
-+/* Computes the modular exponentiation (num^exp % mod).  num, exp, and mod are
-+ * big endian numbers of size len, in bytes.  Each len value must be a multiple
-+ * of 4. */
-+int dwc_dh_modpow(void *mem_ctx, void *num, uint32_t num_len,
-+		  void *exp, uint32_t exp_len,
-+		  void *mod, uint32_t mod_len,
-+		  void *out)
-+{
-+	/* modpow() takes little endian numbers.  AM uses big-endian.  This
-+	 * function swaps bytes of numbers before passing onto modpow. */
-+
-+	int retval = 0;
-+	uint32_t *result;
-+
-+	uint32_t *bignum_num = dwc_alloc(mem_ctx, num_len + 4);
-+	uint32_t *bignum_exp = dwc_alloc(mem_ctx, exp_len + 4);
-+	uint32_t *bignum_mod = dwc_alloc(mem_ctx, mod_len + 4);
-+
-+	dh_swap_bytes(num, &bignum_num[1], num_len);
-+	bignum_num[0] = num_len / 4;
-+
-+	dh_swap_bytes(exp, &bignum_exp[1], exp_len);
-+	bignum_exp[0] = exp_len / 4;
-+
-+	dh_swap_bytes(mod, &bignum_mod[1], mod_len);
-+	bignum_mod[0] = mod_len / 4;
-+
-+	result = dwc_modpow(mem_ctx, bignum_num, bignum_exp, bignum_mod);
-+	if (!result) {
-+		retval = -1;
-+		goto dh_modpow_nomem;
-+	}
-+
-+	dh_swap_bytes(&result[1], out, result[0] * 4);
-+	dwc_free(mem_ctx, result);
-+
-+ dh_modpow_nomem:
-+	dwc_free(mem_ctx, bignum_num);
-+	dwc_free(mem_ctx, bignum_exp);
-+	dwc_free(mem_ctx, bignum_mod);
-+	return retval;
-+}
-+
-+
-+int dwc_dh_pk(void *mem_ctx, uint8_t nd, uint8_t *exp, uint8_t *pk, uint8_t *hash)
-+{
-+	int retval;
-+	uint8_t m3[385];
-+
-+#ifndef DH_TEST_VECTORS
-+	DWC_RANDOM_BYTES(exp, 32);
-+#endif
-+
-+	/* Compute the pkd */
-+	if ((retval = dwc_dh_modpow(mem_ctx, dh_g, 4,
-+				    exp, 32,
-+				    dh_p, 384, pk))) {
-+		return retval;
-+	}
-+
-+	m3[384] = nd;
-+	DWC_MEMCPY(&m3[0], pk, 384);
-+	DWC_SHA256(m3, 385, hash);
-+
-+	dh_dump("PK", pk, 384);
-+	dh_dump("SHA-256(M3)", hash, 32);
-+	return 0;
-+}
-+
-+int dwc_dh_derive_keys(void *mem_ctx, uint8_t nd, uint8_t *pkh, uint8_t *pkd,
-+		       uint8_t *exp, int is_host,
-+		       char *dd, uint8_t *ck, uint8_t *kdk)
-+{
-+	int retval;
-+	uint8_t mv[784];
-+	uint8_t sha_result[32];
-+	uint8_t dhkey[384];
-+	uint8_t shared_secret[384];
-+	char *message;
-+	uint32_t vd;
-+
-+	uint8_t *pk;
-+
-+	if (is_host) {
-+		pk = pkd;
-+	}
-+	else {
-+		pk = pkh;
-+	}
-+
-+	if ((retval = dwc_dh_modpow(mem_ctx, pk, 384,
-+				    exp, 32,
-+				    dh_p, 384, shared_secret))) {
-+		return retval;
-+	}
-+	dh_dump("Shared Secret", shared_secret, 384);
-+
-+	DWC_SHA256(shared_secret, 384, dhkey);
-+	dh_dump("DHKEY", dhkey, 384);
-+
-+	DWC_MEMCPY(&mv[0], pkd, 384);
-+	DWC_MEMCPY(&mv[384], pkh, 384);
-+	DWC_MEMCPY(&mv[768], "displayed digest", 16);
-+	dh_dump("MV", mv, 784);
-+
-+	DWC_SHA256(mv, 784, sha_result);
-+	dh_dump("SHA-256(MV)", sha_result, 32);
-+	dh_dump("First 32-bits of SHA-256(MV)", sha_result, 4);
-+
-+	dh_swap_bytes(sha_result, &vd, 4);
-+#ifdef DEBUG
-+	DWC_PRINTF("Vd (decimal) = %d\n", vd);
-+#endif
-+
-+	switch (nd) {
-+	case 2:
-+		vd = vd % 100;
-+		DWC_SPRINTF(dd, "%02d", vd);
-+		break;
-+	case 3:
-+		vd = vd % 1000;
-+		DWC_SPRINTF(dd, "%03d", vd);
-+		break;
-+	case 4:
-+		vd = vd % 10000;
-+		DWC_SPRINTF(dd, "%04d", vd);
-+		break;
-+	}
-+#ifdef DEBUG
-+	DWC_PRINTF("Display Digits: %s\n", dd);
-+#endif
-+
-+	message = "connection key";
-+	DWC_HMAC_SHA256(message, DWC_STRLEN(message), dhkey, 32, sha_result);
-+	dh_dump("HMAC(SHA-256, DHKey, connection key)", sha_result, 32);
-+	DWC_MEMCPY(ck, sha_result, 16);
-+
-+	message = "key derivation key";
-+	DWC_HMAC_SHA256(message, DWC_STRLEN(message), dhkey, 32, sha_result);
-+	dh_dump("HMAC(SHA-256, DHKey, key derivation key)", sha_result, 32);
-+	DWC_MEMCPY(kdk, sha_result, 32);
-+
-+	return 0;
-+}
-+
-+
-+#ifdef DH_TEST_VECTORS
-+
-+static __u8 dh_a[] = {
-+	0x44, 0x00, 0x51, 0xd6,
-+	0xf0, 0xb5, 0x5e, 0xa9,
-+	0x67, 0xab, 0x31, 0xc6,
-+	0x8a, 0x8b, 0x5e, 0x37,
-+	0xd9, 0x10, 0xda, 0xe0,
-+	0xe2, 0xd4, 0x59, 0xa4,
-+	0x86, 0x45, 0x9c, 0xaa,
-+	0xdf, 0x36, 0x75, 0x16,
-+};
-+
-+static __u8 dh_b[] = {
-+	0x5d, 0xae, 0xc7, 0x86,
-+	0x79, 0x80, 0xa3, 0x24,
-+	0x8c, 0xe3, 0x57, 0x8f,
-+	0xc7, 0x5f, 0x1b, 0x0f,
-+	0x2d, 0xf8, 0x9d, 0x30,
-+	0x6f, 0xa4, 0x52, 0xcd,
-+	0xe0, 0x7a, 0x04, 0x8a,
-+	0xde, 0xd9, 0x26, 0x56,
-+};
-+
-+void dwc_run_dh_test_vectors(void *mem_ctx)
-+{
-+	uint8_t pkd[384];
-+	uint8_t pkh[384];
-+	uint8_t hashd[32];
-+	uint8_t hashh[32];
-+	uint8_t ck[16];
-+	uint8_t kdk[32];
-+	char dd[5];
-+
-+	DWC_PRINTF("\n\n\nDH_TEST_VECTORS\n\n");
-+
-+	/* compute the PKd and SHA-256(PKd || Nd) */
-+	DWC_PRINTF("Computing PKd\n");
-+	dwc_dh_pk(mem_ctx, 2, dh_a, pkd, hashd);
-+
-+	/* compute the PKd and SHA-256(PKh || Nd) */
-+	DWC_PRINTF("Computing PKh\n");
-+	dwc_dh_pk(mem_ctx, 2, dh_b, pkh, hashh);
-+
-+	/* compute the dhkey */
-+	dwc_dh_derive_keys(mem_ctx, 2, pkh, pkd, dh_a, 0, dd, ck, kdk);
-+}
-+#endif /* DH_TEST_VECTORS */
-+
-+#endif /* !CONFIG_MACH_IPMATE */
-+
-+#endif /* DWC_CRYPTOLIB */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_dh.h
-@@ -0,0 +1,106 @@
-+/* =========================================================================
-+ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_dh.h $
-+ * $Revision: #4 $
-+ * $Date: 2010/09/28 $
-+ * $Change: 1596182 $
-+ *
-+ * Synopsys Portability Library Software and documentation
-+ * (hereinafter, "Software") is an Unsupported proprietary work of
-+ * Synopsys, Inc. unless otherwise expressly agreed to in writing
-+ * between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for
-+ * Licensed Product with Synopsys or any supplement thereto. You are
-+ * permitted to use and redistribute this Software in source and binary
-+ * forms, with or without modification, provided that redistributions
-+ * of source code must retain this notice. You may not view, use,
-+ * disclose, copy or distribute this file or any information contained
-+ * herein except pursuant to this license grant from Synopsys. If you
-+ * do not agree with this notice, including the disclaimer below, then
-+ * you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
-+ * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================= */
-+#ifndef _DWC_DH_H_
-+#define _DWC_DH_H_
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#include "dwc_os.h"
-+
-+/** @file
-+ *
-+ * This file defines the common functions on device and host for performing
-+ * numeric association as defined in the WUSB spec.  They are only to be
-+ * used internally by the DWC UWB modules. */
-+
-+extern int dwc_dh_sha256(uint8_t *message, uint32_t len, uint8_t *out);
-+extern int dwc_dh_hmac_sha256(uint8_t *message, uint32_t messagelen,
-+			      uint8_t *key, uint32_t keylen,
-+			      uint8_t *out);
-+extern int dwc_dh_modpow(void *mem_ctx, void *num, uint32_t num_len,
-+			 void *exp, uint32_t exp_len,
-+			 void *mod, uint32_t mod_len,
-+			 void *out);
-+
-+/** Computes PKD or PKH, and SHA-256(PKd || Nd)
-+ *
-+ * PK = g^exp mod p.
-+ *
-+ * Input:
-+ * Nd = Number of digits on the device.
-+ *
-+ * Output:
-+ * exp = A 32-byte buffer to be filled with a randomly generated number.
-+ *       used as either A or B.
-+ * pk = A 384-byte buffer to be filled with the PKH or PKD.
-+ * hash = A 32-byte buffer to be filled with SHA-256(PK || ND).
-+ */
-+extern int dwc_dh_pk(void *mem_ctx, uint8_t nd, uint8_t *exp, uint8_t *pkd, uint8_t *hash);
-+
-+/** Computes the DHKEY, and VD.
-+ *
-+ * If called from host, then it will comput DHKEY=PKD^exp % p.
-+ * If called from device, then it will comput DHKEY=PKH^exp % p.
-+ *
-+ * Input:
-+ * pkd = The PKD value.
-+ * pkh = The PKH value.
-+ * exp = The A value (if device) or B value (if host) generated in dwc_wudev_dh_pk.
-+ * is_host = Set to non zero if a WUSB host is calling this function.
-+ *
-+ * Output:
-+
-+ * dd = A pointer to an buffer to be set to the displayed digits string to be shown
-+ *      to the user.  This buffer should be at 5 bytes long to hold 4 digits plus a
-+ *      null termination character.  This buffer can be used directly for display.
-+ * ck = A 16-byte buffer to be filled with the CK.
-+ * kdk = A 32-byte buffer to be filled with the KDK.
-+ */
-+extern int dwc_dh_derive_keys(void *mem_ctx, uint8_t nd, uint8_t *pkh, uint8_t *pkd,
-+			      uint8_t *exp, int is_host,
-+			      char *dd, uint8_t *ck, uint8_t *kdk);
-+
-+#ifdef DH_TEST_VECTORS
-+extern void dwc_run_dh_test_vectors(void);
-+#endif
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _DWC_DH_H_ */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_list.h
-@@ -0,0 +1,594 @@
-+/*	$OpenBSD: queue.h,v 1.26 2004/05/04 16:59:32 grange Exp $	*/
-+/*	$NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $	*/
-+
-+/*
-+ * Copyright (c) 1991, 1993
-+ *	The Regents of the University of California.  All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the University nor the names of its contributors
-+ *    may be used to endorse or promote products derived from this software
-+ *    without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ *	@(#)queue.h	8.5 (Berkeley) 8/20/94
-+ */
-+
-+#ifndef _DWC_LIST_H_
-+#define _DWC_LIST_H_
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/** @file
-+ *
-+ * This file defines linked list operations.  It is derived from BSD with
-+ * only the MACRO names being prefixed with DWC_.  This is because a few of
-+ * these names conflict with those on Linux.  For documentation on use, see the
-+ * inline comments in the source code.  The original license for this source
-+ * code applies and is preserved in the dwc_list.h source file.
-+ */
-+
-+/*
-+ * This file defines five types of data structures: singly-linked lists,
-+ * lists, simple queues, tail queues, and circular queues.
-+ *
-+ *
-+ * A singly-linked list is headed by a single forward pointer. The elements
-+ * are singly linked for minimum space and pointer manipulation overhead at
-+ * the expense of O(n) removal for arbitrary elements. New elements can be
-+ * added to the list after an existing element or at the head of the list.
-+ * Elements being removed from the head of the list should use the explicit
-+ * macro for this purpose for optimum efficiency. A singly-linked list may
-+ * only be traversed in the forward direction.  Singly-linked lists are ideal
-+ * for applications with large datasets and few or no removals or for
-+ * implementing a LIFO queue.
-+ *
-+ * A list is headed by a single forward pointer (or an array of forward
-+ * pointers for a hash table header). The elements are doubly linked
-+ * so that an arbitrary element can be removed without a need to
-+ * traverse the list. New elements can be added to the list before
-+ * or after an existing element or at the head of the list. A list
-+ * may only be traversed in the forward direction.
-+ *
-+ * A simple queue is headed by a pair of pointers, one the head of the
-+ * list and the other to the tail of the list. The elements are singly
-+ * linked to save space, so elements can only be removed from the
-+ * head of the list. New elements can be added to the list before or after
-+ * an existing element, at the head of the list, or at the end of the
-+ * list. A simple queue may only be traversed in the forward direction.
-+ *
-+ * A tail queue is headed by a pair of pointers, one to the head of the
-+ * list and the other to the tail of the list. The elements are doubly
-+ * linked so that an arbitrary element can be removed without a need to
-+ * traverse the list. New elements can be added to the list before or
-+ * after an existing element, at the head of the list, or at the end of
-+ * the list. A tail queue may be traversed in either direction.
-+ *
-+ * A circle queue is headed by a pair of pointers, one to the head of the
-+ * list and the other to the tail of the list. The elements are doubly
-+ * linked so that an arbitrary element can be removed without a need to
-+ * traverse the list. New elements can be added to the list before or after
-+ * an existing element, at the head of the list, or at the end of the list.
-+ * A circle queue may be traversed in either direction, but has a more
-+ * complex end of list detection.
-+ *
-+ * For details on the use of these macros, see the queue(3) manual page.
-+ */
-+
-+/*
-+ * Double-linked List.
-+ */
-+
-+typedef struct dwc_list_link {
-+	struct dwc_list_link *next;
-+	struct dwc_list_link *prev;
-+} dwc_list_link_t;
-+
-+#define DWC_LIST_INIT(link) do {	\
-+	(link)->next = (link);		\
-+	(link)->prev = (link);		\
-+} while (0)
-+
-+#define DWC_LIST_FIRST(link)	((link)->next)
-+#define DWC_LIST_LAST(link)	((link)->prev)
-+#define DWC_LIST_END(link)	(link)
-+#define DWC_LIST_NEXT(link)	((link)->next)
-+#define DWC_LIST_PREV(link)	((link)->prev)
-+#define DWC_LIST_EMPTY(link)	\
-+	(DWC_LIST_FIRST(link) == DWC_LIST_END(link))
-+#define DWC_LIST_ENTRY(link, type, field)			\
-+	(type *)((uint8_t *)(link) - (size_t)(&((type *)0)->field))
-+
-+#if 0
-+#define DWC_LIST_INSERT_HEAD(list, link) do {			\
-+	(link)->next = (list)->next;				\
-+	(link)->prev = (list);					\
-+	(list)->next->prev = (link);				\
-+	(list)->next = (link);					\
-+} while (0)
-+
-+#define DWC_LIST_INSERT_TAIL(list, link) do {			\
-+	(link)->next = (list);					\
-+	(link)->prev = (list)->prev;				\
-+	(list)->prev->next = (link);				\
-+	(list)->prev = (link);					\
-+} while (0)
-+#else
-+#define DWC_LIST_INSERT_HEAD(list, link) do {			\
-+	dwc_list_link_t *__next__ = (list)->next;		\
-+	__next__->prev = (link);				\
-+	(link)->next = __next__;				\
-+	(link)->prev = (list);					\
-+	(list)->next = (link);					\
-+} while (0)
-+
-+#define DWC_LIST_INSERT_TAIL(list, link) do {			\
-+	dwc_list_link_t *__prev__ = (list)->prev;		\
-+	(list)->prev = (link);					\
-+	(link)->next = (list);					\
-+	(link)->prev = __prev__;				\
-+	__prev__->next = (link);				\
-+} while (0)
-+#endif
-+
-+#if 0
-+static inline void __list_add(struct list_head *new,
-+                              struct list_head *prev,
-+                              struct list_head *next)
-+{
-+        next->prev = new;
-+        new->next = next;
-+        new->prev = prev;
-+        prev->next = new;
-+}
-+
-+static inline void list_add(struct list_head *new, struct list_head *head)
-+{
-+        __list_add(new, head, head->next);
-+}
-+
-+static inline void list_add_tail(struct list_head *new, struct list_head *head)
-+{
-+        __list_add(new, head->prev, head);
-+}
-+
-+static inline void __list_del(struct list_head * prev, struct list_head * next)
-+{
-+        next->prev = prev;
-+        prev->next = next;
-+}
-+
-+static inline void list_del(struct list_head *entry)
-+{
-+        __list_del(entry->prev, entry->next);
-+        entry->next = LIST_POISON1;
-+        entry->prev = LIST_POISON2;
-+}
-+#endif
-+
-+#define DWC_LIST_REMOVE(link) do {				\
-+	(link)->next->prev = (link)->prev;			\
-+	(link)->prev->next = (link)->next;			\
-+} while (0)
-+
-+#define DWC_LIST_REMOVE_INIT(link) do {				\
-+	DWC_LIST_REMOVE(link);					\
-+	DWC_LIST_INIT(link);					\
-+} while (0)
-+
-+#define DWC_LIST_MOVE_HEAD(list, link) do {			\
-+	DWC_LIST_REMOVE(link);					\
-+	DWC_LIST_INSERT_HEAD(list, link);			\
-+} while (0)
-+
-+#define DWC_LIST_MOVE_TAIL(list, link) do {			\
-+	DWC_LIST_REMOVE(link);					\
-+	DWC_LIST_INSERT_TAIL(list, link);			\
-+} while (0)
-+
-+#define DWC_LIST_FOREACH(var, list)				\
-+	for((var) = DWC_LIST_FIRST(list);			\
-+	    (var) != DWC_LIST_END(list);			\
-+	    (var) = DWC_LIST_NEXT(var))
-+
-+#define DWC_LIST_FOREACH_SAFE(var, var2, list)			\
-+	for((var) = DWC_LIST_FIRST(list), (var2) = DWC_LIST_NEXT(var);	\
-+	    (var) != DWC_LIST_END(list);			\
-+	    (var) = (var2), (var2) = DWC_LIST_NEXT(var2))
-+
-+#define DWC_LIST_FOREACH_REVERSE(var, list)			\
-+	for((var) = DWC_LIST_LAST(list);			\
-+	    (var) != DWC_LIST_END(list);			\
-+	    (var) = DWC_LIST_PREV(var))
-+
-+/*
-+ * Singly-linked List definitions.
-+ */
-+#define DWC_SLIST_HEAD(name, type)					\
-+struct name {								\
-+	struct type *slh_first;	/* first element */			\
-+}
-+
-+#define DWC_SLIST_HEAD_INITIALIZER(head)				\
-+	{ NULL }
-+
-+#define DWC_SLIST_ENTRY(type)						\
-+struct {								\
-+	struct type *sle_next;	/* next element */			\
-+}
-+
-+/*
-+ * Singly-linked List access methods.
-+ */
-+#define DWC_SLIST_FIRST(head)	((head)->slh_first)
-+#define DWC_SLIST_END(head)		NULL
-+#define DWC_SLIST_EMPTY(head)	(SLIST_FIRST(head) == SLIST_END(head))
-+#define DWC_SLIST_NEXT(elm, field)	((elm)->field.sle_next)
-+
-+#define DWC_SLIST_FOREACH(var, head, field)				\
-+	for((var) = SLIST_FIRST(head);					\
-+	    (var) != SLIST_END(head);					\
-+	    (var) = SLIST_NEXT(var, field))
-+
-+#define DWC_SLIST_FOREACH_PREVPTR(var, varp, head, field)		\
-+	for((varp) = &SLIST_FIRST((head));				\
-+	    ((var) = *(varp)) != SLIST_END(head);			\
-+	    (varp) = &SLIST_NEXT((var), field))
-+
-+/*
-+ * Singly-linked List functions.
-+ */
-+#define DWC_SLIST_INIT(head) {						\
-+	SLIST_FIRST(head) = SLIST_END(head);				\
-+}
-+
-+#define DWC_SLIST_INSERT_AFTER(slistelm, elm, field) do {		\
-+	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
-+	(slistelm)->field.sle_next = (elm);				\
-+} while (0)
-+
-+#define DWC_SLIST_INSERT_HEAD(head, elm, field) do {			\
-+	(elm)->field.sle_next = (head)->slh_first;			\
-+	(head)->slh_first = (elm);					\
-+} while (0)
-+
-+#define DWC_SLIST_REMOVE_NEXT(head, elm, field) do {			\
-+	(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;	\
-+} while (0)
-+
-+#define DWC_SLIST_REMOVE_HEAD(head, field) do {				\
-+	(head)->slh_first = (head)->slh_first->field.sle_next;		\
-+} while (0)
-+
-+#define DWC_SLIST_REMOVE(head, elm, type, field) do {			\
-+	if ((head)->slh_first == (elm)) {				\
-+		SLIST_REMOVE_HEAD((head), field);			\
-+	}								\
-+	else {								\
-+		struct type *curelm = (head)->slh_first;		\
-+		while( curelm->field.sle_next != (elm) )		\
-+			curelm = curelm->field.sle_next;		\
-+		curelm->field.sle_next =				\
-+		    curelm->field.sle_next->field.sle_next;		\
-+	}								\
-+} while (0)
-+
-+/*
-+ * Simple queue definitions.
-+ */
-+#define DWC_SIMPLEQ_HEAD(name, type)					\
-+struct name {								\
-+	struct type *sqh_first;	/* first element */			\
-+	struct type **sqh_last;	/* addr of last next element */		\
-+}
-+
-+#define DWC_SIMPLEQ_HEAD_INITIALIZER(head)				\
-+	{ NULL, &(head).sqh_first }
-+
-+#define DWC_SIMPLEQ_ENTRY(type)						\
-+struct {								\
-+	struct type *sqe_next;	/* next element */			\
-+}
-+
-+/*
-+ * Simple queue access methods.
-+ */
-+#define DWC_SIMPLEQ_FIRST(head)	    ((head)->sqh_first)
-+#define DWC_SIMPLEQ_END(head)	    NULL
-+#define DWC_SIMPLEQ_EMPTY(head)	    (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
-+#define DWC_SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
-+
-+#define DWC_SIMPLEQ_FOREACH(var, head, field)				\
-+	for((var) = SIMPLEQ_FIRST(head);				\
-+	    (var) != SIMPLEQ_END(head);					\
-+	    (var) = SIMPLEQ_NEXT(var, field))
-+
-+/*
-+ * Simple queue functions.
-+ */
-+#define DWC_SIMPLEQ_INIT(head) do {					\
-+	(head)->sqh_first = NULL;					\
-+	(head)->sqh_last = &(head)->sqh_first;				\
-+} while (0)
-+
-+#define DWC_SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
-+	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
-+		(head)->sqh_last = &(elm)->field.sqe_next;		\
-+	(head)->sqh_first = (elm);					\
-+} while (0)
-+
-+#define DWC_SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
-+	(elm)->field.sqe_next = NULL;					\
-+	*(head)->sqh_last = (elm);					\
-+	(head)->sqh_last = &(elm)->field.sqe_next;			\
-+} while (0)
-+
-+#define DWC_SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {	\
-+	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
-+		(head)->sqh_last = &(elm)->field.sqe_next;		\
-+	(listelm)->field.sqe_next = (elm);				\
-+} while (0)
-+
-+#define DWC_SIMPLEQ_REMOVE_HEAD(head, field) do {			\
-+	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
-+		(head)->sqh_last = &(head)->sqh_first;			\
-+} while (0)
-+
-+/*
-+ * Tail queue definitions.
-+ */
-+#define DWC_TAILQ_HEAD(name, type)					\
-+struct name {								\
-+	struct type *tqh_first;	/* first element */			\
-+	struct type **tqh_last;	/* addr of last next element */		\
-+}
-+
-+#define DWC_TAILQ_HEAD_INITIALIZER(head)				\
-+	{ NULL, &(head).tqh_first }
-+
-+#define DWC_TAILQ_ENTRY(type)						\
-+struct {								\
-+	struct type *tqe_next;	/* next element */			\
-+	struct type **tqe_prev;	/* address of previous next element */	\
-+}
-+
-+/*
-+ * tail queue access methods
-+ */
-+#define DWC_TAILQ_FIRST(head)		((head)->tqh_first)
-+#define DWC_TAILQ_END(head)		NULL
-+#define DWC_TAILQ_NEXT(elm, field)	((elm)->field.tqe_next)
-+#define DWC_TAILQ_LAST(head, headname)					\
-+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
-+/* XXX */
-+#define DWC_TAILQ_PREV(elm, headname, field)				\
-+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-+#define DWC_TAILQ_EMPTY(head)						\
-+	(DWC_TAILQ_FIRST(head) == DWC_TAILQ_END(head))
-+
-+#define DWC_TAILQ_FOREACH(var, head, field)				\
-+	for ((var) = DWC_TAILQ_FIRST(head);				\
-+	    (var) != DWC_TAILQ_END(head);				\
-+	    (var) = DWC_TAILQ_NEXT(var, field))
-+
-+#define DWC_TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
-+	for ((var) = DWC_TAILQ_LAST(head, headname);			\
-+	    (var) != DWC_TAILQ_END(head);				\
-+	    (var) = DWC_TAILQ_PREV(var, headname, field))
-+
-+/*
-+ * Tail queue functions.
-+ */
-+#define DWC_TAILQ_INIT(head) do {					\
-+	(head)->tqh_first = NULL;					\
-+	(head)->tqh_last = &(head)->tqh_first;				\
-+} while (0)
-+
-+#define DWC_TAILQ_INSERT_HEAD(head, elm, field) do {			\
-+	if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)	\
-+		(head)->tqh_first->field.tqe_prev =			\
-+		    &(elm)->field.tqe_next;				\
-+	else								\
-+		(head)->tqh_last = &(elm)->field.tqe_next;		\
-+	(head)->tqh_first = (elm);					\
-+	(elm)->field.tqe_prev = &(head)->tqh_first;			\
-+} while (0)
-+
-+#define DWC_TAILQ_INSERT_TAIL(head, elm, field) do {			\
-+	(elm)->field.tqe_next = NULL;					\
-+	(elm)->field.tqe_prev = (head)->tqh_last;			\
-+	*(head)->tqh_last = (elm);					\
-+	(head)->tqh_last = &(elm)->field.tqe_next;			\
-+} while (0)
-+
-+#define DWC_TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
-+	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
-+		(elm)->field.tqe_next->field.tqe_prev =			\
-+		    &(elm)->field.tqe_next;				\
-+	else								\
-+		(head)->tqh_last = &(elm)->field.tqe_next;		\
-+	(listelm)->field.tqe_next = (elm);				\
-+	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
-+} while (0)
-+
-+#define DWC_TAILQ_INSERT_BEFORE(listelm, elm, field) do {		\
-+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
-+	(elm)->field.tqe_next = (listelm);				\
-+	*(listelm)->field.tqe_prev = (elm);				\
-+	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
-+} while (0)
-+
-+#define DWC_TAILQ_REMOVE(head, elm, field) do {				\
-+	if (((elm)->field.tqe_next) != NULL)				\
-+		(elm)->field.tqe_next->field.tqe_prev =			\
-+		    (elm)->field.tqe_prev;				\
-+	else								\
-+		(head)->tqh_last = (elm)->field.tqe_prev;		\
-+	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
-+} while (0)
-+
-+#define DWC_TAILQ_REPLACE(head, elm, elm2, field) do {			\
-+	if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL)	\
-+		(elm2)->field.tqe_next->field.tqe_prev =		\
-+		    &(elm2)->field.tqe_next;				\
-+	else								\
-+		(head)->tqh_last = &(elm2)->field.tqe_next;		\
-+	(elm2)->field.tqe_prev = (elm)->field.tqe_prev;			\
-+	*(elm2)->field.tqe_prev = (elm2);				\
-+} while (0)
-+
-+/*
-+ * Circular queue definitions.
-+ */
-+#define DWC_CIRCLEQ_HEAD(name, type)					\
-+struct name {								\
-+	struct type *cqh_first;		/* first element */		\
-+	struct type *cqh_last;		/* last element */		\
-+}
-+
-+#define DWC_CIRCLEQ_HEAD_INITIALIZER(head)				\
-+	{ DWC_CIRCLEQ_END(&head), DWC_CIRCLEQ_END(&head) }
-+
-+#define DWC_CIRCLEQ_ENTRY(type)						\
-+struct {								\
-+	struct type *cqe_next;		/* next element */		\
-+	struct type *cqe_prev;		/* previous element */		\
-+}
-+
-+/*
-+ * Circular queue access methods
-+ */
-+#define DWC_CIRCLEQ_FIRST(head)		((head)->cqh_first)
-+#define DWC_CIRCLEQ_LAST(head)		((head)->cqh_last)
-+#define DWC_CIRCLEQ_END(head)		((void *)(head))
-+#define DWC_CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
-+#define DWC_CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
-+#define DWC_CIRCLEQ_EMPTY(head)						\
-+	(DWC_CIRCLEQ_FIRST(head) == DWC_CIRCLEQ_END(head))
-+
-+#define DWC_CIRCLEQ_EMPTY_ENTRY(elm, field) (((elm)->field.cqe_next == NULL) && ((elm)->field.cqe_prev == NULL))
-+
-+#define DWC_CIRCLEQ_FOREACH(var, head, field)				\
-+	for((var) = DWC_CIRCLEQ_FIRST(head);				\
-+	    (var) != DWC_CIRCLEQ_END(head);				\
-+	    (var) = DWC_CIRCLEQ_NEXT(var, field))
-+
-+#define DWC_CIRCLEQ_FOREACH_SAFE(var, var2, head, field)			\
-+	for((var) = DWC_CIRCLEQ_FIRST(head), var2 = DWC_CIRCLEQ_NEXT(var, field); \
-+	    (var) != DWC_CIRCLEQ_END(head);					\
-+	    (var) = var2, var2 = DWC_CIRCLEQ_NEXT(var, field))
-+
-+#define DWC_CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
-+	for((var) = DWC_CIRCLEQ_LAST(head);				\
-+	    (var) != DWC_CIRCLEQ_END(head);				\
-+	    (var) = DWC_CIRCLEQ_PREV(var, field))
-+
-+/*
-+ * Circular queue functions.
-+ */
-+#define DWC_CIRCLEQ_INIT(head) do {					\
-+	(head)->cqh_first = DWC_CIRCLEQ_END(head);			\
-+	(head)->cqh_last = DWC_CIRCLEQ_END(head);			\
-+} while (0)
-+
-+#define DWC_CIRCLEQ_INIT_ENTRY(elm, field) do {				\
-+	(elm)->field.cqe_next = NULL;					\
-+	(elm)->field.cqe_prev = NULL;					\
-+} while (0)
-+
-+#define DWC_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {	\
-+	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
-+	(elm)->field.cqe_prev = (listelm);				\
-+	if ((listelm)->field.cqe_next == DWC_CIRCLEQ_END(head))		\
-+		(head)->cqh_last = (elm);				\
-+	else								\
-+		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
-+	(listelm)->field.cqe_next = (elm);				\
-+} while (0)
-+
-+#define DWC_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {	\
-+	(elm)->field.cqe_next = (listelm);				\
-+	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
-+	if ((listelm)->field.cqe_prev == DWC_CIRCLEQ_END(head))		\
-+		(head)->cqh_first = (elm);				\
-+	else								\
-+		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
-+	(listelm)->field.cqe_prev = (elm);				\
-+} while (0)
-+
-+#define DWC_CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
-+	(elm)->field.cqe_next = (head)->cqh_first;			\
-+	(elm)->field.cqe_prev = DWC_CIRCLEQ_END(head);			\
-+	if ((head)->cqh_last == DWC_CIRCLEQ_END(head))			\
-+		(head)->cqh_last = (elm);				\
-+	else								\
-+		(head)->cqh_first->field.cqe_prev = (elm);		\
-+	(head)->cqh_first = (elm);					\
-+} while (0)
-+
-+#define DWC_CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
-+	(elm)->field.cqe_next = DWC_CIRCLEQ_END(head);			\
-+	(elm)->field.cqe_prev = (head)->cqh_last;			\
-+	if ((head)->cqh_first == DWC_CIRCLEQ_END(head))			\
-+		(head)->cqh_first = (elm);				\
-+	else								\
-+		(head)->cqh_last->field.cqe_next = (elm);		\
-+	(head)->cqh_last = (elm);					\
-+} while (0)
-+
-+#define DWC_CIRCLEQ_REMOVE(head, elm, field) do {			\
-+	if ((elm)->field.cqe_next == DWC_CIRCLEQ_END(head))		\
-+		(head)->cqh_last = (elm)->field.cqe_prev;		\
-+	else								\
-+		(elm)->field.cqe_next->field.cqe_prev =			\
-+		    (elm)->field.cqe_prev;				\
-+	if ((elm)->field.cqe_prev == DWC_CIRCLEQ_END(head))		\
-+		(head)->cqh_first = (elm)->field.cqe_next;		\
-+	else								\
-+		(elm)->field.cqe_prev->field.cqe_next =			\
-+		    (elm)->field.cqe_next;				\
-+} while (0)
-+
-+#define DWC_CIRCLEQ_REMOVE_INIT(head, elm, field) do {			\
-+	DWC_CIRCLEQ_REMOVE(head, elm, field);				\
-+	DWC_CIRCLEQ_INIT_ENTRY(elm, field);				\
-+} while (0)
-+
-+#define DWC_CIRCLEQ_REPLACE(head, elm, elm2, field) do {		\
-+	if (((elm2)->field.cqe_next = (elm)->field.cqe_next) ==		\
-+	    DWC_CIRCLEQ_END(head))					\
-+		(head).cqh_last = (elm2);				\
-+	else								\
-+		(elm2)->field.cqe_next->field.cqe_prev = (elm2);	\
-+	if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) ==		\
-+	    DWC_CIRCLEQ_END(head))					\
-+		(head).cqh_first = (elm2);				\
-+	else								\
-+		(elm2)->field.cqe_prev->field.cqe_next = (elm2);	\
-+} while (0)
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _DWC_LIST_H_ */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_mem.c
-@@ -0,0 +1,245 @@
-+/* Memory Debugging */
-+#ifdef DWC_DEBUG_MEMORY
-+
-+#include "dwc_os.h"
-+#include "dwc_list.h"
-+
-+struct allocation {
-+	void *addr;
-+	void *ctx;
-+	char *func;
-+	int line;
-+	uint32_t size;
-+	int dma;
-+	DWC_CIRCLEQ_ENTRY(allocation) entry;
-+};
-+
-+DWC_CIRCLEQ_HEAD(allocation_queue, allocation);
-+
-+struct allocation_manager {
-+	void *mem_ctx;
-+	struct allocation_queue allocations;
-+
-+	/* statistics */
-+	int num;
-+	int num_freed;
-+	int num_active;
-+	uint32_t total;
-+	uint32_t cur;
-+	uint32_t max;
-+};
-+
-+static struct allocation_manager *manager = NULL;
-+
-+static int add_allocation(void *ctx, uint32_t size, char const *func, int line, void *addr,
-+			  int dma)
-+{
-+	struct allocation *a;
-+
-+	DWC_ASSERT(manager != NULL, "manager not allocated");
-+
-+	a = __DWC_ALLOC_ATOMIC(manager->mem_ctx, sizeof(*a));
-+	if (!a) {
-+		return -DWC_E_NO_MEMORY;
-+	}
-+
-+	a->func = __DWC_ALLOC_ATOMIC(manager->mem_ctx, DWC_STRLEN(func) + 1);
-+	if (!a->func) {
-+		__DWC_FREE(manager->mem_ctx, a);
-+		return -DWC_E_NO_MEMORY;
-+	}
-+
-+	DWC_MEMCPY(a->func, func, DWC_STRLEN(func) + 1);
-+	a->addr = addr;
-+	a->ctx = ctx;
-+	a->line = line;
-+	a->size = size;
-+	a->dma = dma;
-+	DWC_CIRCLEQ_INSERT_TAIL(&manager->allocations, a, entry);
-+
-+	/* Update stats */
-+	manager->num++;
-+	manager->num_active++;
-+	manager->total += size;
-+	manager->cur += size;
-+
-+	if (manager->max < manager->cur) {
-+		manager->max = manager->cur;
-+	}
-+
-+	return 0;
-+}
-+
-+static struct allocation *find_allocation(void *ctx, void *addr)
-+{
-+	struct allocation *a;
-+
-+	DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) {
-+		if (a->ctx == ctx && a->addr == addr) {
-+			return a;
-+		}
-+	}
-+
-+	return NULL;
-+}
-+
-+static void free_allocation(void *ctx, void *addr, char const *func, int line)
-+{
-+	struct allocation *a = find_allocation(ctx, addr);
-+
-+	if (!a) {
-+		DWC_ASSERT(0,
-+			   "Free of address %p that was never allocated or already freed %s:%d",
-+			   addr, func, line);
-+		return;
-+	}
-+
-+	DWC_CIRCLEQ_REMOVE(&manager->allocations, a, entry);
-+
-+	manager->num_active--;
-+	manager->num_freed++;
-+	manager->cur -= a->size;
-+	__DWC_FREE(manager->mem_ctx, a->func);
-+	__DWC_FREE(manager->mem_ctx, a);
-+}
-+
-+int dwc_memory_debug_start(void *mem_ctx)
-+{
-+	DWC_ASSERT(manager == NULL, "Memory debugging has already started\n");
-+
-+	if (manager) {
-+		return -DWC_E_BUSY;
-+	}
-+
-+	manager = __DWC_ALLOC(mem_ctx, sizeof(*manager));
-+	if (!manager) {
-+		return -DWC_E_NO_MEMORY;
-+	}
-+
-+	DWC_CIRCLEQ_INIT(&manager->allocations);
-+	manager->mem_ctx = mem_ctx;
-+	manager->num = 0;
-+	manager->num_freed = 0;
-+	manager->num_active = 0;
-+	manager->total = 0;
-+	manager->cur = 0;
-+	manager->max = 0;
-+
-+	return 0;
-+}
-+
-+void dwc_memory_debug_stop(void)
-+{
-+	struct allocation *a;
-+
-+	dwc_memory_debug_report();
-+
-+	DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) {
-+		DWC_ERROR("Memory leaked from %s:%d\n", a->func, a->line);
-+		free_allocation(a->ctx, a->addr, NULL, -1);
-+	}
-+
-+	__DWC_FREE(manager->mem_ctx, manager);
-+}
-+
-+void dwc_memory_debug_report(void)
-+{
-+	struct allocation *a;
-+
-+	DWC_PRINTF("\n\n\n----------------- Memory Debugging Report -----------------\n\n");
-+	DWC_PRINTF("Num Allocations = %d\n", manager->num);
-+	DWC_PRINTF("Freed = %d\n", manager->num_freed);
-+	DWC_PRINTF("Active = %d\n", manager->num_active);
-+	DWC_PRINTF("Current Memory Used = %d\n", manager->cur);
-+	DWC_PRINTF("Total Memory Used = %d\n", manager->total);
-+	DWC_PRINTF("Maximum Memory Used at Once = %d\n", manager->max);
-+	DWC_PRINTF("Unfreed allocations:\n");
-+
-+	DWC_CIRCLEQ_FOREACH(a, &manager->allocations, entry) {
-+		DWC_PRINTF("    addr=%p, size=%d from %s:%d, DMA=%d\n",
-+			   a->addr, a->size, a->func, a->line, a->dma);
-+	}
-+}
-+
-+/* The replacement functions */
-+void *dwc_alloc_debug(void *mem_ctx, uint32_t size, char const *func, int line)
-+{
-+	void *addr = __DWC_ALLOC(mem_ctx, size);
-+
-+	if (!addr) {
-+		return NULL;
-+	}
-+
-+	if (add_allocation(mem_ctx, size, func, line, addr, 0)) {
-+		__DWC_FREE(mem_ctx, addr);
-+		return NULL;
-+	}
-+
-+	return addr;
-+}
-+
-+void *dwc_alloc_atomic_debug(void *mem_ctx, uint32_t size, char const *func,
-+			     int line)
-+{
-+	void *addr = __DWC_ALLOC_ATOMIC(mem_ctx, size);
-+
-+	if (!addr) {
-+		return NULL;
-+	}
-+
-+	if (add_allocation(mem_ctx, size, func, line, addr, 0)) {
-+		__DWC_FREE(mem_ctx, addr);
-+		return NULL;
-+	}
-+
-+	return addr;
-+}
-+
-+void dwc_free_debug(void *mem_ctx, void *addr, char const *func, int line)
-+{
-+	free_allocation(mem_ctx, addr, func, line);
-+	__DWC_FREE(mem_ctx, addr);
-+}
-+
-+void *dwc_dma_alloc_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr,
-+			  char const *func, int line)
-+{
-+	void *addr = __DWC_DMA_ALLOC(dma_ctx, size, dma_addr);
-+
-+	if (!addr) {
-+		return NULL;
-+	}
-+
-+	if (add_allocation(dma_ctx, size, func, line, addr, 1)) {
-+		__DWC_DMA_FREE(dma_ctx, size, addr, *dma_addr);
-+		return NULL;
-+	}
-+
-+	return addr;
-+}
-+
-+void *dwc_dma_alloc_atomic_debug(void *dma_ctx, uint32_t size,
-+				 dwc_dma_t *dma_addr, char const *func, int line)
-+{
-+	void *addr = __DWC_DMA_ALLOC_ATOMIC(dma_ctx, size, dma_addr);
-+
-+	if (!addr) {
-+		return NULL;
-+	}
-+
-+	if (add_allocation(dma_ctx, size, func, line, addr, 1)) {
-+		__DWC_DMA_FREE(dma_ctx, size, addr, *dma_addr);
-+		return NULL;
-+	}
-+
-+	return addr;
-+}
-+
-+void dwc_dma_free_debug(void *dma_ctx, uint32_t size, void *virt_addr,
-+			dwc_dma_t dma_addr, char const *func, int line)
-+{
-+	free_allocation(dma_ctx, virt_addr, func, line);
-+	__DWC_DMA_FREE(dma_ctx, size, virt_addr, dma_addr);
-+}
-+
-+#endif /* DWC_DEBUG_MEMORY */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_modpow.c
-@@ -0,0 +1,636 @@
-+/* Bignum routines adapted from PUTTY sources.  PuTTY copyright notice follows.
-+ *
-+ * PuTTY is copyright 1997-2007 Simon Tatham.
-+ *
-+ * Portions copyright Robert de Bath, Joris van Rantwijk, Delian
-+ * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
-+ * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
-+ * Kuhn, and CORE SDI S.A.
-+ *
-+ * Permission is hereby granted, free of charge, to any person
-+ * obtaining a copy of this software and associated documentation files
-+ * (the "Software"), to deal in the Software without restriction,
-+ * including without limitation the rights to use, copy, modify, merge,
-+ * publish, distribute, sublicense, and/or sell copies of the Software,
-+ * and to permit persons to whom the Software is furnished to do so,
-+ * subject to the following conditions:
-+ *
-+ * The above copyright notice and this permission notice shall be
-+ * included in all copies or substantial portions of the Software.
-+
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
-+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-+ *
-+ */
-+#ifdef DWC_CRYPTOLIB
-+
-+#ifndef CONFIG_MACH_IPMATE
-+
-+#include "dwc_modpow.h"
-+
-+#define BIGNUM_INT_MASK  0xFFFFFFFFUL
-+#define BIGNUM_TOP_BIT   0x80000000UL
-+#define BIGNUM_INT_BITS  32
-+
-+
-+static void *snmalloc(void *mem_ctx, size_t n, size_t size)
-+{
-+    void *p;
-+    size *= n;
-+    if (size == 0) size = 1;
-+    p = dwc_alloc(mem_ctx, size);
-+    return p;
-+}
-+
-+#define snewn(ctx, n, type) ((type *)snmalloc((ctx), (n), sizeof(type)))
-+#define sfree dwc_free
-+
-+/*
-+ * Usage notes:
-+ *  * Do not call the DIVMOD_WORD macro with expressions such as array
-+ *    subscripts, as some implementations object to this (see below).
-+ *  * Note that none of the division methods below will cope if the
-+ *    quotient won't fit into BIGNUM_INT_BITS. Callers should be careful
-+ *    to avoid this case.
-+ *    If this condition occurs, in the case of the x86 DIV instruction,
-+ *    an overflow exception will occur, which (according to a correspondent)
-+ *    will manifest on Windows as something like
-+ *      0xC0000095: Integer overflow
-+ *    The C variant won't give the right answer, either.
-+ */
-+
-+#define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
-+
-+#if defined __GNUC__ && defined __i386__
-+#define DIVMOD_WORD(q, r, hi, lo, w) \
-+    __asm__("div %2" : \
-+	    "=d" (r), "=a" (q) : \
-+	    "r" (w), "d" (hi), "a" (lo))
-+#else
-+#define DIVMOD_WORD(q, r, hi, lo, w) do { \
-+    BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \
-+    q = n / w; \
-+    r = n % w; \
-+} while (0)
-+#endif
-+
-+//    q = n / w;
-+//    r = n % w;
-+
-+#define BIGNUM_INT_BYTES (BIGNUM_INT_BITS / 8)
-+
-+#define BIGNUM_INTERNAL
-+
-+static Bignum newbn(void *mem_ctx, int length)
-+{
-+    Bignum b = snewn(mem_ctx, length + 1, BignumInt);
-+    //if (!b)
-+    //abort();		       /* FIXME */
-+    DWC_MEMSET(b, 0, (length + 1) * sizeof(*b));
-+    b[0] = length;
-+    return b;
-+}
-+
-+void freebn(void *mem_ctx, Bignum b)
-+{
-+    /*
-+     * Burn the evidence, just in case.
-+     */
-+    DWC_MEMSET(b, 0, sizeof(b[0]) * (b[0] + 1));
-+    sfree(mem_ctx, b);
-+}
-+
-+/*
-+ * Compute c = a * b.
-+ * Input is in the first len words of a and b.
-+ * Result is returned in the first 2*len words of c.
-+ */
-+static void internal_mul(BignumInt *a, BignumInt *b,
-+			 BignumInt *c, int len)
-+{
-+    int i, j;
-+    BignumDblInt t;
-+
-+    for (j = 0; j < 2 * len; j++)
-+	c[j] = 0;
-+
-+    for (i = len - 1; i >= 0; i--) {
-+	t = 0;
-+	for (j = len - 1; j >= 0; j--) {
-+	    t += MUL_WORD(a[i], (BignumDblInt) b[j]);
-+	    t += (BignumDblInt) c[i + j + 1];
-+	    c[i + j + 1] = (BignumInt) t;
-+	    t = t >> BIGNUM_INT_BITS;
-+	}
-+	c[i] = (BignumInt) t;
-+    }
-+}
-+
-+static void internal_add_shifted(BignumInt *number,
-+				 unsigned n, int shift)
-+{
-+    int word = 1 + (shift / BIGNUM_INT_BITS);
-+    int bshift = shift % BIGNUM_INT_BITS;
-+    BignumDblInt addend;
-+
-+    addend = (BignumDblInt)n << bshift;
-+
-+    while (addend) {
-+	addend += number[word];
-+	number[word] = (BignumInt) addend & BIGNUM_INT_MASK;
-+	addend >>= BIGNUM_INT_BITS;
-+	word++;
-+    }
-+}
-+
-+/*
-+ * Compute a = a % m.
-+ * Input in first alen words of a and first mlen words of m.
-+ * Output in first alen words of a
-+ * (of which first alen-mlen words will be zero).
-+ * The MSW of m MUST have its high bit set.
-+ * Quotient is accumulated in the `quotient' array, which is a Bignum
-+ * rather than the internal bigendian format. Quotient parts are shifted
-+ * left by `qshift' before adding into quot.
-+ */
-+static void internal_mod(BignumInt *a, int alen,
-+			 BignumInt *m, int mlen,
-+			 BignumInt *quot, int qshift)
-+{
-+    BignumInt m0, m1;
-+    unsigned int h;
-+    int i, k;
-+
-+    m0 = m[0];
-+    if (mlen > 1)
-+	m1 = m[1];
-+    else
-+	m1 = 0;
-+
-+    for (i = 0; i <= alen - mlen; i++) {
-+	BignumDblInt t;
-+	unsigned int q, r, c, ai1;
-+
-+	if (i == 0) {
-+	    h = 0;
-+	} else {
-+	    h = a[i - 1];
-+	    a[i - 1] = 0;
-+	}
-+
-+	if (i == alen - 1)
-+	    ai1 = 0;
-+	else
-+	    ai1 = a[i + 1];
-+
-+	/* Find q = h:a[i] / m0 */
-+	if (h >= m0) {
-+	    /*
-+	     * Special case.
-+	     *
-+	     * To illustrate it, suppose a BignumInt is 8 bits, and
-+	     * we are dividing (say) A1:23:45:67 by A1:B2:C3. Then
-+	     * our initial division will be 0xA123 / 0xA1, which
-+	     * will give a quotient of 0x100 and a divide overflow.
-+	     * However, the invariants in this division algorithm
-+	     * are not violated, since the full number A1:23:... is
-+	     * _less_ than the quotient prefix A1:B2:... and so the
-+	     * following correction loop would have sorted it out.
-+	     *
-+	     * In this situation we set q to be the largest
-+	     * quotient we _can_ stomach (0xFF, of course).
-+	     */
-+	    q = BIGNUM_INT_MASK;
-+	} else {
-+	    /* Macro doesn't want an array subscript expression passed
-+	     * into it (see definition), so use a temporary. */
-+	    BignumInt tmplo = a[i];
-+	    DIVMOD_WORD(q, r, h, tmplo, m0);
-+
-+	    /* Refine our estimate of q by looking at
-+	     h:a[i]:a[i+1] / m0:m1 */
-+	    t = MUL_WORD(m1, q);
-+	    if (t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) {
-+		q--;
-+		t -= m1;
-+		r = (r + m0) & BIGNUM_INT_MASK;     /* overflow? */
-+		if (r >= (BignumDblInt) m0 &&
-+		    t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) q--;
-+	    }
-+	}
-+
-+	/* Subtract q * m from a[i...] */
-+	c = 0;
-+	for (k = mlen - 1; k >= 0; k--) {
-+	    t = MUL_WORD(q, m[k]);
-+	    t += c;
-+	    c = (unsigned)(t >> BIGNUM_INT_BITS);
-+	    if ((BignumInt) t > a[i + k])
-+		c++;
-+	    a[i + k] -= (BignumInt) t;
-+	}
-+
-+	/* Add back m in case of borrow */
-+	if (c != h) {
-+	    t = 0;
-+	    for (k = mlen - 1; k >= 0; k--) {
-+		t += m[k];
-+		t += a[i + k];
-+		a[i + k] = (BignumInt) t;
-+		t = t >> BIGNUM_INT_BITS;
-+	    }
-+	    q--;
-+	}
-+	if (quot)
-+	    internal_add_shifted(quot, q, qshift + BIGNUM_INT_BITS * (alen - mlen - i));
-+    }
-+}
-+
-+/*
-+ * Compute p % mod.
-+ * The most significant word of mod MUST be non-zero.
-+ * We assume that the result array is the same size as the mod array.
-+ * We optionally write out a quotient if `quotient' is non-NULL.
-+ * We can avoid writing out the result if `result' is NULL.
-+ */
-+void bigdivmod(void *mem_ctx, Bignum p, Bignum mod, Bignum result, Bignum quotient)
-+{
-+    BignumInt *n, *m;
-+    int mshift;
-+    int plen, mlen, i, j;
-+
-+    /* Allocate m of size mlen, copy mod to m */
-+    /* We use big endian internally */
-+    mlen = mod[0];
-+    m = snewn(mem_ctx, mlen, BignumInt);
-+    //if (!m)
-+    //abort();		       /* FIXME */
-+    for (j = 0; j < mlen; j++)
-+	m[j] = mod[mod[0] - j];
-+
-+    /* Shift m left to make msb bit set */
-+    for (mshift = 0; mshift < BIGNUM_INT_BITS-1; mshift++)
-+	if ((m[0] << mshift) & BIGNUM_TOP_BIT)
-+	    break;
-+    if (mshift) {
-+	for (i = 0; i < mlen - 1; i++)
-+	    m[i] = (m[i] << mshift) | (m[i + 1] >> (BIGNUM_INT_BITS - mshift));
-+	m[mlen - 1] = m[mlen - 1] << mshift;
-+    }
-+
-+    plen = p[0];
-+    /* Ensure plen > mlen */
-+    if (plen <= mlen)
-+	plen = mlen + 1;
-+
-+    /* Allocate n of size plen, copy p to n */
-+    n = snewn(mem_ctx, plen, BignumInt);
-+    //if (!n)
-+    //abort();		       /* FIXME */
-+    for (j = 0; j < plen; j++)
-+	n[j] = 0;
-+    for (j = 1; j <= (int)p[0]; j++)
-+	n[plen - j] = p[j];
-+
-+    /* Main computation */
-+    internal_mod(n, plen, m, mlen, quotient, mshift);
-+
-+    /* Fixup result in case the modulus was shifted */
-+    if (mshift) {
-+	for (i = plen - mlen - 1; i < plen - 1; i++)
-+	    n[i] = (n[i] << mshift) | (n[i + 1] >> (BIGNUM_INT_BITS - mshift));
-+	n[plen - 1] = n[plen - 1] << mshift;
-+	internal_mod(n, plen, m, mlen, quotient, 0);
-+	for (i = plen - 1; i >= plen - mlen; i--)
-+	    n[i] = (n[i] >> mshift) | (n[i - 1] << (BIGNUM_INT_BITS - mshift));
-+    }
-+
-+    /* Copy result to buffer */
-+    if (result) {
-+	for (i = 1; i <= (int)result[0]; i++) {
-+	    int j = plen - i;
-+	    result[i] = j >= 0 ? n[j] : 0;
-+	}
-+    }
-+
-+    /* Free temporary arrays */
-+    for (i = 0; i < mlen; i++)
-+	m[i] = 0;
-+    sfree(mem_ctx, m);
-+    for (i = 0; i < plen; i++)
-+	n[i] = 0;
-+    sfree(mem_ctx, n);
-+}
-+
-+/*
-+ * Simple remainder.
-+ */
-+Bignum bigmod(void *mem_ctx, Bignum a, Bignum b)
-+{
-+    Bignum r = newbn(mem_ctx, b[0]);
-+    bigdivmod(mem_ctx, a, b, r, NULL);
-+    return r;
-+}
-+
-+/*
-+ * Compute (base ^ exp) % mod.
-+ */
-+Bignum dwc_modpow(void *mem_ctx, Bignum base_in, Bignum exp, Bignum mod)
-+{
-+    BignumInt *a, *b, *n, *m;
-+    int mshift;
-+    int mlen, i, j;
-+    Bignum base, result;
-+
-+    /*
-+     * The most significant word of mod needs to be non-zero. It
-+     * should already be, but let's make sure.
-+     */
-+    //assert(mod[mod[0]] != 0);
-+
-+    /*
-+     * Make sure the base is smaller than the modulus, by reducing
-+     * it modulo the modulus if not.
-+     */
-+    base = bigmod(mem_ctx, base_in, mod);
-+
-+    /* Allocate m of size mlen, copy mod to m */
-+    /* We use big endian internally */
-+    mlen = mod[0];
-+    m = snewn(mem_ctx, mlen, BignumInt);
-+    //if (!m)
-+    //abort();		       /* FIXME */
-+    for (j = 0; j < mlen; j++)
-+	m[j] = mod[mod[0] - j];
-+
-+    /* Shift m left to make msb bit set */
-+    for (mshift = 0; mshift < BIGNUM_INT_BITS - 1; mshift++)
-+	if ((m[0] << mshift) & BIGNUM_TOP_BIT)
-+	    break;
-+    if (mshift) {
-+	for (i = 0; i < mlen - 1; i++)
-+	    m[i] =
-+		(m[i] << mshift) | (m[i + 1] >>
-+				    (BIGNUM_INT_BITS - mshift));
-+	m[mlen - 1] = m[mlen - 1] << mshift;
-+    }
-+
-+    /* Allocate n of size mlen, copy base to n */
-+    n = snewn(mem_ctx, mlen, BignumInt);
-+    //if (!n)
-+    //abort();		       /* FIXME */
-+    i = mlen - base[0];
-+    for (j = 0; j < i; j++)
-+	n[j] = 0;
-+    for (j = 0; j < base[0]; j++)
-+	n[i + j] = base[base[0] - j];
-+
-+    /* Allocate a and b of size 2*mlen. Set a = 1 */
-+    a = snewn(mem_ctx, 2 * mlen, BignumInt);
-+    //if (!a)
-+    //abort();		       /* FIXME */
-+    b = snewn(mem_ctx, 2 * mlen, BignumInt);
-+    //if (!b)
-+    //abort();		       /* FIXME */
-+    for (i = 0; i < 2 * mlen; i++)
-+	a[i] = 0;
-+    a[2 * mlen - 1] = 1;
-+
-+    /* Skip leading zero bits of exp. */
-+    i = 0;
-+    j = BIGNUM_INT_BITS - 1;
-+    while (i < exp[0] && (exp[exp[0] - i] & (1 << j)) == 0) {
-+	j--;
-+	if (j < 0) {
-+	    i++;
-+	    j = BIGNUM_INT_BITS - 1;
-+	}
-+    }
-+
-+    /* Main computation */
-+    while (i < exp[0]) {
-+	while (j >= 0) {
-+	    internal_mul(a + mlen, a + mlen, b, mlen);
-+	    internal_mod(b, mlen * 2, m, mlen, NULL, 0);
-+	    if ((exp[exp[0] - i] & (1 << j)) != 0) {
-+		internal_mul(b + mlen, n, a, mlen);
-+		internal_mod(a, mlen * 2, m, mlen, NULL, 0);
-+	    } else {
-+		BignumInt *t;
-+		t = a;
-+		a = b;
-+		b = t;
-+	    }
-+	    j--;
-+	}
-+	i++;
-+	j = BIGNUM_INT_BITS - 1;
-+    }
-+
-+    /* Fixup result in case the modulus was shifted */
-+    if (mshift) {
-+	for (i = mlen - 1; i < 2 * mlen - 1; i++)
-+	    a[i] =
-+		(a[i] << mshift) | (a[i + 1] >>
-+				    (BIGNUM_INT_BITS - mshift));
-+	a[2 * mlen - 1] = a[2 * mlen - 1] << mshift;
-+	internal_mod(a, mlen * 2, m, mlen, NULL, 0);
-+	for (i = 2 * mlen - 1; i >= mlen; i--)
-+	    a[i] =
-+		(a[i] >> mshift) | (a[i - 1] <<
-+				    (BIGNUM_INT_BITS - mshift));
-+    }
-+
-+    /* Copy result to buffer */
-+    result = newbn(mem_ctx, mod[0]);
-+    for (i = 0; i < mlen; i++)
-+	result[result[0] - i] = a[i + mlen];
-+    while (result[0] > 1 && result[result[0]] == 0)
-+	result[0]--;
-+
-+    /* Free temporary arrays */
-+    for (i = 0; i < 2 * mlen; i++)
-+	a[i] = 0;
-+    sfree(mem_ctx, a);
-+    for (i = 0; i < 2 * mlen; i++)
-+	b[i] = 0;
-+    sfree(mem_ctx, b);
-+    for (i = 0; i < mlen; i++)
-+	m[i] = 0;
-+    sfree(mem_ctx, m);
-+    for (i = 0; i < mlen; i++)
-+	n[i] = 0;
-+    sfree(mem_ctx, n);
-+
-+    freebn(mem_ctx, base);
-+
-+    return result;
-+}
-+
-+
-+#ifdef UNITTEST
-+
-+static __u32 dh_p[] = {
-+	96,
-+	0xFFFFFFFF,
-+	0xFFFFFFFF,
-+	0xA93AD2CA,
-+	0x4B82D120,
-+	0xE0FD108E,
-+	0x43DB5BFC,
-+	0x74E5AB31,
-+	0x08E24FA0,
-+	0xBAD946E2,
-+	0x770988C0,
-+	0x7A615D6C,
-+	0xBBE11757,
-+	0x177B200C,
-+	0x521F2B18,
-+	0x3EC86A64,
-+	0xD8760273,
-+	0xD98A0864,
-+	0xF12FFA06,
-+	0x1AD2EE6B,
-+	0xCEE3D226,
-+	0x4A25619D,
-+	0x1E8C94E0,
-+	0xDB0933D7,
-+	0xABF5AE8C,
-+	0xA6E1E4C7,
-+	0xB3970F85,
-+	0x5D060C7D,
-+	0x8AEA7157,
-+	0x58DBEF0A,
-+	0xECFB8504,
-+	0xDF1CBA64,
-+	0xA85521AB,
-+	0x04507A33,
-+	0xAD33170D,
-+	0x8AAAC42D,
-+	0x15728E5A,
-+	0x98FA0510,
-+	0x15D22618,
-+	0xEA956AE5,
-+	0x3995497C,
-+	0x95581718,
-+	0xDE2BCBF6,
-+	0x6F4C52C9,
-+	0xB5C55DF0,
-+	0xEC07A28F,
-+	0x9B2783A2,
-+	0x180E8603,
-+	0xE39E772C,
-+	0x2E36CE3B,
-+	0x32905E46,
-+	0xCA18217C,
-+	0xF1746C08,
-+	0x4ABC9804,
-+	0x670C354E,
-+	0x7096966D,
-+	0x9ED52907,
-+	0x208552BB,
-+	0x1C62F356,
-+	0xDCA3AD96,
-+	0x83655D23,
-+	0xFD24CF5F,
-+	0x69163FA8,
-+	0x1C55D39A,
-+	0x98DA4836,
-+	0xA163BF05,
-+	0xC2007CB8,
-+	0xECE45B3D,
-+	0x49286651,
-+	0x7C4B1FE6,
-+	0xAE9F2411,
-+	0x5A899FA5,
-+	0xEE386BFB,
-+	0xF406B7ED,
-+	0x0BFF5CB6,
-+	0xA637ED6B,
-+	0xF44C42E9,
-+	0x625E7EC6,
-+	0xE485B576,
-+	0x6D51C245,
-+	0x4FE1356D,
-+	0xF25F1437,
-+	0x302B0A6D,
-+	0xCD3A431B,
-+	0xEF9519B3,
-+	0x8E3404DD,
-+	0x514A0879,
-+	0x3B139B22,
-+	0x020BBEA6,
-+	0x8A67CC74,
-+	0x29024E08,
-+	0x80DC1CD1,
-+	0xC4C6628B,
-+	0x2168C234,
-+	0xC90FDAA2,
-+	0xFFFFFFFF,
-+	0xFFFFFFFF,
-+};
-+
-+static __u32 dh_a[] = {
-+	8,
-+	0xdf367516,
-+	0x86459caa,
-+	0xe2d459a4,
-+	0xd910dae0,
-+	0x8a8b5e37,
-+	0x67ab31c6,
-+	0xf0b55ea9,
-+	0x440051d6,
-+};
-+
-+static __u32 dh_b[] = {
-+	8,
-+	0xded92656,
-+	0xe07a048a,
-+	0x6fa452cd,
-+	0x2df89d30,
-+	0xc75f1b0f,
-+	0x8ce3578f,
-+	0x7980a324,
-+	0x5daec786,
-+};
-+
-+static __u32 dh_g[] = {
-+	1,
-+	2,
-+};
-+
-+int main(void)
-+{
-+	int i;
-+	__u32 *k;
-+	k = dwc_modpow(NULL, dh_g, dh_a, dh_p);
-+
-+	printf("\n\n");
-+	for (i=0; i<k[0]; i++) {
-+		__u32 word32 = k[k[0] - i];
-+		__u16 l = word32 & 0xffff;
-+		__u16 m = (word32 & 0xffff0000) >> 16;
-+		printf("%04x %04x ", m, l);
-+		if (!((i + 1)%13)) printf("\n");
-+	}
-+	printf("\n\n");
-+
-+	if ((k[0] == 0x60) && (k[1] == 0x28e490e5) && (k[0x60] == 0x5a0d3d4e)) {
-+		printf("PASS\n\n");
-+	}
-+	else {
-+		printf("FAIL\n\n");
-+	}
-+
-+}
-+
-+#endif /* UNITTEST */
-+
-+#endif /* CONFIG_MACH_IPMATE */
-+
-+#endif /*DWC_CRYPTOLIB */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_modpow.h
-@@ -0,0 +1,34 @@
-+/*
-+ * dwc_modpow.h
-+ * See dwc_modpow.c for license and changes
-+ */
-+#ifndef _DWC_MODPOW_H
-+#define _DWC_MODPOW_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#include "dwc_os.h"
-+
-+/** @file
-+ *
-+ * This file defines the module exponentiation function which is only used
-+ * internally by the DWC UWB modules for calculation of PKs during numeric
-+ * association.  The routine is taken from the PUTTY, an open source terminal
-+ * emulator.  The PUTTY License is preserved in the dwc_modpow.c file.
-+ *
-+ */
-+
-+typedef uint32_t BignumInt;
-+typedef uint64_t BignumDblInt;
-+typedef BignumInt *Bignum;
-+
-+/* Compute modular exponentiaion */
-+extern Bignum dwc_modpow(void *mem_ctx, Bignum base_in, Bignum exp, Bignum mod);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _LINUX_BIGNUM_H */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_notifier.c
-@@ -0,0 +1,319 @@
-+#ifdef DWC_NOTIFYLIB
-+
-+#include "dwc_notifier.h"
-+#include "dwc_list.h"
-+
-+typedef struct dwc_observer {
-+	void *observer;
-+	dwc_notifier_callback_t callback;
-+	void *data;
-+	char *notification;
-+	DWC_CIRCLEQ_ENTRY(dwc_observer) list_entry;
-+} observer_t;
-+
-+DWC_CIRCLEQ_HEAD(observer_queue, dwc_observer);
-+
-+typedef struct dwc_notifier {
-+	void *mem_ctx;
-+	void *object;
-+	struct observer_queue observers;
-+	DWC_CIRCLEQ_ENTRY(dwc_notifier) list_entry;
-+} notifier_t;
-+
-+DWC_CIRCLEQ_HEAD(notifier_queue, dwc_notifier);
-+
-+typedef struct manager {
-+	void *mem_ctx;
-+	void *wkq_ctx;
-+	dwc_workq_t *wq;
-+//	dwc_mutex_t *mutex;
-+	struct notifier_queue notifiers;
-+} manager_t;
-+
-+static manager_t *manager = NULL;
-+
-+static int create_manager(void *mem_ctx, void *wkq_ctx)
-+{
-+	manager = dwc_alloc(mem_ctx, sizeof(manager_t));
-+	if (!manager) {
-+		return -DWC_E_NO_MEMORY;
-+	}
-+
-+	DWC_CIRCLEQ_INIT(&manager->notifiers);
-+
-+	manager->wq = dwc_workq_alloc(wkq_ctx, "DWC Notification WorkQ");
-+	if (!manager->wq) {
-+		return -DWC_E_NO_MEMORY;
-+	}
-+
-+	return 0;
-+}
-+
-+static void free_manager(void)
-+{
-+	dwc_workq_free(manager->wq);
-+
-+	/* All notifiers must have unregistered themselves before this module
-+	 * can be removed.  Hitting this assertion indicates a programmer
-+	 * error. */
-+	DWC_ASSERT(DWC_CIRCLEQ_EMPTY(&manager->notifiers),
-+		   "Notification manager being freed before all notifiers have been removed");
-+	dwc_free(manager->mem_ctx, manager);
-+}
-+
-+#ifdef DEBUG
-+static void dump_manager(void)
-+{
-+	notifier_t *n;
-+	observer_t *o;
-+
-+	DWC_ASSERT(manager, "Notification manager not found");
-+
-+	DWC_DEBUG("List of all notifiers and observers:\n");
-+	DWC_CIRCLEQ_FOREACH(n, &manager->notifiers, list_entry) {
-+		DWC_DEBUG("Notifier %p has observers:\n", n->object);
-+		DWC_CIRCLEQ_FOREACH(o, &n->observers, list_entry) {
-+			DWC_DEBUG("    %p watching %s\n", o->observer, o->notification);
-+		}
-+	}
-+}
-+#else
-+#define dump_manager(...)
-+#endif
-+
-+static observer_t *alloc_observer(void *mem_ctx, void *observer, char *notification,
-+				  dwc_notifier_callback_t callback, void *data)
-+{
-+	observer_t *new_observer = dwc_alloc(mem_ctx, sizeof(observer_t));
-+
-+	if (!new_observer) {
-+		return NULL;
-+	}
-+
-+	DWC_CIRCLEQ_INIT_ENTRY(new_observer, list_entry);
-+	new_observer->observer = observer;
-+	new_observer->notification = notification;
-+	new_observer->callback = callback;
-+	new_observer->data = data;
-+	return new_observer;
-+}
-+
-+static void free_observer(void *mem_ctx, observer_t *observer)
-+{
-+	dwc_free(mem_ctx, observer);
-+}
-+
-+static notifier_t *alloc_notifier(void *mem_ctx, void *object)
-+{
-+	notifier_t *notifier;
-+
-+	if (!object) {
-+		return NULL;
-+	}
-+
-+	notifier = dwc_alloc(mem_ctx, sizeof(notifier_t));
-+	if (!notifier) {
-+		return NULL;
-+	}
-+
-+	DWC_CIRCLEQ_INIT(&notifier->observers);
-+	DWC_CIRCLEQ_INIT_ENTRY(notifier, list_entry);
-+
-+	notifier->mem_ctx = mem_ctx;
-+	notifier->object = object;
-+	return notifier;
-+}
-+
-+static void free_notifier(notifier_t *notifier)
-+{
-+	observer_t *observer;
-+
-+	DWC_CIRCLEQ_FOREACH(observer, &notifier->observers, list_entry) {
-+		free_observer(notifier->mem_ctx, observer);
-+	}
-+
-+	dwc_free(notifier->mem_ctx, notifier);
-+}
-+
-+static notifier_t *find_notifier(void *object)
-+{
-+	notifier_t *notifier;
-+
-+	DWC_ASSERT(manager, "Notification manager not found");
-+
-+	if (!object) {
-+		return NULL;
-+	}
-+
-+	DWC_CIRCLEQ_FOREACH(notifier, &manager->notifiers, list_entry) {
-+		if (notifier->object == object) {
-+			return notifier;
-+		}
-+	}
-+
-+	return NULL;
-+}
-+
-+int dwc_alloc_notification_manager(void *mem_ctx, void *wkq_ctx)
-+{
-+	return create_manager(mem_ctx, wkq_ctx);
-+}
-+
-+void dwc_free_notification_manager(void)
-+{
-+	free_manager();
-+}
-+
-+dwc_notifier_t *dwc_register_notifier(void *mem_ctx, void *object)
-+{
-+	notifier_t *notifier;
-+
-+	DWC_ASSERT(manager, "Notification manager not found");
-+
-+	notifier = find_notifier(object);
-+	if (notifier) {
-+		DWC_ERROR("Notifier %p is already registered\n", object);
-+		return NULL;
-+	}
-+
-+	notifier = alloc_notifier(mem_ctx, object);
-+	if (!notifier) {
-+		return NULL;
-+	}
-+
-+	DWC_CIRCLEQ_INSERT_TAIL(&manager->notifiers, notifier, list_entry);
-+
-+	DWC_INFO("Notifier %p registered", object);
-+	dump_manager();
-+
-+	return notifier;
-+}
-+
-+void dwc_unregister_notifier(dwc_notifier_t *notifier)
-+{
-+	DWC_ASSERT(manager, "Notification manager not found");
-+
-+	if (!DWC_CIRCLEQ_EMPTY(&notifier->observers)) {
-+		observer_t *o;
-+
-+		DWC_ERROR("Notifier %p has active observers when removing\n", notifier->object);
-+		DWC_CIRCLEQ_FOREACH(o, &notifier->observers, list_entry) {
-+			DWC_DEBUGC("    %p watching %s\n", o->observer, o->notification);
-+		}
-+
-+		DWC_ASSERT(DWC_CIRCLEQ_EMPTY(&notifier->observers),
-+			   "Notifier %p has active observers when removing", notifier);
-+	}
-+
-+	DWC_CIRCLEQ_REMOVE_INIT(&manager->notifiers, notifier, list_entry);
-+	free_notifier(notifier);
-+
-+	DWC_INFO("Notifier unregistered");
-+	dump_manager();
-+}
-+
-+/* Add an observer to observe the notifier for a particular state, event, or notification. */
-+int dwc_add_observer(void *observer, void *object, char *notification,
-+		     dwc_notifier_callback_t callback, void *data)
-+{
-+	notifier_t *notifier = find_notifier(object);
-+	observer_t *new_observer;
-+
-+	if (!notifier) {
-+		DWC_ERROR("Notifier %p is not found when adding observer\n", object);
-+		return -DWC_E_INVALID;
-+	}
-+
-+	new_observer = alloc_observer(notifier->mem_ctx, observer, notification, callback, data);
-+	if (!new_observer) {
-+		return -DWC_E_NO_MEMORY;
-+	}
-+
-+	DWC_CIRCLEQ_INSERT_TAIL(&notifier->observers, new_observer, list_entry);
-+
-+	DWC_INFO("Added observer %p to notifier %p observing notification %s, callback=%p, data=%p",
-+		 observer, object, notification, callback, data);
-+
-+	dump_manager();
-+	return 0;
-+}
-+
-+int dwc_remove_observer(void *observer)
-+{
-+	notifier_t *n;
-+
-+	DWC_ASSERT(manager, "Notification manager not found");
-+
-+	DWC_CIRCLEQ_FOREACH(n, &manager->notifiers, list_entry) {
-+		observer_t *o;
-+		observer_t *o2;
-+
-+		DWC_CIRCLEQ_FOREACH_SAFE(o, o2, &n->observers, list_entry) {
-+			if (o->observer == observer) {
-+				DWC_CIRCLEQ_REMOVE_INIT(&n->observers, o, list_entry);
-+				DWC_INFO("Removing observer %p from notifier %p watching notification %s:",
-+					 o->observer, n->object, o->notification);
-+				free_observer(n->mem_ctx, o);
-+			}
-+		}
-+	}
-+
-+	dump_manager();
-+	return 0;
-+}
-+
-+typedef struct callback_data {
-+	void *mem_ctx;
-+	dwc_notifier_callback_t cb;
-+	void *observer;
-+	void *data;
-+	void *object;
-+	char *notification;
-+	void *notification_data;
-+} cb_data_t;
-+
-+static void cb_task(void *data)
-+{
-+	cb_data_t *cb = (cb_data_t *)data;
-+
-+	cb->cb(cb->object, cb->notification, cb->observer, cb->notification_data, cb->data);
-+	dwc_free(cb->mem_ctx, cb);
-+}
-+
-+void dwc_notify(dwc_notifier_t *notifier, char *notification, void *notification_data)
-+{
-+	observer_t *o;
-+
-+	DWC_ASSERT(manager, "Notification manager not found");
-+
-+	DWC_CIRCLEQ_FOREACH(o, &notifier->observers, list_entry) {
-+		int len = DWC_STRLEN(notification);
-+
-+		if (DWC_STRLEN(o->notification) != len) {
-+			continue;
-+		}
-+
-+		if (DWC_STRNCMP(o->notification, notification, len) == 0) {
-+			cb_data_t *cb_data = dwc_alloc(notifier->mem_ctx, sizeof(cb_data_t));
-+
-+			if (!cb_data) {
-+				DWC_ERROR("Failed to allocate callback data\n");
-+				return;
-+			}
-+
-+			cb_data->mem_ctx = notifier->mem_ctx;
-+			cb_data->cb = o->callback;
-+			cb_data->observer = o->observer;
-+			cb_data->data = o->data;
-+			cb_data->object = notifier->object;
-+			cb_data->notification = notification;
-+			cb_data->notification_data = notification_data;
-+			DWC_DEBUGC("Observer found %p for notification %s\n", o->observer, notification);
-+			DWC_WORKQ_SCHEDULE(manager->wq, cb_task, cb_data,
-+					   "Notify callback from %p for Notification %s, to observer %p",
-+					   cb_data->object, notification, cb_data->observer);
-+		}
-+	}
-+}
-+
-+#endif	/* DWC_NOTIFYLIB */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_notifier.h
-@@ -0,0 +1,122 @@
-+
-+#ifndef __DWC_NOTIFIER_H__
-+#define __DWC_NOTIFIER_H__
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#include "dwc_os.h"
-+
-+/** @file
-+ *
-+ * A simple implementation of the Observer pattern.  Any "module" can
-+ * register as an observer or notifier.  The notion of "module" is abstract and
-+ * can mean anything used to identify either an observer or notifier.  Usually
-+ * it will be a pointer to a data structure which contains some state, ie an
-+ * object.
-+ *
-+ * Before any notifiers can be added, the global notification manager must be
-+ * brought up with dwc_alloc_notification_manager().
-+ * dwc_free_notification_manager() will bring it down and free all resources.
-+ * These would typically be called upon module load and unload.  The
-+ * notification manager is a single global instance that handles all registered
-+ * observable modules and observers so this should be done only once.
-+ *
-+ * A module can be observable by using Notifications to publicize some general
-+ * information about it's state or operation.  It does not care who listens, or
-+ * even if anyone listens, or what they do with the information.  The observable
-+ * modules do not need to know any information about it's observers or their
-+ * interface, or their state or data.
-+ *
-+ * Any module can register to emit Notifications.  It should publish a list of
-+ * notifications that it can emit and their behavior, such as when they will get
-+ * triggered, and what information will be provided to the observer.  Then it
-+ * should register itself as an observable module. See dwc_register_notifier().
-+ *
-+ * Any module can observe any observable, registered module, provided it has a
-+ * handle to the other module and knows what notifications to observe.  See
-+ * dwc_add_observer().
-+ *
-+ * A function of type dwc_notifier_callback_t is called whenever a notification
-+ * is triggered with one or more observers observing it.  This function is
-+ * called in it's own process so it may sleep or block if needed.  It is
-+ * guaranteed to be called sometime after the notification has occurred and will
-+ * be called once per each time the notification is triggered.  It will NOT be
-+ * called in the same process context used to trigger the notification.
-+ *
-+ * @section Limitiations
-+ *
-+ * Keep in mind that Notifications that can be triggered in rapid sucession may
-+ * schedule too many processes too handle.  Be aware of this limitation when
-+ * designing to use notifications, and only add notifications for appropriate
-+ * observable information.
-+ *
-+ * Also Notification callbacks are not synchronous.  If you need to synchronize
-+ * the behavior between module/observer you must use other means.  And perhaps
-+ * that will mean Notifications are not the proper solution.
-+ */
-+
-+struct dwc_notifier;
-+typedef struct dwc_notifier dwc_notifier_t;
-+
-+/** The callback function must be of this type.
-+ *
-+ * @param object This is the object that is being observed.
-+ * @param notification This is the notification that was triggered.
-+ * @param observer This is the observer
-+ * @param notification_data This is notification-specific data that the notifier
-+ * has included in this notification.  The value of this should be published in
-+ * the documentation of the observable module with the notifications.
-+ * @param user_data This is any custom data that the observer provided when
-+ * adding itself as an observer to the notification. */
-+typedef void (*dwc_notifier_callback_t)(void *object, char *notification, void *observer,
-+					void *notification_data, void *user_data);
-+
-+/** Brings up the notification manager. */
-+extern int dwc_alloc_notification_manager(void *mem_ctx, void *wkq_ctx);
-+/** Brings down the notification manager. */
-+extern void dwc_free_notification_manager(void);
-+
-+/** This function registers an observable module.  A dwc_notifier_t object is
-+ * returned to the observable module.  This is an opaque object that is used by
-+ * the observable module to trigger notifications.  This object should only be
-+ * accessible to functions that are authorized to trigger notifications for this
-+ * module.  Observers do not need this object. */
-+extern dwc_notifier_t *dwc_register_notifier(void *mem_ctx, void *object);
-+
-+/** This function unregisters an observable module.  All observers have to be
-+ * removed prior to unregistration. */
-+extern void dwc_unregister_notifier(dwc_notifier_t *notifier);
-+
-+/** Add a module as an observer to the observable module.  The observable module
-+ * needs to have previously registered with the notification manager.
-+ *
-+ * @param observer The observer module
-+ * @param object The module to observe
-+ * @param notification The notification to observe
-+ * @param callback The callback function to call
-+ * @param user_data Any additional user data to pass into the callback function */
-+extern int dwc_add_observer(void *observer, void *object, char *notification,
-+			    dwc_notifier_callback_t callback, void *user_data);
-+
-+/** Removes the specified observer from all notifications that it is currently
-+ * observing. */
-+extern int dwc_remove_observer(void *observer);
-+
-+/** This function triggers a Notification.  It should be called by the
-+ * observable module, or any module or library which the observable module
-+ * allows to trigger notification on it's behalf.  Such as the dwc_cc_t.
-+ *
-+ * dwc_notify is a non-blocking function.  Callbacks are scheduled called in
-+ * their own process context for each trigger.  Callbacks can be blocking.
-+ * dwc_notify can be called from interrupt context if needed.
-+ *
-+ */
-+void dwc_notify(dwc_notifier_t *notifier, char *notification, void *notification_data);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* __DWC_NOTIFIER_H__ */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/dwc_os.h
-@@ -0,0 +1,1276 @@
-+/* =========================================================================
-+ * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_os.h $
-+ * $Revision: #14 $
-+ * $Date: 2010/11/04 $
-+ * $Change: 1621695 $
-+ *
-+ * Synopsys Portability Library Software and documentation
-+ * (hereinafter, "Software") is an Unsupported proprietary work of
-+ * Synopsys, Inc. unless otherwise expressly agreed to in writing
-+ * between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product
-+ * under any End User Software License Agreement or Agreement for
-+ * Licensed Product with Synopsys or any supplement thereto. You are
-+ * permitted to use and redistribute this Software in source and binary
-+ * forms, with or without modification, provided that redistributions
-+ * of source code must retain this notice. You may not view, use,
-+ * disclose, copy or distribute this file or any information contained
-+ * herein except pursuant to this license grant from Synopsys. If you
-+ * do not agree with this notice, including the disclaimer below, then
-+ * you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
-+ * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+ * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
-+ * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================= */
-+#ifndef _DWC_OS_H_
-+#define _DWC_OS_H_
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/** @file
-+ *
-+ * DWC portability library, low level os-wrapper functions
-+ *
-+ */
-+
-+/* These basic types need to be defined by some OS header file or custom header
-+ * file for your specific target architecture.
-+ *
-+ * uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t
-+ *
-+ * Any custom or alternate header file must be added and enabled here.
-+ */
-+
-+#ifdef DWC_LINUX
-+# include <linux/types.h>
-+# ifdef CONFIG_DEBUG_MUTEXES
-+#  include <linux/mutex.h>
-+# endif
-+# include <linux/spinlock.h>
-+# include <linux/errno.h>
-+# include <stdarg.h>
-+#endif
-+
-+#if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
-+# include <os_dep.h>
-+#endif
-+
-+
-+/** @name Primitive Types and Values */
-+
-+/** We define a boolean type for consistency.  Can be either YES or NO */
-+typedef uint8_t dwc_bool_t;
-+#define YES  1
-+#define NO   0
-+
-+#ifdef DWC_LINUX
-+
-+/** @name Error Codes */
-+#define DWC_E_INVALID		EINVAL
-+#define DWC_E_NO_MEMORY		ENOMEM
-+#define DWC_E_NO_DEVICE		ENODEV
-+#define DWC_E_NOT_SUPPORTED	EOPNOTSUPP
-+#define DWC_E_TIMEOUT		ETIMEDOUT
-+#define DWC_E_BUSY		EBUSY
-+#define DWC_E_AGAIN		EAGAIN
-+#define DWC_E_RESTART		ERESTART
-+#define DWC_E_ABORT		ECONNABORTED
-+#define DWC_E_SHUTDOWN		ESHUTDOWN
-+#define DWC_E_NO_DATA		ENODATA
-+#define DWC_E_DISCONNECT	ECONNRESET
-+#define DWC_E_UNKNOWN		EINVAL
-+#define DWC_E_NO_STREAM_RES	ENOSR
-+#define DWC_E_COMMUNICATION	ECOMM
-+#define DWC_E_OVERFLOW		EOVERFLOW
-+#define DWC_E_PROTOCOL		EPROTO
-+#define DWC_E_IN_PROGRESS	EINPROGRESS
-+#define DWC_E_PIPE		EPIPE
-+#define DWC_E_IO		EIO
-+#define DWC_E_NO_SPACE		ENOSPC
-+
-+#else
-+
-+/** @name Error Codes */
-+#define DWC_E_INVALID		1001
-+#define DWC_E_NO_MEMORY		1002
-+#define DWC_E_NO_DEVICE		1003
-+#define DWC_E_NOT_SUPPORTED	1004
-+#define DWC_E_TIMEOUT		1005
-+#define DWC_E_BUSY		1006
-+#define DWC_E_AGAIN		1007
-+#define DWC_E_RESTART		1008
-+#define DWC_E_ABORT		1009
-+#define DWC_E_SHUTDOWN		1010
-+#define DWC_E_NO_DATA		1011
-+#define DWC_E_DISCONNECT	2000
-+#define DWC_E_UNKNOWN		3000
-+#define DWC_E_NO_STREAM_RES	4001
-+#define DWC_E_COMMUNICATION	4002
-+#define DWC_E_OVERFLOW		4003
-+#define DWC_E_PROTOCOL		4004
-+#define DWC_E_IN_PROGRESS	4005
-+#define DWC_E_PIPE		4006
-+#define DWC_E_IO		4007
-+#define DWC_E_NO_SPACE		4008
-+
-+#endif
-+
-+
-+/** @name Tracing/Logging Functions
-+ *
-+ * These function provide the capability to add tracing, debugging, and error
-+ * messages, as well exceptions as assertions.  The WUDEV uses these
-+ * extensively.  These could be logged to the main console, the serial port, an
-+ * internal buffer, etc.  These functions could also be no-op if they are too
-+ * expensive on your system.  By default undefining the DEBUG macro already
-+ * no-ops some of these functions. */
-+
-+/** Returns non-zero if in interrupt context. */
-+extern dwc_bool_t DWC_IN_IRQ(void);
-+#define dwc_in_irq DWC_IN_IRQ
-+
-+/** Returns "IRQ" if DWC_IN_IRQ is true. */
-+static inline char *dwc_irq(void) {
-+	return DWC_IN_IRQ() ? "IRQ" : "";
-+}
-+
-+/** Returns non-zero if in bottom-half context. */
-+extern dwc_bool_t DWC_IN_BH(void);
-+#define dwc_in_bh DWC_IN_BH
-+
-+/** Returns "BH" if DWC_IN_BH is true. */
-+static inline char *dwc_bh(void) {
-+	return DWC_IN_BH() ? "BH" : "";
-+}
-+
-+/**
-+ * A vprintf() clone.  Just call vprintf if you've got it.
-+ */
-+extern void DWC_VPRINTF(char *format, va_list args);
-+#define dwc_vprintf DWC_VPRINTF
-+
-+/**
-+ * A vsnprintf() clone.  Just call vprintf if you've got it.
-+ */
-+extern int DWC_VSNPRINTF(char *str, int size, char *format, va_list args);
-+#define dwc_vsnprintf DWC_VSNPRINTF
-+
-+/**
-+ * printf() clone.  Just call printf if you've go it.
-+ */
-+extern void DWC_PRINTF(char *format, ...)
-+/* This provides compiler level static checking of the parameters if you're
-+ * using GCC. */
-+#ifdef __GNUC__
-+	__attribute__ ((format(printf, 1, 2)));
-+#else
-+	;
-+#endif
-+#define dwc_printf DWC_PRINTF
-+
-+/**
-+ * sprintf() clone.  Just call sprintf if you've got it.
-+ */
-+extern int DWC_SPRINTF(char *string, char *format, ...)
-+#ifdef __GNUC__
-+	__attribute__ ((format(printf, 2, 3)));
-+#else
-+	;
-+#endif
-+#define dwc_sprintf DWC_SPRINTF
-+
-+/**
-+ * snprintf() clone.  Just call snprintf if you've got it.
-+ */
-+extern int DWC_SNPRINTF(char *string, int size, char *format, ...)
-+#ifdef __GNUC__
-+	__attribute__ ((format(printf, 3, 4)));
-+#else
-+	;
-+#endif
-+#define dwc_snprintf DWC_SNPRINTF
-+
-+/**
-+ * Prints a WARNING message.  On systems that don't differentiate between
-+ * warnings and regular log messages, just print it.  Indicates that something
-+ * may be wrong with the driver.  Works like printf().
-+ *
-+ * Use the DWC_WARN macro to call this function.
-+ */
-+extern void __DWC_WARN(char *format, ...)
-+#ifdef __GNUC__
-+	__attribute__ ((format(printf, 1, 2)));
-+#else
-+	;
-+#endif
-+
-+/**
-+ * Prints an error message.  On systems that don't differentiate between errors
-+ * and regular log messages, just print it.  Indicates that something went wrong
-+ * with the driver.  Works like printf().
-+ *
-+ * Use the DWC_ERROR macro to call this function.
-+ */
-+extern void __DWC_ERROR(char *format, ...)
-+#ifdef __GNUC__
-+	__attribute__ ((format(printf, 1, 2)));
-+#else
-+	;
-+#endif
-+
-+/**
-+ * Prints an exception error message and takes some user-defined action such as
-+ * print out a backtrace or trigger a breakpoint.  Indicates that something went
-+ * abnormally wrong with the driver such as programmer error, or other
-+ * exceptional condition.  It should not be ignored so even on systems without
-+ * printing capability, some action should be taken to notify the developer of
-+ * it.  Works like printf().
-+ */
-+extern void DWC_EXCEPTION(char *format, ...)
-+#ifdef __GNUC__
-+	__attribute__ ((format(printf, 1, 2)));
-+#else
-+	;
-+#endif
-+#define dwc_exception DWC_EXCEPTION
-+
-+#ifndef DWC_OTG_DEBUG_LEV
-+#define DWC_OTG_DEBUG_LEV 0
-+#endif
-+
-+#ifdef DEBUG
-+/**
-+ * Prints out a debug message.  Used for logging/trace messages.
-+ *
-+ * Use the DWC_DEBUG macro to call this function
-+ */
-+extern void __DWC_DEBUG(char *format, ...)
-+#ifdef __GNUC__
-+	__attribute__ ((format(printf, 1, 2)));
-+#else
-+	;
-+#endif
-+#else
-+#define __DWC_DEBUG printk
-+#endif
-+
-+/**
-+ * Prints out a Debug message.
-+ */
-+#define DWC_DEBUG(_format, _args...) __DWC_DEBUG("DEBUG:%s:%s: " _format "\n", \
-+						 __func__, dwc_irq(), ## _args)
-+#define dwc_debug DWC_DEBUG
-+/**
-+ * Prints out a Debug message if enabled at compile time.
-+ */
-+#if DWC_OTG_DEBUG_LEV > 0
-+#define DWC_DEBUGC(_format, _args...) DWC_DEBUG(_format, ##_args )
-+#else
-+#define DWC_DEBUGC(_format, _args...)
-+#endif
-+#define dwc_debugc DWC_DEBUGC
-+/**
-+ * Prints out an informative message.
-+ */
-+#define DWC_INFO(_format, _args...) DWC_PRINTF("INFO:%s: " _format "\n", \
-+					       dwc_irq(), ## _args)
-+#define dwc_info DWC_INFO
-+/**
-+ * Prints out an informative message if enabled at compile time.
-+ */
-+#if DWC_OTG_DEBUG_LEV > 1
-+#define DWC_INFOC(_format, _args...) DWC_INFO(_format, ##_args )
-+#else
-+#define DWC_INFOC(_format, _args...)
-+#endif
-+#define dwc_infoc DWC_INFOC
-+/**
-+ * Prints out a warning message.
-+ */
-+#define DWC_WARN(_format, _args...) __DWC_WARN("WARN:%s:%s:%d: " _format "\n", \
-+					dwc_irq(), __func__, __LINE__, ## _args)
-+#define dwc_warn DWC_WARN
-+/**
-+ * Prints out an error message.
-+ */
-+#define DWC_ERROR(_format, _args...) __DWC_ERROR("ERROR:%s:%s:%d: " _format "\n", \
-+					dwc_irq(), __func__, __LINE__, ## _args)
-+#define dwc_error DWC_ERROR
-+
-+#define DWC_PROTO_ERROR(_format, _args...) __DWC_WARN("ERROR:%s:%s:%d: " _format "\n", \
-+						dwc_irq(), __func__, __LINE__, ## _args)
-+#define dwc_proto_error DWC_PROTO_ERROR
-+
-+#ifdef DEBUG
-+/** Prints out a exception error message if the _expr expression fails.  Disabled
-+ * if DEBUG is not enabled. */
-+#define DWC_ASSERT(_expr, _format, _args...) do { \
-+	if (!(_expr)) { DWC_EXCEPTION("%s:%s:%d: " _format "\n", dwc_irq(), \
-+				      __FILE__, __LINE__, ## _args); } \
-+	} while (0)
-+#else
-+#define DWC_ASSERT(_x...)
-+#endif
-+#define dwc_assert DWC_ASSERT
-+
-+
-+/** @name Byte Ordering
-+ * The following functions are for conversions between processor's byte ordering
-+ * and specific ordering you want.
-+ */
-+
-+/** Converts 32 bit data in CPU byte ordering to little endian. */
-+extern uint32_t DWC_CPU_TO_LE32(uint32_t *p);
-+#define dwc_cpu_to_le32 DWC_CPU_TO_LE32
-+
-+/** Converts 32 bit data in CPU byte orderint to big endian. */
-+extern uint32_t DWC_CPU_TO_BE32(uint32_t *p);
-+#define dwc_cpu_to_be32 DWC_CPU_TO_BE32
-+
-+/** Converts 32 bit little endian data to CPU byte ordering. */
-+extern uint32_t DWC_LE32_TO_CPU(uint32_t *p);
-+#define dwc_le32_to_cpu DWC_LE32_TO_CPU
-+
-+/** Converts 32 bit big endian data to CPU byte ordering. */
-+extern uint32_t DWC_BE32_TO_CPU(uint32_t *p);
-+#define dwc_be32_to_cpu DWC_BE32_TO_CPU
-+
-+/** Converts 16 bit data in CPU byte ordering to little endian. */
-+extern uint16_t DWC_CPU_TO_LE16(uint16_t *p);
-+#define dwc_cpu_to_le16 DWC_CPU_TO_LE16
-+
-+/** Converts 16 bit data in CPU byte orderint to big endian. */
-+extern uint16_t DWC_CPU_TO_BE16(uint16_t *p);
-+#define dwc_cpu_to_be16 DWC_CPU_TO_BE16
-+
-+/** Converts 16 bit little endian data to CPU byte ordering. */
-+extern uint16_t DWC_LE16_TO_CPU(uint16_t *p);
-+#define dwc_le16_to_cpu DWC_LE16_TO_CPU
-+
-+/** Converts 16 bit bi endian data to CPU byte ordering. */
-+extern uint16_t DWC_BE16_TO_CPU(uint16_t *p);
-+#define dwc_be16_to_cpu DWC_BE16_TO_CPU
-+
-+
-+/** @name Register Read/Write
-+ *
-+ * The following six functions should be implemented to read/write registers of
-+ * 32-bit and 64-bit sizes.  All modules use this to read/write register values.
-+ * The reg value is a pointer to the register calculated from the void *base
-+ * variable passed into the driver when it is started.  */
-+
-+#ifdef DWC_LINUX
-+/* Linux doesn't need any extra parameters for register read/write, so we
-+ * just throw away the IO context parameter.
-+ */
-+/** Reads the content of a 32-bit register. */
-+extern uint32_t DWC_READ_REG32(uint32_t volatile *reg);
-+#define dwc_read_reg32(_ctx_,_reg_) DWC_READ_REG32(_reg_)
-+
-+/** Reads the content of a 64-bit register. */
-+extern uint64_t DWC_READ_REG64(uint64_t volatile *reg);
-+#define dwc_read_reg64(_ctx_,_reg_) DWC_READ_REG64(_reg_)
-+
-+/** Writes to a 32-bit register. */
-+extern void DWC_WRITE_REG32(uint32_t volatile *reg, uint32_t value);
-+#define dwc_write_reg32(_ctx_,_reg_,_val_) DWC_WRITE_REG32(_reg_, _val_)
-+
-+/** Writes to a 64-bit register. */
-+extern void DWC_WRITE_REG64(uint64_t volatile *reg, uint64_t value);
-+#define dwc_write_reg64(_ctx_,_reg_,_val_) DWC_WRITE_REG64(_reg_, _val_)
-+
-+/**
-+ * Modify bit values in a register.  Using the
-+ * algorithm: (reg_contents & ~clear_mask) | set_mask.
-+ */
-+extern void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask);
-+#define dwc_modify_reg32(_ctx_,_reg_,_cmsk_,_smsk_) DWC_MODIFY_REG32(_reg_,_cmsk_,_smsk_)
-+extern void DWC_MODIFY_REG64(uint64_t volatile *reg, uint64_t clear_mask, uint64_t set_mask);
-+#define dwc_modify_reg64(_ctx_,_reg_,_cmsk_,_smsk_) DWC_MODIFY_REG64(_reg_,_cmsk_,_smsk_)
-+
-+#endif	/* DWC_LINUX */
-+
-+#if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
-+typedef struct dwc_ioctx {
-+	struct device *dev;
-+	bus_space_tag_t iot;
-+	bus_space_handle_t ioh;
-+} dwc_ioctx_t;
-+
-+/** BSD needs two extra parameters for register read/write, so we pass
-+ * them in using the IO context parameter.
-+ */
-+/** Reads the content of a 32-bit register. */
-+extern uint32_t DWC_READ_REG32(void *io_ctx, uint32_t volatile *reg);
-+#define dwc_read_reg32 DWC_READ_REG32
-+
-+/** Reads the content of a 64-bit register. */
-+extern uint64_t DWC_READ_REG64(void *io_ctx, uint64_t volatile *reg);
-+#define dwc_read_reg64 DWC_READ_REG64
-+
-+/** Writes to a 32-bit register. */
-+extern void DWC_WRITE_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t value);
-+#define dwc_write_reg32 DWC_WRITE_REG32
-+
-+/** Writes to a 64-bit register. */
-+extern void DWC_WRITE_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t value);
-+#define dwc_write_reg64 DWC_WRITE_REG64
-+
-+/**
-+ * Modify bit values in a register.  Using the
-+ * algorithm: (reg_contents & ~clear_mask) | set_mask.
-+ */
-+extern void DWC_MODIFY_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask);
-+#define dwc_modify_reg32 DWC_MODIFY_REG32
-+extern void DWC_MODIFY_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t clear_mask, uint64_t set_mask);
-+#define dwc_modify_reg64 DWC_MODIFY_REG64
-+
-+#endif	/* DWC_FREEBSD || DWC_NETBSD */
-+
-+/** @cond */
-+
-+/** @name Some convenience MACROS used internally.  Define DWC_DEBUG_REGS to log the
-+ * register writes. */
-+
-+#ifdef DWC_LINUX
-+
-+# ifdef DWC_DEBUG_REGS
-+
-+#define dwc_define_read_write_reg_n(_reg,_container_type) \
-+static inline uint32_t dwc_read_##_reg##_n(_container_type *container, int num) { \
-+	return DWC_READ_REG32(&container->regs->_reg[num]); \
-+} \
-+static inline void dwc_write_##_reg##_n(_container_type *container, int num, uint32_t data) { \
-+	DWC_DEBUG("WRITING %8s[%d]: %p: %08x", #_reg, num, \
-+		  &(((uint32_t*)container->regs->_reg)[num]), data); \
-+	DWC_WRITE_REG32(&(((uint32_t*)container->regs->_reg)[num]), data); \
-+}
-+
-+#define dwc_define_read_write_reg(_reg,_container_type) \
-+static inline uint32_t dwc_read_##_reg(_container_type *container) { \
-+	return DWC_READ_REG32(&container->regs->_reg); \
-+} \
-+static inline void dwc_write_##_reg(_container_type *container, uint32_t data) { \
-+	DWC_DEBUG("WRITING %11s: %p: %08x", #_reg, &container->regs->_reg, data); \
-+	DWC_WRITE_REG32(&container->regs->_reg, data); \
-+}
-+
-+# else	/* DWC_DEBUG_REGS */
-+
-+#define dwc_define_read_write_reg_n(_reg,_container_type) \
-+static inline uint32_t dwc_read_##_reg##_n(_container_type *container, int num) { \
-+	return DWC_READ_REG32(&container->regs->_reg[num]); \
-+} \
-+static inline void dwc_write_##_reg##_n(_container_type *container, int num, uint32_t data) { \
-+	DWC_WRITE_REG32(&(((uint32_t*)container->regs->_reg)[num]), data); \
-+}
-+
-+#define dwc_define_read_write_reg(_reg,_container_type) \
-+static inline uint32_t dwc_read_##_reg(_container_type *container) { \
-+	return DWC_READ_REG32(&container->regs->_reg); \
-+} \
-+static inline void dwc_write_##_reg(_container_type *container, uint32_t data) { \
-+	DWC_WRITE_REG32(&container->regs->_reg, data); \
-+}
-+
-+# endif	/* DWC_DEBUG_REGS */
-+
-+#endif	/* DWC_LINUX */
-+
-+#if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
-+
-+# ifdef DWC_DEBUG_REGS
-+
-+#define dwc_define_read_write_reg_n(_reg,_container_type) \
-+static inline uint32_t dwc_read_##_reg##_n(void *io_ctx, _container_type *container, int num) { \
-+	return DWC_READ_REG32(io_ctx, &container->regs->_reg[num]); \
-+} \
-+static inline void dwc_write_##_reg##_n(void *io_ctx, _container_type *container, int num, uint32_t data) { \
-+	DWC_DEBUG("WRITING %8s[%d]: %p: %08x", #_reg, num, \
-+		  &(((uint32_t*)container->regs->_reg)[num]), data); \
-+	DWC_WRITE_REG32(io_ctx, &(((uint32_t*)container->regs->_reg)[num]), data); \
-+}
-+
-+#define dwc_define_read_write_reg(_reg,_container_type) \
-+static inline uint32_t dwc_read_##_reg(void *io_ctx, _container_type *container) { \
-+	return DWC_READ_REG32(io_ctx, &container->regs->_reg); \
-+} \
-+static inline void dwc_write_##_reg(void *io_ctx, _container_type *container, uint32_t data) { \
-+	DWC_DEBUG("WRITING %11s: %p: %08x", #_reg, &container->regs->_reg, data); \
-+	DWC_WRITE_REG32(io_ctx, &container->regs->_reg, data); \
-+}
-+
-+# else	/* DWC_DEBUG_REGS */
-+
-+#define dwc_define_read_write_reg_n(_reg,_container_type) \
-+static inline uint32_t dwc_read_##_reg##_n(void *io_ctx, _container_type *container, int num) { \
-+	return DWC_READ_REG32(io_ctx, &container->regs->_reg[num]); \
-+} \
-+static inline void dwc_write_##_reg##_n(void *io_ctx, _container_type *container, int num, uint32_t data) { \
-+	DWC_WRITE_REG32(io_ctx, &(((uint32_t*)container->regs->_reg)[num]), data); \
-+}
-+
-+#define dwc_define_read_write_reg(_reg,_container_type) \
-+static inline uint32_t dwc_read_##_reg(void *io_ctx, _container_type *container) { \
-+	return DWC_READ_REG32(io_ctx, &container->regs->_reg); \
-+} \
-+static inline void dwc_write_##_reg(void *io_ctx, _container_type *container, uint32_t data) { \
-+	DWC_WRITE_REG32(io_ctx, &container->regs->_reg, data); \
-+}
-+
-+# endif	/* DWC_DEBUG_REGS */
-+
-+#endif	/* DWC_FREEBSD || DWC_NETBSD */
-+
-+/** @endcond */
-+
-+
-+#ifdef DWC_CRYPTOLIB
-+/** @name Crypto Functions
-+ *
-+ * These are the low-level cryptographic functions used by the driver. */
-+
-+/** Perform AES CBC */
-+extern int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out);
-+#define dwc_aes_cbc DWC_AES_CBC
-+
-+/** Fill the provided buffer with random bytes.  These should be cryptographic grade random numbers. */
-+extern void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length);
-+#define dwc_random_bytes DWC_RANDOM_BYTES
-+
-+/** Perform the SHA-256 hash function */
-+extern int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out);
-+#define dwc_sha256 DWC_SHA256
-+
-+/** Calculated the HMAC-SHA256 */
-+extern int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t *out);
-+#define dwc_hmac_sha256 DWC_HMAC_SHA256
-+
-+#endif	/* DWC_CRYPTOLIB */
-+
-+
-+/** @name Memory Allocation
-+ *
-+ * These function provide access to memory allocation.  There are only 2 DMA
-+ * functions and 3 Regular memory functions that need to be implemented.  None
-+ * of the memory debugging routines need to be implemented.  The allocation
-+ * routines all ZERO the contents of the memory.
-+ *
-+ * Defining DWC_DEBUG_MEMORY turns on memory debugging and statistic gathering.
-+ * This checks for memory leaks, keeping track of alloc/free pairs.  It also
-+ * keeps track of how much memory the driver is using at any given time. */
-+
-+#define DWC_PAGE_SIZE 4096
-+#define DWC_PAGE_OFFSET(addr) (((uint32_t)addr) & 0xfff)
-+#define DWC_PAGE_ALIGNED(addr) ((((uint32_t)addr) & 0xfff) == 0)
-+
-+#define DWC_INVALID_DMA_ADDR 0x0
-+
-+#ifdef DWC_LINUX
-+/** Type for a DMA address */
-+typedef dma_addr_t dwc_dma_t;
-+#endif
-+
-+#if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
-+typedef bus_addr_t dwc_dma_t;
-+#endif
-+
-+#ifdef DWC_FREEBSD
-+typedef struct dwc_dmactx {
-+	struct device *dev;
-+	bus_dma_tag_t dma_tag;
-+	bus_dmamap_t dma_map;
-+	bus_addr_t dma_paddr;
-+	void *dma_vaddr;
-+} dwc_dmactx_t;
-+#endif
-+
-+#ifdef DWC_NETBSD
-+typedef struct dwc_dmactx {
-+	struct device *dev;
-+	bus_dma_tag_t dma_tag;
-+	bus_dmamap_t dma_map;
-+	bus_dma_segment_t segs[1];
-+	int nsegs;
-+	bus_addr_t dma_paddr;
-+	void *dma_vaddr;
-+} dwc_dmactx_t;
-+#endif
-+
-+/* @todo these functions will be added in the future */
-+#if 0
-+/**
-+ * Creates a DMA pool from which you can allocate DMA buffers.  Buffers
-+ * allocated from this pool will be guaranteed to meet the size, alignment, and
-+ * boundary requirements specified.
-+ *
-+ * @param[in] size Specifies the size of the buffers that will be allocated from
-+ * this pool.
-+ * @param[in] align Specifies the byte alignment requirements of the buffers
-+ * allocated from this pool.  Must be a power of 2.
-+ * @param[in] boundary Specifies the N-byte boundary that buffers allocated from
-+ * this pool must not cross.
-+ *
-+ * @returns A pointer to an internal opaque structure which is not to be
-+ * accessed outside of these library functions.  Use this handle to specify
-+ * which pools to allocate/free DMA buffers from and also to destroy the pool,
-+ * when you are done with it.
-+ */
-+extern dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size, uint32_t align, uint32_t boundary);
-+
-+/**
-+ * Destroy a DMA pool.  All buffers allocated from that pool must be freed first.
-+ */
-+extern void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool);
-+
-+/**
-+ * Allocate a buffer from the specified DMA pool and zeros its contents.
-+ */
-+extern void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr);
-+
-+/**
-+ * Free a previously allocated buffer from the DMA pool.
-+ */
-+extern void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr);
-+#endif
-+
-+/** Allocates a DMA capable buffer and zeroes its contents. */
-+extern void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr);
-+
-+/** Allocates a DMA capable buffer and zeroes its contents in atomic contest */
-+extern void *__DWC_DMA_ALLOC_ATOMIC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr);
-+
-+/** Frees a previously allocated buffer. */
-+extern void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr);
-+
-+/** Allocates a block of memory and zeroes its contents. */
-+extern void *__DWC_ALLOC(void *mem_ctx, uint32_t size);
-+
-+/** Allocates a block of memory and zeroes its contents, in an atomic manner
-+ * which can be used inside interrupt context.  The size should be sufficiently
-+ * small, a few KB at most, such that failures are not likely to occur.  Can just call
-+ * __DWC_ALLOC if it is atomic. */
-+extern void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size);
-+
-+/** Frees a previously allocated buffer. */
-+extern void __DWC_FREE(void *mem_ctx, void *addr);
-+
-+#ifndef DWC_DEBUG_MEMORY
-+
-+#define DWC_ALLOC(_size_) __DWC_ALLOC(NULL, _size_)
-+#define DWC_ALLOC_ATOMIC(_size_) __DWC_ALLOC_ATOMIC(NULL, _size_)
-+#define DWC_FREE(_addr_) __DWC_FREE(NULL, _addr_)
-+
-+# ifdef DWC_LINUX
-+#define DWC_DMA_ALLOC(_size_,_dma_) __DWC_DMA_ALLOC(NULL, _size_, _dma_)
-+#define DWC_DMA_ALLOC_ATOMIC(_size_,_dma_) __DWC_DMA_ALLOC_ATOMIC(NULL, _size_,_dma_)
-+#define DWC_DMA_FREE(_size_,_virt_,_dma_) __DWC_DMA_FREE(NULL, _size_, _virt_, _dma_)
-+# endif
-+
-+# if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
-+#define DWC_DMA_ALLOC __DWC_DMA_ALLOC
-+#define DWC_DMA_FREE __DWC_DMA_FREE
-+# endif
-+extern void *dwc_dma_alloc_atomic_debug(uint32_t size, dwc_dma_t *dma_addr, char const *func, int line);
-+
-+#else	/* DWC_DEBUG_MEMORY */
-+
-+extern void *dwc_alloc_debug(void *mem_ctx, uint32_t size, char const *func, int line);
-+extern void *dwc_alloc_atomic_debug(void *mem_ctx, uint32_t size, char const *func, int line);
-+extern void dwc_free_debug(void *mem_ctx, void *addr, char const *func, int line);
-+extern void *dwc_dma_alloc_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr,
-+				 char const *func, int line);
-+extern void *dwc_dma_alloc_atomic_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr,
-+				char const *func, int line);
-+extern void dwc_dma_free_debug(void *dma_ctx, uint32_t size, void *virt_addr,
-+			       dwc_dma_t dma_addr, char const *func, int line);
-+
-+extern int dwc_memory_debug_start(void *mem_ctx);
-+extern void dwc_memory_debug_stop(void);
-+extern void dwc_memory_debug_report(void);
-+
-+#define DWC_ALLOC(_size_) dwc_alloc_debug(NULL, _size_, __func__, __LINE__)
-+#define DWC_ALLOC_ATOMIC(_size_) dwc_alloc_atomic_debug(NULL, _size_, \
-+							__func__, __LINE__)
-+#define DWC_FREE(_addr_) dwc_free_debug(NULL, _addr_, __func__, __LINE__)
-+
-+# ifdef DWC_LINUX
-+#define DWC_DMA_ALLOC(_size_,_dma_) dwc_dma_alloc_debug(NULL, _size_, \
-+						_dma_, __func__, __LINE__)
-+#define DWC_DMA_ALLOC_ATOMIC(_size_,_dma_) dwc_dma_alloc_atomic_debug(NULL, _size_, \
-+						_dma_, __func__, __LINE__)
-+#define DWC_DMA_FREE(_size_,_virt_,_dma_) dwc_dma_free_debug(NULL, _size_, \
-+						_virt_, _dma_, __func__, __LINE__)
-+# endif
-+
-+# if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
-+#define DWC_DMA_ALLOC(_ctx_,_size_,_dma_) dwc_dma_alloc_debug(_ctx_, _size_, \
-+						_dma_, __func__, __LINE__)
-+#define DWC_DMA_FREE(_ctx_,_size_,_virt_,_dma_) dwc_dma_free_debug(_ctx_, _size_, \
-+						 _virt_, _dma_, __func__, __LINE__)
-+# endif
-+
-+#endif /* DWC_DEBUG_MEMORY */
-+
-+#define dwc_alloc(_ctx_,_size_) DWC_ALLOC(_size_)
-+#define dwc_alloc_atomic(_ctx_,_size_) DWC_ALLOC_ATOMIC(_size_)
-+#define dwc_free(_ctx_,_addr_) DWC_FREE(_addr_)
-+
-+#ifdef DWC_LINUX
-+/* Linux doesn't need any extra parameters for DMA buffer allocation, so we
-+ * just throw away the DMA context parameter.
-+ */
-+#define dwc_dma_alloc(_ctx_,_size_,_dma_) DWC_DMA_ALLOC(_size_, _dma_)
-+#define dwc_dma_alloc_atomic(_ctx_,_size_,_dma_) DWC_DMA_ALLOC_ATOMIC(_size_, _dma_)
-+#define dwc_dma_free(_ctx_,_size_,_virt_,_dma_) DWC_DMA_FREE(_size_, _virt_, _dma_)
-+#endif
-+
-+#if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
-+/** BSD needs several extra parameters for DMA buffer allocation, so we pass
-+ * them in using the DMA context parameter.
-+ */
-+#define dwc_dma_alloc DWC_DMA_ALLOC
-+#define dwc_dma_free DWC_DMA_FREE
-+#endif
-+
-+
-+/** @name Memory and String Processing */
-+
-+/** memset() clone */
-+extern void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size);
-+#define dwc_memset DWC_MEMSET
-+
-+/** memcpy() clone */
-+extern void *DWC_MEMCPY(void *dest, void const *src, uint32_t size);
-+#define dwc_memcpy DWC_MEMCPY
-+
-+/** memmove() clone */
-+extern void *DWC_MEMMOVE(void *dest, void *src, uint32_t size);
-+#define dwc_memmove DWC_MEMMOVE
-+
-+/** memcmp() clone */
-+extern int DWC_MEMCMP(void *m1, void *m2, uint32_t size);
-+#define dwc_memcmp DWC_MEMCMP
-+
-+/** strcmp() clone */
-+extern int DWC_STRCMP(void *s1, void *s2);
-+#define dwc_strcmp DWC_STRCMP
-+
-+/** strncmp() clone */
-+extern int DWC_STRNCMP(void *s1, void *s2, uint32_t size);
-+#define dwc_strncmp DWC_STRNCMP
-+
-+/** strlen() clone, for NULL terminated ASCII strings */
-+extern int DWC_STRLEN(char const *str);
-+#define dwc_strlen DWC_STRLEN
-+
-+/** strcpy() clone, for NULL terminated ASCII strings */
-+extern char *DWC_STRCPY(char *to, const char *from);
-+#define dwc_strcpy DWC_STRCPY
-+
-+/** strdup() clone.  If you wish to use memory allocation debugging, this
-+ * implementation of strdup should use the DWC_* memory routines instead of
-+ * calling a predefined strdup.  Otherwise the memory allocated by this routine
-+ * will not be seen by the debugging routines. */
-+extern char *DWC_STRDUP(char const *str);
-+#define dwc_strdup(_ctx_,_str_) DWC_STRDUP(_str_)
-+
-+/** NOT an atoi() clone.  Read the description carefully.  Returns an integer
-+ * converted from the string str in base 10 unless the string begins with a "0x"
-+ * in which case it is base 16.  String must be a NULL terminated sequence of
-+ * ASCII characters and may optionally begin with whitespace, a + or -, and a
-+ * "0x" prefix if base 16.  The remaining characters must be valid digits for
-+ * the number and end with a NULL character.  If any invalid characters are
-+ * encountered or it returns with a negative error code and the results of the
-+ * conversion are undefined.  On sucess it returns 0.  Overflow conditions are
-+ * undefined.  An example implementation using atoi() can be referenced from the
-+ * Linux implementation. */
-+extern int DWC_ATOI(const char *str, int32_t *value);
-+#define dwc_atoi DWC_ATOI
-+
-+/** Same as above but for unsigned. */
-+extern int DWC_ATOUI(const char *str, uint32_t *value);
-+#define dwc_atoui DWC_ATOUI
-+
-+#ifdef DWC_UTFLIB
-+/** This routine returns a UTF16LE unicode encoded string from a UTF8 string. */
-+extern int DWC_UTF8_TO_UTF16LE(uint8_t const *utf8string, uint16_t *utf16string, unsigned len);
-+#define dwc_utf8_to_utf16le DWC_UTF8_TO_UTF16LE
-+#endif
-+
-+
-+/** @name Wait queues
-+ *
-+ * Wait queues provide a means of synchronizing between threads or processes.  A
-+ * process can block on a waitq if some condition is not true, waiting for it to
-+ * become true.  When the waitq is triggered all waiting process will get
-+ * unblocked and the condition will be check again.  Waitqs should be triggered
-+ * every time a condition can potentially change.*/
-+struct dwc_waitq;
-+
-+/** Type for a waitq */
-+typedef struct dwc_waitq dwc_waitq_t;
-+
-+/** The type of waitq condition callback function.  This is called every time
-+ * condition is evaluated. */
-+typedef int (*dwc_waitq_condition_t)(void *data);
-+
-+/** Allocate a waitq */
-+extern dwc_waitq_t *DWC_WAITQ_ALLOC(void);
-+#define dwc_waitq_alloc(_ctx_) DWC_WAITQ_ALLOC()
-+
-+/** Free a waitq */
-+extern void DWC_WAITQ_FREE(dwc_waitq_t *wq);
-+#define dwc_waitq_free DWC_WAITQ_FREE
-+
-+/** Check the condition and if it is false, block on the waitq.  When unblocked, check the
-+ * condition again.  The function returns when the condition becomes true.  The return value
-+ * is 0 on condition true, DWC_WAITQ_ABORTED on abort or killed, or DWC_WAITQ_UNKNOWN on error. */
-+extern int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data);
-+#define dwc_waitq_wait DWC_WAITQ_WAIT
-+
-+/** Check the condition and if it is false, block on the waitq.  When unblocked,
-+ * check the condition again.  The function returns when the condition become
-+ * true or the timeout has passed.  The return value is 0 on condition true or
-+ * DWC_TIMED_OUT on timeout, or DWC_WAITQ_ABORTED, or DWC_WAITQ_UNKNOWN on
-+ * error. */
-+extern int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond,
-+				      void *data, int32_t msecs);
-+#define dwc_waitq_wait_timeout DWC_WAITQ_WAIT_TIMEOUT
-+
-+/** Trigger a waitq, unblocking all processes.  This should be called whenever a condition
-+ * has potentially changed. */
-+extern void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq);
-+#define dwc_waitq_trigger DWC_WAITQ_TRIGGER
-+
-+/** Unblock all processes waiting on the waitq with an ABORTED result. */
-+extern void DWC_WAITQ_ABORT(dwc_waitq_t *wq);
-+#define dwc_waitq_abort DWC_WAITQ_ABORT
-+
-+
-+/** @name Threads
-+ *
-+ * A thread must be explicitly stopped.  It must check DWC_THREAD_SHOULD_STOP
-+ * whenever it is woken up, and then return.  The DWC_THREAD_STOP function
-+ * returns the value from the thread.
-+ */
-+
-+struct dwc_thread;
-+
-+/** Type for a thread */
-+typedef struct dwc_thread dwc_thread_t;
-+
-+/** The thread function */
-+typedef int (*dwc_thread_function_t)(void *data);
-+
-+/** Create a thread and start it running the thread_function.  Returns a handle
-+ * to the thread */
-+extern dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data);
-+#define dwc_thread_run(_ctx_,_func_,_name_,_data_) DWC_THREAD_RUN(_func_, _name_, _data_)
-+
-+/** Stops a thread.  Return the value returned by the thread.  Or will return
-+ * DWC_ABORT if the thread never started. */
-+extern int DWC_THREAD_STOP(dwc_thread_t *thread);
-+#define dwc_thread_stop DWC_THREAD_STOP
-+
-+/** Signifies to the thread that it must stop. */
-+#ifdef DWC_LINUX
-+/* Linux doesn't need any parameters for kthread_should_stop() */
-+extern dwc_bool_t DWC_THREAD_SHOULD_STOP(void);
-+#define dwc_thread_should_stop(_thrd_) DWC_THREAD_SHOULD_STOP()
-+
-+/* No thread_exit function in Linux */
-+#define dwc_thread_exit(_thrd_)
-+#endif
-+
-+#if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
-+/** BSD needs the thread pointer for kthread_suspend_check() */
-+extern dwc_bool_t DWC_THREAD_SHOULD_STOP(dwc_thread_t *thread);
-+#define dwc_thread_should_stop DWC_THREAD_SHOULD_STOP
-+
-+/** The thread must call this to exit. */
-+extern void DWC_THREAD_EXIT(dwc_thread_t *thread);
-+#define dwc_thread_exit DWC_THREAD_EXIT
-+#endif
-+
-+
-+/** @name Work queues
-+ *
-+ * Workqs are used to queue a callback function to be called at some later time,
-+ * in another thread. */
-+struct dwc_workq;
-+
-+/** Type for a workq */
-+typedef struct dwc_workq dwc_workq_t;
-+
-+/** The type of the callback function to be called. */
-+typedef void (*dwc_work_callback_t)(void *data);
-+
-+/** Allocate a workq */
-+extern dwc_workq_t *DWC_WORKQ_ALLOC(char *name);
-+#define dwc_workq_alloc(_ctx_,_name_) DWC_WORKQ_ALLOC(_name_)
-+
-+/** Free a workq.  All work must be completed before being freed. */
-+extern void DWC_WORKQ_FREE(dwc_workq_t *workq);
-+#define dwc_workq_free DWC_WORKQ_FREE
-+
-+/** Schedule a callback on the workq, passing in data.  The function will be
-+ * scheduled at some later time. */
-+extern void DWC_WORKQ_SCHEDULE(dwc_workq_t *workq, dwc_work_callback_t cb,
-+			       void *data, char *format, ...)
-+#ifdef __GNUC__
-+	__attribute__ ((format(printf, 4, 5)));
-+#else
-+	;
-+#endif
-+#define dwc_workq_schedule DWC_WORKQ_SCHEDULE
-+
-+/** Schedule a callback on the workq, that will be called until at least
-+ * given number miliseconds have passed. */
-+extern void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *workq, dwc_work_callback_t cb,
-+				       void *data, uint32_t time, char *format, ...)
-+#ifdef __GNUC__
-+	__attribute__ ((format(printf, 5, 6)));
-+#else
-+	;
-+#endif
-+#define dwc_workq_schedule_delayed DWC_WORKQ_SCHEDULE_DELAYED
-+
-+/** The number of processes in the workq */
-+extern int DWC_WORKQ_PENDING(dwc_workq_t *workq);
-+#define dwc_workq_pending DWC_WORKQ_PENDING
-+
-+/** Blocks until all the work in the workq is complete or timed out.  Returns <
-+ * 0 on timeout. */
-+extern int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout);
-+#define dwc_workq_wait_work_done DWC_WORKQ_WAIT_WORK_DONE
-+
-+
-+/** @name Tasklets
-+ *
-+ */
-+struct dwc_tasklet;
-+
-+/** Type for a tasklet */
-+typedef struct dwc_tasklet dwc_tasklet_t;
-+
-+/** The type of the callback function to be called */
-+typedef void (*dwc_tasklet_callback_t)(void *data);
-+
-+/** Allocates a tasklet */
-+extern dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data);
-+#define dwc_task_alloc(_ctx_,_name_,_cb_,_data_) DWC_TASK_ALLOC(_name_, _cb_, _data_)
-+
-+/** Frees a tasklet */
-+extern void DWC_TASK_FREE(dwc_tasklet_t *task);
-+#define dwc_task_free DWC_TASK_FREE
-+
-+/** Schedules a tasklet to run */
-+extern void DWC_TASK_SCHEDULE(dwc_tasklet_t *task);
-+#define dwc_task_schedule DWC_TASK_SCHEDULE
-+
-+extern void DWC_TASK_HI_SCHEDULE(dwc_tasklet_t *task);
-+#define dwc_task_hi_schedule DWC_TASK_HI_SCHEDULE
-+
-+/** @name Timer
-+ *
-+ * Callbacks must be small and atomic.
-+ */
-+struct dwc_timer;
-+
-+/** Type for a timer */
-+typedef struct dwc_timer dwc_timer_t;
-+
-+/** The type of the callback function to be called */
-+typedef void (*dwc_timer_callback_t)(void *data);
-+
-+/** Allocates a timer */
-+extern dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data);
-+#define dwc_timer_alloc(_ctx_,_name_,_cb_,_data_) DWC_TIMER_ALLOC(_name_,_cb_,_data_)
-+
-+/** Frees a timer */
-+extern void DWC_TIMER_FREE(dwc_timer_t *timer);
-+#define dwc_timer_free DWC_TIMER_FREE
-+
-+/** Schedules the timer to run at time ms from now.  And will repeat at every
-+ * repeat_interval msec therafter
-+ *
-+ * Modifies a timer that is still awaiting execution to a new expiration time.
-+ * The mod_time is added to the old time.  */
-+extern void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time);
-+#define dwc_timer_schedule DWC_TIMER_SCHEDULE
-+
-+/** Disables the timer from execution. */
-+extern void DWC_TIMER_CANCEL(dwc_timer_t *timer);
-+#define dwc_timer_cancel DWC_TIMER_CANCEL
-+
-+
-+/** @name Spinlocks
-+ *
-+ * These locks are used when the work between the lock/unlock is atomic and
-+ * short.  Interrupts are also disabled during the lock/unlock and thus they are
-+ * suitable to lock between interrupt/non-interrupt context.  They also lock
-+ * between processes if you have multiple CPUs or Preemption.  If you don't have
-+ * multiple CPUS or Preemption, then the you can simply implement the
-+ * DWC_SPINLOCK and DWC_SPINUNLOCK to disable and enable interrupts.  Because
-+ * the work between the lock/unlock is atomic, the process context will never
-+ * change, and so you never have to lock between processes.  */
-+
-+struct dwc_spinlock;
-+
-+/** Type for a spinlock */
-+typedef struct dwc_spinlock dwc_spinlock_t;
-+
-+/** Type for the 'flags' argument to spinlock funtions */
-+typedef unsigned long dwc_irqflags_t;
-+
-+/** Returns an initialized lock variable.  This function should allocate and
-+ * initialize the OS-specific data structure used for locking.  This data
-+ * structure is to be used for the DWC_LOCK and DWC_UNLOCK functions and should
-+ * be freed by the DWC_FREE_LOCK when it is no longer used.
-+ *
-+ * For Linux Spinlock Debugging make it macro because the debugging routines use
-+ * the symbol name to determine recursive locking. Using a wrapper function
-+ * makes it falsely think recursive locking occurs. */
-+#if defined(DWC_LINUX) && defined(CONFIG_DEBUG_SPINLOCK)
-+#define DWC_SPINLOCK_ALLOC_LINUX_DEBUG(lock) ({ \
-+	lock = DWC_ALLOC(sizeof(spinlock_t)); \
-+	if (lock) { \
-+		spin_lock_init((spinlock_t *)lock); \
-+	} \
-+})
-+#else
-+extern dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void);
-+#define dwc_spinlock_alloc(_ctx_) DWC_SPINLOCK_ALLOC()
-+#endif
-+
-+/** Frees an initialized lock variable. */
-+extern void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock);
-+#define dwc_spinlock_free(_ctx_,_lock_) DWC_SPINLOCK_FREE(_lock_)
-+
-+/** Disables interrupts and blocks until it acquires the lock.
-+ *
-+ * @param lock Pointer to the spinlock.
-+ * @param flags Unsigned long for irq flags storage.
-+ */
-+extern void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags);
-+#define dwc_spinlock_irqsave DWC_SPINLOCK_IRQSAVE
-+
-+/** Re-enables the interrupt and releases the lock.
-+ *
-+ * @param lock Pointer to the spinlock.
-+ * @param flags Unsigned long for irq flags storage.  Must be the same as was
-+ * passed into DWC_LOCK.
-+ */
-+extern void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags);
-+#define dwc_spinunlock_irqrestore DWC_SPINUNLOCK_IRQRESTORE
-+
-+/** Blocks until it acquires the lock.
-+ *
-+ * @param lock Pointer to the spinlock.
-+ */
-+extern void DWC_SPINLOCK(dwc_spinlock_t *lock);
-+#define dwc_spinlock DWC_SPINLOCK
-+
-+/** Releases the lock.
-+ *
-+ * @param lock Pointer to the spinlock.
-+ */
-+extern void DWC_SPINUNLOCK(dwc_spinlock_t *lock);
-+#define dwc_spinunlock DWC_SPINUNLOCK
-+
-+
-+/** @name Mutexes
-+ *
-+ * Unlike spinlocks Mutexes lock only between processes and the work between the
-+ * lock/unlock CAN block, therefore it CANNOT be called from interrupt context.
-+ */
-+
-+struct dwc_mutex;
-+
-+/** Type for a mutex */
-+typedef struct dwc_mutex dwc_mutex_t;
-+
-+/* For Linux Mutex Debugging make it inline because the debugging routines use
-+ * the symbol to determine recursive locking.  This makes it falsely think
-+ * recursive locking occurs. */
-+#if defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES)
-+#define DWC_MUTEX_ALLOC_LINUX_DEBUG(__mutexp) ({ \
-+	__mutexp = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mutex)); \
-+	mutex_init((struct mutex *)__mutexp); \
-+})
-+#endif
-+
-+/** Allocate a mutex */
-+extern dwc_mutex_t *DWC_MUTEX_ALLOC(void);
-+#define dwc_mutex_alloc(_ctx_) DWC_MUTEX_ALLOC()
-+
-+/* For memory leak debugging when using Linux Mutex Debugging */
-+#if defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES)
-+#define DWC_MUTEX_FREE(__mutexp) do { \
-+	mutex_destroy((struct mutex *)__mutexp); \
-+	DWC_FREE(__mutexp); \
-+} while(0)
-+#else
-+/** Free a mutex */
-+extern void DWC_MUTEX_FREE(dwc_mutex_t *mutex);
-+#define dwc_mutex_free(_ctx_,_mutex_) DWC_MUTEX_FREE(_mutex_)
-+#endif
-+
-+/** Lock a mutex */
-+extern void DWC_MUTEX_LOCK(dwc_mutex_t *mutex);
-+#define dwc_mutex_lock DWC_MUTEX_LOCK
-+
-+/** Non-blocking lock returns 1 on successful lock. */
-+extern int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex);
-+#define dwc_mutex_trylock DWC_MUTEX_TRYLOCK
-+
-+/** Unlock a mutex */
-+extern void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex);
-+#define dwc_mutex_unlock DWC_MUTEX_UNLOCK
-+
-+
-+/** @name Time */
-+
-+/** Microsecond delay.
-+ *
-+ * @param usecs  Microseconds to delay.
-+ */
-+extern void DWC_UDELAY(uint32_t usecs);
-+#define dwc_udelay DWC_UDELAY
-+
-+/** Millisecond delay.
-+ *
-+ * @param msecs  Milliseconds to delay.
-+ */
-+extern void DWC_MDELAY(uint32_t msecs);
-+#define dwc_mdelay DWC_MDELAY
-+
-+/** Non-busy waiting.
-+ * Sleeps for specified number of milliseconds.
-+ *
-+ * @param msecs Milliseconds to sleep.
-+ */
-+extern void DWC_MSLEEP(uint32_t msecs);
-+#define dwc_msleep DWC_MSLEEP
-+
-+/**
-+ * Returns number of milliseconds since boot.
-+ */
-+extern uint32_t DWC_TIME(void);
-+#define dwc_time DWC_TIME
-+
-+
-+
-+
-+/* @mainpage DWC Portability and Common Library
-+ *
-+ * This is the documentation for the DWC Portability and Common Library.
-+ *
-+ * @section intro Introduction
-+ *
-+ * The DWC Portability library consists of wrapper calls and data structures to
-+ * all low-level functions which are typically provided by the OS.  The WUDEV
-+ * driver uses only these functions.  In order to port the WUDEV driver, only
-+ * the functions in this library need to be re-implemented, with the same
-+ * behavior as documented here.
-+ *
-+ * The Common library consists of higher level functions, which rely only on
-+ * calling the functions from the DWC Portability library.  These common
-+ * routines are shared across modules.  Some of the common libraries need to be
-+ * used directly by the driver programmer when porting WUDEV.  Such as the
-+ * parameter and notification libraries.
-+ *
-+ * @section low Portability Library OS Wrapper Functions
-+ *
-+ * Any function starting with DWC and in all CAPS is a low-level OS-wrapper that
-+ * needs to be implemented when porting, for example DWC_MUTEX_ALLOC().  All of
-+ * these functions are included in the dwc_os.h file.
-+ *
-+ * There are many functions here covering a wide array of OS services.  Please
-+ * see dwc_os.h for details, and implementation notes for each function.
-+ *
-+ * @section common Common Library Functions
-+ *
-+ * Any function starting with dwc and in all lowercase is a common library
-+ * routine.  These functions have a portable implementation and do not need to
-+ * be reimplemented when porting.  The common routines can be used by any
-+ * driver, and some must be used by the end user to control the drivers.  For
-+ * example, you must use the Parameter common library in order to set the
-+ * parameters in the WUDEV module.
-+ *
-+ * The common libraries consist of the following:
-+ *
-+ * - Connection Contexts - Used internally and can be used by end-user.  See dwc_cc.h
-+ * - Parameters - Used internally and can be used by end-user.  See dwc_params.h
-+ * - Notifications - Used internally and can be used by end-user.  See dwc_notifier.h
-+ * - Lists - Used internally and can be used by end-user.  See dwc_list.h
-+ * - Memory Debugging - Used internally and can be used by end-user.  See dwc_os.h
-+ * - Modpow - Used internally only.  See dwc_modpow.h
-+ * - DH - Used internally only.  See dwc_dh.h
-+ * - Crypto - Used internally only.  See dwc_crypto.h
-+ *
-+ *
-+ * @section prereq Prerequistes For dwc_os.h
-+ * @subsection types Data Types
-+ *
-+ * The dwc_os.h file assumes that several low-level data types are pre defined for the
-+ * compilation environment.  These data types are:
-+ *
-+ * - uint8_t - unsigned 8-bit data type
-+ * - int8_t - signed 8-bit data type
-+ * - uint16_t - unsigned 16-bit data type
-+ * - int16_t - signed 16-bit data type
-+ * - uint32_t - unsigned 32-bit data type
-+ * - int32_t - signed 32-bit data type
-+ * - uint64_t - unsigned 64-bit data type
-+ * - int64_t - signed 64-bit data type
-+ *
-+ * Ensure that these are defined before using dwc_os.h.  The easiest way to do
-+ * that is to modify the top of the file to include the appropriate header.
-+ * This is already done for the Linux environment.  If the DWC_LINUX macro is
-+ * defined, the correct header will be added.  A standard header <stdint.h> is
-+ * also used for environments where standard C headers are available.
-+ *
-+ * @subsection stdarg Variable Arguments
-+ *
-+ * Variable arguments are provided by a standard C header <stdarg.h>.  it is
-+ * available in Both the Linux and ANSI C enviornment.  An equivalent must be
-+ * provided in your enviornment in order to use dwc_os.h with the debug and
-+ * tracing message functionality.
-+ *
-+ * @subsection thread Threading
-+ *
-+ * WUDEV Core must be run on an operating system that provides for multiple
-+ * threads/processes.  Threading can be implemented in many ways, even in
-+ * embedded systems without an operating system.  At the bare minimum, the
-+ * system should be able to start any number of processes at any time to handle
-+ * special work.  It need not be a pre-emptive system.  Process context can
-+ * change upon a call to a blocking function.  The hardware interrupt context
-+ * that calls the module's ISR() function must be differentiable from process
-+ * context, even if your processes are impemented via a hardware interrupt.
-+ * Further locking mechanism between process must exist (or be implemented), and
-+ * process context must have a way to disable interrupts for a period of time to
-+ * lock them out.  If all of this exists, the functions in dwc_os.h related to
-+ * threading should be able to be implemented with the defined behavior.
-+ *
-+ */
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _DWC_OS_H_ */
---- /dev/null
-+++ b/drivers/usb/host/dwc_common_port/usb.h
-@@ -0,0 +1,946 @@
-+/*
-+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
-+ * All rights reserved.
-+ *
-+ * This code is derived from software contributed to The NetBSD Foundation
-+ * by Lennart Augustsson (lennart at augustsson.net) at
-+ * Carlstedt Research & Technology.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ *    must display the following acknowledgement:
-+ *        This product includes software developed by the NetBSD
-+ *        Foundation, Inc. and its contributors.
-+ * 4. Neither the name of The NetBSD Foundation nor the names of its
-+ *    contributors may be used to endorse or promote products derived
-+ *    from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+/* Modified by Synopsys, Inc, 12/12/2007 */
-+
-+
-+#ifndef _USB_H_
-+#define _USB_H_
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * The USB records contain some unaligned little-endian word
-+ * components.  The U[SG]ETW macros take care of both the alignment
-+ * and endian problem and should always be used to access non-byte
-+ * values.
-+ */
-+typedef u_int8_t uByte;
-+typedef u_int8_t uWord[2];
-+typedef u_int8_t uDWord[4];
-+
-+#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h))
-+#define UCONSTW(x)	{ (x) & 0xff, ((x) >> 8) & 0xff }
-+#define UCONSTDW(x)	{ (x) & 0xff, ((x) >> 8) & 0xff, \
-+			  ((x) >> 16) & 0xff, ((x) >> 24) & 0xff }
-+
-+#if 1
-+#define UGETW(w) ((w)[0] | ((w)[1] << 8))
-+#define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8))
-+#define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24))
-+#define USETDW(w,v) ((w)[0] = (u_int8_t)(v), \
-+		     (w)[1] = (u_int8_t)((v) >> 8), \
-+		     (w)[2] = (u_int8_t)((v) >> 16), \
-+		     (w)[3] = (u_int8_t)((v) >> 24))
-+#else
-+/*
-+ * On little-endian machines that can handle unanliged accesses
-+ * (e.g. i386) these macros can be replaced by the following.
-+ */
-+#define UGETW(w) (*(u_int16_t *)(w))
-+#define USETW(w,v) (*(u_int16_t *)(w) = (v))
-+#define UGETDW(w) (*(u_int32_t *)(w))
-+#define USETDW(w,v) (*(u_int32_t *)(w) = (v))
-+#endif
-+
-+/*
-+ * Macros for accessing UAS IU fields, which are big-endian
-+ */
-+#define IUSETW2(w,h,l) ((w)[0] = (u_int8_t)(h), (w)[1] = (u_int8_t)(l))
-+#define IUCONSTW(x)	{ ((x) >> 8) & 0xff, (x) & 0xff }
-+#define IUCONSTDW(x)	{ ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
-+			((x) >> 8) & 0xff, (x) & 0xff }
-+#define IUGETW(w) (((w)[0] << 8) | (w)[1])
-+#define IUSETW(w,v) ((w)[0] = (u_int8_t)((v) >> 8), (w)[1] = (u_int8_t)(v))
-+#define IUGETDW(w) (((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3])
-+#define IUSETDW(w,v) ((w)[0] = (u_int8_t)((v) >> 24), \
-+		      (w)[1] = (u_int8_t)((v) >> 16), \
-+		      (w)[2] = (u_int8_t)((v) >> 8), \
-+		      (w)[3] = (u_int8_t)(v))
-+
-+#define UPACKED __attribute__((__packed__))
-+
-+typedef struct {
-+	uByte		bmRequestType;
-+	uByte		bRequest;
-+	uWord		wValue;
-+	uWord		wIndex;
-+	uWord		wLength;
-+} UPACKED usb_device_request_t;
-+
-+#define UT_GET_DIR(a) ((a) & 0x80)
-+#define UT_WRITE		0x00
-+#define UT_READ			0x80
-+
-+#define UT_GET_TYPE(a) ((a) & 0x60)
-+#define UT_STANDARD		0x00
-+#define UT_CLASS		0x20
-+#define UT_VENDOR		0x40
-+
-+#define UT_GET_RECIPIENT(a) ((a) & 0x1f)
-+#define UT_DEVICE		0x00
-+#define UT_INTERFACE		0x01
-+#define UT_ENDPOINT		0x02
-+#define UT_OTHER		0x03
-+
-+#define UT_READ_DEVICE		(UT_READ  | UT_STANDARD | UT_DEVICE)
-+#define UT_READ_INTERFACE	(UT_READ  | UT_STANDARD | UT_INTERFACE)
-+#define UT_READ_ENDPOINT	(UT_READ  | UT_STANDARD | UT_ENDPOINT)
-+#define UT_WRITE_DEVICE		(UT_WRITE | UT_STANDARD | UT_DEVICE)
-+#define UT_WRITE_INTERFACE	(UT_WRITE | UT_STANDARD | UT_INTERFACE)
-+#define UT_WRITE_ENDPOINT	(UT_WRITE | UT_STANDARD | UT_ENDPOINT)
-+#define UT_READ_CLASS_DEVICE	(UT_READ  | UT_CLASS | UT_DEVICE)
-+#define UT_READ_CLASS_INTERFACE	(UT_READ  | UT_CLASS | UT_INTERFACE)
-+#define UT_READ_CLASS_OTHER	(UT_READ  | UT_CLASS | UT_OTHER)
-+#define UT_READ_CLASS_ENDPOINT	(UT_READ  | UT_CLASS | UT_ENDPOINT)
-+#define UT_WRITE_CLASS_DEVICE	(UT_WRITE | UT_CLASS | UT_DEVICE)
-+#define UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE)
-+#define UT_WRITE_CLASS_OTHER	(UT_WRITE | UT_CLASS | UT_OTHER)
-+#define UT_WRITE_CLASS_ENDPOINT	(UT_WRITE | UT_CLASS | UT_ENDPOINT)
-+#define UT_READ_VENDOR_DEVICE	(UT_READ  | UT_VENDOR | UT_DEVICE)
-+#define UT_READ_VENDOR_INTERFACE (UT_READ  | UT_VENDOR | UT_INTERFACE)
-+#define UT_READ_VENDOR_OTHER	(UT_READ  | UT_VENDOR | UT_OTHER)
-+#define UT_READ_VENDOR_ENDPOINT	(UT_READ  | UT_VENDOR | UT_ENDPOINT)
-+#define UT_WRITE_VENDOR_DEVICE	(UT_WRITE | UT_VENDOR | UT_DEVICE)
-+#define UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE)
-+#define UT_WRITE_VENDOR_OTHER	(UT_WRITE | UT_VENDOR | UT_OTHER)
-+#define UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT)
-+
-+/* Requests */
-+#define UR_GET_STATUS		0x00
-+#define  USTAT_STANDARD_STATUS  0x00
-+#define  WUSTAT_WUSB_FEATURE    0x01
-+#define  WUSTAT_CHANNEL_INFO    0x02
-+#define  WUSTAT_RECEIVED_DATA   0x03
-+#define  WUSTAT_MAS_AVAILABILITY 0x04
-+#define  WUSTAT_CURRENT_TRANSMIT_POWER 0x05
-+#define UR_CLEAR_FEATURE	0x01
-+#define UR_SET_FEATURE		0x03
-+#define UR_SET_AND_TEST_FEATURE 0x0c
-+#define UR_SET_ADDRESS		0x05
-+#define UR_GET_DESCRIPTOR	0x06
-+#define  UDESC_DEVICE		0x01
-+#define  UDESC_CONFIG		0x02
-+#define  UDESC_STRING		0x03
-+#define  UDESC_INTERFACE	0x04
-+#define  UDESC_ENDPOINT		0x05
-+#define  UDESC_SS_USB_COMPANION	0x30
-+#define  UDESC_DEVICE_QUALIFIER	0x06
-+#define  UDESC_OTHER_SPEED_CONFIGURATION 0x07
-+#define  UDESC_INTERFACE_POWER	0x08
-+#define  UDESC_OTG		0x09
-+#define  WUDESC_SECURITY	0x0c
-+#define  WUDESC_KEY		0x0d
-+#define   WUD_GET_KEY_INDEX(_wValue_) ((_wValue_) & 0xf)
-+#define   WUD_GET_KEY_TYPE(_wValue_) (((_wValue_) & 0x30) >> 4)
-+#define    WUD_KEY_TYPE_ASSOC    0x01
-+#define    WUD_KEY_TYPE_GTK      0x02
-+#define   WUD_GET_KEY_ORIGIN(_wValue_) (((_wValue_) & 0x40) >> 6)
-+#define    WUD_KEY_ORIGIN_HOST   0x00
-+#define    WUD_KEY_ORIGIN_DEVICE 0x01
-+#define  WUDESC_ENCRYPTION_TYPE	0x0e
-+#define  WUDESC_BOS		0x0f
-+#define  WUDESC_DEVICE_CAPABILITY 0x10
-+#define  WUDESC_WIRELESS_ENDPOINT_COMPANION 0x11
-+#define  UDESC_BOS		0x0f
-+#define  UDESC_DEVICE_CAPABILITY 0x10
-+#define  UDESC_CS_DEVICE	0x21	/* class specific */
-+#define  UDESC_CS_CONFIG	0x22
-+#define  UDESC_CS_STRING	0x23
-+#define  UDESC_CS_INTERFACE	0x24
-+#define  UDESC_CS_ENDPOINT	0x25
-+#define  UDESC_HUB		0x29
-+#define UR_SET_DESCRIPTOR	0x07
-+#define UR_GET_CONFIG		0x08
-+#define UR_SET_CONFIG		0x09
-+#define UR_GET_INTERFACE	0x0a
-+#define UR_SET_INTERFACE	0x0b
-+#define UR_SYNCH_FRAME		0x0c
-+#define WUR_SET_ENCRYPTION      0x0d
-+#define WUR_GET_ENCRYPTION	0x0e
-+#define WUR_SET_HANDSHAKE	0x0f
-+#define WUR_GET_HANDSHAKE	0x10
-+#define WUR_SET_CONNECTION	0x11
-+#define WUR_SET_SECURITY_DATA	0x12
-+#define WUR_GET_SECURITY_DATA	0x13
-+#define WUR_SET_WUSB_DATA	0x14
-+#define  WUDATA_DRPIE_INFO	0x01
-+#define  WUDATA_TRANSMIT_DATA	0x02
-+#define  WUDATA_TRANSMIT_PARAMS	0x03
-+#define  WUDATA_RECEIVE_PARAMS	0x04
-+#define  WUDATA_TRANSMIT_POWER	0x05
-+#define WUR_LOOPBACK_DATA_WRITE	0x15
-+#define WUR_LOOPBACK_DATA_READ	0x16
-+#define WUR_SET_INTERFACE_DS	0x17
-+
-+/* Feature numbers */
-+#define UF_ENDPOINT_HALT	0
-+#define UF_DEVICE_REMOTE_WAKEUP	1
-+#define UF_TEST_MODE		2
-+#define UF_DEVICE_B_HNP_ENABLE	3
-+#define UF_DEVICE_A_HNP_SUPPORT	4
-+#define UF_DEVICE_A_ALT_HNP_SUPPORT 5
-+#define WUF_WUSB		3
-+#define  WUF_TX_DRPIE		0x0
-+#define  WUF_DEV_XMIT_PACKET	0x1
-+#define  WUF_COUNT_PACKETS	0x2
-+#define  WUF_CAPTURE_PACKETS	0x3
-+#define UF_FUNCTION_SUSPEND	0
-+#define UF_U1_ENABLE		48
-+#define UF_U2_ENABLE		49
-+#define UF_LTM_ENABLE		50
-+
-+/* Class requests from the USB 2.0 hub spec, table 11-15 */
-+#define UCR_CLEAR_HUB_FEATURE		(0x2000 | UR_CLEAR_FEATURE)
-+#define UCR_CLEAR_PORT_FEATURE		(0x2300 | UR_CLEAR_FEATURE)
-+#define UCR_GET_HUB_DESCRIPTOR		(0xa000 | UR_GET_DESCRIPTOR)
-+#define UCR_GET_HUB_STATUS		(0xa000 | UR_GET_STATUS)
-+#define UCR_GET_PORT_STATUS		(0xa300 | UR_GET_STATUS)
-+#define UCR_SET_HUB_FEATURE		(0x2000 | UR_SET_FEATURE)
-+#define UCR_SET_PORT_FEATURE		(0x2300 | UR_SET_FEATURE)
-+#define UCR_SET_AND_TEST_PORT_FEATURE	(0xa300 | UR_SET_AND_TEST_FEATURE)
-+
-+#ifdef _MSC_VER
-+#include <pshpack1.h>
-+#endif
-+
-+typedef struct {
-+	uByte		bLength;
-+	uByte		bDescriptorType;
-+	uByte		bDescriptorSubtype;
-+} UPACKED usb_descriptor_t;
-+
-+typedef struct {
-+	uByte		bLength;
-+	uByte		bDescriptorType;
-+} UPACKED usb_descriptor_header_t;
-+
-+typedef struct {
-+	uByte		bLength;
-+	uByte		bDescriptorType;
-+	uWord		bcdUSB;
-+#define UD_USB_2_0		0x0200
-+#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0)
-+	uByte		bDeviceClass;
-+	uByte		bDeviceSubClass;
-+	uByte		bDeviceProtocol;
-+	uByte		bMaxPacketSize;
-+	/* The fields below are not part of the initial descriptor. */
-+	uWord		idVendor;
-+	uWord		idProduct;
-+	uWord		bcdDevice;
-+	uByte		iManufacturer;
-+	uByte		iProduct;
-+	uByte		iSerialNumber;
-+	uByte		bNumConfigurations;
-+} UPACKED usb_device_descriptor_t;
-+#define USB_DEVICE_DESCRIPTOR_SIZE 18
-+
-+typedef struct {
-+	uByte		bLength;
-+	uByte		bDescriptorType;
-+	uWord		wTotalLength;
-+	uByte		bNumInterface;
-+	uByte		bConfigurationValue;
-+	uByte		iConfiguration;
-+#define UC_ATT_ONE		(1 << 7)	/* must be set */
-+#define UC_ATT_SELFPOWER	(1 << 6)	/* self powered */
-+#define UC_ATT_WAKEUP		(1 << 5)	/* can wakeup */
-+#define UC_ATT_BATTERY		(1 << 4)	/* battery powered */
-+	uByte		bmAttributes;
-+#define UC_BUS_POWERED		0x80
-+#define UC_SELF_POWERED		0x40
-+#define UC_REMOTE_WAKEUP	0x20
-+	uByte		bMaxPower; /* max current in 2 mA units */
-+#define UC_POWER_FACTOR 2
-+} UPACKED usb_config_descriptor_t;
-+#define USB_CONFIG_DESCRIPTOR_SIZE 9
-+
-+typedef struct {
-+	uByte		bLength;
-+	uByte		bDescriptorType;
-+	uByte		bInterfaceNumber;
-+	uByte		bAlternateSetting;
-+	uByte		bNumEndpoints;
-+	uByte		bInterfaceClass;
-+	uByte		bInterfaceSubClass;
-+	uByte		bInterfaceProtocol;
-+	uByte		iInterface;
-+} UPACKED usb_interface_descriptor_t;
-+#define USB_INTERFACE_DESCRIPTOR_SIZE 9
-+
-+typedef struct {
-+	uByte		bLength;
-+	uByte		bDescriptorType;
-+	uByte		bEndpointAddress;
-+#define UE_GET_DIR(a)	((a) & 0x80)
-+#define UE_SET_DIR(a,d)	((a) | (((d)&1) << 7))
-+#define UE_DIR_IN	0x80
-+#define UE_DIR_OUT	0x00
-+#define UE_ADDR		0x0f
-+#define UE_GET_ADDR(a)	((a) & UE_ADDR)
-+	uByte		bmAttributes;
-+#define UE_XFERTYPE	0x03
-+#define  UE_CONTROL	0x00
-+#define  UE_ISOCHRONOUS	0x01
-+#define  UE_BULK	0x02
-+#define  UE_INTERRUPT	0x03
-+#define UE_GET_XFERTYPE(a)	((a) & UE_XFERTYPE)
-+#define UE_ISO_TYPE	0x0c
-+#define  UE_ISO_ASYNC	0x04
-+#define  UE_ISO_ADAPT	0x08
-+#define  UE_ISO_SYNC	0x0c
-+#define UE_GET_ISO_TYPE(a)	((a) & UE_ISO_TYPE)
-+	uWord		wMaxPacketSize;
-+	uByte		bInterval;
-+} UPACKED usb_endpoint_descriptor_t;
-+#define USB_ENDPOINT_DESCRIPTOR_SIZE 7
-+
-+typedef struct ss_endpoint_companion_descriptor {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uByte bMaxBurst;
-+#define USSE_GET_MAX_STREAMS(a)		((a) & 0x1f)
-+#define USSE_SET_MAX_STREAMS(a, b)	((a) | ((b) & 0x1f))
-+#define USSE_GET_MAX_PACKET_NUM(a)	((a) & 0x03)
-+#define USSE_SET_MAX_PACKET_NUM(a, b)	((a) | ((b) & 0x03))
-+	uByte bmAttributes;
-+	uWord wBytesPerInterval;
-+} UPACKED ss_endpoint_companion_descriptor_t;
-+#define USB_SS_ENDPOINT_COMPANION_DESCRIPTOR_SIZE 6
-+
-+typedef struct {
-+	uByte		bLength;
-+	uByte		bDescriptorType;
-+	uWord		bString[127];
-+} UPACKED usb_string_descriptor_t;
-+#define USB_MAX_STRING_LEN 128
-+#define USB_LANGUAGE_TABLE 0	/* # of the string language id table */
-+
-+/* Hub specific request */
-+#define UR_GET_BUS_STATE	0x02
-+#define UR_CLEAR_TT_BUFFER	0x08
-+#define UR_RESET_TT		0x09
-+#define UR_GET_TT_STATE		0x0a
-+#define UR_STOP_TT		0x0b
-+
-+/* Hub features */
-+#define UHF_C_HUB_LOCAL_POWER	0
-+#define UHF_C_HUB_OVER_CURRENT	1
-+#define UHF_PORT_CONNECTION	0
-+#define UHF_PORT_ENABLE		1
-+#define UHF_PORT_SUSPEND	2
-+#define UHF_PORT_OVER_CURRENT	3
-+#define UHF_PORT_RESET		4
-+#define UHF_PORT_L1		5
-+#define UHF_PORT_POWER		8
-+#define UHF_PORT_LOW_SPEED	9
-+#define UHF_PORT_HIGH_SPEED	10
-+#define UHF_C_PORT_CONNECTION	16
-+#define UHF_C_PORT_ENABLE	17
-+#define UHF_C_PORT_SUSPEND	18
-+#define UHF_C_PORT_OVER_CURRENT	19
-+#define UHF_C_PORT_RESET	20
-+#define UHF_C_PORT_L1		23
-+#define UHF_PORT_TEST		21
-+#define UHF_PORT_INDICATOR	22
-+
-+typedef struct {
-+	uByte		bDescLength;
-+	uByte		bDescriptorType;
-+	uByte		bNbrPorts;
-+	uWord		wHubCharacteristics;
-+#define UHD_PWR			0x0003
-+#define  UHD_PWR_GANGED		0x0000
-+#define  UHD_PWR_INDIVIDUAL	0x0001
-+#define  UHD_PWR_NO_SWITCH	0x0002
-+#define UHD_COMPOUND		0x0004
-+#define UHD_OC			0x0018
-+#define  UHD_OC_GLOBAL		0x0000
-+#define  UHD_OC_INDIVIDUAL	0x0008
-+#define  UHD_OC_NONE		0x0010
-+#define UHD_TT_THINK		0x0060
-+#define  UHD_TT_THINK_8		0x0000
-+#define  UHD_TT_THINK_16	0x0020
-+#define  UHD_TT_THINK_24	0x0040
-+#define  UHD_TT_THINK_32	0x0060
-+#define UHD_PORT_IND		0x0080
-+	uByte		bPwrOn2PwrGood;	/* delay in 2 ms units */
-+#define UHD_PWRON_FACTOR 2
-+	uByte		bHubContrCurrent;
-+	uByte		DeviceRemovable[32]; /* max 255 ports */
-+#define UHD_NOT_REMOV(desc, i) \
-+    (((desc)->DeviceRemovable[(i)/8] >> ((i) % 8)) & 1)
-+	/* deprecated */ uByte		PortPowerCtrlMask[1];
-+} UPACKED usb_hub_descriptor_t;
-+#define USB_HUB_DESCRIPTOR_SIZE 9 /* includes deprecated PortPowerCtrlMask */
-+
-+typedef struct {
-+	uByte		bLength;
-+	uByte		bDescriptorType;
-+	uWord		bcdUSB;
-+	uByte		bDeviceClass;
-+	uByte		bDeviceSubClass;
-+	uByte		bDeviceProtocol;
-+	uByte		bMaxPacketSize0;
-+	uByte		bNumConfigurations;
-+	uByte		bReserved;
-+} UPACKED usb_device_qualifier_t;
-+#define USB_DEVICE_QUALIFIER_SIZE 10
-+
-+typedef struct {
-+	uByte		bLength;
-+	uByte		bDescriptorType;
-+	uByte		bmAttributes;
-+#define UOTG_SRP	0x01
-+#define UOTG_HNP	0x02
-+} UPACKED usb_otg_descriptor_t;
-+
-+/* OTG feature selectors */
-+#define UOTG_B_HNP_ENABLE	3
-+#define UOTG_A_HNP_SUPPORT	4
-+#define UOTG_A_ALT_HNP_SUPPORT	5
-+
-+typedef struct {
-+	uWord		wStatus;
-+/* Device status flags */
-+#define UDS_SELF_POWERED		0x0001
-+#define UDS_REMOTE_WAKEUP		0x0002
-+/* Endpoint status flags */
-+#define UES_HALT			0x0001
-+} UPACKED usb_status_t;
-+
-+typedef struct {
-+	uWord		wHubStatus;
-+#define UHS_LOCAL_POWER			0x0001
-+#define UHS_OVER_CURRENT		0x0002
-+	uWord		wHubChange;
-+} UPACKED usb_hub_status_t;
-+
-+typedef struct {
-+	uWord		wPortStatus;
-+#define UPS_CURRENT_CONNECT_STATUS	0x0001
-+#define UPS_PORT_ENABLED		0x0002
-+#define UPS_SUSPEND			0x0004
-+#define UPS_OVERCURRENT_INDICATOR	0x0008
-+#define UPS_RESET			0x0010
-+#define UPS_PORT_POWER			0x0100
-+#define UPS_LOW_SPEED			0x0200
-+#define UPS_HIGH_SPEED			0x0400
-+#define UPS_PORT_TEST			0x0800
-+#define UPS_PORT_INDICATOR		0x1000
-+	uWord		wPortChange;
-+#define UPS_C_CONNECT_STATUS		0x0001
-+#define UPS_C_PORT_ENABLED		0x0002
-+#define UPS_C_SUSPEND			0x0004
-+#define UPS_C_OVERCURRENT_INDICATOR	0x0008
-+#define UPS_C_PORT_RESET		0x0010
-+} UPACKED usb_port_status_t;
-+
-+#ifdef _MSC_VER
-+#include <poppack.h>
-+#endif
-+
-+/* Device class codes */
-+#define UDCLASS_IN_INTERFACE	0x00
-+#define UDCLASS_COMM		0x02
-+#define UDCLASS_HUB		0x09
-+#define  UDSUBCLASS_HUB		0x00
-+#define  UDPROTO_FSHUB		0x00
-+#define  UDPROTO_HSHUBSTT	0x01
-+#define  UDPROTO_HSHUBMTT	0x02
-+#define UDCLASS_DIAGNOSTIC	0xdc
-+#define UDCLASS_WIRELESS	0xe0
-+#define  UDSUBCLASS_RF		0x01
-+#define   UDPROTO_BLUETOOTH	0x01
-+#define UDCLASS_VENDOR		0xff
-+
-+/* Interface class codes */
-+#define UICLASS_UNSPEC		0x00
-+
-+#define UICLASS_AUDIO		0x01
-+#define  UISUBCLASS_AUDIOCONTROL	1
-+#define  UISUBCLASS_AUDIOSTREAM		2
-+#define  UISUBCLASS_MIDISTREAM		3
-+
-+#define UICLASS_CDC		0x02 /* communication */
-+#define  UISUBCLASS_DIRECT_LINE_CONTROL_MODEL	1
-+#define  UISUBCLASS_ABSTRACT_CONTROL_MODEL	2
-+#define  UISUBCLASS_TELEPHONE_CONTROL_MODEL	3
-+#define  UISUBCLASS_MULTICHANNEL_CONTROL_MODEL	4
-+#define  UISUBCLASS_CAPI_CONTROLMODEL		5
-+#define  UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
-+#define  UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
-+#define   UIPROTO_CDC_AT			1
-+
-+#define UICLASS_HID		0x03
-+#define  UISUBCLASS_BOOT	1
-+#define  UIPROTO_BOOT_KEYBOARD	1
-+
-+#define UICLASS_PHYSICAL	0x05
-+
-+#define UICLASS_IMAGE		0x06
-+
-+#define UICLASS_PRINTER		0x07
-+#define  UISUBCLASS_PRINTER	1
-+#define  UIPROTO_PRINTER_UNI	1
-+#define  UIPROTO_PRINTER_BI	2
-+#define  UIPROTO_PRINTER_1284	3
-+
-+#define UICLASS_MASS		0x08
-+#define  UISUBCLASS_RBC		1
-+#define  UISUBCLASS_SFF8020I	2
-+#define  UISUBCLASS_QIC157	3
-+#define  UISUBCLASS_UFI		4
-+#define  UISUBCLASS_SFF8070I	5
-+#define  UISUBCLASS_SCSI	6
-+#define  UIPROTO_MASS_CBI_I	0
-+#define  UIPROTO_MASS_CBI	1
-+#define  UIPROTO_MASS_BBB_OLD	2	/* Not in the spec anymore */
-+#define  UIPROTO_MASS_BBB	80	/* 'P' for the Iomega Zip drive */
-+
-+#define UICLASS_HUB		0x09
-+#define  UISUBCLASS_HUB		0
-+#define  UIPROTO_FSHUB		0
-+#define  UIPROTO_HSHUBSTT	0 /* Yes, same as previous */
-+#define  UIPROTO_HSHUBMTT	1
-+
-+#define UICLASS_CDC_DATA	0x0a
-+#define  UISUBCLASS_DATA		0
-+#define   UIPROTO_DATA_ISDNBRI		0x30    /* Physical iface */
-+#define   UIPROTO_DATA_HDLC		0x31    /* HDLC */
-+#define   UIPROTO_DATA_TRANSPARENT	0x32    /* Transparent */
-+#define   UIPROTO_DATA_Q921M		0x50    /* Management for Q921 */
-+#define   UIPROTO_DATA_Q921		0x51    /* Data for Q921 */
-+#define   UIPROTO_DATA_Q921TM		0x52    /* TEI multiplexer for Q921 */
-+#define   UIPROTO_DATA_V42BIS		0x90    /* Data compression */
-+#define   UIPROTO_DATA_Q931		0x91    /* Euro-ISDN */
-+#define   UIPROTO_DATA_V120		0x92    /* V.24 rate adaption */
-+#define   UIPROTO_DATA_CAPI		0x93    /* CAPI 2.0 commands */
-+#define   UIPROTO_DATA_HOST_BASED	0xfd    /* Host based driver */
-+#define   UIPROTO_DATA_PUF		0xfe    /* see Prot. Unit Func. Desc.*/
-+#define   UIPROTO_DATA_VENDOR		0xff    /* Vendor specific */
-+
-+#define UICLASS_SMARTCARD	0x0b
-+
-+/*#define UICLASS_FIRM_UPD	0x0c*/
-+
-+#define UICLASS_SECURITY	0x0d
-+
-+#define UICLASS_DIAGNOSTIC	0xdc
-+
-+#define UICLASS_WIRELESS	0xe0
-+#define  UISUBCLASS_RF			0x01
-+#define   UIPROTO_BLUETOOTH		0x01
-+
-+#define UICLASS_APPL_SPEC	0xfe
-+#define  UISUBCLASS_FIRMWARE_DOWNLOAD	1
-+#define  UISUBCLASS_IRDA		2
-+#define  UIPROTO_IRDA			0
-+
-+#define UICLASS_VENDOR		0xff
-+
-+#define USB_HUB_MAX_DEPTH 5
-+
-+/*
-+ * Minimum time a device needs to be powered down to go through
-+ * a power cycle.  XXX Are these time in the spec?
-+ */
-+#define USB_POWER_DOWN_TIME	200 /* ms */
-+#define USB_PORT_POWER_DOWN_TIME	100 /* ms */
-+
-+#if 0
-+/* These are the values from the spec. */
-+#define USB_PORT_RESET_DELAY	10  /* ms */
-+#define USB_PORT_ROOT_RESET_DELAY 50  /* ms */
-+#define USB_PORT_RESET_RECOVERY	10  /* ms */
-+#define USB_PORT_POWERUP_DELAY	100 /* ms */
-+#define USB_SET_ADDRESS_SETTLE	2   /* ms */
-+#define USB_RESUME_DELAY	(20*5)  /* ms */
-+#define USB_RESUME_WAIT		10  /* ms */
-+#define USB_RESUME_RECOVERY	10  /* ms */
-+#define USB_EXTRA_POWER_UP_TIME	0   /* ms */
-+#else
-+/* Allow for marginal (i.e. non-conforming) devices. */
-+#define USB_PORT_RESET_DELAY	50  /* ms */
-+#define USB_PORT_ROOT_RESET_DELAY 250  /* ms */
-+#define USB_PORT_RESET_RECOVERY	250  /* ms */
-+#define USB_PORT_POWERUP_DELAY	300 /* ms */
-+#define USB_SET_ADDRESS_SETTLE	10  /* ms */
-+#define USB_RESUME_DELAY	(50*5)  /* ms */
-+#define USB_RESUME_WAIT		50  /* ms */
-+#define USB_RESUME_RECOVERY	50  /* ms */
-+#define USB_EXTRA_POWER_UP_TIME	20  /* ms */
-+#endif
-+
-+#define USB_MIN_POWER		100 /* mA */
-+#define USB_MAX_POWER		500 /* mA */
-+
-+#define USB_BUS_RESET_DELAY	100 /* ms XXX?*/
-+
-+#define USB_UNCONFIG_NO 0
-+#define USB_UNCONFIG_INDEX (-1)
-+
-+/*** ioctl() related stuff ***/
-+
-+struct usb_ctl_request {
-+	int	ucr_addr;
-+	usb_device_request_t ucr_request;
-+	void	*ucr_data;
-+	int	ucr_flags;
-+#define USBD_SHORT_XFER_OK	0x04	/* allow short reads */
-+	int	ucr_actlen;		/* actual length transferred */
-+};
-+
-+struct usb_alt_interface {
-+	int	uai_config_index;
-+	int	uai_interface_index;
-+	int	uai_alt_no;
-+};
-+
-+#define USB_CURRENT_CONFIG_INDEX (-1)
-+#define USB_CURRENT_ALT_INDEX (-1)
-+
-+struct usb_config_desc {
-+	int	ucd_config_index;
-+	usb_config_descriptor_t ucd_desc;
-+};
-+
-+struct usb_interface_desc {
-+	int	uid_config_index;
-+	int	uid_interface_index;
-+	int	uid_alt_index;
-+	usb_interface_descriptor_t uid_desc;
-+};
-+
-+struct usb_endpoint_desc {
-+	int	ued_config_index;
-+	int	ued_interface_index;
-+	int	ued_alt_index;
-+	int	ued_endpoint_index;
-+	usb_endpoint_descriptor_t ued_desc;
-+};
-+
-+struct usb_full_desc {
-+	int	ufd_config_index;
-+	u_int	ufd_size;
-+	u_char	*ufd_data;
-+};
-+
-+struct usb_string_desc {
-+	int	usd_string_index;
-+	int	usd_language_id;
-+	usb_string_descriptor_t usd_desc;
-+};
-+
-+struct usb_ctl_report_desc {
-+	int	ucrd_size;
-+	u_char	ucrd_data[1024];	/* filled data size will vary */
-+};
-+
-+typedef struct { u_int32_t cookie; } usb_event_cookie_t;
-+
-+#define USB_MAX_DEVNAMES 4
-+#define USB_MAX_DEVNAMELEN 16
-+struct usb_device_info {
-+	u_int8_t	udi_bus;
-+	u_int8_t	udi_addr;	/* device address */
-+	usb_event_cookie_t udi_cookie;
-+	char		udi_product[USB_MAX_STRING_LEN];
-+	char		udi_vendor[USB_MAX_STRING_LEN];
-+	char		udi_release[8];
-+	u_int16_t	udi_productNo;
-+	u_int16_t	udi_vendorNo;
-+	u_int16_t	udi_releaseNo;
-+	u_int8_t	udi_class;
-+	u_int8_t	udi_subclass;
-+	u_int8_t	udi_protocol;
-+	u_int8_t	udi_config;
-+	u_int8_t	udi_speed;
-+#define USB_SPEED_UNKNOWN	0
-+#define USB_SPEED_LOW		1
-+#define USB_SPEED_FULL		2
-+#define USB_SPEED_HIGH		3
-+#define USB_SPEED_VARIABLE	4
-+#define USB_SPEED_SUPER		5
-+	int		udi_power;	/* power consumption in mA, 0 if selfpowered */
-+	int		udi_nports;
-+	char		udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
-+	u_int8_t	udi_ports[16];/* hub only: addresses of devices on ports */
-+#define USB_PORT_ENABLED 0xff
-+#define USB_PORT_SUSPENDED 0xfe
-+#define USB_PORT_POWERED 0xfd
-+#define USB_PORT_DISABLED 0xfc
-+};
-+
-+struct usb_ctl_report {
-+	int	ucr_report;
-+	u_char	ucr_data[1024];	/* filled data size will vary */
-+};
-+
-+struct usb_device_stats {
-+	u_long	uds_requests[4];	/* indexed by transfer type UE_* */
-+};
-+
-+#define WUSB_MIN_IE			0x80
-+#define WUSB_WCTA_IE			0x80
-+#define WUSB_WCONNECTACK_IE		0x81
-+#define WUSB_WHOSTINFO_IE		0x82
-+#define  WUHI_GET_CA(_bmAttributes_) ((_bmAttributes_) & 0x3)
-+#define   WUHI_CA_RECONN		0x00
-+#define   WUHI_CA_LIMITED		0x01
-+#define   WUHI_CA_ALL			0x03
-+#define  WUHI_GET_MLSI(_bmAttributes_) (((_bmAttributes_) & 0x38) >> 3)
-+#define WUSB_WCHCHANGEANNOUNCE_IE	0x83
-+#define WUSB_WDEV_DISCONNECT_IE		0x84
-+#define WUSB_WHOST_DISCONNECT_IE	0x85
-+#define WUSB_WRELEASE_CHANNEL_IE	0x86
-+#define WUSB_WWORK_IE			0x87
-+#define WUSB_WCHANNEL_STOP_IE		0x88
-+#define WUSB_WDEV_KEEPALIVE_IE		0x89
-+#define WUSB_WISOCH_DISCARD_IE		0x8A
-+#define WUSB_WRESETDEVICE_IE		0x8B
-+#define WUSB_WXMIT_PACKET_ADJUST_IE	0x8C
-+#define WUSB_MAX_IE			0x8C
-+
-+/* Device Notification Types */
-+
-+#define WUSB_DN_MIN			0x01
-+#define WUSB_DN_CONNECT			0x01
-+# define WUSB_DA_OLDCONN	0x00
-+# define WUSB_DA_NEWCONN	0x01
-+# define WUSB_DA_SELF_BEACON	0x02
-+# define WUSB_DA_DIR_BEACON	0x04
-+# define WUSB_DA_NO_BEACON	0x06
-+#define WUSB_DN_DISCONNECT		0x02
-+#define WUSB_DN_EPRDY			0x03
-+#define WUSB_DN_MASAVAILCHANGED		0x04
-+#define WUSB_DN_REMOTEWAKEUP		0x05
-+#define WUSB_DN_SLEEP			0x06
-+#define WUSB_DN_ALIVE			0x07
-+#define WUSB_DN_MAX			0x07
-+
-+#ifdef _MSC_VER
-+#include <pshpack1.h>
-+#endif
-+
-+/* WUSB Handshake Data.  Used during the SET/GET HANDSHAKE requests */
-+typedef struct wusb_hndshk_data {
-+	uByte bMessageNumber;
-+	uByte bStatus;
-+	uByte tTKID[3];
-+	uByte bReserved;
-+	uByte CDID[16];
-+	uByte Nonce[16];
-+	uByte MIC[8];
-+} UPACKED wusb_hndshk_data_t;
-+#define WUSB_HANDSHAKE_LEN_FOR_MIC	38
-+
-+/* WUSB Connection Context */
-+typedef struct wusb_conn_context {
-+	uByte CHID [16];
-+	uByte CDID [16];
-+	uByte CK [16];
-+} UPACKED wusb_conn_context_t;
-+
-+/* WUSB Security Descriptor */
-+typedef struct wusb_security_desc {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uWord wTotalLength;
-+	uByte bNumEncryptionTypes;
-+} UPACKED wusb_security_desc_t;
-+
-+/* WUSB Encryption Type Descriptor */
-+typedef struct wusb_encrypt_type_desc {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+
-+	uByte bEncryptionType;
-+#define WUETD_UNSECURE		0
-+#define WUETD_WIRED		1
-+#define WUETD_CCM_1		2
-+#define WUETD_RSA_1		3
-+
-+	uByte bEncryptionValue;
-+	uByte bAuthKeyIndex;
-+} UPACKED wusb_encrypt_type_desc_t;
-+
-+/* WUSB Key Descriptor */
-+typedef struct wusb_key_desc {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uByte tTKID[3];
-+	uByte bReserved;
-+	uByte KeyData[1];	/* variable length */
-+} UPACKED wusb_key_desc_t;
-+
-+/* WUSB BOS Descriptor (Binary device Object Store) */
-+typedef struct wusb_bos_desc {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uWord wTotalLength;
-+	uByte bNumDeviceCaps;
-+} UPACKED wusb_bos_desc_t;
-+
-+#define USB_DEVICE_CAPABILITY_20_EXTENSION	0x02
-+typedef struct usb_dev_cap_20_ext_desc {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uByte bDevCapabilityType;
-+#define USB_20_EXT_LPM				0x02
-+	uDWord bmAttributes;
-+} UPACKED usb_dev_cap_20_ext_desc_t;
-+
-+#define USB_DEVICE_CAPABILITY_SS_USB		0x03
-+typedef struct usb_dev_cap_ss_usb {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uByte bDevCapabilityType;
-+#define USB_DC_SS_USB_LTM_CAPABLE		0x02
-+	uByte bmAttributes;
-+#define USB_DC_SS_USB_SPEED_SUPPORT_LOW		0x01
-+#define USB_DC_SS_USB_SPEED_SUPPORT_FULL	0x02
-+#define USB_DC_SS_USB_SPEED_SUPPORT_HIGH	0x04
-+#define USB_DC_SS_USB_SPEED_SUPPORT_SS		0x08
-+	uWord wSpeedsSupported;
-+	uByte bFunctionalitySupport;
-+	uByte bU1DevExitLat;
-+	uWord wU2DevExitLat;
-+} UPACKED usb_dev_cap_ss_usb_t;
-+
-+#define USB_DEVICE_CAPABILITY_CONTAINER_ID	0x04
-+typedef struct usb_dev_cap_container_id {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uByte bDevCapabilityType;
-+	uByte bReserved;
-+	uByte containerID[16];
-+} UPACKED usb_dev_cap_container_id_t;
-+
-+/* Device Capability Type Codes */
-+#define WUSB_DEVICE_CAPABILITY_WIRELESS_USB 0x01
-+
-+/* Device Capability Descriptor */
-+typedef struct wusb_dev_cap_desc {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uByte bDevCapabilityType;
-+	uByte caps[1];	/* Variable length */
-+} UPACKED wusb_dev_cap_desc_t;
-+
-+/* Device Capability Descriptor */
-+typedef struct wusb_dev_cap_uwb_desc {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uByte bDevCapabilityType;
-+	uByte bmAttributes;
-+	uWord wPHYRates;	/* Bitmap */
-+	uByte bmTFITXPowerInfo;
-+	uByte bmFFITXPowerInfo;
-+	uWord bmBandGroup;
-+	uByte bReserved;
-+} UPACKED wusb_dev_cap_uwb_desc_t;
-+
-+/* Wireless USB Endpoint Companion Descriptor */
-+typedef struct wusb_endpoint_companion_desc {
-+	uByte bLength;
-+	uByte bDescriptorType;
-+	uByte bMaxBurst;
-+	uByte bMaxSequence;
-+	uWord wMaxStreamDelay;
-+	uWord wOverTheAirPacketSize;
-+	uByte bOverTheAirInterval;
-+	uByte bmCompAttributes;
-+} UPACKED wusb_endpoint_companion_desc_t;
-+
-+/* Wireless USB Numeric Association M1 Data Structure */
-+typedef struct wusb_m1_data {
-+	uByte version;
-+	uWord langId;
-+	uByte deviceFriendlyNameLength;
-+	uByte sha_256_m3[32];
-+	uByte deviceFriendlyName[256];
-+} UPACKED wusb_m1_data_t;
-+
-+typedef struct wusb_m2_data {
-+	uByte version;
-+	uWord langId;
-+	uByte hostFriendlyNameLength;
-+	uByte pkh[384];
-+	uByte hostFriendlyName[256];
-+} UPACKED wusb_m2_data_t;
-+
-+typedef struct wusb_m3_data {
-+	uByte pkd[384];
-+	uByte nd;
-+} UPACKED wusb_m3_data_t;
-+
-+typedef struct wusb_m4_data {
-+	uDWord _attributeTypeIdAndLength_1;
-+	uWord  associationTypeId;
-+
-+	uDWord _attributeTypeIdAndLength_2;
-+	uWord  associationSubTypeId;
-+
-+	uDWord _attributeTypeIdAndLength_3;
-+	uDWord length;
-+
-+	uDWord _attributeTypeIdAndLength_4;
-+	uDWord associationStatus;
-+
-+	uDWord _attributeTypeIdAndLength_5;
-+	uByte  chid[16];
-+
-+	uDWord _attributeTypeIdAndLength_6;
-+	uByte  cdid[16];
-+
-+	uDWord _attributeTypeIdAndLength_7;
-+	uByte  bandGroups[2];
-+} UPACKED wusb_m4_data_t;
-+
-+#ifdef _MSC_VER
-+#include <poppack.h>
-+#endif
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _USB_H_ */
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/Makefile
-@@ -0,0 +1,82 @@
-+#
-+# Makefile for DWC_otg Highspeed USB controller driver
-+#
-+
-+ifneq ($(KERNELRELEASE),)
-+
-+# Use the BUS_INTERFACE variable to compile the software for either
-+# PCI(PCI_INTERFACE) or LM(LM_INTERFACE) bus.
-+ifeq ($(BUS_INTERFACE),)
-+#	BUS_INTERFACE = -DPCI_INTERFACE
-+#	BUS_INTERFACE = -DLM_INTERFACE
-+        BUS_INTERFACE = -DPLATFORM_INTERFACE
-+endif
-+
-+#ccflags-y	+= -DDEBUG
-+#ccflags-y	+= -DDWC_OTG_DEBUGLEV=1 # reduce common debug msgs
-+
-+# Use one of the following flags to compile the software in host-only or
-+# device-only mode.
-+#ccflags-y        += -DDWC_HOST_ONLY
-+#ccflags-y        += -DDWC_DEVICE_ONLY
-+
-+ccflags-y	+= -Dlinux -DDWC_HS_ELECT_TST
-+#ccflags-y	+= -DDWC_EN_ISOC
-+ccflags-y   	+= -I$(obj)/../dwc_common_port
-+#ccflags-y   	+= -I$(PORTLIB)
-+ccflags-y   	+= -DDWC_LINUX
-+ccflags-y   	+= $(CFI)
-+ccflags-y	+= $(BUS_INTERFACE)
-+#ccflags-y	+= -DDWC_DEV_SRPCAP
-+
-+obj-$(CONFIG_USB_DWCOTG) += dwc_otg.o
-+
-+dwc_otg-objs	:= dwc_otg_driver.o dwc_otg_attr.o
-+dwc_otg-objs	+= dwc_otg_cil.o dwc_otg_cil_intr.o
-+dwc_otg-objs	+= dwc_otg_pcd_linux.o dwc_otg_pcd.o dwc_otg_pcd_intr.o
-+dwc_otg-objs	+= dwc_otg_hcd.o dwc_otg_hcd_linux.o dwc_otg_hcd_intr.o dwc_otg_hcd_queue.o dwc_otg_hcd_ddma.o
-+dwc_otg-objs	+= dwc_otg_adp.o
-+dwc_otg-objs	+= dwc_otg_fiq_fsm.o
-+dwc_otg-objs	+= dwc_otg_fiq_stub.o
-+ifneq ($(CFI),)
-+dwc_otg-objs	+= dwc_otg_cfi.o
-+endif
-+
-+kernrelwd := $(subst ., ,$(KERNELRELEASE))
-+kernrel3 := $(word 1,$(kernrelwd)).$(word 2,$(kernrelwd)).$(word 3,$(kernrelwd))
-+
-+ifneq ($(kernrel3),2.6.20)
-+ccflags-y += $(CPPFLAGS)
-+endif
-+
-+else
-+
-+PWD		:= $(shell pwd)
-+PORTLIB		:= $(PWD)/../dwc_common_port
-+
-+# Command paths
-+CTAGS		:= $(CTAGS)
-+DOXYGEN		:= $(DOXYGEN)
-+
-+default: portlib
-+	$(MAKE) -C$(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
-+
-+install: default
-+	$(MAKE) -C$(KDIR) M=$(PORTLIB) modules_install
-+	$(MAKE) -C$(KDIR) M=$(PWD) modules_install
-+
-+portlib:
-+	$(MAKE) -C$(KDIR) M=$(PORTLIB) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
-+	cp $(PORTLIB)/Module.symvers $(PWD)/
-+
-+docs:	$(wildcard *.[hc]) doc/doxygen.cfg
-+	$(DOXYGEN) doc/doxygen.cfg
-+
-+tags:	$(wildcard *.[hc])
-+	$(CTAGS) -e $(wildcard *.[hc]) $(wildcard linux/*.[hc]) $(wildcard $(KDIR)/include/linux/usb*.h)
-+
-+
-+clean:
-+	rm -rf   *.o *.ko .*cmd *.mod.c .tmp_versions Module.symvers
-+
-+endif
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/doc/doxygen.cfg
-@@ -0,0 +1,224 @@
-+# Doxyfile 1.3.9.1
-+
-+#---------------------------------------------------------------------------
-+# Project related configuration options
-+#---------------------------------------------------------------------------
-+PROJECT_NAME           = "DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver"
-+PROJECT_NUMBER         = v3.00a
-+OUTPUT_DIRECTORY       = ./doc/
-+CREATE_SUBDIRS         = NO
-+OUTPUT_LANGUAGE        = English
-+BRIEF_MEMBER_DESC      = YES
-+REPEAT_BRIEF           = YES
-+ABBREVIATE_BRIEF       = "The $name class" \
-+                         "The $name widget" \
-+                         "The $name file" \
-+                         is \
-+                         provides \
-+                         specifies \
-+                         contains \
-+                         represents \
-+                         a \
-+                         an \
-+                         the
-+ALWAYS_DETAILED_SEC    = NO
-+INLINE_INHERITED_MEMB  = NO
-+FULL_PATH_NAMES        = NO
-+STRIP_FROM_PATH        =
-+STRIP_FROM_INC_PATH    =
-+SHORT_NAMES            = NO
-+JAVADOC_AUTOBRIEF      = YES
-+MULTILINE_CPP_IS_BRIEF = NO
-+INHERIT_DOCS           = YES
-+DISTRIBUTE_GROUP_DOC   = NO
-+TAB_SIZE               = 8
-+ALIASES                =
-+OPTIMIZE_OUTPUT_FOR_C  = YES
-+OPTIMIZE_OUTPUT_JAVA   = NO
-+SUBGROUPING            = YES
-+#---------------------------------------------------------------------------
-+# Build related configuration options
-+#---------------------------------------------------------------------------
-+EXTRACT_ALL            = NO
-+EXTRACT_PRIVATE        = YES
-+EXTRACT_STATIC         = YES
-+EXTRACT_LOCAL_CLASSES  = YES
-+EXTRACT_LOCAL_METHODS  = NO
-+HIDE_UNDOC_MEMBERS     = NO
-+HIDE_UNDOC_CLASSES     = NO
-+HIDE_FRIEND_COMPOUNDS  = NO
-+HIDE_IN_BODY_DOCS      = NO
-+INTERNAL_DOCS          = NO
-+CASE_SENSE_NAMES       = NO
-+HIDE_SCOPE_NAMES       = NO
-+SHOW_INCLUDE_FILES     = YES
-+INLINE_INFO            = YES
-+SORT_MEMBER_DOCS       = NO
-+SORT_BRIEF_DOCS        = NO
-+SORT_BY_SCOPE_NAME     = NO
-+GENERATE_TODOLIST      = YES
-+GENERATE_TESTLIST      = YES
-+GENERATE_BUGLIST       = YES
-+GENERATE_DEPRECATEDLIST= YES
-+ENABLED_SECTIONS       =
-+MAX_INITIALIZER_LINES  = 30
-+SHOW_USED_FILES        = YES
-+SHOW_DIRECTORIES       = YES
-+#---------------------------------------------------------------------------
-+# configuration options related to warning and progress messages
-+#---------------------------------------------------------------------------
-+QUIET                  = YES
-+WARNINGS               = YES
-+WARN_IF_UNDOCUMENTED   = NO
-+WARN_IF_DOC_ERROR      = YES
-+WARN_FORMAT            = "$file:$line: $text"
-+WARN_LOGFILE           =
-+#---------------------------------------------------------------------------
-+# configuration options related to the input files
-+#---------------------------------------------------------------------------
-+INPUT                  = .
-+FILE_PATTERNS          = *.c \
-+                         *.h \
-+                         ./linux/*.c \
-+                         ./linux/*.h
-+RECURSIVE              = NO
-+EXCLUDE                = ./test/ \
-+                         ./dwc_otg/.AppleDouble/
-+EXCLUDE_SYMLINKS       = YES
-+EXCLUDE_PATTERNS       = *.mod.*
-+EXAMPLE_PATH           =
-+EXAMPLE_PATTERNS       = *
-+EXAMPLE_RECURSIVE      = NO
-+IMAGE_PATH             =
-+INPUT_FILTER           =
-+FILTER_PATTERNS        =
-+FILTER_SOURCE_FILES    = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to source browsing
-+#---------------------------------------------------------------------------
-+SOURCE_BROWSER         = YES
-+INLINE_SOURCES         = NO
-+STRIP_CODE_COMMENTS    = YES
-+REFERENCED_BY_RELATION = NO
-+REFERENCES_RELATION    = NO
-+VERBATIM_HEADERS       = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to the alphabetical class index
-+#---------------------------------------------------------------------------
-+ALPHABETICAL_INDEX     = NO
-+COLS_IN_ALPHA_INDEX    = 5
-+IGNORE_PREFIX          =
-+#---------------------------------------------------------------------------
-+# configuration options related to the HTML output
-+#---------------------------------------------------------------------------
-+GENERATE_HTML          = YES
-+HTML_OUTPUT            = html
-+HTML_FILE_EXTENSION    = .html
-+HTML_HEADER            =
-+HTML_FOOTER            =
-+HTML_STYLESHEET        =
-+HTML_ALIGN_MEMBERS     = YES
-+GENERATE_HTMLHELP      = NO
-+CHM_FILE               =
-+HHC_LOCATION           =
-+GENERATE_CHI           = NO
-+BINARY_TOC             = NO
-+TOC_EXPAND             = NO
-+DISABLE_INDEX          = NO
-+ENUM_VALUES_PER_LINE   = 4
-+GENERATE_TREEVIEW      = YES
-+TREEVIEW_WIDTH         = 250
-+#---------------------------------------------------------------------------
-+# configuration options related to the LaTeX output
-+#---------------------------------------------------------------------------
-+GENERATE_LATEX         = NO
-+LATEX_OUTPUT           = latex
-+LATEX_CMD_NAME         = latex
-+MAKEINDEX_CMD_NAME     = makeindex
-+COMPACT_LATEX          = NO
-+PAPER_TYPE             = a4wide
-+EXTRA_PACKAGES         =
-+LATEX_HEADER           =
-+PDF_HYPERLINKS         = NO
-+USE_PDFLATEX           = NO
-+LATEX_BATCHMODE        = NO
-+LATEX_HIDE_INDICES     = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to the RTF output
-+#---------------------------------------------------------------------------
-+GENERATE_RTF           = NO
-+RTF_OUTPUT             = rtf
-+COMPACT_RTF            = NO
-+RTF_HYPERLINKS         = NO
-+RTF_STYLESHEET_FILE    =
-+RTF_EXTENSIONS_FILE    =
-+#---------------------------------------------------------------------------
-+# configuration options related to the man page output
-+#---------------------------------------------------------------------------
-+GENERATE_MAN           = NO
-+MAN_OUTPUT             = man
-+MAN_EXTENSION          = .3
-+MAN_LINKS              = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to the XML output
-+#---------------------------------------------------------------------------
-+GENERATE_XML           = NO
-+XML_OUTPUT             = xml
-+XML_SCHEMA             =
-+XML_DTD                =
-+XML_PROGRAMLISTING     = YES
-+#---------------------------------------------------------------------------
-+# configuration options for the AutoGen Definitions output
-+#---------------------------------------------------------------------------
-+GENERATE_AUTOGEN_DEF   = NO
-+#---------------------------------------------------------------------------
-+# configuration options related to the Perl module output
-+#---------------------------------------------------------------------------
-+GENERATE_PERLMOD       = NO
-+PERLMOD_LATEX          = NO
-+PERLMOD_PRETTY         = YES
-+PERLMOD_MAKEVAR_PREFIX =
-+#---------------------------------------------------------------------------
-+# Configuration options related to the preprocessor
-+#---------------------------------------------------------------------------
-+ENABLE_PREPROCESSING   = YES
-+MACRO_EXPANSION        = YES
-+EXPAND_ONLY_PREDEF     = YES
-+SEARCH_INCLUDES        = YES
-+INCLUDE_PATH           =
-+INCLUDE_FILE_PATTERNS  =
-+PREDEFINED             = DEVICE_ATTR DWC_EN_ISOC
-+EXPAND_AS_DEFINED      = DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW DWC_OTG_DEVICE_ATTR_BITFIELD_STORE DWC_OTG_DEVICE_ATTR_BITFIELD_RW DWC_OTG_DEVICE_ATTR_BITFIELD_RO DWC_OTG_DEVICE_ATTR_REG_SHOW DWC_OTG_DEVICE_ATTR_REG_STORE DWC_OTG_DEVICE_ATTR_REG32_RW DWC_OTG_DEVICE_ATTR_REG32_RO DWC_EN_ISOC
-+SKIP_FUNCTION_MACROS   = NO
-+#---------------------------------------------------------------------------
-+# Configuration::additions related to external references
-+#---------------------------------------------------------------------------
-+TAGFILES               =
-+GENERATE_TAGFILE       =
-+ALLEXTERNALS           = NO
-+EXTERNAL_GROUPS        = YES
-+PERL_PATH              = /usr/bin/perl
-+#---------------------------------------------------------------------------
-+# Configuration options related to the dot tool
-+#---------------------------------------------------------------------------
-+CLASS_DIAGRAMS         = YES
-+HIDE_UNDOC_RELATIONS   = YES
-+HAVE_DOT               = NO
-+CLASS_GRAPH            = YES
-+COLLABORATION_GRAPH    = YES
-+UML_LOOK               = NO
-+TEMPLATE_RELATIONS     = NO
-+INCLUDE_GRAPH          = YES
-+INCLUDED_BY_GRAPH      = YES
-+CALL_GRAPH             = NO
-+GRAPHICAL_HIERARCHY    = YES
-+DOT_IMAGE_FORMAT       = png
-+DOT_PATH               =
-+DOTFILE_DIRS           =
-+MAX_DOT_GRAPH_DEPTH    = 1000
-+GENERATE_LEGEND        = YES
-+DOT_CLEANUP            = YES
-+#---------------------------------------------------------------------------
-+# Configuration::additions related to the search engine
-+#---------------------------------------------------------------------------
-+SEARCHENGINE           = NO
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/dummy_audio.c
-@@ -0,0 +1,1575 @@
-+/*
-+ * zero.c -- Gadget Zero, for USB development
-+ *
-+ * Copyright (C) 2003-2004 David Brownell
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions, and the following disclaimer,
-+ *    without modification.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. The names of the above-listed copyright holders may not be used
-+ *    to endorse or promote products derived from this software without
-+ *    specific prior written permission.
-+ *
-+ * ALTERNATIVELY, this software may be distributed under the terms of the
-+ * GNU General Public License ("GPL") as published by the Free Software
-+ * Foundation, either version 2 of that License or (at your option) any
-+ * later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ */
-+
-+
-+/*
-+ * Gadget Zero only needs two bulk endpoints, and is an example of how you
-+ * can write a hardware-agnostic gadget driver running inside a USB device.
-+ *
-+ * Hardware details are visible (see CONFIG_USB_ZERO_* below) but don't
-+ * affect most of the driver.
-+ *
-+ * Use it with the Linux host/master side "usbtest" driver to get a basic
-+ * functional test of your device-side usb stack, or with "usb-skeleton".
-+ *
-+ * It supports two similar configurations.  One sinks whatever the usb host
-+ * writes, and in return sources zeroes.  The other loops whatever the host
-+ * writes back, so the host can read it.  Module options include:
-+ *
-+ *   buflen=N		default N=4096, buffer size used
-+ *   qlen=N		default N=32, how many buffers in the loopback queue
-+ *   loopdefault	default false, list loopback config first
-+ *
-+ * Many drivers will only have one configuration, letting them be much
-+ * simpler if they also don't support high speed operation (like this
-+ * driver does).
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/ioport.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/smp_lock.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/list.h>
-+#include <linux/interrupt.h>
-+#include <linux/uts.h>
-+#include <linux/version.h>
-+#include <linux/device.h>
-+#include <linux/moduleparam.h>
-+#include <linux/proc_fs.h>
-+
-+#include <asm/byteorder.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/system.h>
-+#include <asm/unaligned.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
-+# include <linux/usb/ch9.h>
-+#else
-+# include <linux/usb_ch9.h>
-+#endif
-+
-+#include <linux/usb_gadget.h>
-+
-+
-+/*-------------------------------------------------------------------------*/
-+/*-------------------------------------------------------------------------*/
-+
-+
-+static int utf8_to_utf16le(const char *s, u16 *cp, unsigned len)
-+{
-+	int	count = 0;
-+	u8	c;
-+	u16	uchar;
-+
-+	/* this insists on correct encodings, though not minimal ones.
-+	 * BUT it currently rejects legit 4-byte UTF-8 code points,
-+	 * which need surrogate pairs.  (Unicode 3.1 can use them.)
-+	 */
-+	while (len != 0 && (c = (u8) *s++) != 0) {
-+		if (unlikely(c & 0x80)) {
-+			// 2-byte sequence:
-+			// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
-+			if ((c & 0xe0) == 0xc0) {
-+				uchar = (c & 0x1f) << 6;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c;
-+
-+			// 3-byte sequence (most CJKV characters):
-+			// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
-+			} else if ((c & 0xf0) == 0xe0) {
-+				uchar = (c & 0x0f) << 12;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c << 6;
-+
-+				c = (u8) *s++;
-+				if ((c & 0xc0) != 0xc0)
-+					goto fail;
-+				c &= 0x3f;
-+				uchar |= c;
-+
-+				/* no bogus surrogates */
-+				if (0xd800 <= uchar && uchar <= 0xdfff)
-+					goto fail;
-+
-+			// 4-byte sequence (surrogate pairs, currently rare):
-+			// 11101110wwwwzzzzyy + 110111yyyyxxxxxx
-+			//     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
-+			// (uuuuu = wwww + 1)
-+			// FIXME accept the surrogate code points (only)
-+
-+			} else
-+				goto fail;
-+		} else
-+			uchar = c;
-+		put_unaligned (cpu_to_le16 (uchar), cp++);
-+		count++;
-+		len--;
-+	}
-+	return count;
-+fail:
-+	return -1;
-+}
-+
-+
-+/**
-+ * usb_gadget_get_string - fill out a string descriptor
-+ * @table: of c strings encoded using UTF-8
-+ * @id: string id, from low byte of wValue in get string descriptor
-+ * @buf: at least 256 bytes
-+ *
-+ * Finds the UTF-8 string matching the ID, and converts it into a
-+ * string descriptor in utf16-le.
-+ * Returns length of descriptor (always even) or negative errno
-+ *
-+ * If your driver needs stings in multiple languages, you'll probably
-+ * "switch (wIndex) { ... }"  in your ep0 string descriptor logic,
-+ * using this routine after choosing which set of UTF-8 strings to use.
-+ * Note that US-ASCII is a strict subset of UTF-8; any string bytes with
-+ * the eighth bit set will be multibyte UTF-8 characters, not ISO-8859/1
-+ * characters (which are also widely used in C strings).
-+ */
-+int
-+usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf)
-+{
-+	struct usb_string	*s;
-+	int			len;
-+
-+	/* descriptor 0 has the language id */
-+	if (id == 0) {
-+		buf [0] = 4;
-+		buf [1] = USB_DT_STRING;
-+		buf [2] = (u8) table->language;
-+		buf [3] = (u8) (table->language >> 8);
-+		return 4;
-+	}
-+	for (s = table->strings; s && s->s; s++)
-+		if (s->id == id)
-+			break;
-+
-+	/* unrecognized: stall. */
-+	if (!s || !s->s)
-+		return -EINVAL;
-+
-+	/* string descriptors have length, tag, then UTF16-LE text */
-+	len = min ((size_t) 126, strlen (s->s));
-+	memset (buf + 2, 0, 2 * len);	/* zero all the bytes */
-+	len = utf8_to_utf16le(s->s, (u16 *)&buf[2], len);
-+	if (len < 0)
-+		return -EINVAL;
-+	buf [0] = (len + 1) * 2;
-+	buf [1] = USB_DT_STRING;
-+	return buf [0];
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+/*-------------------------------------------------------------------------*/
-+
-+
-+/**
-+ * usb_descriptor_fillbuf - fill buffer with descriptors
-+ * @buf: Buffer to be filled
-+ * @buflen: Size of buf
-+ * @src: Array of descriptor pointers, terminated by null pointer.
-+ *
-+ * Copies descriptors into the buffer, returning the length or a
-+ * negative error code if they can't all be copied.  Useful when
-+ * assembling descriptors for an associated set of interfaces used
-+ * as part of configuring a composite device; or in other cases where
-+ * sets of descriptors need to be marshaled.
-+ */
-+int
-+usb_descriptor_fillbuf(void *buf, unsigned buflen,
-+		const struct usb_descriptor_header **src)
-+{
-+	u8	*dest = buf;
-+
-+	if (!src)
-+		return -EINVAL;
-+
-+	/* fill buffer from src[] until null descriptor ptr */
-+	for (; 0 != *src; src++) {
-+		unsigned		len = (*src)->bLength;
-+
-+		if (len > buflen)
-+			return -EINVAL;
-+		memcpy(dest, *src, len);
-+		buflen -= len;
-+		dest += len;
-+	}
-+	return dest - (u8 *)buf;
-+}
-+
-+
-+/**
-+ * usb_gadget_config_buf - builts a complete configuration descriptor
-+ * @config: Header for the descriptor, including characteristics such
-+ *	as power requirements and number of interfaces.
-+ * @desc: Null-terminated vector of pointers to the descriptors (interface,
-+ *	endpoint, etc) defining all functions in this device configuration.
-+ * @buf: Buffer for the resulting configuration descriptor.
-+ * @length: Length of buffer.  If this is not big enough to hold the
-+ *	entire configuration descriptor, an error code will be returned.
-+ *
-+ * This copies descriptors into the response buffer, building a descriptor
-+ * for that configuration.  It returns the buffer length or a negative
-+ * status code.  The config.wTotalLength field is set to match the length
-+ * of the result, but other descriptor fields (including power usage and
-+ * interface count) must be set by the caller.
-+ *
-+ * Gadget drivers could use this when constructing a config descriptor
-+ * in response to USB_REQ_GET_DESCRIPTOR.  They will need to patch the
-+ * resulting bDescriptorType value if USB_DT_OTHER_SPEED_CONFIG is needed.
-+ */
-+int usb_gadget_config_buf(
-+	const struct usb_config_descriptor	*config,
-+	void					*buf,
-+	unsigned				length,
-+	const struct usb_descriptor_header	**desc
-+)
-+{
-+	struct usb_config_descriptor		*cp = buf;
-+	int					len;
-+
-+	/* config descriptor first */
-+	if (length < USB_DT_CONFIG_SIZE || !desc)
-+		return -EINVAL;
-+	*cp = *config;
-+
-+	/* then interface/endpoint/class/vendor/... */
-+	len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8*)buf,
-+			length - USB_DT_CONFIG_SIZE, desc);
-+	if (len < 0)
-+		return len;
-+	len += USB_DT_CONFIG_SIZE;
-+	if (len > 0xffff)
-+		return -EINVAL;
-+
-+	/* patch up the config descriptor */
-+	cp->bLength = USB_DT_CONFIG_SIZE;
-+	cp->bDescriptorType = USB_DT_CONFIG;
-+	cp->wTotalLength = cpu_to_le16(len);
-+	cp->bmAttributes |= USB_CONFIG_ATT_ONE;
-+	return len;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+/*-------------------------------------------------------------------------*/
-+
-+
-+#define RBUF_LEN (1024*1024)
-+static int rbuf_start;
-+static int rbuf_len;
-+static __u8 rbuf[RBUF_LEN];
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#define DRIVER_VERSION		"St Patrick's Day 2004"
-+
-+static const char shortname [] = "zero";
-+static const char longname [] = "YAMAHA YST-MS35D USB Speaker  ";
-+
-+static const char source_sink [] = "source and sink data";
-+static const char loopback [] = "loop input to output";
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * driver assumes self-powered hardware, and
-+ * has no way for users to trigger remote wakeup.
-+ *
-+ * this version autoconfigures as much as possible,
-+ * which is reasonable for most "bulk-only" drivers.
-+ */
-+static const char *EP_IN_NAME;		/* source */
-+static const char *EP_OUT_NAME;		/* sink */
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* big enough to hold our biggest descriptor */
-+#define USB_BUFSIZ	512
-+
-+struct zero_dev {
-+	spinlock_t		lock;
-+	struct usb_gadget	*gadget;
-+	struct usb_request	*req;		/* for control responses */
-+
-+	/* when configured, we have one of two configs:
-+	 * - source data (in to host) and sink it (out from host)
-+	 * - or loop it back (out from host back in to host)
-+	 */
-+	u8			config;
-+	struct usb_ep		*in_ep, *out_ep;
-+
-+	/* autoresume timer */
-+	struct timer_list	resume;
-+};
-+
-+#define xprintk(d,level,fmt,args...) \
-+	dev_printk(level , &(d)->gadget->dev , fmt , ## args)
-+
-+#ifdef DEBUG
-+#define DBG(dev,fmt,args...) \
-+	xprintk(dev , KERN_DEBUG , fmt , ## args)
-+#else
-+#define DBG(dev,fmt,args...) \
-+	do { } while (0)
-+#endif /* DEBUG */
-+
-+#ifdef VERBOSE
-+#define VDBG	DBG
-+#else
-+#define VDBG(dev,fmt,args...) \
-+	do { } while (0)
-+#endif /* VERBOSE */
-+
-+#define ERROR(dev,fmt,args...) \
-+	xprintk(dev , KERN_ERR , fmt , ## args)
-+#define WARN(dev,fmt,args...) \
-+	xprintk(dev , KERN_WARNING , fmt , ## args)
-+#define INFO(dev,fmt,args...) \
-+	xprintk(dev , KERN_INFO , fmt , ## args)
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static unsigned buflen = 4096;
-+static unsigned qlen = 32;
-+static unsigned pattern = 0;
-+
-+module_param (buflen, uint, S_IRUGO|S_IWUSR);
-+module_param (qlen, uint, S_IRUGO|S_IWUSR);
-+module_param (pattern, uint, S_IRUGO|S_IWUSR);
-+
-+/*
-+ * if it's nonzero, autoresume says how many seconds to wait
-+ * before trying to wake up the host after suspend.
-+ */
-+static unsigned autoresume = 0;
-+module_param (autoresume, uint, 0);
-+
-+/*
-+ * Normally the "loopback" configuration is second (index 1) so
-+ * it's not the default.  Here's where to change that order, to
-+ * work better with hosts where config changes are problematic.
-+ * Or controllers (like superh) that only support one config.
-+ */
-+static int loopdefault = 0;
-+
-+module_param (loopdefault, bool, S_IRUGO|S_IWUSR);
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Thanks to NetChip Technologies for donating this product ID.
-+ *
-+ * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
-+ * Instead:  allocate your own, using normal USB-IF procedures.
-+ */
-+#ifndef	CONFIG_USB_ZERO_HNPTEST
-+#define DRIVER_VENDOR_NUM	0x0525		/* NetChip */
-+#define DRIVER_PRODUCT_NUM	0xa4a0		/* Linux-USB "Gadget Zero" */
-+#else
-+#define DRIVER_VENDOR_NUM	0x1a0a		/* OTG test device IDs */
-+#define DRIVER_PRODUCT_NUM	0xbadd
-+#endif
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/*
-+ * DESCRIPTORS ... most are static, but strings and (full)
-+ * configuration descriptors are built on demand.
-+ */
-+
-+/*
-+#define STRING_MANUFACTURER		25
-+#define STRING_PRODUCT			42
-+#define STRING_SERIAL			101
-+*/
-+#define STRING_MANUFACTURER		1
-+#define STRING_PRODUCT			2
-+#define STRING_SERIAL			3
-+
-+#define STRING_SOURCE_SINK		250
-+#define STRING_LOOPBACK			251
-+
-+/*
-+ * This device advertises two configurations; these numbers work
-+ * on a pxa250 as well as more flexible hardware.
-+ */
-+#define	CONFIG_SOURCE_SINK	3
-+#define	CONFIG_LOOPBACK		2
-+
-+/*
-+static struct usb_device_descriptor
-+device_desc = {
-+	.bLength =		sizeof device_desc,
-+	.bDescriptorType =	USB_DT_DEVICE,
-+
-+	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
-+	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
-+
-+	.idVendor =		__constant_cpu_to_le16 (DRIVER_VENDOR_NUM),
-+	.idProduct =		__constant_cpu_to_le16 (DRIVER_PRODUCT_NUM),
-+	.iManufacturer =	STRING_MANUFACTURER,
-+	.iProduct =		STRING_PRODUCT,
-+	.iSerialNumber =	STRING_SERIAL,
-+	.bNumConfigurations =	2,
-+};
-+*/
-+static struct usb_device_descriptor
-+device_desc = {
-+	.bLength =		sizeof device_desc,
-+	.bDescriptorType =	USB_DT_DEVICE,
-+	.bcdUSB =		__constant_cpu_to_le16 (0x0100),
-+	.bDeviceClass =		USB_CLASS_PER_INTERFACE,
-+	.bDeviceSubClass =      0,
-+	.bDeviceProtocol =      0,
-+	.bMaxPacketSize0 =      64,
-+	.bcdDevice =            __constant_cpu_to_le16 (0x0100),
-+	.idVendor =		__constant_cpu_to_le16 (0x0499),
-+	.idProduct =		__constant_cpu_to_le16 (0x3002),
-+	.iManufacturer =	STRING_MANUFACTURER,
-+	.iProduct =		STRING_PRODUCT,
-+	.iSerialNumber =	STRING_SERIAL,
-+	.bNumConfigurations =	1,
-+};
-+
-+static struct usb_config_descriptor
-+z_config = {
-+	.bLength =		sizeof z_config,
-+	.bDescriptorType =	USB_DT_CONFIG,
-+
-+	/* compute wTotalLength on the fly */
-+	.bNumInterfaces =	2,
-+	.bConfigurationValue =	1,
-+	.iConfiguration =	0,
-+	.bmAttributes =		0x40,
-+	.bMaxPower =		0,	/* self-powered */
-+};
-+
-+
-+static struct usb_otg_descriptor
-+otg_descriptor = {
-+	.bLength =		sizeof otg_descriptor,
-+	.bDescriptorType =	USB_DT_OTG,
-+
-+	.bmAttributes =		USB_OTG_SRP,
-+};
-+
-+/* one interface in each configuration */
-+#ifdef	CONFIG_USB_GADGET_DUALSPEED
-+
-+/*
-+ * usb 2.0 devices need to expose both high speed and full speed
-+ * descriptors, unless they only run at full speed.
-+ *
-+ * that means alternate endpoint descriptors (bigger packets)
-+ * and a "device qualifier" ... plus more construction options
-+ * for the config descriptor.
-+ */
-+
-+static struct usb_qualifier_descriptor
-+dev_qualifier = {
-+	.bLength =		sizeof dev_qualifier,
-+	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
-+
-+	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
-+	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
-+
-+	.bNumConfigurations =	2,
-+};
-+
-+
-+struct usb_cs_as_general_descriptor {
-+	__u8  bLength;
-+	__u8  bDescriptorType;
-+
-+	__u8  bDescriptorSubType;
-+	__u8  bTerminalLink;
-+	__u8  bDelay;
-+	__u16  wFormatTag;
-+} __attribute__ ((packed));
-+
-+struct usb_cs_as_format_descriptor {
-+	__u8  bLength;
-+	__u8  bDescriptorType;
-+
-+	__u8  bDescriptorSubType;
-+	__u8  bFormatType;
-+	__u8  bNrChannels;
-+	__u8  bSubframeSize;
-+	__u8  bBitResolution;
-+	__u8  bSamfreqType;
-+	__u8  tLowerSamFreq[3];
-+	__u8  tUpperSamFreq[3];
-+} __attribute__ ((packed));
-+
-+static const struct usb_interface_descriptor
-+z_audio_control_if_desc = {
-+	.bLength =		sizeof z_audio_control_if_desc,
-+	.bDescriptorType =	USB_DT_INTERFACE,
-+	.bInterfaceNumber = 0,
-+	.bAlternateSetting = 0,
-+	.bNumEndpoints = 0,
-+	.bInterfaceClass = USB_CLASS_AUDIO,
-+	.bInterfaceSubClass = 0x1,
-+	.bInterfaceProtocol = 0,
-+	.iInterface = 0,
-+};
-+
-+static const struct usb_interface_descriptor
-+z_audio_if_desc = {
-+	.bLength =		sizeof z_audio_if_desc,
-+	.bDescriptorType =	USB_DT_INTERFACE,
-+	.bInterfaceNumber = 1,
-+	.bAlternateSetting = 0,
-+	.bNumEndpoints = 0,
-+	.bInterfaceClass = USB_CLASS_AUDIO,
-+	.bInterfaceSubClass = 0x2,
-+	.bInterfaceProtocol = 0,
-+	.iInterface = 0,
-+};
-+
-+static const struct usb_interface_descriptor
-+z_audio_if_desc2 = {
-+	.bLength =		sizeof z_audio_if_desc,
-+	.bDescriptorType =	USB_DT_INTERFACE,
-+	.bInterfaceNumber = 1,
-+	.bAlternateSetting = 1,
-+	.bNumEndpoints = 1,
-+	.bInterfaceClass = USB_CLASS_AUDIO,
-+	.bInterfaceSubClass = 0x2,
-+	.bInterfaceProtocol = 0,
-+	.iInterface = 0,
-+};
-+
-+static const struct usb_cs_as_general_descriptor
-+z_audio_cs_as_if_desc = {
-+	.bLength = 7,
-+	.bDescriptorType = 0x24,
-+
-+	.bDescriptorSubType = 0x01,
-+	.bTerminalLink = 0x01,
-+	.bDelay = 0x0,
-+	.wFormatTag = __constant_cpu_to_le16 (0x0001)
-+};
-+
-+
-+static const struct usb_cs_as_format_descriptor
-+z_audio_cs_as_format_desc = {
-+	.bLength = 0xe,
-+	.bDescriptorType = 0x24,
-+
-+	.bDescriptorSubType = 2,
-+	.bFormatType = 1,
-+	.bNrChannels = 1,
-+	.bSubframeSize = 1,
-+	.bBitResolution = 8,
-+	.bSamfreqType = 0,
-+	.tLowerSamFreq = {0x7e, 0x13, 0x00},
-+	.tUpperSamFreq = {0xe2, 0xd6, 0x00},
-+};
-+
-+static const struct usb_endpoint_descriptor
-+z_iso_ep = {
-+	.bLength = 0x09,
-+	.bDescriptorType = 0x05,
-+	.bEndpointAddress = 0x04,
-+	.bmAttributes = 0x09,
-+	.wMaxPacketSize = 0x0038,
-+	.bInterval = 0x01,
-+	.bRefresh = 0x00,
-+	.bSynchAddress = 0x00,
-+};
-+
-+static char z_iso_ep2[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
-+
-+// 9 bytes
-+static char z_ac_interface_header_desc[] =
-+{ 0x09, 0x24, 0x01, 0x00, 0x01, 0x2b, 0x00, 0x01, 0x01 };
-+
-+// 12 bytes
-+static char z_0[] = {0x0c, 0x24, 0x02, 0x01, 0x01, 0x01, 0x00, 0x02,
-+		     0x03, 0x00, 0x00, 0x00};
-+// 13 bytes
-+static char z_1[] = {0x0d, 0x24, 0x06, 0x02, 0x01, 0x02, 0x15, 0x00,
-+		     0x02, 0x00, 0x02, 0x00, 0x00};
-+// 9 bytes
-+static char z_2[] = {0x09, 0x24, 0x03, 0x03, 0x01, 0x03, 0x00, 0x02,
-+		     0x00};
-+
-+static char za_0[] = {0x09, 0x04, 0x01, 0x02, 0x01, 0x01, 0x02, 0x00,
-+		      0x00};
-+
-+static char za_1[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
-+
-+static char za_2[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x01, 0x08, 0x00,
-+		      0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};
-+
-+static char za_3[] = {0x09, 0x05, 0x04, 0x09, 0x70, 0x00, 0x01, 0x00,
-+		      0x00};
-+
-+static char za_4[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
-+
-+static char za_5[] = {0x09, 0x04, 0x01, 0x03, 0x01, 0x01, 0x02, 0x00,
-+		      0x00};
-+
-+static char za_6[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
-+
-+static char za_7[] = {0x0e, 0x24, 0x02, 0x01, 0x01, 0x02, 0x10, 0x00,
-+		      0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};
-+
-+static char za_8[] = {0x09, 0x05, 0x04, 0x09, 0x70, 0x00, 0x01, 0x00,
-+		      0x00};
-+
-+static char za_9[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
-+
-+static char za_10[] = {0x09, 0x04, 0x01, 0x04, 0x01, 0x01, 0x02, 0x00,
-+		       0x00};
-+
-+static char za_11[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
-+
-+static char za_12[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x02, 0x10, 0x00,
-+		       0x73, 0x13, 0x00, 0xe2, 0xd6, 0x00};
-+
-+static char za_13[] = {0x09, 0x05, 0x04, 0x09, 0xe0, 0x00, 0x01, 0x00,
-+		       0x00};
-+
-+static char za_14[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
-+
-+static char za_15[] = {0x09, 0x04, 0x01, 0x05, 0x01, 0x01, 0x02, 0x00,
-+		       0x00};
-+
-+static char za_16[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
-+
-+static char za_17[] = {0x0e, 0x24, 0x02, 0x01, 0x01, 0x03, 0x14, 0x00,
-+		       0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};
-+
-+static char za_18[] = {0x09, 0x05, 0x04, 0x09, 0xa8, 0x00, 0x01, 0x00,
-+		       0x00};
-+
-+static char za_19[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
-+
-+static char za_20[] = {0x09, 0x04, 0x01, 0x06, 0x01, 0x01, 0x02, 0x00,
-+		       0x00};
-+
-+static char za_21[] = {0x07, 0x24, 0x01, 0x01, 0x00, 0x01, 0x00};
-+
-+static char za_22[] = {0x0e, 0x24, 0x02, 0x01, 0x02, 0x03, 0x14, 0x00,
-+		       0x7e, 0x13, 0x00, 0xe2, 0xd6, 0x00};
-+
-+static char za_23[] = {0x09, 0x05, 0x04, 0x09, 0x50, 0x01, 0x01, 0x00,
-+		       0x00};
-+
-+static char za_24[] = {0x07, 0x25, 0x01, 0x00, 0x02, 0x00, 0x02};
-+
-+
-+
-+static const struct usb_descriptor_header *z_function [] = {
-+	(struct usb_descriptor_header *) &z_audio_control_if_desc,
-+	(struct usb_descriptor_header *) &z_ac_interface_header_desc,
-+	(struct usb_descriptor_header *) &z_0,
-+	(struct usb_descriptor_header *) &z_1,
-+	(struct usb_descriptor_header *) &z_2,
-+	(struct usb_descriptor_header *) &z_audio_if_desc,
-+	(struct usb_descriptor_header *) &z_audio_if_desc2,
-+	(struct usb_descriptor_header *) &z_audio_cs_as_if_desc,
-+	(struct usb_descriptor_header *) &z_audio_cs_as_format_desc,
-+	(struct usb_descriptor_header *) &z_iso_ep,
-+	(struct usb_descriptor_header *) &z_iso_ep2,
-+	(struct usb_descriptor_header *) &za_0,
-+	(struct usb_descriptor_header *) &za_1,
-+	(struct usb_descriptor_header *) &za_2,
-+	(struct usb_descriptor_header *) &za_3,
-+	(struct usb_descriptor_header *) &za_4,
-+	(struct usb_descriptor_header *) &za_5,
-+	(struct usb_descriptor_header *) &za_6,
-+	(struct usb_descriptor_header *) &za_7,
-+	(struct usb_descriptor_header *) &za_8,
-+	(struct usb_descriptor_header *) &za_9,
-+	(struct usb_descriptor_header *) &za_10,
-+	(struct usb_descriptor_header *) &za_11,
-+	(struct usb_descriptor_header *) &za_12,
-+	(struct usb_descriptor_header *) &za_13,
-+	(struct usb_descriptor_header *) &za_14,
-+	(struct usb_descriptor_header *) &za_15,
-+	(struct usb_descriptor_header *) &za_16,
-+	(struct usb_descriptor_header *) &za_17,
-+	(struct usb_descriptor_header *) &za_18,
-+	(struct usb_descriptor_header *) &za_19,
-+	(struct usb_descriptor_header *) &za_20,
-+	(struct usb_descriptor_header *) &za_21,
-+	(struct usb_descriptor_header *) &za_22,
-+	(struct usb_descriptor_header *) &za_23,
-+	(struct usb_descriptor_header *) &za_24,
-+	NULL,
-+};
-+
-+/* maxpacket and other transfer characteristics vary by speed. */
-+#define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs))
-+
-+#else
-+
-+/* if there's no high speed support, maxpacket doesn't change. */
-+#define ep_desc(g,hs,fs) fs
-+
-+#endif	/* !CONFIG_USB_GADGET_DUALSPEED */
-+
-+static char				manufacturer [40];
-+//static char				serial [40];
-+static char				serial [] = "Ser 00 em";
-+
-+/* static strings, in UTF-8 */
-+static struct usb_string		strings [] = {
-+	{ STRING_MANUFACTURER, manufacturer, },
-+	{ STRING_PRODUCT, longname, },
-+	{ STRING_SERIAL, serial, },
-+	{ STRING_LOOPBACK, loopback, },
-+	{ STRING_SOURCE_SINK, source_sink, },
-+	{  }			/* end of list */
-+};
-+
-+static struct usb_gadget_strings	stringtab = {
-+	.language	= 0x0409,	/* en-us */
-+	.strings	= strings,
-+};
-+
-+/*
-+ * config descriptors are also handcrafted.  these must agree with code
-+ * that sets configurations, and with code managing interfaces and their
-+ * altsettings.  other complexity may come from:
-+ *
-+ *  - high speed support, including "other speed config" rules
-+ *  - multiple configurations
-+ *  - interfaces with alternate settings
-+ *  - embedded class or vendor-specific descriptors
-+ *
-+ * this handles high speed, and has a second config that could as easily
-+ * have been an alternate interface setting (on most hardware).
-+ *
-+ * NOTE:  to demonstrate (and test) more USB capabilities, this driver
-+ * should include an altsetting to test interrupt transfers, including
-+ * high bandwidth modes at high speed.  (Maybe work like Intel's test
-+ * device?)
-+ */
-+static int
-+config_buf (struct usb_gadget *gadget, u8 *buf, u8 type, unsigned index)
-+{
-+	int len;
-+	const struct usb_descriptor_header **function;
-+
-+	function = z_function;
-+	len = usb_gadget_config_buf (&z_config, buf, USB_BUFSIZ, function);
-+	if (len < 0)
-+		return len;
-+	((struct usb_config_descriptor *) buf)->bDescriptorType = type;
-+	return len;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static struct usb_request *
-+alloc_ep_req (struct usb_ep *ep, unsigned length)
-+{
-+	struct usb_request	*req;
-+
-+	req = usb_ep_alloc_request (ep, GFP_ATOMIC);
-+	if (req) {
-+		req->length = length;
-+		req->buf = usb_ep_alloc_buffer (ep, length,
-+				&req->dma, GFP_ATOMIC);
-+		if (!req->buf) {
-+			usb_ep_free_request (ep, req);
-+			req = NULL;
-+		}
-+	}
-+	return req;
-+}
-+
-+static void free_ep_req (struct usb_ep *ep, struct usb_request *req)
-+{
-+	if (req->buf)
-+		usb_ep_free_buffer (ep, req->buf, req->dma, req->length);
-+	usb_ep_free_request (ep, req);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* optionally require specific source/sink data patterns  */
-+
-+static int
-+check_read_data (
-+	struct zero_dev		*dev,
-+	struct usb_ep		*ep,
-+	struct usb_request	*req
-+)
-+{
-+	unsigned	i;
-+	u8		*buf = req->buf;
-+
-+	for (i = 0; i < req->actual; i++, buf++) {
-+		switch (pattern) {
-+		/* all-zeroes has no synchronization issues */
-+		case 0:
-+			if (*buf == 0)
-+				continue;
-+			break;
-+		/* mod63 stays in sync with short-terminated transfers,
-+		 * or otherwise when host and gadget agree on how large
-+		 * each usb transfer request should be.  resync is done
-+		 * with set_interface or set_config.
-+		 */
-+		case 1:
-+			if (*buf == (u8)(i % 63))
-+				continue;
-+			break;
-+		}
-+		ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf);
-+		usb_ep_set_halt (ep);
-+		return -EINVAL;
-+	}
-+	return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void zero_reset_config (struct zero_dev *dev)
-+{
-+	if (dev->config == 0)
-+		return;
-+
-+	DBG (dev, "reset config\n");
-+
-+	/* just disable endpoints, forcing completion of pending i/o.
-+	 * all our completion handlers free their requests in this case.
-+	 */
-+	if (dev->in_ep) {
-+		usb_ep_disable (dev->in_ep);
-+		dev->in_ep = NULL;
-+	}
-+	if (dev->out_ep) {
-+		usb_ep_disable (dev->out_ep);
-+		dev->out_ep = NULL;
-+	}
-+	dev->config = 0;
-+	del_timer (&dev->resume);
-+}
-+
-+#define _write(f, buf, sz) (f->f_op->write(f, buf, sz, &f->f_pos))
-+
-+static void
-+zero_isoc_complete (struct usb_ep *ep, struct usb_request *req)
-+{
-+	struct zero_dev	*dev = ep->driver_data;
-+	int		status = req->status;
-+	int i, j;
-+
-+	switch (status) {
-+
-+	case 0: 			/* normal completion? */
-+		//printk ("\nzero ---------------> isoc normal completion %d bytes\n", req->actual);
-+		for (i=0, j=rbuf_start; i<req->actual; i++) {
-+			//printk ("%02x ", ((__u8*)req->buf)[i]);
-+			rbuf[j] = ((__u8*)req->buf)[i];
-+			j++;
-+			if (j >= RBUF_LEN) j=0;
-+		}
-+		rbuf_start = j;
-+		//printk ("\n\n");
-+
-+		if (rbuf_len < RBUF_LEN) {
-+			rbuf_len += req->actual;
-+			if (rbuf_len > RBUF_LEN) {
-+				rbuf_len = RBUF_LEN;
-+			}
-+		}
-+
-+		break;
-+
-+	/* this endpoint is normally active while we're configured */
-+	case -ECONNABORTED: 		/* hardware forced ep reset */
-+	case -ECONNRESET:		/* request dequeued */
-+	case -ESHUTDOWN:		/* disconnect from host */
-+		VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status,
-+				req->actual, req->length);
-+		if (ep == dev->out_ep)
-+			check_read_data (dev, ep, req);
-+		free_ep_req (ep, req);
-+		return;
-+
-+	case -EOVERFLOW:		/* buffer overrun on read means that
-+					 * we didn't provide a big enough
-+					 * buffer.
-+					 */
-+	default:
-+#if 1
-+		DBG (dev, "%s complete --> %d, %d/%d\n", ep->name,
-+				status, req->actual, req->length);
-+#endif
-+	case -EREMOTEIO:		/* short read */
-+		break;
-+	}
-+
-+	status = usb_ep_queue (ep, req, GFP_ATOMIC);
-+	if (status) {
-+		ERROR (dev, "kill %s:  resubmit %d bytes --> %d\n",
-+				ep->name, req->length, status);
-+		usb_ep_set_halt (ep);
-+		/* FIXME recover later ... somehow */
-+	}
-+}
-+
-+static struct usb_request *
-+zero_start_isoc_ep (struct usb_ep *ep, int gfp_flags)
-+{
-+	struct usb_request	*req;
-+	int			status;
-+
-+	req = alloc_ep_req (ep, 512);
-+	if (!req)
-+		return NULL;
-+
-+	req->complete = zero_isoc_complete;
-+
-+	status = usb_ep_queue (ep, req, gfp_flags);
-+	if (status) {
-+		struct zero_dev	*dev = ep->driver_data;
-+
-+		ERROR (dev, "start %s --> %d\n", ep->name, status);
-+		free_ep_req (ep, req);
-+		req = NULL;
-+	}
-+
-+	return req;
-+}
-+
-+/* change our operational config.  this code must agree with the code
-+ * that returns config descriptors, and altsetting code.
-+ *
-+ * it's also responsible for power management interactions. some
-+ * configurations might not work with our current power sources.
-+ *
-+ * note that some device controller hardware will constrain what this
-+ * code can do, perhaps by disallowing more than one configuration or
-+ * by limiting configuration choices (like the pxa2xx).
-+ */
-+static int
-+zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags)
-+{
-+	int			result = 0;
-+	struct usb_gadget	*gadget = dev->gadget;
-+	const struct usb_endpoint_descriptor	*d;
-+	struct usb_ep		*ep;
-+
-+	if (number == dev->config)
-+		return 0;
-+
-+	zero_reset_config (dev);
-+
-+	gadget_for_each_ep (ep, gadget) {
-+
-+		if (strcmp (ep->name, "ep4") == 0) {
-+
-+			d = (struct usb_endpoint_descripter *)&za_23; // isoc ep desc for audio i/f alt setting 6
-+			result = usb_ep_enable (ep, d);
-+
-+			if (result == 0) {
-+				ep->driver_data = dev;
-+				dev->in_ep = ep;
-+
-+				if (zero_start_isoc_ep (ep, gfp_flags) != 0) {
-+
-+					dev->in_ep = ep;
-+					continue;
-+				}
-+
-+				usb_ep_disable (ep);
-+				result = -EIO;
-+			}
-+		}
-+
-+	}
-+
-+	dev->config = number;
-+	return result;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req)
-+{
-+	if (req->status || req->actual != req->length)
-+		DBG ((struct zero_dev *) ep->driver_data,
-+				"setup complete --> %d, %d/%d\n",
-+				req->status, req->actual, req->length);
-+}
-+
-+/*
-+ * The setup() callback implements all the ep0 functionality that's
-+ * not handled lower down, in hardware or the hardware driver (like
-+ * device and endpoint feature flags, and their status).  It's all
-+ * housekeeping for the gadget function we're implementing.  Most of
-+ * the work is in config-specific setup.
-+ */
-+static int
-+zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
-+{
-+	struct zero_dev		*dev = get_gadget_data (gadget);
-+	struct usb_request	*req = dev->req;
-+	int			value = -EOPNOTSUPP;
-+
-+	/* usually this stores reply data in the pre-allocated ep0 buffer,
-+	 * but config change events will reconfigure hardware.
-+	 */
-+	req->zero = 0;
-+	switch (ctrl->bRequest) {
-+
-+	case USB_REQ_GET_DESCRIPTOR:
-+
-+		switch (ctrl->wValue >> 8) {
-+
-+		case USB_DT_DEVICE:
-+			value = min (ctrl->wLength, (u16) sizeof device_desc);
-+			memcpy (req->buf, &device_desc, value);
-+			break;
-+#ifdef CONFIG_USB_GADGET_DUALSPEED
-+		case USB_DT_DEVICE_QUALIFIER:
-+			if (!gadget->is_dualspeed)
-+				break;
-+			value = min (ctrl->wLength, (u16) sizeof dev_qualifier);
-+			memcpy (req->buf, &dev_qualifier, value);
-+			break;
-+
-+		case USB_DT_OTHER_SPEED_CONFIG:
-+			if (!gadget->is_dualspeed)
-+				break;
-+			// FALLTHROUGH
-+#endif /* CONFIG_USB_GADGET_DUALSPEED */
-+		case USB_DT_CONFIG:
-+			value = config_buf (gadget, req->buf,
-+					ctrl->wValue >> 8,
-+					ctrl->wValue & 0xff);
-+			if (value >= 0)
-+				value = min (ctrl->wLength, (u16) value);
-+			break;
-+
-+		case USB_DT_STRING:
-+			/* wIndex == language code.
-+			 * this driver only handles one language, you can
-+			 * add string tables for other languages, using
-+			 * any UTF-8 characters
-+			 */
-+			value = usb_gadget_get_string (&stringtab,
-+					ctrl->wValue & 0xff, req->buf);
-+			if (value >= 0) {
-+				value = min (ctrl->wLength, (u16) value);
-+			}
-+			break;
-+		}
-+		break;
-+
-+	/* currently two configs, two speeds */
-+	case USB_REQ_SET_CONFIGURATION:
-+		if (ctrl->bRequestType != 0)
-+			goto unknown;
-+
-+		spin_lock (&dev->lock);
-+		value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC);
-+		spin_unlock (&dev->lock);
-+		break;
-+	case USB_REQ_GET_CONFIGURATION:
-+		if (ctrl->bRequestType != USB_DIR_IN)
-+			goto unknown;
-+		*(u8 *)req->buf = dev->config;
-+		value = min (ctrl->wLength, (u16) 1);
-+		break;
-+
-+	/* until we add altsetting support, or other interfaces,
-+	 * only 0/0 are possible.  pxa2xx only supports 0/0 (poorly)
-+	 * and already killed pending endpoint I/O.
-+	 */
-+	case USB_REQ_SET_INTERFACE:
-+
-+		if (ctrl->bRequestType != USB_RECIP_INTERFACE)
-+			goto unknown;
-+		spin_lock (&dev->lock);
-+		if (dev->config) {
-+			u8		config = dev->config;
-+
-+			/* resets interface configuration, forgets about
-+			 * previous transaction state (queued bufs, etc)
-+			 * and re-inits endpoint state (toggle etc)
-+			 * no response queued, just zero status == success.
-+			 * if we had more than one interface we couldn't
-+			 * use this "reset the config" shortcut.
-+			 */
-+			zero_reset_config (dev);
-+			zero_set_config (dev, config, GFP_ATOMIC);
-+			value = 0;
-+		}
-+		spin_unlock (&dev->lock);
-+		break;
-+	case USB_REQ_GET_INTERFACE:
-+		if ((ctrl->bRequestType == 0x21) && (ctrl->wIndex == 0x02)) {
-+			value = ctrl->wLength;
-+			break;
-+		}
-+		else {
-+			if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
-+				goto unknown;
-+			if (!dev->config)
-+				break;
-+			if (ctrl->wIndex != 0) {
-+				value = -EDOM;
-+				break;
-+			}
-+			*(u8 *)req->buf = 0;
-+			value = min (ctrl->wLength, (u16) 1);
-+		}
-+		break;
-+
-+	/*
-+	 * These are the same vendor-specific requests supported by
-+	 * Intel's USB 2.0 compliance test devices.  We exceed that
-+	 * device spec by allowing multiple-packet requests.
-+	 */
-+	case 0x5b:	/* control WRITE test -- fill the buffer */
-+		if (ctrl->bRequestType != (USB_DIR_OUT|USB_TYPE_VENDOR))
-+			goto unknown;
-+		if (ctrl->wValue || ctrl->wIndex)
-+			break;
-+		/* just read that many bytes into the buffer */
-+		if (ctrl->wLength > USB_BUFSIZ)
-+			break;
-+		value = ctrl->wLength;
-+		break;
-+	case 0x5c:	/* control READ test -- return the buffer */
-+		if (ctrl->bRequestType != (USB_DIR_IN|USB_TYPE_VENDOR))
-+			goto unknown;
-+		if (ctrl->wValue || ctrl->wIndex)
-+			break;
-+		/* expect those bytes are still in the buffer; send back */
-+		if (ctrl->wLength > USB_BUFSIZ
-+				|| ctrl->wLength != req->length)
-+			break;
-+		value = ctrl->wLength;
-+		break;
-+
-+	case 0x01: // SET_CUR
-+	case 0x02:
-+	case 0x03:
-+	case 0x04:
-+	case 0x05:
-+		value = ctrl->wLength;
-+		break;
-+	case 0x81:
-+		switch (ctrl->wValue) {
-+		case 0x0201:
-+		case 0x0202:
-+			((u8*)req->buf)[0] = 0x00;
-+			((u8*)req->buf)[1] = 0xe3;
-+			break;
-+		case 0x0300:
-+		case 0x0500:
-+			((u8*)req->buf)[0] = 0x00;
-+			break;
-+		}
-+		//((u8*)req->buf)[0] = 0x81;
-+		//((u8*)req->buf)[1] = 0x81;
-+		value = ctrl->wLength;
-+		break;
-+	case 0x82:
-+		switch (ctrl->wValue) {
-+		case 0x0201:
-+		case 0x0202:
-+			((u8*)req->buf)[0] = 0x00;
-+			((u8*)req->buf)[1] = 0xc3;
-+			break;
-+		case 0x0300:
-+		case 0x0500:
-+			((u8*)req->buf)[0] = 0x00;
-+			break;
-+		}
-+		//((u8*)req->buf)[0] = 0x82;
-+		//((u8*)req->buf)[1] = 0x82;
-+		value = ctrl->wLength;
-+		break;
-+	case 0x83:
-+		switch (ctrl->wValue) {
-+		case 0x0201:
-+		case 0x0202:
-+			((u8*)req->buf)[0] = 0x00;
-+			((u8*)req->buf)[1] = 0x00;
-+			break;
-+		case 0x0300:
-+			((u8*)req->buf)[0] = 0x60;
-+			break;
-+		case 0x0500:
-+			((u8*)req->buf)[0] = 0x18;
-+			break;
-+		}
-+		//((u8*)req->buf)[0] = 0x83;
-+		//((u8*)req->buf)[1] = 0x83;
-+		value = ctrl->wLength;
-+		break;
-+	case 0x84:
-+		switch (ctrl->wValue) {
-+		case 0x0201:
-+		case 0x0202:
-+			((u8*)req->buf)[0] = 0x00;
-+			((u8*)req->buf)[1] = 0x01;
-+			break;
-+		case 0x0300:
-+		case 0x0500:
-+			((u8*)req->buf)[0] = 0x08;
-+			break;
-+		}
-+		//((u8*)req->buf)[0] = 0x84;
-+		//((u8*)req->buf)[1] = 0x84;
-+		value = ctrl->wLength;
-+		break;
-+	case 0x85:
-+		((u8*)req->buf)[0] = 0x85;
-+		((u8*)req->buf)[1] = 0x85;
-+		value = ctrl->wLength;
-+		break;
-+
-+
-+	default:
-+unknown:
-+		printk("unknown control req%02x.%02x v%04x i%04x l%d\n",
-+			ctrl->bRequestType, ctrl->bRequest,
-+			ctrl->wValue, ctrl->wIndex, ctrl->wLength);
-+	}
-+
-+	/* respond with data transfer before status phase? */
-+	if (value >= 0) {
-+		req->length = value;
-+		req->zero = value < ctrl->wLength
-+				&& (value % gadget->ep0->maxpacket) == 0;
-+		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
-+		if (value < 0) {
-+			DBG (dev, "ep_queue < 0 --> %d\n", value);
-+			req->status = 0;
-+			zero_setup_complete (gadget->ep0, req);
-+		}
-+	}
-+
-+	/* device either stalls (value < 0) or reports success */
-+	return value;
-+}
-+
-+static void
-+zero_disconnect (struct usb_gadget *gadget)
-+{
-+	struct zero_dev		*dev = get_gadget_data (gadget);
-+	unsigned long		flags;
-+
-+	spin_lock_irqsave (&dev->lock, flags);
-+	zero_reset_config (dev);
-+
-+	/* a more significant application might have some non-usb
-+	 * activities to quiesce here, saving resources like power
-+	 * or pushing the notification up a network stack.
-+	 */
-+	spin_unlock_irqrestore (&dev->lock, flags);
-+
-+	/* next we may get setup() calls to enumerate new connections;
-+	 * or an unbind() during shutdown (including removing module).
-+	 */
-+}
-+
-+static void
-+zero_autoresume (unsigned long _dev)
-+{
-+	struct zero_dev	*dev = (struct zero_dev *) _dev;
-+	int		status;
-+
-+	/* normally the host would be woken up for something
-+	 * more significant than just a timer firing...
-+	 */
-+	if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
-+		status = usb_gadget_wakeup (dev->gadget);
-+		DBG (dev, "wakeup --> %d\n", status);
-+	}
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void
-+zero_unbind (struct usb_gadget *gadget)
-+{
-+	struct zero_dev		*dev = get_gadget_data (gadget);
-+
-+	DBG (dev, "unbind\n");
-+
-+	/* we've already been disconnected ... no i/o is active */
-+	if (dev->req)
-+		free_ep_req (gadget->ep0, dev->req);
-+	del_timer_sync (&dev->resume);
-+	kfree (dev);
-+	set_gadget_data (gadget, NULL);
-+}
-+
-+static int
-+zero_bind (struct usb_gadget *gadget)
-+{
-+	struct zero_dev		*dev;
-+	//struct usb_ep		*ep;
-+
-+	printk("binding\n");
-+	/*
-+	 * DRIVER POLICY CHOICE:  you may want to do this differently.
-+	 * One thing to avoid is reusing a bcdDevice revision code
-+	 * with different host-visible configurations or behavior
-+	 * restrictions -- using ep1in/ep2out vs ep1out/ep3in, etc
-+	 */
-+	//device_desc.bcdDevice = __constant_cpu_to_le16 (0x0201);
-+
-+
-+	/* ok, we made sense of the hardware ... */
-+	dev = kmalloc (sizeof *dev, SLAB_KERNEL);
-+	if (!dev)
-+		return -ENOMEM;
-+	memset (dev, 0, sizeof *dev);
-+	spin_lock_init (&dev->lock);
-+	dev->gadget = gadget;
-+	set_gadget_data (gadget, dev);
-+
-+	/* preallocate control response and buffer */
-+	dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
-+	if (!dev->req)
-+		goto enomem;
-+	dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ,
-+				&dev->req->dma, GFP_KERNEL);
-+	if (!dev->req->buf)
-+		goto enomem;
-+
-+	dev->req->complete = zero_setup_complete;
-+
-+	device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
-+
-+#ifdef CONFIG_USB_GADGET_DUALSPEED
-+	/* assume ep0 uses the same value for both speeds ... */
-+	dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0;
-+
-+	/* and that all endpoints are dual-speed */
-+	//hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
-+	//hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
-+#endif
-+
-+	usb_gadget_set_selfpowered (gadget);
-+
-+	init_timer (&dev->resume);
-+	dev->resume.function = zero_autoresume;
-+	dev->resume.data = (unsigned long) dev;
-+
-+	gadget->ep0->driver_data = dev;
-+
-+	INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname);
-+	INFO (dev, "using %s, OUT %s IN %s\n", gadget->name,
-+		EP_OUT_NAME, EP_IN_NAME);
-+
-+	snprintf (manufacturer, sizeof manufacturer,
-+		UTS_SYSNAME " " UTS_RELEASE " with %s",
-+		gadget->name);
-+
-+	return 0;
-+
-+enomem:
-+	zero_unbind (gadget);
-+	return -ENOMEM;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void
-+zero_suspend (struct usb_gadget *gadget)
-+{
-+	struct zero_dev		*dev = get_gadget_data (gadget);
-+
-+	if (gadget->speed == USB_SPEED_UNKNOWN)
-+		return;
-+
-+	if (autoresume) {
-+		mod_timer (&dev->resume, jiffies + (HZ * autoresume));
-+		DBG (dev, "suspend, wakeup in %d seconds\n", autoresume);
-+	} else
-+		DBG (dev, "suspend\n");
-+}
-+
-+static void
-+zero_resume (struct usb_gadget *gadget)
-+{
-+	struct zero_dev		*dev = get_gadget_data (gadget);
-+
-+	DBG (dev, "resume\n");
-+	del_timer (&dev->resume);
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static struct usb_gadget_driver zero_driver = {
-+#ifdef CONFIG_USB_GADGET_DUALSPEED
-+	.speed		= USB_SPEED_HIGH,
-+#else
-+	.speed		= USB_SPEED_FULL,
-+#endif
-+	.function	= (char *) longname,
-+	.bind		= zero_bind,
-+	.unbind		= zero_unbind,
-+
-+	.setup		= zero_setup,
-+	.disconnect	= zero_disconnect,
-+
-+	.suspend	= zero_suspend,
-+	.resume		= zero_resume,
-+
-+	.driver 	= {
-+		.name		= (char *) shortname,
-+		// .shutdown = ...
-+		// .suspend = ...
-+		// .resume = ...
-+	},
-+};
-+
-+MODULE_AUTHOR ("David Brownell");
-+MODULE_LICENSE ("Dual BSD/GPL");
-+
-+static struct proc_dir_entry *pdir, *pfile;
-+
-+static int isoc_read_data (char *page, char **start,
-+			   off_t off, int count,
-+			   int *eof, void *data)
-+{
-+	int i;
-+	static int c = 0;
-+	static int done = 0;
-+	static int s = 0;
-+
-+/*
-+	printk ("\ncount: %d\n", count);
-+	printk ("rbuf_start: %d\n", rbuf_start);
-+	printk ("rbuf_len: %d\n", rbuf_len);
-+	printk ("off: %d\n", off);
-+	printk ("start: %p\n\n", *start);
-+*/
-+	if (done) {
-+		c = 0;
-+		done = 0;
-+		*eof = 1;
-+		return 0;
-+	}
-+
-+	if (c == 0) {
-+		if (rbuf_len == RBUF_LEN)
-+			s = rbuf_start;
-+		else s = 0;
-+	}
-+
-+	for (i=0; i<count && c<rbuf_len; i++, c++) {
-+		page[i] = rbuf[(c+s) % RBUF_LEN];
-+	}
-+	*start = page;
-+
-+	if (c >= rbuf_len) {
-+		*eof = 1;
-+		done = 1;
-+	}
-+
-+
-+	return i;
-+}
-+
-+static int __init init (void)
-+{
-+
-+	int retval = 0;
-+
-+	pdir = proc_mkdir("isoc_test", NULL);
-+	if(pdir == NULL) {
-+		retval = -ENOMEM;
-+		printk("Error creating dir\n");
-+		goto done;
-+	}
-+	pdir->owner = THIS_MODULE;
-+
-+	pfile = create_proc_read_entry("isoc_data",
-+				       0444, pdir,
-+				       isoc_read_data,
-+				       NULL);
-+	if (pfile == NULL) {
-+		retval = -ENOMEM;
-+		printk("Error creating file\n");
-+		goto no_file;
-+	}
-+	pfile->owner = THIS_MODULE;
-+
-+	return usb_gadget_register_driver (&zero_driver);
-+
-+ no_file:
-+	remove_proc_entry("isoc_data", NULL);
-+ done:
-+	return retval;
-+}
-+module_init (init);
-+
-+static void __exit cleanup (void)
-+{
-+
-+	usb_gadget_unregister_driver (&zero_driver);
-+
-+	remove_proc_entry("isoc_data", pdir);
-+	remove_proc_entry("isoc_test", NULL);
-+}
-+module_exit (cleanup);
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/dwc_cfi_common.h
-@@ -0,0 +1,142 @@
-+/* ==========================================================================
-+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
-+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
-+ * otherwise expressly agreed to in writing between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product under
-+ * any End User Software License Agreement or Agreement for Licensed Product
-+ * with Synopsys or any supplement thereto. You are permitted to use and
-+ * redistribute this Software in source and binary forms, with or without
-+ * modification, provided that redistributions of source code must retain this
-+ * notice. You may not view, use, disclose, copy or distribute this file or
-+ * any information contained herein except pursuant to this license grant from
-+ * Synopsys. If you do not agree with this notice, including the disclaimer
-+ * below, then you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================== */
-+
-+#if !defined(__DWC_CFI_COMMON_H__)
-+#define __DWC_CFI_COMMON_H__
-+
-+//#include <linux/types.h>
-+
-+/**
-+ * @file
-+ *
-+ * This file contains the CFI specific common constants, interfaces
-+ * (functions and macros) and structures for Linux. No PCD specific
-+ * data structure or definition is to be included in this file.
-+ *
-+ */
-+
-+/** This is a request for all Core Features */
-+#define VEN_CORE_GET_FEATURES		0xB1
-+
-+/** This is a request to get the value of a specific Core Feature */
-+#define VEN_CORE_GET_FEATURE		0xB2
-+
-+/** This command allows the host to set the value of a specific Core Feature */
-+#define VEN_CORE_SET_FEATURE		0xB3
-+
-+/** This command allows the host to set the default values of
-+ * either all or any specific Core Feature
-+ */
-+#define VEN_CORE_RESET_FEATURES		0xB4
-+
-+/** This command forces the PCD to write the deferred values of a Core Features */
-+#define VEN_CORE_ACTIVATE_FEATURES	0xB5
-+
-+/** This request reads a DWORD value from a register at the specified offset */
-+#define VEN_CORE_READ_REGISTER		0xB6
-+
-+/** This request writes a DWORD value into a register at the specified offset */
-+#define VEN_CORE_WRITE_REGISTER		0xB7
-+
-+/** This structure is the header of the Core Features dataset returned to
-+ *  the Host
-+ */
-+struct cfi_all_features_header {
-+/** The features header structure length is */
-+#define CFI_ALL_FEATURES_HDR_LEN		8
-+	/**
-+	 * The total length of the features dataset returned to the Host
-+	 */
-+	uint16_t wTotalLen;
-+
-+	/**
-+	 * CFI version number inBinary-Coded Decimal (i.e., 1.00 is 100H).
-+	 * This field identifies the version of the CFI Specification with which
-+	 * the device is compliant.
-+	 */
-+	uint16_t wVersion;
-+
-+	/** The ID of the Core */
-+	uint16_t wCoreID;
-+#define CFI_CORE_ID_UDC		1
-+#define CFI_CORE_ID_OTG		2
-+#define CFI_CORE_ID_WUDEV	3
-+
-+	/** Number of features returned by VEN_CORE_GET_FEATURES request */
-+	uint16_t wNumFeatures;
-+} UPACKED;
-+
-+typedef struct cfi_all_features_header cfi_all_features_header_t;
-+
-+/** This structure is a header of the Core Feature descriptor dataset returned to
-+ *  the Host after the VEN_CORE_GET_FEATURES request
-+ */
-+struct cfi_feature_desc_header {
-+#define CFI_FEATURE_DESC_HDR_LEN	8
-+
-+	/** The feature ID */
-+	uint16_t wFeatureID;
-+
-+	/** Length of this feature descriptor in bytes - including the
-+	 * length of the feature name string
-+	 */
-+	uint16_t wLength;
-+
-+	/** The data length of this feature in bytes */
-+	uint16_t wDataLength;
-+
-+	/**
-+	 * Attributes of this features
-+	 * D0: Access rights
-+	 * 0 - Read/Write
-+	 * 1 - Read only
-+	 */
-+	uint8_t bmAttributes;
-+#define CFI_FEATURE_ATTR_RO		1
-+#define CFI_FEATURE_ATTR_RW		0
-+
-+	/** Length of the feature name in bytes */
-+	uint8_t bNameLen;
-+
-+	/** The feature name buffer */
-+	//uint8_t *name;
-+} UPACKED;
-+
-+typedef struct cfi_feature_desc_header cfi_feature_desc_header_t;
-+
-+/**
-+ * This structure describes a NULL terminated string referenced by its id field.
-+ * It is very similar to usb_string structure but has the id field type set to 16-bit.
-+ */
-+struct cfi_string {
-+	uint16_t id;
-+	const uint8_t *s;
-+};
-+typedef struct cfi_string cfi_string_t;
-+
-+#endif
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_adp.c
-@@ -0,0 +1,854 @@
-+/* ==========================================================================
-+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_adp.c $
-+ * $Revision: #12 $
-+ * $Date: 2011/10/26 $
-+ * $Change: 1873028 $
-+ *
-+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
-+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
-+ * otherwise expressly agreed to in writing between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product under
-+ * any End User Software License Agreement or Agreement for Licensed Product
-+ * with Synopsys or any supplement thereto. You are permitted to use and
-+ * redistribute this Software in source and binary forms, with or without
-+ * modification, provided that redistributions of source code must retain this
-+ * notice. You may not view, use, disclose, copy or distribute this file or
-+ * any information contained herein except pursuant to this license grant from
-+ * Synopsys. If you do not agree with this notice, including the disclaimer
-+ * below, then you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================== */
-+
-+#include "dwc_os.h"
-+#include "dwc_otg_regs.h"
-+#include "dwc_otg_cil.h"
-+#include "dwc_otg_adp.h"
-+
-+/** @file
-+ *
-+ * This file contains the most of the Attach Detect Protocol implementation for
-+ * the driver to support OTG Rev2.0.
-+ *
-+ */
-+
-+void dwc_otg_adp_write_reg(dwc_otg_core_if_t * core_if, uint32_t value)
-+{
-+	adpctl_data_t adpctl;
-+
-+	adpctl.d32 = value;
-+	adpctl.b.ar = 0x2;
-+
-+	DWC_WRITE_REG32(&core_if->core_global_regs->adpctl, adpctl.d32);
-+
-+	while (adpctl.b.ar) {
-+		adpctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->adpctl);
-+	}
-+
-+}
-+
-+/**
-+ * Function is called to read ADP registers
-+ */
-+uint32_t dwc_otg_adp_read_reg(dwc_otg_core_if_t * core_if)
-+{
-+	adpctl_data_t adpctl;
-+
-+	adpctl.d32 = 0;
-+	adpctl.b.ar = 0x1;
-+
-+	DWC_WRITE_REG32(&core_if->core_global_regs->adpctl, adpctl.d32);
-+
-+	while (adpctl.b.ar) {
-+		adpctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->adpctl);
-+	}
-+
-+	return adpctl.d32;
-+}
-+
-+/**
-+ * Function is called to read ADPCTL register and filter Write-clear bits
-+ */
-+uint32_t dwc_otg_adp_read_reg_filter(dwc_otg_core_if_t * core_if)
-+{
-+	adpctl_data_t adpctl;
-+
-+	adpctl.d32 = dwc_otg_adp_read_reg(core_if);
-+	adpctl.b.adp_tmout_int = 0;
-+	adpctl.b.adp_prb_int = 0;
-+	adpctl.b.adp_tmout_int = 0;
-+
-+	return adpctl.d32;
-+}
-+
-+/**
-+ * Function is called to write ADP registers
-+ */
-+void dwc_otg_adp_modify_reg(dwc_otg_core_if_t * core_if, uint32_t clr,
-+			    uint32_t set)
-+{
-+	dwc_otg_adp_write_reg(core_if,
-+			      (dwc_otg_adp_read_reg(core_if) & (~clr)) | set);
-+}
-+
-+static void adp_sense_timeout(void *ptr)
-+{
-+	dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr;
-+	core_if->adp.sense_timer_started = 0;
-+	DWC_PRINTF("ADP SENSE TIMEOUT\n");
-+	if (core_if->adp_enable) {
-+		dwc_otg_adp_sense_stop(core_if);
-+		dwc_otg_adp_probe_start(core_if);
-+	}
-+}
-+
-+/**
-+ * This function is called when the ADP vbus timer expires. Timeout is 1.1s.
-+ */
-+static void adp_vbuson_timeout(void *ptr)
-+{
-+	gpwrdn_data_t gpwrdn;
-+	dwc_otg_core_if_t *core_if = (dwc_otg_core_if_t *) ptr;
-+	hprt0_data_t hprt0 = {.d32 = 0 };
-+	pcgcctl_data_t pcgcctl = {.d32 = 0 };
-+	DWC_PRINTF("%s: 1.1 seconds expire after turning on VBUS\n",__FUNCTION__);
-+	if (core_if) {
-+		core_if->adp.vbuson_timer_started = 0;
-+		/* Turn off vbus */
-+		hprt0.b.prtpwr = 1;
-+		DWC_MODIFY_REG32(core_if->host_if->hprt0, hprt0.d32, 0);
-+		gpwrdn.d32 = 0;
-+
-+		/* Power off the core */
-+		if (core_if->power_down == 2) {
-+			/* Enable Wakeup Logic */
-+//                      gpwrdn.b.wkupactiv = 1;
-+			gpwrdn.b.pmuactv = 0;
-+			gpwrdn.b.pwrdnrstn = 1;
-+			gpwrdn.b.pwrdnclmp = 1;
-+			DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0,
-+					 gpwrdn.d32);
-+
-+			/* Suspend the Phy Clock */
-+			pcgcctl.b.stoppclk = 1;
-+			DWC_MODIFY_REG32(core_if->pcgcctl, 0, pcgcctl.d32);
-+
-+			/* Switch on VDD */
-+//                      gpwrdn.b.wkupactiv = 1;
-+			gpwrdn.b.pmuactv = 1;
-+			gpwrdn.b.pwrdnrstn = 1;
-+			gpwrdn.b.pwrdnclmp = 1;
-+			DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0,
-+					 gpwrdn.d32);
-+		} else {
-+			/* Enable Power Down Logic */
-+			gpwrdn.b.pmuintsel = 1;
-+			gpwrdn.b.pmuactv = 1;
-+			DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
-+		}
-+
-+		/* Power off the core */
-+		if (core_if->power_down == 2) {
-+			gpwrdn.d32 = 0;
-+			gpwrdn.b.pwrdnswtch = 1;
-+			DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn,
-+					 gpwrdn.d32, 0);
-+		}
-+
-+		/* Unmask SRP detected interrupt from Power Down Logic */
-+		gpwrdn.d32 = 0;
-+		gpwrdn.b.srp_det_msk = 1;
-+		DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
-+
-+		dwc_otg_adp_probe_start(core_if);
-+		dwc_otg_dump_global_registers(core_if);
-+		dwc_otg_dump_host_registers(core_if);
-+	}
-+
-+}
-+
-+/**
-+ * Start the ADP Initial Probe timer to detect if Port Connected interrupt is
-+ * not asserted within 1.1 seconds.
-+ *
-+ * @param core_if the pointer to core_if strucure.
-+ */
-+void dwc_otg_adp_vbuson_timer_start(dwc_otg_core_if_t * core_if)
-+{
-+	core_if->adp.vbuson_timer_started = 1;
-+	if (core_if->adp.vbuson_timer)
-+	{
-+		DWC_PRINTF("SCHEDULING VBUSON TIMER\n");
-+		/* 1.1 secs + 60ms necessary for cil_hcd_start*/
-+		DWC_TIMER_SCHEDULE(core_if->adp.vbuson_timer, 1160);
-+	} else {
-+		DWC_WARN("VBUSON_TIMER = %p\n",core_if->adp.vbuson_timer);
-+	}
-+}
-+
-+#if 0
-+/**
-+ * Masks all DWC OTG core interrupts
-+ *
-+ */
-+static void mask_all_interrupts(dwc_otg_core_if_t * core_if)
-+{
-+	int i;
-+	gahbcfg_data_t ahbcfg = {.d32 = 0 };
-+
-+	/* Mask Host Interrupts */
-+
-+	/* Clear and disable HCINTs */
-+	for (i = 0; i < core_if->core_params->host_channels; i++) {
-+		DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcintmsk, 0);
-+		DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcint, 0xFFFFFFFF);
-+
-+	}
-+
-+	/* Clear and disable HAINT */
-+	DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk, 0x0000);
-+	DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haint, 0xFFFFFFFF);
-+
-+	/* Mask Device Interrupts */
-+	if (!core_if->multiproc_int_enable) {
-+		/* Clear and disable IN Endpoint interrupts */
-+		DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->diepmsk, 0);
-+		for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
-+			DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->
-+					diepint, 0xFFFFFFFF);
-+		}
-+
-+		/* Clear and disable OUT Endpoint interrupts */
-+		DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->doepmsk, 0);
-+		for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
-+			DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->
-+					doepint, 0xFFFFFFFF);
-+		}
-+
-+		/* Clear and disable DAINT */
-+		DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daint,
-+				0xFFFFFFFF);
-+		DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daintmsk, 0);
-+	} else {
-+		for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
-+			DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
-+					diepeachintmsk[i], 0);
-+			DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->
-+					diepint, 0xFFFFFFFF);
-+		}
-+
-+		for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
-+			DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
-+					doepeachintmsk[i], 0);
-+			DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->
-+					doepint, 0xFFFFFFFF);
-+		}
-+
-+		DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->deachintmsk,
-+				0);
-+		DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->deachint,
-+				0xFFFFFFFF);
-+
-+	}
-+
-+	/* Disable interrupts */
-+	ahbcfg.b.glblintrmsk = 1;
-+	DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
-+
-+	/* Disable all interrupts. */
-+	DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0);
-+
-+	/* Clear any pending interrupts */
-+	DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
-+
-+	/* Clear any pending OTG Interrupts */
-+	DWC_WRITE_REG32(&core_if->core_global_regs->gotgint, 0xFFFFFFFF);
-+}
-+
-+/**
-+ * Unmask Port Connection Detected interrupt
-+ *
-+ */
-+static void unmask_conn_det_intr(dwc_otg_core_if_t * core_if)
-+{
-+	gintmsk_data_t gintmsk = {.d32 = 0,.b.portintr = 1 };
-+
-+	DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
-+}
-+#endif
-+
-+/**
-+ * Starts the ADP Probing
-+ *
-+ * @param core_if the pointer to core_if structure.
-+ */
-+uint32_t dwc_otg_adp_probe_start(dwc_otg_core_if_t * core_if)
-+{
-+
-+	adpctl_data_t adpctl = {.d32 = 0};
-+	gpwrdn_data_t gpwrdn;
-+#if 0
-+	adpctl_data_t adpctl_int = {.d32 = 0, .b.adp_prb_int = 1,
-+								.b.adp_sns_int = 1, b.adp_tmout_int};
-+#endif
-+	dwc_otg_disable_global_interrupts(core_if);
-+	DWC_PRINTF("ADP Probe Start\n");
-+	core_if->adp.probe_enabled = 1;
-+
-+	adpctl.b.adpres = 1;
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+
-+	while (adpctl.b.adpres) {
-+		adpctl.d32 = dwc_otg_adp_read_reg(core_if);
-+	}
-+
-+	adpctl.d32 = 0;
-+	gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
-+
-+	/* In Host mode unmask SRP detected interrupt */
-+	gpwrdn.d32 = 0;
-+	gpwrdn.b.sts_chngint_msk = 1;
-+	if (!gpwrdn.b.idsts) {
-+		gpwrdn.b.srp_det_msk = 1;
-+	}
-+	DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
-+
-+	adpctl.b.adp_tmout_int_msk = 1;
-+	adpctl.b.adp_prb_int_msk = 1;
-+	adpctl.b.prb_dschg = 1;
-+	adpctl.b.prb_delta = 1;
-+	adpctl.b.prb_per = 1;
-+	adpctl.b.adpen = 1;
-+	adpctl.b.enaprb = 1;
-+
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+	DWC_PRINTF("ADP Probe Finish\n");
-+	return 0;
-+}
-+
-+/**
-+ * Starts the ADP Sense timer to detect if ADP Sense interrupt is not asserted
-+ * within 3 seconds.
-+ *
-+ * @param core_if the pointer to core_if strucure.
-+ */
-+void dwc_otg_adp_sense_timer_start(dwc_otg_core_if_t * core_if)
-+{
-+	core_if->adp.sense_timer_started = 1;
-+	DWC_TIMER_SCHEDULE(core_if->adp.sense_timer, 3000 /* 3 secs */ );
-+}
-+
-+/**
-+ * Starts the ADP Sense
-+ *
-+ * @param core_if the pointer to core_if strucure.
-+ */
-+uint32_t dwc_otg_adp_sense_start(dwc_otg_core_if_t * core_if)
-+{
-+	adpctl_data_t adpctl;
-+
-+	DWC_PRINTF("ADP Sense Start\n");
-+
-+	/* Unmask ADP sense interrupt and mask all other from the core */
-+	adpctl.d32 = dwc_otg_adp_read_reg_filter(core_if);
-+	adpctl.b.adp_sns_int_msk = 1;
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+	dwc_otg_disable_global_interrupts(core_if); // vahrama
-+
-+	/* Set ADP reset bit*/
-+	adpctl.d32 = dwc_otg_adp_read_reg_filter(core_if);
-+	adpctl.b.adpres = 1;
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+
-+	while (adpctl.b.adpres) {
-+		adpctl.d32 = dwc_otg_adp_read_reg(core_if);
-+	}
-+
-+	adpctl.b.adpres = 0;
-+	adpctl.b.adpen = 1;
-+	adpctl.b.enasns = 1;
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+
-+	dwc_otg_adp_sense_timer_start(core_if);
-+
-+	return 0;
-+}
-+
-+/**
-+ * Stops the ADP Probing
-+ *
-+ * @param core_if the pointer to core_if strucure.
-+ */
-+uint32_t dwc_otg_adp_probe_stop(dwc_otg_core_if_t * core_if)
-+{
-+
-+	adpctl_data_t adpctl;
-+	DWC_PRINTF("Stop ADP probe\n");
-+	core_if->adp.probe_enabled = 0;
-+	core_if->adp.probe_counter = 0;
-+	adpctl.d32 = dwc_otg_adp_read_reg(core_if);
-+
-+	adpctl.b.adpen = 0;
-+	adpctl.b.adp_prb_int = 1;
-+	adpctl.b.adp_tmout_int = 1;
-+	adpctl.b.adp_sns_int = 1;
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+
-+	return 0;
-+}
-+
-+/**
-+ * Stops the ADP Sensing
-+ *
-+ * @param core_if the pointer to core_if strucure.
-+ */
-+uint32_t dwc_otg_adp_sense_stop(dwc_otg_core_if_t * core_if)
-+{
-+	adpctl_data_t adpctl;
-+
-+	core_if->adp.sense_enabled = 0;
-+
-+	adpctl.d32 = dwc_otg_adp_read_reg_filter(core_if);
-+	adpctl.b.enasns = 0;
-+	adpctl.b.adp_sns_int = 1;
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+
-+	return 0;
-+}
-+
-+/**
-+ * Called to turn on the VBUS after initial ADP probe in host mode.
-+ * If port power was already enabled in cil_hcd_start function then
-+ * only schedule a timer.
-+ *
-+ * @param core_if the pointer to core_if structure.
-+ */
-+void dwc_otg_adp_turnon_vbus(dwc_otg_core_if_t * core_if)
-+{
-+	hprt0_data_t hprt0 = {.d32 = 0 };
-+	hprt0.d32 = dwc_otg_read_hprt0(core_if);
-+	DWC_PRINTF("Turn on VBUS for 1.1s, port power is %d\n", hprt0.b.prtpwr);
-+
-+	if (hprt0.b.prtpwr == 0) {
-+		hprt0.b.prtpwr = 1;
-+		//DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
-+	}
-+
-+	dwc_otg_adp_vbuson_timer_start(core_if);
-+}
-+
-+/**
-+ * Called right after driver is loaded
-+ * to perform initial actions for ADP
-+ *
-+ * @param core_if the pointer to core_if structure.
-+ * @param is_host - flag for current mode of operation either from GINTSTS or GPWRDN
-+ */
-+void dwc_otg_adp_start(dwc_otg_core_if_t * core_if, uint8_t is_host)
-+{
-+	gpwrdn_data_t gpwrdn;
-+
-+	DWC_PRINTF("ADP Initial Start\n");
-+	core_if->adp.adp_started = 1;
-+
-+	DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
-+	dwc_otg_disable_global_interrupts(core_if);
-+	if (is_host) {
-+		DWC_PRINTF("HOST MODE\n");
-+		/* Enable Power Down Logic Interrupt*/
-+		gpwrdn.d32 = 0;
-+		gpwrdn.b.pmuintsel = 1;
-+		gpwrdn.b.pmuactv = 1;
-+		DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
-+		/* Initialize first ADP probe to obtain Ramp Time value */
-+		core_if->adp.initial_probe = 1;
-+		dwc_otg_adp_probe_start(core_if);
-+	} else {
-+		gotgctl_data_t gotgctl;
-+		gotgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
-+		DWC_PRINTF("DEVICE MODE\n");
-+		if (gotgctl.b.bsesvld == 0) {
-+			/* Enable Power Down Logic Interrupt*/
-+			gpwrdn.d32 = 0;
-+			DWC_PRINTF("VBUS is not valid - start ADP probe\n");
-+			gpwrdn.b.pmuintsel = 1;
-+			gpwrdn.b.pmuactv = 1;
-+			DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
-+			core_if->adp.initial_probe = 1;
-+			dwc_otg_adp_probe_start(core_if);
-+		} else {
-+			DWC_PRINTF("VBUS is valid - initialize core as a Device\n");
-+			core_if->op_state = B_PERIPHERAL;
-+			dwc_otg_core_init(core_if);
-+			dwc_otg_enable_global_interrupts(core_if);
-+			cil_pcd_start(core_if);
-+			dwc_otg_dump_global_registers(core_if);
-+			dwc_otg_dump_dev_registers(core_if);
-+		}
-+	}
-+}
-+
-+void dwc_otg_adp_init(dwc_otg_core_if_t * core_if)
-+{
-+	core_if->adp.adp_started = 0;
-+	core_if->adp.initial_probe = 0;
-+	core_if->adp.probe_timer_values[0] = -1;
-+	core_if->adp.probe_timer_values[1] = -1;
-+	core_if->adp.probe_enabled = 0;
-+	core_if->adp.sense_enabled = 0;
-+	core_if->adp.sense_timer_started = 0;
-+	core_if->adp.vbuson_timer_started = 0;
-+	core_if->adp.probe_counter = 0;
-+	core_if->adp.gpwrdn = 0;
-+	core_if->adp.attached = DWC_OTG_ADP_UNKOWN;
-+	/* Initialize timers */
-+	core_if->adp.sense_timer =
-+	    DWC_TIMER_ALLOC("ADP SENSE TIMER", adp_sense_timeout, core_if);
-+	core_if->adp.vbuson_timer =
-+	    DWC_TIMER_ALLOC("ADP VBUS ON TIMER", adp_vbuson_timeout, core_if);
-+	if (!core_if->adp.sense_timer || !core_if->adp.vbuson_timer)
-+	{
-+		DWC_ERROR("Could not allocate memory for ADP timers\n");
-+	}
-+}
-+
-+void dwc_otg_adp_remove(dwc_otg_core_if_t * core_if)
-+{
-+	gpwrdn_data_t gpwrdn = { .d32 = 0 };
-+	gpwrdn.b.pmuintsel = 1;
-+	gpwrdn.b.pmuactv = 1;
-+	DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
-+
-+	if (core_if->adp.probe_enabled)
-+		dwc_otg_adp_probe_stop(core_if);
-+	if (core_if->adp.sense_enabled)
-+		dwc_otg_adp_sense_stop(core_if);
-+	if (core_if->adp.sense_timer_started)
-+		DWC_TIMER_CANCEL(core_if->adp.sense_timer);
-+	if (core_if->adp.vbuson_timer_started)
-+		DWC_TIMER_CANCEL(core_if->adp.vbuson_timer);
-+	DWC_TIMER_FREE(core_if->adp.sense_timer);
-+	DWC_TIMER_FREE(core_if->adp.vbuson_timer);
-+}
-+
-+/////////////////////////////////////////////////////////////////////
-+////////////// ADP Interrupt Handlers ///////////////////////////////
-+/////////////////////////////////////////////////////////////////////
-+/**
-+ * This function sets Ramp Timer values
-+ */
-+static uint32_t set_timer_value(dwc_otg_core_if_t * core_if, uint32_t val)
-+{
-+	if (core_if->adp.probe_timer_values[0] == -1) {
-+		core_if->adp.probe_timer_values[0] = val;
-+		core_if->adp.probe_timer_values[1] = -1;
-+		return 1;
-+	} else {
-+		core_if->adp.probe_timer_values[1] =
-+		    core_if->adp.probe_timer_values[0];
-+		core_if->adp.probe_timer_values[0] = val;
-+		return 0;
-+	}
-+}
-+
-+/**
-+ * This function compares Ramp Timer values
-+ */
-+static uint32_t compare_timer_values(dwc_otg_core_if_t * core_if)
-+{
-+	uint32_t diff;
-+	if (core_if->adp.probe_timer_values[0]>=core_if->adp.probe_timer_values[1])
-+			diff = core_if->adp.probe_timer_values[0]-core_if->adp.probe_timer_values[1];
-+	else
-+			diff = core_if->adp.probe_timer_values[1]-core_if->adp.probe_timer_values[0];
-+	if(diff < 2) {
-+		return 0;
-+	} else {
-+		return 1;
-+	}
-+}
-+
-+/**
-+ * This function handles ADP Probe Interrupts
-+ */
-+static int32_t dwc_otg_adp_handle_prb_intr(dwc_otg_core_if_t * core_if,
-+						 uint32_t val)
-+{
-+	adpctl_data_t adpctl = {.d32 = 0 };
-+	gpwrdn_data_t gpwrdn, temp;
-+	adpctl.d32 = val;
-+
-+	temp.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
-+	core_if->adp.probe_counter++;
-+	core_if->adp.gpwrdn = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
-+	if (adpctl.b.rtim == 0 && !temp.b.idsts){
-+		DWC_PRINTF("RTIM value is 0\n");
-+		goto exit;
-+	}
-+	if (set_timer_value(core_if, adpctl.b.rtim) &&
-+	    core_if->adp.initial_probe) {
-+		core_if->adp.initial_probe = 0;
-+		dwc_otg_adp_probe_stop(core_if);
-+		gpwrdn.d32 = 0;
-+		gpwrdn.b.pmuactv = 1;
-+		gpwrdn.b.pmuintsel = 1;
-+		DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
-+		DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
-+
-+		/* check which value is for device mode and which for Host mode */
-+		if (!temp.b.idsts) {	/* considered host mode value is 0 */
-+			/*
-+			 * Turn on VBUS after initial ADP probe.
-+			 */
-+			core_if->op_state = A_HOST;
-+			dwc_otg_enable_global_interrupts(core_if);
-+			DWC_SPINUNLOCK(core_if->lock);
-+			cil_hcd_start(core_if);
-+			dwc_otg_adp_turnon_vbus(core_if);
-+			DWC_SPINLOCK(core_if->lock);
-+		} else {
-+			/*
-+			 * Initiate SRP after initial ADP probe.
-+			 */
-+			dwc_otg_enable_global_interrupts(core_if);
-+			dwc_otg_initiate_srp(core_if);
-+		}
-+	} else if (core_if->adp.probe_counter > 2){
-+		gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
-+		if (compare_timer_values(core_if)) {
-+			DWC_PRINTF("Difference in timer values !!! \n");
-+//                      core_if->adp.attached = DWC_OTG_ADP_ATTACHED;
-+			dwc_otg_adp_probe_stop(core_if);
-+
-+			/* Power on the core */
-+			if (core_if->power_down == 2) {
-+				gpwrdn.b.pwrdnswtch = 1;
-+				DWC_MODIFY_REG32(&core_if->core_global_regs->
-+						 gpwrdn, 0, gpwrdn.d32);
-+			}
-+
-+			/* check which value is for device mode and which for Host mode */
-+			if (!temp.b.idsts) {	/* considered host mode value is 0 */
-+				/* Disable Interrupt from Power Down Logic */
-+				gpwrdn.d32 = 0;
-+				gpwrdn.b.pmuintsel = 1;
-+				gpwrdn.b.pmuactv = 1;
-+				DWC_MODIFY_REG32(&core_if->core_global_regs->
-+						 gpwrdn, gpwrdn.d32, 0);
-+
-+				/*
-+				 * Initialize the Core for Host mode.
-+				 */
-+				core_if->op_state = A_HOST;
-+				dwc_otg_core_init(core_if);
-+				dwc_otg_enable_global_interrupts(core_if);
-+				cil_hcd_start(core_if);
-+			} else {
-+				gotgctl_data_t gotgctl;
-+				/* Mask SRP detected interrupt from Power Down Logic */
-+				gpwrdn.d32 = 0;
-+				gpwrdn.b.srp_det_msk = 1;
-+				DWC_MODIFY_REG32(&core_if->core_global_regs->
-+						 gpwrdn, gpwrdn.d32, 0);
-+
-+				/* Disable Power Down Logic */
-+				gpwrdn.d32 = 0;
-+				gpwrdn.b.pmuintsel = 1;
-+				gpwrdn.b.pmuactv = 1;
-+				DWC_MODIFY_REG32(&core_if->core_global_regs->
-+						 gpwrdn, gpwrdn.d32, 0);
-+
-+				/*
-+				 * Initialize the Core for Device mode.
-+				 */
-+				core_if->op_state = B_PERIPHERAL;
-+				dwc_otg_core_init(core_if);
-+				dwc_otg_enable_global_interrupts(core_if);
-+				cil_pcd_start(core_if);
-+
-+				gotgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
-+				if (!gotgctl.b.bsesvld) {
-+					dwc_otg_initiate_srp(core_if);
-+				}
-+			}
-+		}
-+		if (core_if->power_down == 2) {
-+			if (gpwrdn.b.bsessvld) {
-+				/* Mask SRP detected interrupt from Power Down Logic */
-+				gpwrdn.d32 = 0;
-+				gpwrdn.b.srp_det_msk = 1;
-+				DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
-+
-+				/* Disable Power Down Logic */
-+				gpwrdn.d32 = 0;
-+				gpwrdn.b.pmuactv = 1;
-+				DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
-+
-+				/*
-+				 * Initialize the Core for Device mode.
-+				 */
-+				core_if->op_state = B_PERIPHERAL;
-+				dwc_otg_core_init(core_if);
-+				dwc_otg_enable_global_interrupts(core_if);
-+				cil_pcd_start(core_if);
-+			}
-+		}
-+	}
-+exit:
-+	/* Clear interrupt */
-+	adpctl.d32 = dwc_otg_adp_read_reg(core_if);
-+	adpctl.b.adp_prb_int = 1;
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+
-+	return 0;
-+}
-+
-+/**
-+ * This function hadles ADP Sense Interrupt
-+ */
-+static int32_t dwc_otg_adp_handle_sns_intr(dwc_otg_core_if_t * core_if)
-+{
-+	adpctl_data_t adpctl;
-+	/* Stop ADP Sense timer */
-+	DWC_TIMER_CANCEL(core_if->adp.sense_timer);
-+
-+	/* Restart ADP Sense timer */
-+	dwc_otg_adp_sense_timer_start(core_if);
-+
-+	/* Clear interrupt */
-+	adpctl.d32 = dwc_otg_adp_read_reg(core_if);
-+	adpctl.b.adp_sns_int = 1;
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+
-+	return 0;
-+}
-+
-+/**
-+ * This function handles ADP Probe Interrupts
-+ */
-+static int32_t dwc_otg_adp_handle_prb_tmout_intr(dwc_otg_core_if_t * core_if,
-+						 uint32_t val)
-+{
-+	adpctl_data_t adpctl = {.d32 = 0 };
-+	adpctl.d32 = val;
-+	set_timer_value(core_if, adpctl.b.rtim);
-+
-+	/* Clear interrupt */
-+	adpctl.d32 = dwc_otg_adp_read_reg(core_if);
-+	adpctl.b.adp_tmout_int = 1;
-+	dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+
-+	return 0;
-+}
-+
-+/**
-+ * ADP Interrupt handler.
-+ *
-+ */
-+int32_t dwc_otg_adp_handle_intr(dwc_otg_core_if_t * core_if)
-+{
-+	int retval = 0;
-+	adpctl_data_t adpctl = {.d32 = 0};
-+
-+	adpctl.d32 = dwc_otg_adp_read_reg(core_if);
-+	DWC_PRINTF("ADPCTL = %08x\n",adpctl.d32);
-+
-+	if (adpctl.b.adp_sns_int & adpctl.b.adp_sns_int_msk) {
-+		DWC_PRINTF("ADP Sense interrupt\n");
-+		retval |= dwc_otg_adp_handle_sns_intr(core_if);
-+	}
-+	if (adpctl.b.adp_tmout_int & adpctl.b.adp_tmout_int_msk) {
-+		DWC_PRINTF("ADP timeout interrupt\n");
-+		retval |= dwc_otg_adp_handle_prb_tmout_intr(core_if, adpctl.d32);
-+	}
-+	if (adpctl.b.adp_prb_int & adpctl.b.adp_prb_int_msk) {
-+		DWC_PRINTF("ADP Probe interrupt\n");
-+		adpctl.b.adp_prb_int = 1;
-+		retval |= dwc_otg_adp_handle_prb_intr(core_if, adpctl.d32);
-+	}
-+
-+//	dwc_otg_adp_modify_reg(core_if, adpctl.d32, 0);
-+	//dwc_otg_adp_write_reg(core_if, adpctl.d32);
-+	DWC_PRINTF("RETURN FROM ADP ISR\n");
-+
-+	return retval;
-+}
-+
-+/**
-+ *
-+ * @param core_if Programming view of DWC_otg controller.
-+ */
-+int32_t dwc_otg_adp_handle_srp_intr(dwc_otg_core_if_t * core_if)
-+{
-+
-+#ifndef DWC_HOST_ONLY
-+	hprt0_data_t hprt0;
-+	gpwrdn_data_t gpwrdn;
-+	DWC_DEBUGPL(DBG_ANY, "++ Power Down Logic Session Request Interrupt++\n");
-+
-+	gpwrdn.d32 = DWC_READ_REG32(&core_if->core_global_regs->gpwrdn);
-+	/* check which value is for device mode and which for Host mode */
-+	if (!gpwrdn.b.idsts) {	/* considered host mode value is 0 */
-+		DWC_PRINTF("SRP: Host mode\n");
-+
-+		if (core_if->adp_enable) {
-+			dwc_otg_adp_probe_stop(core_if);
-+
-+			/* Power on the core */
-+			if (core_if->power_down == 2) {
-+				gpwrdn.b.pwrdnswtch = 1;
-+				DWC_MODIFY_REG32(&core_if->core_global_regs->
-+						 gpwrdn, 0, gpwrdn.d32);
-+			}
-+
-+			core_if->op_state = A_HOST;
-+			dwc_otg_core_init(core_if);
-+			dwc_otg_enable_global_interrupts(core_if);
-+			cil_hcd_start(core_if);
-+		}
-+
-+		/* Turn on the port power bit. */
-+		hprt0.d32 = dwc_otg_read_hprt0(core_if);
-+		hprt0.b.prtpwr = 1;
-+		DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
-+
-+		/* Start the Connection timer. So a message can be displayed
-+		 * if connect does not occur within 10 seconds. */
-+		cil_hcd_session_start(core_if);
-+	} else {
-+		DWC_PRINTF("SRP: Device mode %s\n", __FUNCTION__);
-+		if (core_if->adp_enable) {
-+			dwc_otg_adp_probe_stop(core_if);
-+
-+			/* Power on the core */
-+			if (core_if->power_down == 2) {
-+				gpwrdn.b.pwrdnswtch = 1;
-+				DWC_MODIFY_REG32(&core_if->core_global_regs->
-+						 gpwrdn, 0, gpwrdn.d32);
-+			}
-+
-+			gpwrdn.d32 = 0;
-+			gpwrdn.b.pmuactv = 0;
-+			DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0,
-+					 gpwrdn.d32);
-+
-+			core_if->op_state = B_PERIPHERAL;
-+			dwc_otg_core_init(core_if);
-+			dwc_otg_enable_global_interrupts(core_if);
-+			cil_pcd_start(core_if);
-+		}
-+	}
-+#endif
-+	return 1;
-+}
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_adp.h
-@@ -0,0 +1,80 @@
-+/* ==========================================================================
-+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_adp.h $
-+ * $Revision: #7 $
-+ * $Date: 2011/10/24 $
-+ * $Change: 1871159 $
-+ *
-+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
-+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
-+ * otherwise expressly agreed to in writing between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product under
-+ * any End User Software License Agreement or Agreement for Licensed Product
-+ * with Synopsys or any supplement thereto. You are permitted to use and
-+ * redistribute this Software in source and binary forms, with or without
-+ * modification, provided that redistributions of source code must retain this
-+ * notice. You may not view, use, disclose, copy or distribute this file or
-+ * any information contained herein except pursuant to this license grant from
-+ * Synopsys. If you do not agree with this notice, including the disclaimer
-+ * below, then you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================== */
-+
-+#ifndef __DWC_OTG_ADP_H__
-+#define __DWC_OTG_ADP_H__
-+
-+/**
-+ * @file
-+ *
-+ * This file contains the Attach Detect Protocol interfaces and defines
-+ * (functions) and structures for Linux.
-+ *
-+ */
-+
-+#define DWC_OTG_ADP_UNATTACHED	0
-+#define DWC_OTG_ADP_ATTACHED	1
-+#define DWC_OTG_ADP_UNKOWN	2
-+
-+typedef struct dwc_otg_adp {
-+	uint32_t adp_started;
-+	uint32_t initial_probe;
-+	int32_t probe_timer_values[2];
-+	uint32_t probe_enabled;
-+	uint32_t sense_enabled;
-+	dwc_timer_t *sense_timer;
-+	uint32_t sense_timer_started;
-+	dwc_timer_t *vbuson_timer;
-+	uint32_t vbuson_timer_started;
-+	uint32_t attached;
-+	uint32_t probe_counter;
-+	uint32_t gpwrdn;
-+} dwc_otg_adp_t;
-+
-+/**
-+ * Attach Detect Protocol functions
-+ */
-+
-+extern void dwc_otg_adp_write_reg(dwc_otg_core_if_t * core_if, uint32_t value);
-+extern uint32_t dwc_otg_adp_read_reg(dwc_otg_core_if_t * core_if);
-+extern uint32_t dwc_otg_adp_probe_start(dwc_otg_core_if_t * core_if);
-+extern uint32_t dwc_otg_adp_sense_start(dwc_otg_core_if_t * core_if);
-+extern uint32_t dwc_otg_adp_probe_stop(dwc_otg_core_if_t * core_if);
-+extern uint32_t dwc_otg_adp_sense_stop(dwc_otg_core_if_t * core_if);
-+extern void dwc_otg_adp_start(dwc_otg_core_if_t * core_if, uint8_t is_host);
-+extern void dwc_otg_adp_init(dwc_otg_core_if_t * core_if);
-+extern void dwc_otg_adp_remove(dwc_otg_core_if_t * core_if);
-+extern int32_t dwc_otg_adp_handle_intr(dwc_otg_core_if_t * core_if);
-+extern int32_t dwc_otg_adp_handle_srp_intr(dwc_otg_core_if_t * core_if);
-+
-+#endif //__DWC_OTG_ADP_H__
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.c
-@@ -0,0 +1,1210 @@
-+/* ==========================================================================
-+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.c $
-+ * $Revision: #44 $
-+ * $Date: 2010/11/29 $
-+ * $Change: 1636033 $
-+ *
-+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
-+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
-+ * otherwise expressly agreed to in writing between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product under
-+ * any End User Software License Agreement or Agreement for Licensed Product
-+ * with Synopsys or any supplement thereto. You are permitted to use and
-+ * redistribute this Software in source and binary forms, with or without
-+ * modification, provided that redistributions of source code must retain this
-+ * notice. You may not view, use, disclose, copy or distribute this file or
-+ * any information contained herein except pursuant to this license grant from
-+ * Synopsys. If you do not agree with this notice, including the disclaimer
-+ * below, then you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================== */
-+
-+/** @file
-+ *
-+ * The diagnostic interface will provide access to the controller for
-+ * bringing up the hardware and testing.  The Linux driver attributes
-+ * feature will be used to provide the Linux Diagnostic
-+ * Interface. These attributes are accessed through sysfs.
-+ */
-+
-+/** @page "Linux Module Attributes"
-+ *
-+ * The Linux module attributes feature is used to provide the Linux
-+ * Diagnostic Interface.  These attributes are accessed through sysfs.
-+ * The diagnostic interface will provide access to the controller for
-+ * bringing up the hardware and testing.
-+
-+ The following table shows the attributes.
-+ <table>
-+ <tr>
-+ <td><b> Name</b></td>
-+ <td><b> Description</b></td>
-+ <td><b> Access</b></td>
-+ </tr>
-+
-+ <tr>
-+ <td> mode </td>
-+ <td> Returns the current mode: 0 for device mode, 1 for host mode</td>
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> hnpcapable </td>
-+ <td> Gets or sets the "HNP-capable" bit in the Core USB Configuraton Register.
-+ Read returns the current value.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> srpcapable </td>
-+ <td> Gets or sets the "SRP-capable" bit in the Core USB Configuraton Register.
-+ Read returns the current value.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> hsic_connect </td>
-+ <td> Gets or sets the "HSIC-Connect" bit in the GLPMCFG Register.
-+ Read returns the current value.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> inv_sel_hsic </td>
-+ <td> Gets or sets the "Invert Select HSIC" bit in the GLPMFG Register.
-+ Read returns the current value.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> hnp </td>
-+ <td> Initiates the Host Negotiation Protocol.  Read returns the status.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> srp </td>
-+ <td> Initiates the Session Request Protocol.  Read returns the status.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> buspower </td>
-+ <td> Gets or sets the Power State of the bus (0 - Off or 1 - On)</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> bussuspend </td>
-+ <td> Suspends the USB bus.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> busconnected </td>
-+ <td> Gets the connection status of the bus</td>
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> gotgctl </td>
-+ <td> Gets or sets the Core Control Status Register.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> gusbcfg </td>
-+ <td> Gets or sets the Core USB Configuration Register</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> grxfsiz </td>
-+ <td> Gets or sets the Receive FIFO Size Register</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> gnptxfsiz </td>
-+ <td> Gets or sets the non-periodic Transmit Size Register</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> gpvndctl </td>
-+ <td> Gets or sets the PHY Vendor Control Register</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> ggpio </td>
-+ <td> Gets the value in the lower 16-bits of the General Purpose IO Register
-+ or sets the upper 16 bits.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> guid </td>
-+ <td> Gets or sets the value of the User ID Register</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> gsnpsid </td>
-+ <td> Gets the value of the Synopsys ID Regester</td>
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> devspeed </td>
-+ <td> Gets or sets the device speed setting in the DCFG register</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> enumspeed </td>
-+ <td> Gets the device enumeration Speed.</td>
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> hptxfsiz </td>
-+ <td> Gets the value of the Host Periodic Transmit FIFO</td>
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> hprt0 </td>
-+ <td> Gets or sets the value in the Host Port Control and Status Register</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> regoffset </td>
-+ <td> Sets the register offset for the next Register Access</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> regvalue </td>
-+ <td> Gets or sets the value of the register at the offset in the regoffset attribute.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> remote_wakeup </td>
-+ <td> On read, shows the status of Remote Wakeup. On write, initiates a remote
-+ wakeup of the host. When bit 0 is 1 and Remote Wakeup is enabled, the Remote
-+ Wakeup signalling bit in the Device Control Register is set for 1
-+ milli-second.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> rem_wakeup_pwrdn </td>
-+ <td> On read, shows the status core - hibernated or not. On write, initiates
-+ a remote wakeup of the device from Hibernation. </td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> mode_ch_tim_en </td>
-+ <td> This bit is used to enable or disable the host core to wait for 200 PHY
-+ clock cycles at the end of Resume to change the opmode signal to the PHY to 00
-+ after Suspend or LPM. </td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> fr_interval </td>
-+ <td> On read, shows the value of HFIR Frame Interval. On write, dynamically
-+ reload HFIR register during runtime. The application can write a value to this
-+ register only after the Port Enable bit of the Host Port Control and Status
-+ register (HPRT.PrtEnaPort) has been set </td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> disconnect_us </td>
-+ <td> On read, shows the status of disconnect_device_us. On write, sets disconnect_us
-+ which causes soft disconnect for 100us. Applicable only for device mode of operation.</td>
-+ <td> Read/Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> regdump </td>
-+ <td> Dumps the contents of core registers.</td>
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> spramdump </td>
-+ <td> Dumps the contents of core registers.</td>
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> hcddump </td>
-+ <td> Dumps the current HCD state.</td>
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> hcd_frrem </td>
-+ <td> Shows the average value of the Frame Remaining
-+ field in the Host Frame Number/Frame Remaining register when an SOF interrupt
-+ occurs. This can be used to determine the average interrupt latency. Also
-+ shows the average Frame Remaining value for start_transfer and the "a" and
-+ "b" sample points. The "a" and "b" sample points may be used during debugging
-+ bto determine how long it takes to execute a section of the HCD code.</td>
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> rd_reg_test </td>
-+ <td> Displays the time required to read the GNPTXFSIZ register many times
-+ (the output shows the number of times the register is read).
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> wr_reg_test </td>
-+ <td> Displays the time required to write the GNPTXFSIZ register many times
-+ (the output shows the number of times the register is written).
-+ <td> Read</td>
-+ </tr>
-+
-+ <tr>
-+ <td> lpm_response </td>
-+ <td> Gets or sets lpm_response mode. Applicable only in device mode.
-+ <td> Write</td>
-+ </tr>
-+
-+ <tr>
-+ <td> sleep_status </td>
-+ <td> Shows sleep status of device.
-+ <td> Read</td>
-+ </tr>
-+
-+ </table>
-+
-+ Example usage:
-+ To get the current mode:
-+ cat /sys/devices/lm0/mode
-+
-+ To power down the USB:
-+ echo 0 > /sys/devices/lm0/buspower
-+ */
-+
-+#include "dwc_otg_os_dep.h"
-+#include "dwc_os.h"
-+#include "dwc_otg_driver.h"
-+#include "dwc_otg_attr.h"
-+#include "dwc_otg_core_if.h"
-+#include "dwc_otg_pcd_if.h"
-+#include "dwc_otg_hcd_if.h"
-+
-+/*
-+ * MACROs for defining sysfs attribute
-+ */
-+#ifdef LM_INTERFACE
-+
-+#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
-+{ \
-+	struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
-+	dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev);		\
-+	uint32_t val; \
-+	val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
-+	return sprintf (buf, "%s = 0x%x\n", _string_, val); \
-+}
-+#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
-+					const char *buf, size_t count) \
-+{ \
-+	struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
-+	dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
-+	uint32_t set = simple_strtoul(buf, NULL, 16); \
-+	dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
-+	return count; \
-+}
-+
-+#elif defined(PCI_INTERFACE)
-+
-+#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
-+{ \
-+	dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);	\
-+	uint32_t val; \
-+	val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
-+	return sprintf (buf, "%s = 0x%x\n", _string_, val); \
-+}
-+#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
-+					const char *buf, size_t count) \
-+{ \
-+	dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);  \
-+	uint32_t set = simple_strtoul(buf, NULL, 16); \
-+	dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
-+	return count; \
-+}
-+
-+#elif defined(PLATFORM_INTERFACE)
-+
-+#define DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
-+{ \
-+        struct platform_device *platform_dev = \
-+                container_of(_dev, struct platform_device, dev); \
-+        dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev);  \
-+	uint32_t val; \
-+	DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \
-+                    __func__, _dev, platform_dev, otg_dev); \
-+	val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
-+	return sprintf (buf, "%s = 0x%x\n", _string_, val); \
-+}
-+#define DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
-+					const char *buf, size_t count) \
-+{ \
-+        struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
-+        dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
-+	uint32_t set = simple_strtoul(buf, NULL, 16); \
-+	dwc_otg_set_##_otg_attr_name_(otg_dev->core_if, set);\
-+	return count; \
-+}
-+#endif
-+
-+/*
-+ * MACROs for defining sysfs attribute for 32-bit registers
-+ */
-+#ifdef LM_INTERFACE
-+#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
-+{ \
-+	struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
-+	dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
-+	uint32_t val; \
-+	val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
-+	return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
-+}
-+#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
-+					const char *buf, size_t count) \
-+{ \
-+	struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev); \
-+	dwc_otg_device_t *otg_dev = lm_get_drvdata(lm_dev); \
-+	uint32_t val = simple_strtoul(buf, NULL, 16); \
-+	dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
-+	return count; \
-+}
-+#elif defined(PCI_INTERFACE)
-+#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
-+{ \
-+	dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);  \
-+	uint32_t val; \
-+	val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
-+	return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
-+}
-+#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
-+					const char *buf, size_t count) \
-+{ \
-+	dwc_otg_device_t *otg_dev = dev_get_drvdata(_dev);  \
-+	uint32_t val = simple_strtoul(buf, NULL, 16); \
-+	dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
-+	return count; \
-+}
-+
-+#elif defined(PLATFORM_INTERFACE)
-+#include "dwc_otg_dbg.h"
-+#define DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_show (struct device *_dev, struct device_attribute *attr, char *buf) \
-+{ \
-+	struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
-+	dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
-+	uint32_t val; \
-+	DWC_PRINTF("%s(%p) -> platform_dev %p, otg_dev %p\n", \
-+                    __func__, _dev, platform_dev, otg_dev); \
-+	val = dwc_otg_get_##_otg_attr_name_ (otg_dev->core_if); \
-+	return sprintf (buf, "%s = 0x%08x\n", _string_, val); \
-+}
-+#define DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
-+static ssize_t _otg_attr_name_##_store (struct device *_dev, struct device_attribute *attr, \
-+					const char *buf, size_t count) \
-+{ \
-+	struct platform_device *platform_dev = container_of(_dev, struct platform_device, dev); \
-+	dwc_otg_device_t *otg_dev = platform_get_drvdata(platform_dev); \
-+	uint32_t val = simple_strtoul(buf, NULL, 16); \
-+	dwc_otg_set_##_otg_attr_name_ (otg_dev->core_if, val); \
-+	return count; \
-+}
-+
-+#endif
-+
-+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RW(_otg_attr_name_,_string_) \
-+DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
-+DWC_OTG_DEVICE_ATTR_BITFIELD_STORE(_otg_attr_name_,_string_) \
-+DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
-+
-+#define DWC_OTG_DEVICE_ATTR_BITFIELD_RO(_otg_attr_name_,_string_) \
-+DWC_OTG_DEVICE_ATTR_BITFIELD_SHOW(_otg_attr_name_,_string_) \
-+DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
-+
-+#define DWC_OTG_DEVICE_ATTR_REG32_RW(_otg_attr_name_,_addr_,_string_) \
-+DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
-+DWC_OTG_DEVICE_ATTR_REG_STORE(_otg_attr_name_,_string_) \
-+DEVICE_ATTR(_otg_attr_name_,0644,_otg_attr_name_##_show,_otg_attr_name_##_store);
-+
-+#define DWC_OTG_DEVICE_ATTR_REG32_RO(_otg_attr_name_,_addr_,_string_) \
-+DWC_OTG_DEVICE_ATTR_REG_SHOW(_otg_attr_name_,_string_) \
-+DEVICE_ATTR(_otg_attr_name_,0444,_otg_attr_name_##_show,NULL);
-+
-+/** @name Functions for Show/Store of Attributes */
-+/**@{*/
-+
-+/**
-+ * Helper function returning the otg_device structure of the given device
-+ */
-+static dwc_otg_device_t *dwc_otg_drvdev(struct device *_dev)
-+{
-+        dwc_otg_device_t *otg_dev;
-+        DWC_OTG_GETDRVDEV(otg_dev, _dev);
-+        return otg_dev;
-+}
-+
-+/**
-+ * Show the register offset of the Register Access.
-+ */
-+static ssize_t regoffset_show(struct device *_dev,
-+			      struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	return snprintf(buf, sizeof("0xFFFFFFFF\n") + 1, "0x%08x\n",
-+			otg_dev->os_dep.reg_offset);
-+}
-+
-+/**
-+ * Set the register offset for the next Register Access 	Read/Write
-+ */
-+static ssize_t regoffset_store(struct device *_dev,
-+			       struct device_attribute *attr,
-+			       const char *buf, size_t count)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t offset = simple_strtoul(buf, NULL, 16);
-+#if defined(LM_INTERFACE) || defined(PLATFORM_INTERFACE)
-+	if (offset < SZ_256K) {
-+#elif  defined(PCI_INTERFACE)
-+	if (offset < 0x00040000) {
-+#endif
-+		otg_dev->os_dep.reg_offset = offset;
-+	} else {
-+		dev_err(_dev, "invalid offset\n");
-+	}
-+
-+	return count;
-+}
-+
-+DEVICE_ATTR(regoffset, S_IRUGO | S_IWUSR, regoffset_show, regoffset_store);
-+
-+/**
-+ * Show the value of the register at the offset in the reg_offset
-+ * attribute.
-+ */
-+static ssize_t regvalue_show(struct device *_dev,
-+			     struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t val;
-+	volatile uint32_t *addr;
-+
-+	if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) {
-+		/* Calculate the address */
-+		addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
-+				     (uint8_t *) otg_dev->os_dep.base);
-+		val = DWC_READ_REG32(addr);
-+		return snprintf(buf,
-+				sizeof("Reg at 0xFFFFFFFF = 0xFFFFFFFF\n") + 1,
-+				"Reg at 0x%06x = 0x%08x\n", otg_dev->os_dep.reg_offset,
-+				val);
-+	} else {
-+		dev_err(_dev, "Invalid offset (0x%0x)\n", otg_dev->os_dep.reg_offset);
-+		return sprintf(buf, "invalid offset\n");
-+	}
-+}
-+
-+/**
-+ * Store the value in the register at the offset in the reg_offset
-+ * attribute.
-+ *
-+ */
-+static ssize_t regvalue_store(struct device *_dev,
-+			      struct device_attribute *attr,
-+			      const char *buf, size_t count)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	volatile uint32_t *addr;
-+	uint32_t val = simple_strtoul(buf, NULL, 16);
-+	//dev_dbg(_dev, "Offset=0x%08x Val=0x%08x\n", otg_dev->reg_offset, val);
-+	if (otg_dev->os_dep.reg_offset != 0xFFFFFFFF && 0 != otg_dev->os_dep.base) {
-+		/* Calculate the address */
-+		addr = (uint32_t *) (otg_dev->os_dep.reg_offset +
-+				     (uint8_t *) otg_dev->os_dep.base);
-+		DWC_WRITE_REG32(addr, val);
-+	} else {
-+		dev_err(_dev, "Invalid Register Offset (0x%08x)\n",
-+			otg_dev->os_dep.reg_offset);
-+	}
-+	return count;
-+}
-+
-+DEVICE_ATTR(regvalue, S_IRUGO | S_IWUSR, regvalue_show, regvalue_store);
-+
-+/*
-+ * Attributes
-+ */
-+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(mode, "Mode");
-+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hnpcapable, "HNPCapable");
-+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(srpcapable, "SRPCapable");
-+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(hsic_connect, "HSIC Connect");
-+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(inv_sel_hsic, "Invert Select HSIC");
-+
-+//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(buspower,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
-+//DWC_OTG_DEVICE_ATTR_BITFIELD_RW(bussuspend,&(otg_dev->core_if->core_global_regs->gotgctl),(1<<8),8,"Mode");
-+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(busconnected, "Bus Connected");
-+
-+DWC_OTG_DEVICE_ATTR_REG32_RW(gotgctl, 0, "GOTGCTL");
-+DWC_OTG_DEVICE_ATTR_REG32_RW(gusbcfg,
-+			     &(otg_dev->core_if->core_global_regs->gusbcfg),
-+			     "GUSBCFG");
-+DWC_OTG_DEVICE_ATTR_REG32_RW(grxfsiz,
-+			     &(otg_dev->core_if->core_global_regs->grxfsiz),
-+			     "GRXFSIZ");
-+DWC_OTG_DEVICE_ATTR_REG32_RW(gnptxfsiz,
-+			     &(otg_dev->core_if->core_global_regs->gnptxfsiz),
-+			     "GNPTXFSIZ");
-+DWC_OTG_DEVICE_ATTR_REG32_RW(gpvndctl,
-+			     &(otg_dev->core_if->core_global_regs->gpvndctl),
-+			     "GPVNDCTL");
-+DWC_OTG_DEVICE_ATTR_REG32_RW(ggpio,
-+			     &(otg_dev->core_if->core_global_regs->ggpio),
-+			     "GGPIO");
-+DWC_OTG_DEVICE_ATTR_REG32_RW(guid, &(otg_dev->core_if->core_global_regs->guid),
-+			     "GUID");
-+DWC_OTG_DEVICE_ATTR_REG32_RO(gsnpsid,
-+			     &(otg_dev->core_if->core_global_regs->gsnpsid),
-+			     "GSNPSID");
-+DWC_OTG_DEVICE_ATTR_BITFIELD_RW(devspeed, "Device Speed");
-+DWC_OTG_DEVICE_ATTR_BITFIELD_RO(enumspeed, "Device Enumeration Speed");
-+
-+DWC_OTG_DEVICE_ATTR_REG32_RO(hptxfsiz,
-+			     &(otg_dev->core_if->core_global_regs->hptxfsiz),
-+			     "HPTXFSIZ");
-+DWC_OTG_DEVICE_ATTR_REG32_RW(hprt0, otg_dev->core_if->host_if->hprt0, "HPRT0");
-+
-+/**
-+ * @todo Add code to initiate the HNP.
-+ */
-+/**
-+ * Show the HNP status bit
-+ */
-+static ssize_t hnp_show(struct device *_dev,
-+			struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	return sprintf(buf, "HstNegScs = 0x%x\n",
-+		       dwc_otg_get_hnpstatus(otg_dev->core_if));
-+}
-+
-+/**
-+ * Set the HNP Request bit
-+ */
-+static ssize_t hnp_store(struct device *_dev,
-+			 struct device_attribute *attr,
-+			 const char *buf, size_t count)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t in = simple_strtoul(buf, NULL, 16);
-+	dwc_otg_set_hnpreq(otg_dev->core_if, in);
-+	return count;
-+}
-+
-+DEVICE_ATTR(hnp, 0644, hnp_show, hnp_store);
-+
-+/**
-+ * @todo Add code to initiate the SRP.
-+ */
-+/**
-+ * Show the SRP status bit
-+ */
-+static ssize_t srp_show(struct device *_dev,
-+			struct device_attribute *attr, char *buf)
-+{
-+#ifndef DWC_HOST_ONLY
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	return sprintf(buf, "SesReqScs = 0x%x\n",
-+		       dwc_otg_get_srpstatus(otg_dev->core_if));
-+#else
-+	return sprintf(buf, "Host Only Mode!\n");
-+#endif
-+}
-+
-+/**
-+ * Set the SRP Request bit
-+ */
-+static ssize_t srp_store(struct device *_dev,
-+			 struct device_attribute *attr,
-+			 const char *buf, size_t count)
-+{
-+#ifndef DWC_HOST_ONLY
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	dwc_otg_pcd_initiate_srp(otg_dev->pcd);
-+#endif
-+	return count;
-+}
-+
-+DEVICE_ATTR(srp, 0644, srp_show, srp_store);
-+
-+/**
-+ * @todo Need to do more for power on/off?
-+ */
-+/**
-+ * Show the Bus Power status
-+ */
-+static ssize_t buspower_show(struct device *_dev,
-+			     struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	return sprintf(buf, "Bus Power = 0x%x\n",
-+		       dwc_otg_get_prtpower(otg_dev->core_if));
-+}
-+
-+/**
-+ * Set the Bus Power status
-+ */
-+static ssize_t buspower_store(struct device *_dev,
-+			      struct device_attribute *attr,
-+			      const char *buf, size_t count)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t on = simple_strtoul(buf, NULL, 16);
-+	dwc_otg_set_prtpower(otg_dev->core_if, on);
-+	return count;
-+}
-+
-+DEVICE_ATTR(buspower, 0644, buspower_show, buspower_store);
-+
-+/**
-+ * @todo Need to do more for suspend?
-+ */
-+/**
-+ * Show the Bus Suspend status
-+ */
-+static ssize_t bussuspend_show(struct device *_dev,
-+			       struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	return sprintf(buf, "Bus Suspend = 0x%x\n",
-+		       dwc_otg_get_prtsuspend(otg_dev->core_if));
-+}
-+
-+/**
-+ * Set the Bus Suspend status
-+ */
-+static ssize_t bussuspend_store(struct device *_dev,
-+				struct device_attribute *attr,
-+				const char *buf, size_t count)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t in = simple_strtoul(buf, NULL, 16);
-+	dwc_otg_set_prtsuspend(otg_dev->core_if, in);
-+	return count;
-+}
-+
-+DEVICE_ATTR(bussuspend, 0644, bussuspend_show, bussuspend_store);
-+
-+/**
-+ * Show the Mode Change Ready Timer status
-+ */
-+static ssize_t mode_ch_tim_en_show(struct device *_dev,
-+				   struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	return sprintf(buf, "Mode Change Ready Timer Enable = 0x%x\n",
-+		       dwc_otg_get_mode_ch_tim(otg_dev->core_if));
-+}
-+
-+/**
-+ * Set the Mode Change Ready Timer status
-+ */
-+static ssize_t mode_ch_tim_en_store(struct device *_dev,
-+				    struct device_attribute *attr,
-+				    const char *buf, size_t count)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t in = simple_strtoul(buf, NULL, 16);
-+	dwc_otg_set_mode_ch_tim(otg_dev->core_if, in);
-+	return count;
-+}
-+
-+DEVICE_ATTR(mode_ch_tim_en, 0644, mode_ch_tim_en_show, mode_ch_tim_en_store);
-+
-+/**
-+ * Show the value of HFIR Frame Interval bitfield
-+ */
-+static ssize_t fr_interval_show(struct device *_dev,
-+				struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	return sprintf(buf, "Frame Interval = 0x%x\n",
-+		       dwc_otg_get_fr_interval(otg_dev->core_if));
-+}
-+
-+/**
-+ * Set the HFIR Frame Interval value
-+ */
-+static ssize_t fr_interval_store(struct device *_dev,
-+				 struct device_attribute *attr,
-+				 const char *buf, size_t count)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t in = simple_strtoul(buf, NULL, 10);
-+	dwc_otg_set_fr_interval(otg_dev->core_if, in);
-+	return count;
-+}
-+
-+DEVICE_ATTR(fr_interval, 0644, fr_interval_show, fr_interval_store);
-+
-+/**
-+ * Show the status of Remote Wakeup.
-+ */
-+static ssize_t remote_wakeup_show(struct device *_dev,
-+				  struct device_attribute *attr, char *buf)
-+{
-+#ifndef DWC_HOST_ONLY
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+
-+	return sprintf(buf,
-+		       "Remote Wakeup Sig = %d Enabled = %d LPM Remote Wakeup = %d\n",
-+		       dwc_otg_get_remotewakesig(otg_dev->core_if),
-+		       dwc_otg_pcd_get_rmwkup_enable(otg_dev->pcd),
-+		       dwc_otg_get_lpm_remotewakeenabled(otg_dev->core_if));
-+#else
-+	return sprintf(buf, "Host Only Mode!\n");
-+#endif /* DWC_HOST_ONLY */
-+}
-+
-+/**
-+ * Initiate a remote wakeup of the host.  The Device control register
-+ * Remote Wakeup Signal bit is written if the PCD Remote wakeup enable
-+ * flag is set.
-+ *
-+ */
-+static ssize_t remote_wakeup_store(struct device *_dev,
-+				   struct device_attribute *attr,
-+				   const char *buf, size_t count)
-+{
-+#ifndef DWC_HOST_ONLY
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t val = simple_strtoul(buf, NULL, 16);
-+
-+	if (val & 1) {
-+		dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 1);
-+	} else {
-+		dwc_otg_pcd_remote_wakeup(otg_dev->pcd, 0);
-+	}
-+#endif /* DWC_HOST_ONLY */
-+	return count;
-+}
-+
-+DEVICE_ATTR(remote_wakeup, S_IRUGO | S_IWUSR, remote_wakeup_show,
-+	    remote_wakeup_store);
-+
-+/**
-+ * Show the whether core is hibernated or not.
-+ */
-+static ssize_t rem_wakeup_pwrdn_show(struct device *_dev,
-+				     struct device_attribute *attr, char *buf)
-+{
-+#ifndef DWC_HOST_ONLY
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+
-+	if (dwc_otg_get_core_state(otg_dev->core_if)) {
-+		DWC_PRINTF("Core is in hibernation\n");
-+	} else {
-+		DWC_PRINTF("Core is not in hibernation\n");
-+	}
-+#endif /* DWC_HOST_ONLY */
-+	return 0;
-+}
-+
-+extern int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
-+					      int rem_wakeup, int reset);
-+
-+/**
-+ * Initiate a remote wakeup of the device to exit from hibernation.
-+ */
-+static ssize_t rem_wakeup_pwrdn_store(struct device *_dev,
-+				      struct device_attribute *attr,
-+				      const char *buf, size_t count)
-+{
-+#ifndef DWC_HOST_ONLY
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	dwc_otg_device_hibernation_restore(otg_dev->core_if, 1, 0);
-+#endif
-+	return count;
-+}
-+
-+DEVICE_ATTR(rem_wakeup_pwrdn, S_IRUGO | S_IWUSR, rem_wakeup_pwrdn_show,
-+	    rem_wakeup_pwrdn_store);
-+
-+static ssize_t disconnect_us(struct device *_dev,
-+			     struct device_attribute *attr,
-+			     const char *buf, size_t count)
-+{
-+
-+#ifndef DWC_HOST_ONLY
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t val = simple_strtoul(buf, NULL, 16);
-+	DWC_PRINTF("The Passed value is %04x\n", val);
-+
-+	dwc_otg_pcd_disconnect_us(otg_dev->pcd, 50);
-+
-+#endif /* DWC_HOST_ONLY */
-+	return count;
-+}
-+
-+DEVICE_ATTR(disconnect_us, S_IWUSR, 0, disconnect_us);
-+
-+/**
-+ * Dump global registers and either host or device registers (depending on the
-+ * current mode of the core).
-+ */
-+static ssize_t regdump_show(struct device *_dev,
-+			    struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+
-+	dwc_otg_dump_global_registers(otg_dev->core_if);
-+	if (dwc_otg_is_host_mode(otg_dev->core_if)) {
-+		dwc_otg_dump_host_registers(otg_dev->core_if);
-+	} else {
-+		dwc_otg_dump_dev_registers(otg_dev->core_if);
-+
-+	}
-+	return sprintf(buf, "Register Dump\n");
-+}
-+
-+DEVICE_ATTR(regdump, S_IRUGO, regdump_show, 0);
-+
-+/**
-+ * Dump global registers and either host or device registers (depending on the
-+ * current mode of the core).
-+ */
-+static ssize_t spramdump_show(struct device *_dev,
-+			      struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+
-+	//dwc_otg_dump_spram(otg_dev->core_if);
-+
-+	return sprintf(buf, "SPRAM Dump\n");
-+}
-+
-+DEVICE_ATTR(spramdump, S_IRUGO, spramdump_show, 0);
-+
-+/**
-+ * Dump the current hcd state.
-+ */
-+static ssize_t hcddump_show(struct device *_dev,
-+			    struct device_attribute *attr, char *buf)
-+{
-+#ifndef DWC_DEVICE_ONLY
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	dwc_otg_hcd_dump_state(otg_dev->hcd);
-+#endif /* DWC_DEVICE_ONLY */
-+	return sprintf(buf, "HCD Dump\n");
-+}
-+
-+DEVICE_ATTR(hcddump, S_IRUGO, hcddump_show, 0);
-+
-+/**
-+ * Dump the average frame remaining at SOF. This can be used to
-+ * determine average interrupt latency. Frame remaining is also shown for
-+ * start transfer and two additional sample points.
-+ */
-+static ssize_t hcd_frrem_show(struct device *_dev,
-+			      struct device_attribute *attr, char *buf)
-+{
-+#ifndef DWC_DEVICE_ONLY
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+
-+	dwc_otg_hcd_dump_frrem(otg_dev->hcd);
-+#endif /* DWC_DEVICE_ONLY */
-+	return sprintf(buf, "HCD Dump Frame Remaining\n");
-+}
-+
-+DEVICE_ATTR(hcd_frrem, S_IRUGO, hcd_frrem_show, 0);
-+
-+/**
-+ * Displays the time required to read the GNPTXFSIZ register many times (the
-+ * output shows the number of times the register is read).
-+ */
-+#define RW_REG_COUNT 10000000
-+#define MSEC_PER_JIFFIE 1000/HZ
-+static ssize_t rd_reg_test_show(struct device *_dev,
-+				struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	int i;
-+	int time;
-+	int start_jiffies;
-+
-+	printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
-+	       HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
-+	start_jiffies = jiffies;
-+	for (i = 0; i < RW_REG_COUNT; i++) {
-+		dwc_otg_get_gnptxfsiz(otg_dev->core_if);
-+	}
-+	time = jiffies - start_jiffies;
-+	return sprintf(buf,
-+		       "Time to read GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
-+		       RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
-+}
-+
-+DEVICE_ATTR(rd_reg_test, S_IRUGO, rd_reg_test_show, 0);
-+
-+/**
-+ * Displays the time required to write the GNPTXFSIZ register many times (the
-+ * output shows the number of times the register is written).
-+ */
-+static ssize_t wr_reg_test_show(struct device *_dev,
-+				struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t reg_val;
-+	int i;
-+	int time;
-+	int start_jiffies;
-+
-+	printk("HZ %d, MSEC_PER_JIFFIE %d, loops_per_jiffy %lu\n",
-+	       HZ, MSEC_PER_JIFFIE, loops_per_jiffy);
-+	reg_val = dwc_otg_get_gnptxfsiz(otg_dev->core_if);
-+	start_jiffies = jiffies;
-+	for (i = 0; i < RW_REG_COUNT; i++) {
-+		dwc_otg_set_gnptxfsiz(otg_dev->core_if, reg_val);
-+	}
-+	time = jiffies - start_jiffies;
-+	return sprintf(buf,
-+		       "Time to write GNPTXFSIZ reg %d times: %d msecs (%d jiffies)\n",
-+		       RW_REG_COUNT, time * MSEC_PER_JIFFIE, time);
-+}
-+
-+DEVICE_ATTR(wr_reg_test, S_IRUGO, wr_reg_test_show, 0);
-+
-+#ifdef CONFIG_USB_DWC_OTG_LPM
-+
-+/**
-+* Show the lpm_response attribute.
-+*/
-+static ssize_t lpmresp_show(struct device *_dev,
-+			    struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+
-+	if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if))
-+		return sprintf(buf, "** LPM is DISABLED **\n");
-+
-+	if (!dwc_otg_is_device_mode(otg_dev->core_if)) {
-+		return sprintf(buf, "** Current mode is not device mode\n");
-+	}
-+	return sprintf(buf, "lpm_response = %d\n",
-+		       dwc_otg_get_lpmresponse(otg_dev->core_if));
-+}
-+
-+/**
-+* Store the lpm_response attribute.
-+*/
-+static ssize_t lpmresp_store(struct device *_dev,
-+			     struct device_attribute *attr,
-+			     const char *buf, size_t count)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	uint32_t val = simple_strtoul(buf, NULL, 16);
-+
-+	if (!dwc_otg_get_param_lpm_enable(otg_dev->core_if)) {
-+		return 0;
-+	}
-+
-+	if (!dwc_otg_is_device_mode(otg_dev->core_if)) {
-+		return 0;
-+	}
-+
-+	dwc_otg_set_lpmresponse(otg_dev->core_if, val);
-+	return count;
-+}
-+
-+DEVICE_ATTR(lpm_response, S_IRUGO | S_IWUSR, lpmresp_show, lpmresp_store);
-+
-+/**
-+* Show the sleep_status attribute.
-+*/
-+static ssize_t sleepstatus_show(struct device *_dev,
-+				struct device_attribute *attr, char *buf)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	return sprintf(buf, "Sleep Status = %d\n",
-+		       dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if));
-+}
-+
-+/**
-+ * Store the sleep_status attribure.
-+ */
-+static ssize_t sleepstatus_store(struct device *_dev,
-+				 struct device_attribute *attr,
-+				 const char *buf, size_t count)
-+{
-+        dwc_otg_device_t *otg_dev = dwc_otg_drvdev(_dev);
-+	dwc_otg_core_if_t *core_if = otg_dev->core_if;
-+
-+	if (dwc_otg_get_lpm_portsleepstatus(otg_dev->core_if)) {
-+		if (dwc_otg_is_host_mode(core_if)) {
-+
-+			DWC_PRINTF("Host initiated resume\n");
-+			dwc_otg_set_prtresume(otg_dev->core_if, 1);
-+		}
-+	}
-+
-+	return count;
-+}
-+
-+DEVICE_ATTR(sleep_status, S_IRUGO | S_IWUSR, sleepstatus_show,
-+	    sleepstatus_store);
-+
-+#endif /* CONFIG_USB_DWC_OTG_LPM_ENABLE */
-+
-+/**@}*/
-+
-+/**
-+ * Create the device files
-+ */
-+void dwc_otg_attr_create(
-+#ifdef LM_INTERFACE
-+	struct lm_device *dev
-+#elif  defined(PCI_INTERFACE)
-+	struct pci_dev *dev
-+#elif  defined(PLATFORM_INTERFACE)
-+        struct platform_device *dev
-+#endif
-+    )
-+{
-+	int error;
-+
-+	error = device_create_file(&dev->dev, &dev_attr_regoffset);
-+	error = device_create_file(&dev->dev, &dev_attr_regvalue);
-+	error = device_create_file(&dev->dev, &dev_attr_mode);
-+	error = device_create_file(&dev->dev, &dev_attr_hnpcapable);
-+	error = device_create_file(&dev->dev, &dev_attr_srpcapable);
-+	error = device_create_file(&dev->dev, &dev_attr_hsic_connect);
-+	error = device_create_file(&dev->dev, &dev_attr_inv_sel_hsic);
-+	error = device_create_file(&dev->dev, &dev_attr_hnp);
-+	error = device_create_file(&dev->dev, &dev_attr_srp);
-+	error = device_create_file(&dev->dev, &dev_attr_buspower);
-+	error = device_create_file(&dev->dev, &dev_attr_bussuspend);
-+	error = device_create_file(&dev->dev, &dev_attr_mode_ch_tim_en);
-+	error = device_create_file(&dev->dev, &dev_attr_fr_interval);
-+	error = device_create_file(&dev->dev, &dev_attr_busconnected);
-+	error = device_create_file(&dev->dev, &dev_attr_gotgctl);
-+	error = device_create_file(&dev->dev, &dev_attr_gusbcfg);
-+	error = device_create_file(&dev->dev, &dev_attr_grxfsiz);
-+	error = device_create_file(&dev->dev, &dev_attr_gnptxfsiz);
-+	error = device_create_file(&dev->dev, &dev_attr_gpvndctl);
-+	error = device_create_file(&dev->dev, &dev_attr_ggpio);
-+	error = device_create_file(&dev->dev, &dev_attr_guid);
-+	error = device_create_file(&dev->dev, &dev_attr_gsnpsid);
-+	error = device_create_file(&dev->dev, &dev_attr_devspeed);
-+	error = device_create_file(&dev->dev, &dev_attr_enumspeed);
-+	error = device_create_file(&dev->dev, &dev_attr_hptxfsiz);
-+	error = device_create_file(&dev->dev, &dev_attr_hprt0);
-+	error = device_create_file(&dev->dev, &dev_attr_remote_wakeup);
-+	error = device_create_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn);
-+	error = device_create_file(&dev->dev, &dev_attr_disconnect_us);
-+	error = device_create_file(&dev->dev, &dev_attr_regdump);
-+	error = device_create_file(&dev->dev, &dev_attr_spramdump);
-+	error = device_create_file(&dev->dev, &dev_attr_hcddump);
-+	error = device_create_file(&dev->dev, &dev_attr_hcd_frrem);
-+	error = device_create_file(&dev->dev, &dev_attr_rd_reg_test);
-+	error = device_create_file(&dev->dev, &dev_attr_wr_reg_test);
-+#ifdef CONFIG_USB_DWC_OTG_LPM
-+	error = device_create_file(&dev->dev, &dev_attr_lpm_response);
-+	error = device_create_file(&dev->dev, &dev_attr_sleep_status);
-+#endif
-+}
-+
-+/**
-+ * Remove the device files
-+ */
-+void dwc_otg_attr_remove(
-+#ifdef LM_INTERFACE
-+	struct lm_device *dev
-+#elif  defined(PCI_INTERFACE)
-+	struct pci_dev *dev
-+#elif  defined(PLATFORM_INTERFACE)
-+	struct platform_device *dev
-+#endif
-+    )
-+{
-+	device_remove_file(&dev->dev, &dev_attr_regoffset);
-+	device_remove_file(&dev->dev, &dev_attr_regvalue);
-+	device_remove_file(&dev->dev, &dev_attr_mode);
-+	device_remove_file(&dev->dev, &dev_attr_hnpcapable);
-+	device_remove_file(&dev->dev, &dev_attr_srpcapable);
-+	device_remove_file(&dev->dev, &dev_attr_hsic_connect);
-+	device_remove_file(&dev->dev, &dev_attr_inv_sel_hsic);
-+	device_remove_file(&dev->dev, &dev_attr_hnp);
-+	device_remove_file(&dev->dev, &dev_attr_srp);
-+	device_remove_file(&dev->dev, &dev_attr_buspower);
-+	device_remove_file(&dev->dev, &dev_attr_bussuspend);
-+	device_remove_file(&dev->dev, &dev_attr_mode_ch_tim_en);
-+	device_remove_file(&dev->dev, &dev_attr_fr_interval);
-+	device_remove_file(&dev->dev, &dev_attr_busconnected);
-+	device_remove_file(&dev->dev, &dev_attr_gotgctl);
-+	device_remove_file(&dev->dev, &dev_attr_gusbcfg);
-+	device_remove_file(&dev->dev, &dev_attr_grxfsiz);
-+	device_remove_file(&dev->dev, &dev_attr_gnptxfsiz);
-+	device_remove_file(&dev->dev, &dev_attr_gpvndctl);
-+	device_remove_file(&dev->dev, &dev_attr_ggpio);
-+	device_remove_file(&dev->dev, &dev_attr_guid);
-+	device_remove_file(&dev->dev, &dev_attr_gsnpsid);
-+	device_remove_file(&dev->dev, &dev_attr_devspeed);
-+	device_remove_file(&dev->dev, &dev_attr_enumspeed);
-+	device_remove_file(&dev->dev, &dev_attr_hptxfsiz);
-+	device_remove_file(&dev->dev, &dev_attr_hprt0);
-+	device_remove_file(&dev->dev, &dev_attr_remote_wakeup);
-+	device_remove_file(&dev->dev, &dev_attr_rem_wakeup_pwrdn);
-+	device_remove_file(&dev->dev, &dev_attr_disconnect_us);
-+	device_remove_file(&dev->dev, &dev_attr_regdump);
-+	device_remove_file(&dev->dev, &dev_attr_spramdump);
-+	device_remove_file(&dev->dev, &dev_attr_hcddump);
-+	device_remove_file(&dev->dev, &dev_attr_hcd_frrem);
-+	device_remove_file(&dev->dev, &dev_attr_rd_reg_test);
-+	device_remove_file(&dev->dev, &dev_attr_wr_reg_test);
-+#ifdef CONFIG_USB_DWC_OTG_LPM
-+	device_remove_file(&dev->dev, &dev_attr_lpm_response);
-+	device_remove_file(&dev->dev, &dev_attr_sleep_status);
-+#endif
-+}
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_attr.h
-@@ -0,0 +1,89 @@
-+/* ==========================================================================
-+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.h $
-+ * $Revision: #13 $
-+ * $Date: 2010/06/21 $
-+ * $Change: 1532021 $
-+ *
-+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
-+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
-+ * otherwise expressly agreed to in writing between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product under
-+ * any End User Software License Agreement or Agreement for Licensed Product
-+ * with Synopsys or any supplement thereto. You are permitted to use and
-+ * redistribute this Software in source and binary forms, with or without
-+ * modification, provided that redistributions of source code must retain this
-+ * notice. You may not view, use, disclose, copy or distribute this file or
-+ * any information contained herein except pursuant to this license grant from
-+ * Synopsys. If you do not agree with this notice, including the disclaimer
-+ * below, then you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================== */
-+
-+#if !defined(__DWC_OTG_ATTR_H__)
-+#define __DWC_OTG_ATTR_H__
-+
-+/** @file
-+ * This file contains the interface to the Linux device attributes.
-+ */
-+extern struct device_attribute dev_attr_regoffset;
-+extern struct device_attribute dev_attr_regvalue;
-+
-+extern struct device_attribute dev_attr_mode;
-+extern struct device_attribute dev_attr_hnpcapable;
-+extern struct device_attribute dev_attr_srpcapable;
-+extern struct device_attribute dev_attr_hnp;
-+extern struct device_attribute dev_attr_srp;
-+extern struct device_attribute dev_attr_buspower;
-+extern struct device_attribute dev_attr_bussuspend;
-+extern struct device_attribute dev_attr_mode_ch_tim_en;
-+extern struct device_attribute dev_attr_fr_interval;
-+extern struct device_attribute dev_attr_busconnected;
-+extern struct device_attribute dev_attr_gotgctl;
-+extern struct device_attribute dev_attr_gusbcfg;
-+extern struct device_attribute dev_attr_grxfsiz;
-+extern struct device_attribute dev_attr_gnptxfsiz;
-+extern struct device_attribute dev_attr_gpvndctl;
-+extern struct device_attribute dev_attr_ggpio;
-+extern struct device_attribute dev_attr_guid;
-+extern struct device_attribute dev_attr_gsnpsid;
-+extern struct device_attribute dev_attr_devspeed;
-+extern struct device_attribute dev_attr_enumspeed;
-+extern struct device_attribute dev_attr_hptxfsiz;
-+extern struct device_attribute dev_attr_hprt0;
-+#ifdef CONFIG_USB_DWC_OTG_LPM
-+extern struct device_attribute dev_attr_lpm_response;
-+extern struct device_attribute devi_attr_sleep_status;
-+#endif
-+
-+void dwc_otg_attr_create(
-+#ifdef LM_INTERFACE
-+				struct lm_device *dev
-+#elif  defined(PCI_INTERFACE)
-+				struct pci_dev *dev
-+#elif  defined(PLATFORM_INTERFACE)
-+	struct platform_device *dev
-+#endif
-+    );
-+
-+void dwc_otg_attr_remove(
-+#ifdef LM_INTERFACE
-+				struct lm_device *dev
-+#elif  defined(PCI_INTERFACE)
-+				struct pci_dev *dev
-+#elif  defined(PLATFORM_INTERFACE)
-+	struct platform_device *dev
-+#endif
-+    );
-+#endif
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_cfi.c
-@@ -0,0 +1,1876 @@
-+/* ==========================================================================
-+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
-+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
-+ * otherwise expressly agreed to in writing between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product under
-+ * any End User Software License Agreement or Agreement for Licensed Product
-+ * with Synopsys or any supplement thereto. You are permitted to use and
-+ * redistribute this Software in source and binary forms, with or without
-+ * modification, provided that redistributions of source code must retain this
-+ * notice. You may not view, use, disclose, copy or distribute this file or
-+ * any information contained herein except pursuant to this license grant from
-+ * Synopsys. If you do not agree with this notice, including the disclaimer
-+ * below, then you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================== */
-+
-+/** @file
-+ *
-+ * This file contains the most of the CFI(Core Feature Interface)
-+ * implementation for the OTG.
-+ */
-+
-+#ifdef DWC_UTE_CFI
-+
-+#include "dwc_otg_pcd.h"
-+#include "dwc_otg_cfi.h"
-+
-+/** This definition should actually migrate to the Portability Library */
-+#define DWC_CONSTANT_CPU_TO_LE16(x) (x)
-+
-+extern dwc_otg_pcd_ep_t *get_ep_by_addr(dwc_otg_pcd_t * pcd, u16 wIndex);
-+
-+static int cfi_core_features_buf(uint8_t * buf, uint16_t buflen);
-+static int cfi_get_feature_value(uint8_t * buf, uint16_t buflen,
-+				 struct dwc_otg_pcd *pcd,
-+				 struct cfi_usb_ctrlrequest *ctrl_req);
-+static int cfi_set_feature_value(struct dwc_otg_pcd *pcd);
-+static int cfi_ep_get_sg_val(uint8_t * buf, struct dwc_otg_pcd *pcd,
-+			     struct cfi_usb_ctrlrequest *req);
-+static int cfi_ep_get_concat_val(uint8_t * buf, struct dwc_otg_pcd *pcd,
-+				 struct cfi_usb_ctrlrequest *req);
-+static int cfi_ep_get_align_val(uint8_t * buf, struct dwc_otg_pcd *pcd,
-+				struct cfi_usb_ctrlrequest *req);
-+static int cfi_preproc_reset(struct dwc_otg_pcd *pcd,
-+			     struct cfi_usb_ctrlrequest *req);
-+static void cfi_free_ep_bs_dyn_data(cfi_ep_t * cfiep);
-+
-+static uint16_t get_dfifo_size(dwc_otg_core_if_t * core_if);
-+static int32_t get_rxfifo_size(dwc_otg_core_if_t * core_if, uint16_t wValue);
-+static int32_t get_txfifo_size(struct dwc_otg_pcd *pcd, uint16_t wValue);
-+
-+static uint8_t resize_fifos(dwc_otg_core_if_t * core_if);
-+
-+/** This is the header of the all features descriptor */
-+static cfi_all_features_header_t all_props_desc_header = {
-+	.wVersion = DWC_CONSTANT_CPU_TO_LE16(0x100),
-+	.wCoreID = DWC_CONSTANT_CPU_TO_LE16(CFI_CORE_ID_OTG),
-+	.wNumFeatures = DWC_CONSTANT_CPU_TO_LE16(9),
-+};
-+
-+/** This is an array of statically allocated feature descriptors */
-+static cfi_feature_desc_header_t prop_descs[] = {
-+
-+	/* FT_ID_DMA_MODE */
-+	{
-+	 .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_MODE),
-+	 .bmAttributes = CFI_FEATURE_ATTR_RW,
-+	 .wDataLength = DWC_CONSTANT_CPU_TO_LE16(1),
-+	 },
-+
-+	/* FT_ID_DMA_BUFFER_SETUP */
-+	{
-+	 .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_BUFFER_SETUP),
-+	 .bmAttributes = CFI_FEATURE_ATTR_RW,
-+	 .wDataLength = DWC_CONSTANT_CPU_TO_LE16(6),
-+	 },
-+
-+	/* FT_ID_DMA_BUFF_ALIGN */
-+	{
-+	 .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_BUFF_ALIGN),
-+	 .bmAttributes = CFI_FEATURE_ATTR_RW,
-+	 .wDataLength = DWC_CONSTANT_CPU_TO_LE16(2),
-+	 },
-+
-+	/* FT_ID_DMA_CONCAT_SETUP */
-+	{
-+	 .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_CONCAT_SETUP),
-+	 .bmAttributes = CFI_FEATURE_ATTR_RW,
-+	 //.wDataLength  = DWC_CONSTANT_CPU_TO_LE16(6),
-+	 },
-+
-+	/* FT_ID_DMA_CIRCULAR */
-+	{
-+	 .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DMA_CIRCULAR),
-+	 .bmAttributes = CFI_FEATURE_ATTR_RW,
-+	 .wDataLength = DWC_CONSTANT_CPU_TO_LE16(6),
-+	 },
-+
-+	/* FT_ID_THRESHOLD_SETUP */
-+	{
-+	 .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_THRESHOLD_SETUP),
-+	 .bmAttributes = CFI_FEATURE_ATTR_RW,
-+	 .wDataLength = DWC_CONSTANT_CPU_TO_LE16(6),
-+	 },
-+
-+	/* FT_ID_DFIFO_DEPTH */
-+	{
-+	 .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_DFIFO_DEPTH),
-+	 .bmAttributes = CFI_FEATURE_ATTR_RO,
-+	 .wDataLength = DWC_CONSTANT_CPU_TO_LE16(2),
-+	 },
-+
-+	/* FT_ID_TX_FIFO_DEPTH */
-+	{
-+	 .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_TX_FIFO_DEPTH),
-+	 .bmAttributes = CFI_FEATURE_ATTR_RW,
-+	 .wDataLength = DWC_CONSTANT_CPU_TO_LE16(2),
-+	 },
-+
-+	/* FT_ID_RX_FIFO_DEPTH */
-+	{
-+	 .wFeatureID = DWC_CONSTANT_CPU_TO_LE16(FT_ID_RX_FIFO_DEPTH),
-+	 .bmAttributes = CFI_FEATURE_ATTR_RW,
-+	 .wDataLength = DWC_CONSTANT_CPU_TO_LE16(2),
-+	 }
-+};
-+
-+/** The table of feature names */
-+cfi_string_t prop_name_table[] = {
-+	{FT_ID_DMA_MODE, "dma_mode"},
-+	{FT_ID_DMA_BUFFER_SETUP, "buffer_setup"},
-+	{FT_ID_DMA_BUFF_ALIGN, "buffer_align"},
-+	{FT_ID_DMA_CONCAT_SETUP, "concat_setup"},
-+	{FT_ID_DMA_CIRCULAR, "buffer_circular"},
-+	{FT_ID_THRESHOLD_SETUP, "threshold_setup"},
-+	{FT_ID_DFIFO_DEPTH, "dfifo_depth"},
-+	{FT_ID_TX_FIFO_DEPTH, "txfifo_depth"},
-+	{FT_ID_RX_FIFO_DEPTH, "rxfifo_depth"},
-+	{}
-+};
-+
-+/************************************************************************/
-+
-+/**
-+ * Returns the name of the feature by its ID
-+ * or NULL if no featute ID matches.
-+ *
-+ */
-+const uint8_t *get_prop_name(uint16_t prop_id, int *len)
-+{
-+	cfi_string_t *pstr;
-+	*len = 0;
-+
-+	for (pstr = prop_name_table; pstr && pstr->s; pstr++) {
-+		if (pstr->id == prop_id) {
-+			*len = DWC_STRLEN(pstr->s);
-+			return pstr->s;
-+		}
-+	}
-+	return NULL;
-+}
-+
-+/**
-+ * This function handles all CFI specific control requests.
-+ *
-+ * Return a negative value to stall the DCE.
-+ */
-+int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl)
-+{
-+	int retval = 0;
-+	dwc_otg_pcd_ep_t *ep = NULL;
-+	cfiobject_t *cfi = pcd->cfi;
-+	struct dwc_otg_core_if *coreif = GET_CORE_IF(pcd);
-+	uint16_t wLen = DWC_LE16_TO_CPU(&ctrl->wLength);
-+	uint16_t wValue = DWC_LE16_TO_CPU(&ctrl->wValue);
-+	uint16_t wIndex = DWC_LE16_TO_CPU(&ctrl->wIndex);
-+	uint32_t regaddr = 0;
-+	uint32_t regval = 0;
-+
-+	/* Save this Control Request in the CFI object.
-+	 * The data field will be assigned in the data stage completion CB function.
-+	 */
-+	cfi->ctrl_req = *ctrl;
-+	cfi->ctrl_req.data = NULL;
-+
-+	cfi->need_gadget_att = 0;
-+	cfi->need_status_in_complete = 0;
-+
-+	switch (ctrl->bRequest) {
-+	case VEN_CORE_GET_FEATURES:
-+		retval = cfi_core_features_buf(cfi->buf_in.buf, CFI_IN_BUF_LEN);
-+		if (retval >= 0) {
-+			//dump_msg(cfi->buf_in.buf, retval);
-+			ep = &pcd->ep0;
-+
-+			retval = min((uint16_t) retval, wLen);
-+			/* Transfer this buffer to the host through the EP0-IN EP */
-+			ep->dwc_ep.dma_addr = cfi->buf_in.addr;
-+			ep->dwc_ep.start_xfer_buff = cfi->buf_in.buf;
-+			ep->dwc_ep.xfer_buff = cfi->buf_in.buf;
-+			ep->dwc_ep.xfer_len = retval;
-+			ep->dwc_ep.xfer_count = 0;
-+			ep->dwc_ep.sent_zlp = 0;
-+			ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
-+
-+			pcd->ep0_pending = 1;
-+			dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep);
-+		}
-+		retval = 0;
-+		break;
-+
-+	case VEN_CORE_GET_FEATURE:
-+		CFI_INFO("VEN_CORE_GET_FEATURE\n");
-+		retval = cfi_get_feature_value(cfi->buf_in.buf, CFI_IN_BUF_LEN,
-+					       pcd, ctrl);
-+		if (retval >= 0) {
-+			ep = &pcd->ep0;
-+
-+			retval = min((uint16_t) retval, wLen);
-+			/* Transfer this buffer to the host through the EP0-IN EP */
-+			ep->dwc_ep.dma_addr = cfi->buf_in.addr;
-+			ep->dwc_ep.start_xfer_buff = cfi->buf_in.buf;
-+			ep->dwc_ep.xfer_buff = cfi->buf_in.buf;
-+			ep->dwc_ep.xfer_len = retval;
-+			ep->dwc_ep.xfer_count = 0;
-+			ep->dwc_ep.sent_zlp = 0;
-+			ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
-+
-+			pcd->ep0_pending = 1;
-+			dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep);
-+		}
-+		CFI_INFO("VEN_CORE_GET_FEATURE=%d\n", retval);
-+		dump_msg(cfi->buf_in.buf, retval);
-+		break;
-+
-+	case VEN_CORE_SET_FEATURE:
-+		CFI_INFO("VEN_CORE_SET_FEATURE\n");
-+		/* Set up an XFER to get the data stage of the control request,
-+		 * which is the new value of the feature to be modified.
-+		 */
-+		ep = &pcd->ep0;
-+		ep->dwc_ep.is_in = 0;
-+		ep->dwc_ep.dma_addr = cfi->buf_out.addr;
-+		ep->dwc_ep.start_xfer_buff = cfi->buf_out.buf;
-+		ep->dwc_ep.xfer_buff = cfi->buf_out.buf;
-+		ep->dwc_ep.xfer_len = wLen;
-+		ep->dwc_ep.xfer_count = 0;
-+		ep->dwc_ep.sent_zlp = 0;
-+		ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
-+
-+		pcd->ep0_pending = 1;
-+		/* Read the control write's data stage */
-+		dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep);
-+		retval = 0;
-+		break;
-+
-+	case VEN_CORE_RESET_FEATURES:
-+		CFI_INFO("VEN_CORE_RESET_FEATURES\n");
-+		cfi->need_gadget_att = 1;
-+		cfi->need_status_in_complete = 1;
-+		retval = cfi_preproc_reset(pcd, ctrl);
-+		CFI_INFO("VEN_CORE_RESET_FEATURES = (%d)\n", retval);
-+		break;
-+
-+	case VEN_CORE_ACTIVATE_FEATURES:
-+		CFI_INFO("VEN_CORE_ACTIVATE_FEATURES\n");
-+		break;
-+
-+	case VEN_CORE_READ_REGISTER:
-+		CFI_INFO("VEN_CORE_READ_REGISTER\n");
-+		/* wValue optionally contains the HI WORD of the register offset and
-+		 * wIndex contains the LOW WORD of the register offset
-+		 */
-+		if (wValue == 0) {
-+			/* @TODO - MAS - fix the access to the base field */
-+			regaddr = 0;
-+			//regaddr = (uint32_t) pcd->otg_dev->os_dep.base;
-+			//GET_CORE_IF(pcd)->co
-+			regaddr |= wIndex;
-+		} else {
-+			regaddr = (wValue << 16) | wIndex;
-+		}
-+
-+		/* Read a 32-bit value of the memory at the regaddr */
-+		regval = DWC_READ_REG32((uint32_t *) regaddr);
-+
-+		ep = &pcd->ep0;
-+		dwc_memcpy(cfi->buf_in.buf, &regval, sizeof(uint32_t));
-+		ep->dwc_ep.is_in = 1;
-+		ep->dwc_ep.dma_addr = cfi->buf_in.addr;
-+		ep->dwc_ep.start_xfer_buff = cfi->buf_in.buf;
-+		ep->dwc_ep.xfer_buff = cfi->buf_in.buf;
-+		ep->dwc_ep.xfer_len = wLen;
-+		ep->dwc_ep.xfer_count = 0;
-+		ep->dwc_ep.sent_zlp = 0;
-+		ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
-+
-+		pcd->ep0_pending = 1;
-+		dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep);
-+		cfi->need_gadget_att = 0;
-+		retval = 0;
-+		break;
-+
-+	case VEN_CORE_WRITE_REGISTER:
-+		CFI_INFO("VEN_CORE_WRITE_REGISTER\n");
-+		/* Set up an XFER to get the data stage of the control request,
-+		 * which is the new value of the register to be modified.
-+		 */
-+		ep = &pcd->ep0;
-+		ep->dwc_ep.is_in = 0;
-+		ep->dwc_ep.dma_addr = cfi->buf_out.addr;
-+		ep->dwc_ep.start_xfer_buff = cfi->buf_out.buf;
-+		ep->dwc_ep.xfer_buff = cfi->buf_out.buf;
-+		ep->dwc_ep.xfer_len = wLen;
-+		ep->dwc_ep.xfer_count = 0;
-+		ep->dwc_ep.sent_zlp = 0;
-+		ep->dwc_ep.total_len = ep->dwc_ep.xfer_len;
-+
-+		pcd->ep0_pending = 1;
-+		/* Read the control write's data stage */
-+		dwc_otg_ep0_start_transfer(coreif, &ep->dwc_ep);
-+		retval = 0;
-+		break;
-+
-+	default:
-+		retval = -DWC_E_NOT_SUPPORTED;
-+		break;
-+	}
-+
-+	return retval;
-+}
-+
-+/**
-+ * This function prepares the core features descriptors and copies its
-+ * raw representation into the buffer <buf>.
-+ *
-+ * The buffer structure is as follows:
-+ *	all_features_header (8 bytes)
-+ *	features_#1 (8 bytes + feature name string length)
-+ *	features_#2 (8 bytes + feature name string length)
-+ *	.....
-+ *	features_#n - where n=the total count of feature descriptors
-+ */
-+static int cfi_core_features_buf(uint8_t * buf, uint16_t buflen)
-+{
-+	cfi_feature_desc_header_t *prop_hdr = prop_descs;
-+	cfi_feature_desc_header_t *prop;
-+	cfi_all_features_header_t *all_props_hdr = &all_props_desc_header;
-+	cfi_all_features_header_t *tmp;
-+	uint8_t *tmpbuf = buf;
-+	const uint8_t *pname = NULL;
-+	int i, j, namelen = 0, totlen;
-+
-+	/* Prepare and copy the core features into the buffer */
-+	CFI_INFO("%s:\n", __func__);
-+
-+	tmp = (cfi_all_features_header_t *) tmpbuf;
-+	*tmp = *all_props_hdr;
-+	tmpbuf += CFI_ALL_FEATURES_HDR_LEN;
-+
-+	j = sizeof(prop_descs) / sizeof(cfi_all_features_header_t);
-+	for (i = 0; i < j; i++, prop_hdr++) {
-+		pname = get_prop_name(prop_hdr->wFeatureID, &namelen);
-+		prop = (cfi_feature_desc_header_t *) tmpbuf;
-+		*prop = *prop_hdr;
-+
-+		prop->bNameLen = namelen;
-+		prop->wLength =
-+		    DWC_CONSTANT_CPU_TO_LE16(CFI_FEATURE_DESC_HDR_LEN +
-+					     namelen);
-+
-+		tmpbuf += CFI_FEATURE_DESC_HDR_LEN;
-+		dwc_memcpy(tmpbuf, pname, namelen);
-+		tmpbuf += namelen;
-+	}
-+
-+	totlen = tmpbuf - buf;
-+
-+	if (totlen > 0) {
-+		tmp = (cfi_all_features_header_t *) buf;
-+		tmp->wTotalLen = DWC_CONSTANT_CPU_TO_LE16(totlen);
-+	}
-+
-+	return totlen;
-+}
-+
-+/**
-+ * This function releases all the dynamic memory in the CFI object.
-+ */
-+static void cfi_release(cfiobject_t * cfiobj)
-+{
-+	cfi_ep_t *cfiep;
-+	dwc_list_link_t *tmp;
-+
-+	CFI_INFO("%s\n", __func__);
-+
-+	if (cfiobj->buf_in.buf) {
-+		DWC_DMA_FREE(CFI_IN_BUF_LEN, cfiobj->buf_in.buf,
-+			     cfiobj->buf_in.addr);
-+		cfiobj->buf_in.buf = NULL;
-+	}
-+
-+	if (cfiobj->buf_out.buf) {
-+		DWC_DMA_FREE(CFI_OUT_BUF_LEN, cfiobj->buf_out.buf,
-+			     cfiobj->buf_out.addr);
-+		cfiobj->buf_out.buf = NULL;
-+	}
-+
-+	/* Free the Buffer Setup values for each EP */
-+	//list_for_each_entry(cfiep, &cfiobj->active_eps, lh) {
-+	DWC_LIST_FOREACH(tmp, &cfiobj->active_eps) {
-+		cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
-+		cfi_free_ep_bs_dyn_data(cfiep);
-+	}
-+}
-+
-+/**
-+ * This function frees the dynamically allocated EP buffer setup data.
-+ */
-+static void cfi_free_ep_bs_dyn_data(cfi_ep_t * cfiep)
-+{
-+	if (cfiep->bm_sg) {
-+		DWC_FREE(cfiep->bm_sg);
-+		cfiep->bm_sg = NULL;
-+	}
-+
-+	if (cfiep->bm_align) {
-+		DWC_FREE(cfiep->bm_align);
-+		cfiep->bm_align = NULL;
-+	}
-+
-+	if (cfiep->bm_concat) {
-+		if (NULL != cfiep->bm_concat->wTxBytes) {
-+			DWC_FREE(cfiep->bm_concat->wTxBytes);
-+			cfiep->bm_concat->wTxBytes = NULL;
-+		}
-+		DWC_FREE(cfiep->bm_concat);
-+		cfiep->bm_concat = NULL;
-+	}
-+}
-+
-+/**
-+ * This function initializes the default values of the features
-+ * for a specific endpoint and should be called only once when
-+ * the EP is enabled first time.
-+ */
-+static int cfi_ep_init_defaults(struct dwc_otg_pcd *pcd, cfi_ep_t * cfiep)
-+{
-+	int retval = 0;
-+
-+	cfiep->bm_sg = DWC_ALLOC(sizeof(ddma_sg_buffer_setup_t));
-+	if (NULL == cfiep->bm_sg) {
-+		CFI_INFO("Failed to allocate memory for SG feature value\n");
-+		return -DWC_E_NO_MEMORY;
-+	}
-+	dwc_memset(cfiep->bm_sg, 0, sizeof(ddma_sg_buffer_setup_t));
-+
-+	/* For the Concatenation feature's default value we do not allocate
-+	 * memory for the wTxBytes field - it will be done in the set_feature_value
-+	 * request handler.
-+	 */
-+	cfiep->bm_concat = DWC_ALLOC(sizeof(ddma_concat_buffer_setup_t));
-+	if (NULL == cfiep->bm_concat) {
-+		CFI_INFO
-+		    ("Failed to allocate memory for CONCATENATION feature value\n");
-+		DWC_FREE(cfiep->bm_sg);
-+		return -DWC_E_NO_MEMORY;
-+	}
-+	dwc_memset(cfiep->bm_concat, 0, sizeof(ddma_concat_buffer_setup_t));
-+
-+	cfiep->bm_align = DWC_ALLOC(sizeof(ddma_align_buffer_setup_t));
-+	if (NULL == cfiep->bm_align) {
-+		CFI_INFO
-+		    ("Failed to allocate memory for Alignment feature value\n");
-+		DWC_FREE(cfiep->bm_sg);
-+		DWC_FREE(cfiep->bm_concat);
-+		return -DWC_E_NO_MEMORY;
-+	}
-+	dwc_memset(cfiep->bm_align, 0, sizeof(ddma_align_buffer_setup_t));
-+
-+	return retval;
-+}
-+
-+/**
-+ * The callback function that notifies the CFI on the activation of
-+ * an endpoint in the PCD. The following steps are done in this function:
-+ *
-+ *	Create a dynamically allocated cfi_ep_t object (a CFI wrapper to the PCD's
-+ *		active endpoint)
-+ *	Create MAX_DMA_DESCS_PER_EP count DMA Descriptors for the EP
-+ *	Set the Buffer Mode to standard
-+ *	Initialize the default values for all EP modes (SG, Circular, Concat, Align)
-+ *	Add the cfi_ep_t object to the list of active endpoints in the CFI object
-+ */
-+static int cfi_ep_enable(struct cfiobject *cfi, struct dwc_otg_pcd *pcd,
-+			 struct dwc_otg_pcd_ep *ep)
-+{
-+	cfi_ep_t *cfiep;
-+	int retval = -DWC_E_NOT_SUPPORTED;
-+
-+	CFI_INFO("%s: epname=%s; epnum=0x%02x\n", __func__,
-+		 "EP_" /*ep->ep.name */ , ep->desc->bEndpointAddress);
-+	/* MAS - Check whether this endpoint already is in the list */
-+	cfiep = get_cfi_ep_by_pcd_ep(cfi, ep);
-+
-+	if (NULL == cfiep) {
-+		/* Allocate a cfi_ep_t object */
-+		cfiep = DWC_ALLOC(sizeof(cfi_ep_t));
-+		if (NULL == cfiep) {
-+			CFI_INFO
-+			    ("Unable to allocate memory for <cfiep> in function %s\n",
-+			     __func__);
-+			return -DWC_E_NO_MEMORY;
-+		}
-+		dwc_memset(cfiep, 0, sizeof(cfi_ep_t));
-+
-+		/* Save the dwc_otg_pcd_ep pointer in the cfiep object */
-+		cfiep->ep = ep;
-+
-+		/* Allocate the DMA Descriptors chain of MAX_DMA_DESCS_PER_EP count */
-+		ep->dwc_ep.descs =
-+		    DWC_DMA_ALLOC(MAX_DMA_DESCS_PER_EP *
-+				  sizeof(dwc_otg_dma_desc_t),
-+				  &ep->dwc_ep.descs_dma_addr);
-+
-+		if (NULL == ep->dwc_ep.descs) {
-+			DWC_FREE(cfiep);
-+			return -DWC_E_NO_MEMORY;
-+		}
-+
-+		DWC_LIST_INIT(&cfiep->lh);
-+
-+		/* Set the buffer mode to BM_STANDARD. It will be modified
-+		 * when building descriptors for a specific buffer mode */
-+		ep->dwc_ep.buff_mode = BM_STANDARD;
-+
-+		/* Create and initialize the default values for this EP's Buffer modes */
-+		if ((retval = cfi_ep_init_defaults(pcd, cfiep)) < 0)
-+			return retval;
-+
-+		/* Add the cfi_ep_t object to the CFI object's list of active endpoints */
-+		DWC_LIST_INSERT_TAIL(&cfi->active_eps, &cfiep->lh);
-+		retval = 0;
-+	} else {		/* The sought EP already is in the list */
-+		CFI_INFO("%s: The sought EP already is in the list\n",
-+			 __func__);
-+	}
-+
-+	return retval;
-+}
-+
-+/**
-+ * This function is called when the data stage of a 3-stage Control Write request
-+ * is complete.
-+ *
-+ */
-+static int cfi_ctrl_write_complete(struct cfiobject *cfi,
-+				   struct dwc_otg_pcd *pcd)
-+{
-+	uint32_t addr, reg_value;
-+	uint16_t wIndex, wValue;
-+	uint8_t bRequest;
-+	uint8_t *buf = cfi->buf_out.buf;
-+	//struct usb_ctrlrequest *ctrl_req = &cfi->ctrl_req_saved;
-+	struct cfi_usb_ctrlrequest *ctrl_req = &cfi->ctrl_req;
-+	int retval = -DWC_E_NOT_SUPPORTED;
-+
-+	CFI_INFO("%s\n", __func__);
-+
-+	bRequest = ctrl_req->bRequest;
-+	wIndex = DWC_CONSTANT_CPU_TO_LE16(ctrl_req->wIndex);
-+	wValue = DWC_CONSTANT_CPU_TO_LE16(ctrl_req->wValue);
-+
-+	/*
-+	 * Save the pointer to the data stage in the ctrl_req's <data> field.
-+	 * The request should be already saved in the command stage by now.
-+	 */
-+	ctrl_req->data = cfi->buf_out.buf;
-+	cfi->need_status_in_complete = 0;
-+	cfi->need_gadget_att = 0;
-+
-+	switch (bRequest) {
-+	case VEN_CORE_WRITE_REGISTER:
-+		/* The buffer contains raw data of the new value for the register */
-+		reg_value = *((uint32_t *) buf);
-+		if (wValue == 0) {
-+			addr = 0;
-+			//addr = (uint32_t) pcd->otg_dev->os_dep.base;
-+			addr += wIndex;
-+		} else {
-+			addr = (wValue << 16) | wIndex;
-+		}
-+
-+		//writel(reg_value, addr);
-+
-+		retval = 0;
-+		cfi->need_status_in_complete = 1;
-+		break;
-+
-+	case VEN_CORE_SET_FEATURE:
-+		/* The buffer contains raw data of the new value of the feature */
-+		retval = cfi_set_feature_value(pcd);
-+		if (retval < 0)
-+			return retval;
-+
-+		cfi->need_status_in_complete = 1;
-+		break;
-+
-+	default:
-+		break;
-+	}
-+
-+	return retval;
-+}
-+
-+/**
-+ * This function builds the DMA descriptors for the SG buffer mode.
-+ */
-+static void cfi_build_sg_descs(struct cfiobject *cfi, cfi_ep_t * cfiep,
-+			       dwc_otg_pcd_request_t * req)
-+{
-+	struct dwc_otg_pcd_ep *ep = cfiep->ep;
-+	ddma_sg_buffer_setup_t *sgval = cfiep->bm_sg;
-+	struct dwc_otg_dma_desc *desc = cfiep->ep->dwc_ep.descs;
-+	struct dwc_otg_dma_desc *desc_last = cfiep->ep->dwc_ep.descs;
-+	dma_addr_t buff_addr = req->dma;
-+	int i;
-+	uint32_t txsize, off;
-+
-+	txsize = sgval->wSize;
-+	off = sgval->bOffset;
-+
-+//      CFI_INFO("%s: %s TXSIZE=0x%08x; OFFSET=0x%08x\n",
-+//              __func__, cfiep->ep->ep.name, txsize, off);
-+
-+	for (i = 0; i < sgval->bCount; i++) {
-+		desc->status.b.bs = BS_HOST_BUSY;
-+		desc->buf = buff_addr;
-+		desc->status.b.l = 0;
-+		desc->status.b.ioc = 0;
-+		desc->status.b.sp = 0;
-+		desc->status.b.bytes = txsize;
-+		desc->status.b.bs = BS_HOST_READY;
-+
-+		/* Set the next address of the buffer */
-+		buff_addr += txsize + off;
-+		desc_last = desc;
-+		desc++;
-+	}
-+
-+	/* Set the last, ioc and sp bits on the Last DMA Descriptor */
-+	desc_last->status.b.l = 1;
-+	desc_last->status.b.ioc = 1;
-+	desc_last->status.b.sp = ep->dwc_ep.sent_zlp;
-+	/* Save the last DMA descriptor pointer */
-+	cfiep->dma_desc_last = desc_last;
-+	cfiep->desc_count = sgval->bCount;
-+}
-+
-+/**
-+ * This function builds the DMA descriptors for the Concatenation buffer mode.
-+ */
-+static void cfi_build_concat_descs(struct cfiobject *cfi, cfi_ep_t * cfiep,
-+				   dwc_otg_pcd_request_t * req)
-+{
-+	struct dwc_otg_pcd_ep *ep = cfiep->ep;
-+	ddma_concat_buffer_setup_t *concatval = cfiep->bm_concat;
-+	struct dwc_otg_dma_desc *desc = cfiep->ep->dwc_ep.descs;
-+	struct dwc_otg_dma_desc *desc_last = cfiep->ep->dwc_ep.descs;
-+	dma_addr_t buff_addr = req->dma;
-+	int i;
-+	uint16_t *txsize;
-+
-+	txsize = concatval->wTxBytes;
-+
-+	for (i = 0; i < concatval->hdr.bDescCount; i++) {
-+		desc->buf = buff_addr;
-+		desc->status.b.bs = BS_HOST_BUSY;
-+		desc->status.b.l = 0;
-+		desc->status.b.ioc = 0;
-+		desc->status.b.sp = 0;
-+		desc->status.b.bytes = *txsize;
-+		desc->status.b.bs = BS_HOST_READY;
-+
-+		txsize++;
-+		/* Set the next address of the buffer */
-+		buff_addr += UGETW(ep->desc->wMaxPacketSize);
-+		desc_last = desc;
-+		desc++;
-+	}
-+
-+	/* Set the last, ioc and sp bits on the Last DMA Descriptor */
-+	desc_last->status.b.l = 1;
-+	desc_last->status.b.ioc = 1;
-+	desc_last->status.b.sp = ep->dwc_ep.sent_zlp;
-+	cfiep->dma_desc_last = desc_last;
-+	cfiep->desc_count = concatval->hdr.bDescCount;
-+}
-+
-+/**
-+ * This function builds the DMA descriptors for the Circular buffer mode
-+ */
-+static void cfi_build_circ_descs(struct cfiobject *cfi, cfi_ep_t * cfiep,
-+				 dwc_otg_pcd_request_t * req)
-+{
-+	/* @todo: MAS - add implementation when this feature needs to be tested */
-+}
-+
-+/**
-+ * This function builds the DMA descriptors for the Alignment buffer mode
-+ */
-+static void cfi_build_align_descs(struct cfiobject *cfi, cfi_ep_t * cfiep,
-+				  dwc_otg_pcd_request_t * req)
-+{
-+	struct dwc_otg_pcd_ep *ep = cfiep->ep;
-+	ddma_align_buffer_setup_t *alignval = cfiep->bm_align;
-+	struct dwc_otg_dma_desc *desc = cfiep->ep->dwc_ep.descs;
-+	dma_addr_t buff_addr = req->dma;
-+
-+	desc->status.b.bs = BS_HOST_BUSY;
-+	desc->status.b.l = 1;
-+	desc->status.b.ioc = 1;
-+	desc->status.b.sp = ep->dwc_ep.sent_zlp;
-+	desc->status.b.bytes = req->length;
-+	/* Adjust the buffer alignment */
-+	desc->buf = (buff_addr + alignval->bAlign);
-+	desc->status.b.bs = BS_HOST_READY;
-+	cfiep->dma_desc_last = desc;
-+	cfiep->desc_count = 1;
-+}
-+
-+/**
-+ * This function builds the DMA descriptors chain for different modes of the
-+ * buffer setup of an endpoint.
-+ */
-+static void cfi_build_descriptors(struct cfiobject *cfi,
-+				  struct dwc_otg_pcd *pcd,
-+				  struct dwc_otg_pcd_ep *ep,
-+				  dwc_otg_pcd_request_t * req)
-+{
-+	cfi_ep_t *cfiep;
-+
-+	/* Get the cfiep by the dwc_otg_pcd_ep */
-+	cfiep = get_cfi_ep_by_pcd_ep(cfi, ep);
-+	if (NULL == cfiep) {
-+		CFI_INFO("%s: Unable to find a matching active endpoint\n",
-+			 __func__);
-+		return;
-+	}
-+
-+	cfiep->xfer_len = req->length;
-+
-+	/* Iterate through all the DMA descriptors */
-+	switch (cfiep->ep->dwc_ep.buff_mode) {
-+	case BM_SG:
-+		cfi_build_sg_descs(cfi, cfiep, req);
-+		break;
-+
-+	case BM_CONCAT:
-+		cfi_build_concat_descs(cfi, cfiep, req);
-+		break;
-+
-+	case BM_CIRCULAR:
-+		cfi_build_circ_descs(cfi, cfiep, req);
-+		break;
-+
-+	case BM_ALIGN:
-+		cfi_build_align_descs(cfi, cfiep, req);
-+		break;
-+
-+	default:
-+		break;
-+	}
-+}
-+
-+/**
-+ * Allocate DMA buffer for different Buffer modes.
-+ */
-+static void *cfi_ep_alloc_buf(struct cfiobject *cfi, struct dwc_otg_pcd *pcd,
-+			      struct dwc_otg_pcd_ep *ep, dma_addr_t * dma,
-+			      unsigned size, gfp_t flags)
-+{
-+	return DWC_DMA_ALLOC(size, dma);
-+}
-+
-+/**
-+ * This function initializes the CFI object.
-+ */
-+int init_cfi(cfiobject_t * cfiobj)
-+{
-+	CFI_INFO("%s\n", __func__);
-+
-+	/* Allocate a buffer for IN XFERs */
-+	cfiobj->buf_in.buf =
-+	    DWC_DMA_ALLOC(CFI_IN_BUF_LEN, &cfiobj->buf_in.addr);
-+	if (NULL == cfiobj->buf_in.buf) {
-+		CFI_INFO("Unable to allocate buffer for INs\n");
-+		return -DWC_E_NO_MEMORY;
-+	}
-+
-+	/* Allocate a buffer for OUT XFERs */
-+	cfiobj->buf_out.buf =
-+	    DWC_DMA_ALLOC(CFI_OUT_BUF_LEN, &cfiobj->buf_out.addr);
-+	if (NULL == cfiobj->buf_out.buf) {
-+		CFI_INFO("Unable to allocate buffer for OUT\n");
-+		return -DWC_E_NO_MEMORY;
-+	}
-+
-+	/* Initialize the callback function pointers */
-+	cfiobj->ops.release = cfi_release;
-+	cfiobj->ops.ep_enable = cfi_ep_enable;
-+	cfiobj->ops.ctrl_write_complete = cfi_ctrl_write_complete;
-+	cfiobj->ops.build_descriptors = cfi_build_descriptors;
-+	cfiobj->ops.ep_alloc_buf = cfi_ep_alloc_buf;
-+
-+	/* Initialize the list of active endpoints in the CFI object */
-+	DWC_LIST_INIT(&cfiobj->active_eps);
-+
-+	return 0;
-+}
-+
-+/**
-+ * This function reads the required feature's current value into the buffer
-+ *
-+ * @retval: Returns negative as error, or the data length of the feature
-+ */
-+static int cfi_get_feature_value(uint8_t * buf, uint16_t buflen,
-+				 struct dwc_otg_pcd *pcd,
-+				 struct cfi_usb_ctrlrequest *ctrl_req)
-+{
-+	int retval = -DWC_E_NOT_SUPPORTED;
-+	struct dwc_otg_core_if *coreif = GET_CORE_IF(pcd);
-+	uint16_t dfifo, rxfifo, txfifo;
-+
-+	switch (ctrl_req->wIndex) {
-+		/* Whether the DDMA is enabled or not */
-+	case FT_ID_DMA_MODE:
-+		*buf = (coreif->dma_enable && coreif->dma_desc_enable) ? 1 : 0;
-+		retval = 1;
-+		break;
-+
-+	case FT_ID_DMA_BUFFER_SETUP:
-+		retval = cfi_ep_get_sg_val(buf, pcd, ctrl_req);
-+		break;
-+
-+	case FT_ID_DMA_BUFF_ALIGN:
-+		retval = cfi_ep_get_align_val(buf, pcd, ctrl_req);
-+		break;
-+
-+	case FT_ID_DMA_CONCAT_SETUP:
-+		retval = cfi_ep_get_concat_val(buf, pcd, ctrl_req);
-+		break;
-+
-+	case FT_ID_DMA_CIRCULAR:
-+		CFI_INFO("GetFeature value (FT_ID_DMA_CIRCULAR)\n");
-+		break;
-+
-+	case FT_ID_THRESHOLD_SETUP:
-+		CFI_INFO("GetFeature value (FT_ID_THRESHOLD_SETUP)\n");
-+		break;
-+
-+	case FT_ID_DFIFO_DEPTH:
-+		dfifo = get_dfifo_size(coreif);
-+		*((uint16_t *) buf) = dfifo;
-+		retval = sizeof(uint16_t);
-+		break;
-+
-+	case FT_ID_TX_FIFO_DEPTH:
-+		retval = get_txfifo_size(pcd, ctrl_req->wValue);
-+		if (retval >= 0) {
-+			txfifo = retval;
-+			*((uint16_t *) buf) = txfifo;
-+			retval = sizeof(uint16_t);
-+		}
-+		break;
-+
-+	case FT_ID_RX_FIFO_DEPTH:
-+		retval = get_rxfifo_size(coreif, ctrl_req->wValue);
-+		if (retval >= 0) {
-+			rxfifo = retval;
-+			*((uint16_t *) buf) = rxfifo;
-+			retval = sizeof(uint16_t);
-+		}
-+		break;
-+	}
-+
-+	return retval;
-+}
-+
-+/**
-+ * This function resets the SG for the specified EP to its default value
-+ */
-+static int cfi_reset_sg_val(cfi_ep_t * cfiep)
-+{
-+	dwc_memset(cfiep->bm_sg, 0, sizeof(ddma_sg_buffer_setup_t));
-+	return 0;
-+}
-+
-+/**
-+ * This function resets the Alignment for the specified EP to its default value
-+ */
-+static int cfi_reset_align_val(cfi_ep_t * cfiep)
-+{
-+	dwc_memset(cfiep->bm_sg, 0, sizeof(ddma_sg_buffer_setup_t));
-+	return 0;
-+}
-+
-+/**
-+ * This function resets the Concatenation for the specified EP to its default value
-+ * This function will also set the value of the wTxBytes field to NULL after
-+ * freeing the memory previously allocated for this field.
-+ */
-+static int cfi_reset_concat_val(cfi_ep_t * cfiep)
-+{
-+	/* First we need to free the wTxBytes field */
-+	if (cfiep->bm_concat->wTxBytes) {
-+		DWC_FREE(cfiep->bm_concat->wTxBytes);
-+		cfiep->bm_concat->wTxBytes = NULL;
-+	}
-+
-+	dwc_memset(cfiep->bm_concat, 0, sizeof(ddma_concat_buffer_setup_t));
-+	return 0;
-+}
-+
-+/**
-+ * This function resets all the buffer setups of the specified endpoint
-+ */
-+static int cfi_ep_reset_all_setup_vals(cfi_ep_t * cfiep)
-+{
-+	cfi_reset_sg_val(cfiep);
-+	cfi_reset_align_val(cfiep);
-+	cfi_reset_concat_val(cfiep);
-+	return 0;
-+}
-+
-+static int cfi_handle_reset_fifo_val(struct dwc_otg_pcd *pcd, uint8_t ep_addr,
-+				     uint8_t rx_rst, uint8_t tx_rst)
-+{
-+	int retval = -DWC_E_INVALID;
-+	uint16_t tx_siz[15];
-+	uint16_t rx_siz = 0;
-+	dwc_otg_pcd_ep_t *ep = NULL;
-+	dwc_otg_core_if_t *core_if = GET_CORE_IF(pcd);
-+	dwc_otg_core_params_t *params = GET_CORE_IF(pcd)->core_params;
-+
-+	if (rx_rst) {
-+		rx_siz = params->dev_rx_fifo_size;
-+		params->dev_rx_fifo_size = GET_CORE_IF(pcd)->init_rxfsiz;
-+	}
-+
-+	if (tx_rst) {
-+		if (ep_addr == 0) {
-+			int i;
-+
-+			for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
-+				tx_siz[i] =
-+				    core_if->core_params->dev_tx_fifo_size[i];
-+				core_if->core_params->dev_tx_fifo_size[i] =
-+				    core_if->init_txfsiz[i];
-+			}
-+		} else {
-+
-+			ep = get_ep_by_addr(pcd, ep_addr);
-+
-+			if (NULL == ep) {
-+				CFI_INFO
-+				    ("%s: Unable to get the endpoint addr=0x%02x\n",
-+				     __func__, ep_addr);
-+				return -DWC_E_INVALID;
-+			}
-+
-+			tx_siz[0] =
-+			    params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num -
-+						     1];
-+			params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num - 1] =
-+			    GET_CORE_IF(pcd)->init_txfsiz[ep->
-+							  dwc_ep.tx_fifo_num -
-+							  1];
-+		}
-+	}
-+
-+	if (resize_fifos(GET_CORE_IF(pcd))) {
-+		retval = 0;
-+	} else {
-+		CFI_INFO
-+		    ("%s: Error resetting the feature Reset All(FIFO size)\n",
-+		     __func__);
-+		if (rx_rst) {
-+			params->dev_rx_fifo_size = rx_siz;
-+		}
-+
-+		if (tx_rst) {
-+			if (ep_addr == 0) {
-+				int i;
-+				for (i = 0; i < core_if->hwcfg4.b.num_in_eps;
-+				     i++) {
-+					core_if->
-+					    core_params->dev_tx_fifo_size[i] =
-+					    tx_siz[i];
-+				}
-+			} else {
-+				params->dev_tx_fifo_size[ep->
-+							 dwc_ep.tx_fifo_num -
-+							 1] = tx_siz[0];
-+			}
-+		}
-+		retval = -DWC_E_INVALID;
-+	}
-+	return retval;
-+}
-+
-+static int cfi_handle_reset_all(struct dwc_otg_pcd *pcd, uint8_t addr)
-+{
-+	int retval = 0;
-+	cfi_ep_t *cfiep;
-+	cfiobject_t *cfi = pcd->cfi;
-+	dwc_list_link_t *tmp;
-+
-+	retval = cfi_handle_reset_fifo_val(pcd, addr, 1, 1);
-+	if (retval < 0) {
-+		return retval;
-+	}
-+
-+	/* If the EP address is known then reset the features for only that EP */
-+	if (addr) {
-+		cfiep = get_cfi_ep_by_addr(pcd->cfi, addr);
-+		if (NULL == cfiep) {
-+			CFI_INFO("%s: Error getting the EP address 0x%02x\n",
-+				 __func__, addr);
-+			return -DWC_E_INVALID;
-+		}
-+		retval = cfi_ep_reset_all_setup_vals(cfiep);
-+		cfiep->ep->dwc_ep.buff_mode = BM_STANDARD;
-+	}
-+	/* Otherwise (wValue == 0), reset all features of all EP's */
-+	else {
-+		/* Traverse all the active EP's and reset the feature(s) value(s) */
-+		//list_for_each_entry(cfiep, &cfi->active_eps, lh) {
-+		DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
-+			cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
-+			retval = cfi_ep_reset_all_setup_vals(cfiep);
-+			cfiep->ep->dwc_ep.buff_mode = BM_STANDARD;
-+			if (retval < 0) {
-+				CFI_INFO
-+				    ("%s: Error resetting the feature Reset All\n",
-+				     __func__);
-+				return retval;
-+			}
-+		}
-+	}
-+	return retval;
-+}
-+
-+static int cfi_handle_reset_dma_buff_setup(struct dwc_otg_pcd *pcd,
-+					   uint8_t addr)
-+{
-+	int retval = 0;
-+	cfi_ep_t *cfiep;
-+	cfiobject_t *cfi = pcd->cfi;
-+	dwc_list_link_t *tmp;
-+
-+	/* If the EP address is known then reset the features for only that EP */
-+	if (addr) {
-+		cfiep = get_cfi_ep_by_addr(pcd->cfi, addr);
-+		if (NULL == cfiep) {
-+			CFI_INFO("%s: Error getting the EP address 0x%02x\n",
-+				 __func__, addr);
-+			return -DWC_E_INVALID;
-+		}
-+		retval = cfi_reset_sg_val(cfiep);
-+	}
-+	/* Otherwise (wValue == 0), reset all features of all EP's */
-+	else {
-+		/* Traverse all the active EP's and reset the feature(s) value(s) */
-+		//list_for_each_entry(cfiep, &cfi->active_eps, lh) {
-+		DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
-+			cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
-+			retval = cfi_reset_sg_val(cfiep);
-+			if (retval < 0) {
-+				CFI_INFO
-+				    ("%s: Error resetting the feature Buffer Setup\n",
-+				     __func__);
-+				return retval;
-+			}
-+		}
-+	}
-+	return retval;
-+}
-+
-+static int cfi_handle_reset_concat_val(struct dwc_otg_pcd *pcd, uint8_t addr)
-+{
-+	int retval = 0;
-+	cfi_ep_t *cfiep;
-+	cfiobject_t *cfi = pcd->cfi;
-+	dwc_list_link_t *tmp;
-+
-+	/* If the EP address is known then reset the features for only that EP */
-+	if (addr) {
-+		cfiep = get_cfi_ep_by_addr(pcd->cfi, addr);
-+		if (NULL == cfiep) {
-+			CFI_INFO("%s: Error getting the EP address 0x%02x\n",
-+				 __func__, addr);
-+			return -DWC_E_INVALID;
-+		}
-+		retval = cfi_reset_concat_val(cfiep);
-+	}
-+	/* Otherwise (wValue == 0), reset all features of all EP's */
-+	else {
-+		/* Traverse all the active EP's and reset the feature(s) value(s) */
-+		//list_for_each_entry(cfiep, &cfi->active_eps, lh) {
-+		DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
-+			cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
-+			retval = cfi_reset_concat_val(cfiep);
-+			if (retval < 0) {
-+				CFI_INFO
-+				    ("%s: Error resetting the feature Concatenation Value\n",
-+				     __func__);
-+				return retval;
-+			}
-+		}
-+	}
-+	return retval;
-+}
-+
-+static int cfi_handle_reset_align_val(struct dwc_otg_pcd *pcd, uint8_t addr)
-+{
-+	int retval = 0;
-+	cfi_ep_t *cfiep;
-+	cfiobject_t *cfi = pcd->cfi;
-+	dwc_list_link_t *tmp;
-+
-+	/* If the EP address is known then reset the features for only that EP */
-+	if (addr) {
-+		cfiep = get_cfi_ep_by_addr(pcd->cfi, addr);
-+		if (NULL == cfiep) {
-+			CFI_INFO("%s: Error getting the EP address 0x%02x\n",
-+				 __func__, addr);
-+			return -DWC_E_INVALID;
-+		}
-+		retval = cfi_reset_align_val(cfiep);
-+	}
-+	/* Otherwise (wValue == 0), reset all features of all EP's */
-+	else {
-+		/* Traverse all the active EP's and reset the feature(s) value(s) */
-+		//list_for_each_entry(cfiep, &cfi->active_eps, lh) {
-+		DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
-+			cfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
-+			retval = cfi_reset_align_val(cfiep);
-+			if (retval < 0) {
-+				CFI_INFO
-+				    ("%s: Error resetting the feature Aliignment Value\n",
-+				     __func__);
-+				return retval;
-+			}
-+		}
-+	}
-+	return retval;
-+
-+}
-+
-+static int cfi_preproc_reset(struct dwc_otg_pcd *pcd,
-+			     struct cfi_usb_ctrlrequest *req)
-+{
-+	int retval = 0;
-+
-+	switch (req->wIndex) {
-+	case 0:
-+		/* Reset all features */
-+		retval = cfi_handle_reset_all(pcd, req->wValue & 0xff);
-+		break;
-+
-+	case FT_ID_DMA_BUFFER_SETUP:
-+		/* Reset the SG buffer setup */
-+		retval =
-+		    cfi_handle_reset_dma_buff_setup(pcd, req->wValue & 0xff);
-+		break;
-+
-+	case FT_ID_DMA_CONCAT_SETUP:
-+		/* Reset the Concatenation buffer setup */
-+		retval = cfi_handle_reset_concat_val(pcd, req->wValue & 0xff);
-+		break;
-+
-+	case FT_ID_DMA_BUFF_ALIGN:
-+		/* Reset the Alignment buffer setup */
-+		retval = cfi_handle_reset_align_val(pcd, req->wValue & 0xff);
-+		break;
-+
-+	case FT_ID_TX_FIFO_DEPTH:
-+		retval =
-+		    cfi_handle_reset_fifo_val(pcd, req->wValue & 0xff, 0, 1);
-+		pcd->cfi->need_gadget_att = 0;
-+		break;
-+
-+	case FT_ID_RX_FIFO_DEPTH:
-+		retval = cfi_handle_reset_fifo_val(pcd, 0, 1, 0);
-+		pcd->cfi->need_gadget_att = 0;
-+		break;
-+	default:
-+		break;
-+	}
-+	return retval;
-+}
-+
-+/**
-+ * This function sets a new value for the SG buffer setup.
-+ */
-+static int cfi_ep_set_sg_val(uint8_t * buf, struct dwc_otg_pcd *pcd)
-+{
-+	uint8_t inaddr, outaddr;
-+	cfi_ep_t *epin, *epout;
-+	ddma_sg_buffer_setup_t *psgval;
-+	uint32_t desccount, size;
-+
-+	CFI_INFO("%s\n", __func__);
-+
-+	psgval = (ddma_sg_buffer_setup_t *) buf;
-+	desccount = (uint32_t) psgval->bCount;
-+	size = (uint32_t) psgval->wSize;
-+
-+	/* Check the DMA descriptor count */
-+	if ((desccount > MAX_DMA_DESCS_PER_EP) || (desccount == 0)) {
-+		CFI_INFO
-+		    ("%s: The count of DMA Descriptors should be between 1 and %d\n",
-+		     __func__, MAX_DMA_DESCS_PER_EP);
-+		return -DWC_E_INVALID;
-+	}
-+
-+	/* Check the DMA descriptor count */
-+
-+	if (size == 0) {
-+
-+		CFI_INFO("%s: The transfer size should be at least 1 byte\n",
-+			 __func__);
-+
-+		return -DWC_E_INVALID;
-+
-+	}
-+
-+	inaddr = psgval->bInEndpointAddress;
-+	outaddr = psgval->bOutEndpointAddress;
-+
-+	epin = get_cfi_ep_by_addr(pcd->cfi, inaddr);
-+	epout = get_cfi_ep_by_addr(pcd->cfi, outaddr);
-+
-+	if (NULL == epin || NULL == epout) {
-+		CFI_INFO
-+		    ("%s: Unable to get the endpoints inaddr=0x%02x outaddr=0x%02x\n",
-+		     __func__, inaddr, outaddr);
-+		return -DWC_E_INVALID;
-+	}
-+
-+	epin->ep->dwc_ep.buff_mode = BM_SG;
-+	dwc_memcpy(epin->bm_sg, psgval, sizeof(ddma_sg_buffer_setup_t));
-+
-+	epout->ep->dwc_ep.buff_mode = BM_SG;
-+	dwc_memcpy(epout->bm_sg, psgval, sizeof(ddma_sg_buffer_setup_t));
-+
-+	return 0;
-+}
-+
-+/**
-+ * This function sets a new value for the buffer Alignment setup.
-+ */
-+static int cfi_ep_set_alignment_val(uint8_t * buf, struct dwc_otg_pcd *pcd)
-+{
-+	cfi_ep_t *ep;
-+	uint8_t addr;
-+	ddma_align_buffer_setup_t *palignval;
-+
-+	palignval = (ddma_align_buffer_setup_t *) buf;
-+	addr = palignval->bEndpointAddress;
-+
-+	ep = get_cfi_ep_by_addr(pcd->cfi, addr);
-+
-+	if (NULL == ep) {
-+		CFI_INFO("%s: Unable to get the endpoint addr=0x%02x\n",
-+			 __func__, addr);
-+		return -DWC_E_INVALID;
-+	}
-+
-+	ep->ep->dwc_ep.buff_mode = BM_ALIGN;
-+	dwc_memcpy(ep->bm_align, palignval, sizeof(ddma_align_buffer_setup_t));
-+
-+	return 0;
-+}
-+
-+/**
-+ * This function sets a new value for the Concatenation buffer setup.
-+ */
-+static int cfi_ep_set_concat_val(uint8_t * buf, struct dwc_otg_pcd *pcd)
-+{
-+	uint8_t addr;
-+	cfi_ep_t *ep;
-+	struct _ddma_concat_buffer_setup_hdr *pConcatValHdr;
-+	uint16_t *pVals;
-+	uint32_t desccount;
-+	int i;
-+	uint16_t mps;
-+
-+	pConcatValHdr = (struct _ddma_concat_buffer_setup_hdr *)buf;
-+	desccount = (uint32_t) pConcatValHdr->bDescCount;
-+	pVals = (uint16_t *) (buf + BS_CONCAT_VAL_HDR_LEN);
-+
-+	/* Check the DMA descriptor count */
-+	if (desccount > MAX_DMA_DESCS_PER_EP) {
-+		CFI_INFO("%s: Maximum DMA Descriptor count should be %d\n",
-+			 __func__, MAX_DMA_DESCS_PER_EP);
-+		return -DWC_E_INVALID;
-+	}
-+
-+	addr = pConcatValHdr->bEndpointAddress;
-+	ep = get_cfi_ep_by_addr(pcd->cfi, addr);
-+	if (NULL == ep) {
-+		CFI_INFO("%s: Unable to get the endpoint addr=0x%02x\n",
-+			 __func__, addr);
-+		return -DWC_E_INVALID;
-+	}
-+
-+	mps = UGETW(ep->ep->desc->wMaxPacketSize);
-+
-+#if 0
-+	for (i = 0; i < desccount; i++) {
-+		CFI_INFO("%s: wTxSize[%d]=0x%04x\n", __func__, i, pVals[i]);
-+	}
-+	CFI_INFO("%s: epname=%s; mps=%d\n", __func__, ep->ep->ep.name, mps);
-+#endif
-+
-+	/* Check the wTxSizes to be less than or equal to the mps */
-+	for (i = 0; i < desccount; i++) {
-+		if (pVals[i] > mps) {
-+			CFI_INFO
-+			    ("%s: ERROR - the wTxSize[%d] should be <= MPS (wTxSize=%d)\n",
-+			     __func__, i, pVals[i]);
-+			return -DWC_E_INVALID;
-+		}
-+	}
-+
-+	ep->ep->dwc_ep.buff_mode = BM_CONCAT;
-+	dwc_memcpy(ep->bm_concat, pConcatValHdr, BS_CONCAT_VAL_HDR_LEN);
-+
-+	/* Free the previously allocated storage for the wTxBytes */
-+	if (ep->bm_concat->wTxBytes) {
-+		DWC_FREE(ep->bm_concat->wTxBytes);
-+	}
-+
-+	/* Allocate a new storage for the wTxBytes field */
-+	ep->bm_concat->wTxBytes =
-+	    DWC_ALLOC(sizeof(uint16_t) * pConcatValHdr->bDescCount);
-+	if (NULL == ep->bm_concat->wTxBytes) {
-+		CFI_INFO("%s: Unable to allocate memory\n", __func__);
-+		return -DWC_E_NO_MEMORY;
-+	}
-+
-+	/* Copy the new values into the wTxBytes filed */
-+	dwc_memcpy(ep->bm_concat->wTxBytes, buf + BS_CONCAT_VAL_HDR_LEN,
-+		   sizeof(uint16_t) * pConcatValHdr->bDescCount);
-+
-+	return 0;
-+}
-+
-+/**
-+ * This function calculates the total of all FIFO sizes
-+ *
-+ * @param core_if Programming view of DWC_otg controller
-+ *
-+ * @return The total of data FIFO sizes.
-+ *
-+ */
-+static uint16_t get_dfifo_size(dwc_otg_core_if_t * core_if)
-+{
-+	dwc_otg_core_params_t *params = core_if->core_params;
-+	uint16_t dfifo_total = 0;
-+	int i;
-+
-+	/* The shared RxFIFO size */
-+	dfifo_total =
-+	    params->dev_rx_fifo_size + params->dev_nperio_tx_fifo_size;
-+
-+	/* Add up each TxFIFO size to the total */
-+	for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
-+		dfifo_total += params->dev_tx_fifo_size[i];
-+	}
-+
-+	return dfifo_total;
-+}
-+
-+/**
-+ * This function returns Rx FIFO size
-+ *
-+ * @param core_if Programming view of DWC_otg controller
-+ *
-+ * @return The total of data FIFO sizes.
-+ *
-+ */
-+static int32_t get_rxfifo_size(dwc_otg_core_if_t * core_if, uint16_t wValue)
-+{
-+	switch (wValue >> 8) {
-+	case 0:
-+		return (core_if->pwron_rxfsiz <
-+			32768) ? core_if->pwron_rxfsiz : 32768;
-+		break;
-+	case 1:
-+		return core_if->core_params->dev_rx_fifo_size;
-+		break;
-+	default:
-+		return -DWC_E_INVALID;
-+		break;
-+	}
-+}
-+
-+/**
-+ * This function returns Tx FIFO size for IN EP
-+ *
-+ * @param core_if Programming view of DWC_otg controller
-+ *
-+ * @return The total of data FIFO sizes.
-+ *
-+ */
-+static int32_t get_txfifo_size(struct dwc_otg_pcd *pcd, uint16_t wValue)
-+{
-+	dwc_otg_pcd_ep_t *ep;
-+
-+	ep = get_ep_by_addr(pcd, wValue & 0xff);
-+
-+	if (NULL == ep) {
-+		CFI_INFO("%s: Unable to get the endpoint addr=0x%02x\n",
-+			 __func__, wValue & 0xff);
-+		return -DWC_E_INVALID;
-+	}
-+
-+	if (!ep->dwc_ep.is_in) {
-+		CFI_INFO
-+		    ("%s: No Tx FIFO assingned to the Out endpoint addr=0x%02x\n",
-+		     __func__, wValue & 0xff);
-+		return -DWC_E_INVALID;
-+	}
-+
-+	switch (wValue >> 8) {
-+	case 0:
-+		return (GET_CORE_IF(pcd)->pwron_txfsiz
-+			[ep->dwc_ep.tx_fifo_num - 1] <
-+			768) ? GET_CORE_IF(pcd)->pwron_txfsiz[ep->
-+							      dwc_ep.tx_fifo_num
-+							      - 1] : 32768;
-+		break;
-+	case 1:
-+		return GET_CORE_IF(pcd)->core_params->
-+		    dev_tx_fifo_size[ep->dwc_ep.num - 1];
-+		break;
-+	default:
-+		return -DWC_E_INVALID;
-+		break;
-+	}
-+}
-+
-+/**
-+ * This function checks if the submitted combination of
-+ * device mode FIFO sizes is possible or not.
-+ *
-+ * @param core_if Programming view of DWC_otg controller
-+ *
-+ * @return 1 if possible, 0 otherwise.
-+ *
-+ */
-+static uint8_t check_fifo_sizes(dwc_otg_core_if_t * core_if)
-+{
-+	uint16_t dfifo_actual = 0;
-+	dwc_otg_core_params_t *params = core_if->core_params;
-+	uint16_t start_addr = 0;
-+	int i;
-+
-+	dfifo_actual =
-+	    params->dev_rx_fifo_size + params->dev_nperio_tx_fifo_size;
-+
-+	for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
-+		dfifo_actual += params->dev_tx_fifo_size[i];
-+	}
-+
-+	if (dfifo_actual > core_if->total_fifo_size) {
-+		return 0;
-+	}
-+
-+	if (params->dev_rx_fifo_size > 32768 || params->dev_rx_fifo_size < 16)
-+		return 0;
-+
-+	if (params->dev_nperio_tx_fifo_size > 32768
-+	    || params->dev_nperio_tx_fifo_size < 16)
-+		return 0;
-+
-+	for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
-+
-+		if (params->dev_tx_fifo_size[i] > 768
-+		    || params->dev_tx_fifo_size[i] < 4)
-+			return 0;
-+	}
-+
-+	if (params->dev_rx_fifo_size > core_if->pwron_rxfsiz)
-+		return 0;
-+	start_addr = params->dev_rx_fifo_size;
-+
-+	if (params->dev_nperio_tx_fifo_size > core_if->pwron_gnptxfsiz)
-+		return 0;
-+	start_addr += params->dev_nperio_tx_fifo_size;
-+
-+	for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
-+
-+		if (params->dev_tx_fifo_size[i] > core_if->pwron_txfsiz[i])
-+			return 0;
-+		start_addr += params->dev_tx_fifo_size[i];
-+	}
-+
-+	return 1;
-+}
-+
-+/**
-+ * This function resizes Device mode FIFOs
-+ *
-+ * @param core_if Programming view of DWC_otg controller
-+ *
-+ * @return 1 if successful, 0 otherwise
-+ *
-+ */
-+static uint8_t resize_fifos(dwc_otg_core_if_t * core_if)
-+{
-+	int i = 0;
-+	dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
-+	dwc_otg_core_params_t *params = core_if->core_params;
-+	uint32_t rx_fifo_size;
-+	fifosize_data_t nptxfifosize;
-+	fifosize_data_t txfifosize[15];
-+
-+	uint32_t rx_fsz_bak;
-+	uint32_t nptxfsz_bak;
-+	uint32_t txfsz_bak[15];
-+
-+	uint16_t start_address;
-+	uint8_t retval = 1;
-+
-+	if (!check_fifo_sizes(core_if)) {
-+		return 0;
-+	}
-+
-+	/* Configure data FIFO sizes */
-+	if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
-+		rx_fsz_bak = DWC_READ_REG32(&global_regs->grxfsiz);
-+		rx_fifo_size = params->dev_rx_fifo_size;
-+		DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size);
-+
-+		/*
-+		 * Tx FIFOs These FIFOs are numbered from 1 to 15.
-+		 * Indexes of the FIFO size module parameters in the
-+		 * dev_tx_fifo_size array and the FIFO size registers in
-+		 * the dtxfsiz array run from 0 to 14.
-+		 */
-+
-+		/* Non-periodic Tx FIFO */
-+		nptxfsz_bak = DWC_READ_REG32(&global_regs->gnptxfsiz);
-+		nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
-+		start_address = params->dev_rx_fifo_size;
-+		nptxfifosize.b.startaddr = start_address;
-+
-+		DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfifosize.d32);
-+
-+		start_address += nptxfifosize.b.depth;
-+
-+		for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
-+			txfsz_bak[i] = DWC_READ_REG32(&global_regs->dtxfsiz[i]);
-+
-+			txfifosize[i].b.depth = params->dev_tx_fifo_size[i];
-+			txfifosize[i].b.startaddr = start_address;
-+			DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
-+					txfifosize[i].d32);
-+
-+			start_address += txfifosize[i].b.depth;
-+		}
-+
-+		/** Check if register values are set correctly */
-+		if (rx_fifo_size != DWC_READ_REG32(&global_regs->grxfsiz)) {
-+			retval = 0;
-+		}
-+
-+		if (nptxfifosize.d32 != DWC_READ_REG32(&global_regs->gnptxfsiz)) {
-+			retval = 0;
-+		}
-+
-+		for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
-+			if (txfifosize[i].d32 !=
-+			    DWC_READ_REG32(&global_regs->dtxfsiz[i])) {
-+				retval = 0;
-+			}
-+		}
-+
-+		/** If register values are not set correctly, reset old values */
-+		if (retval == 0) {
-+			DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fsz_bak);
-+
-+			/* Non-periodic Tx FIFO */
-+			DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfsz_bak);
-+
-+			for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
-+				DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
-+						txfsz_bak[i]);
-+			}
-+		}
-+	} else {
-+		return 0;
-+	}
-+
-+	/* Flush the FIFOs */
-+	dwc_otg_flush_tx_fifo(core_if, 0x10);	/* all Tx FIFOs */
-+	dwc_otg_flush_rx_fifo(core_if);
-+
-+	return retval;
-+}
-+
-+/**
-+ * This function sets a new value for the buffer Alignment setup.
-+ */
-+static int cfi_ep_set_tx_fifo_val(uint8_t * buf, dwc_otg_pcd_t * pcd)
-+{
-+	int retval;
-+	uint32_t fsiz;
-+	uint16_t size;
-+	uint16_t ep_addr;
-+	dwc_otg_pcd_ep_t *ep;
-+	dwc_otg_core_params_t *params = GET_CORE_IF(pcd)->core_params;
-+	tx_fifo_size_setup_t *ptxfifoval;
-+
-+	ptxfifoval = (tx_fifo_size_setup_t *) buf;
-+	ep_addr = ptxfifoval->bEndpointAddress;
-+	size = ptxfifoval->wDepth;
-+
-+	ep = get_ep_by_addr(pcd, ep_addr);
-+
-+	CFI_INFO
-+	    ("%s: Set Tx FIFO size: endpoint addr=0x%02x, depth=%d, FIFO Num=%d\n",
-+	     __func__, ep_addr, size, ep->dwc_ep.tx_fifo_num);
-+
-+	if (NULL == ep) {
-+		CFI_INFO("%s: Unable to get the endpoint addr=0x%02x\n",
-+			 __func__, ep_addr);
-+		return -DWC_E_INVALID;
-+	}
-+
-+	fsiz = params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num - 1];
-+	params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num - 1] = size;
-+
-+	if (resize_fifos(GET_CORE_IF(pcd))) {
-+		retval = 0;
-+	} else {
-+		CFI_INFO
-+		    ("%s: Error setting the feature Tx FIFO Size for EP%d\n",
-+		     __func__, ep_addr);
-+		params->dev_tx_fifo_size[ep->dwc_ep.tx_fifo_num - 1] = fsiz;
-+		retval = -DWC_E_INVALID;
-+	}
-+
-+	return retval;
-+}
-+
-+/**
-+ * This function sets a new value for the buffer Alignment setup.
-+ */
-+static int cfi_set_rx_fifo_val(uint8_t * buf, dwc_otg_pcd_t * pcd)
-+{
-+	int retval;
-+	uint32_t fsiz;
-+	uint16_t size;
-+	dwc_otg_core_params_t *params = GET_CORE_IF(pcd)->core_params;
-+	rx_fifo_size_setup_t *prxfifoval;
-+
-+	prxfifoval = (rx_fifo_size_setup_t *) buf;
-+	size = prxfifoval->wDepth;
-+
-+	fsiz = params->dev_rx_fifo_size;
-+	params->dev_rx_fifo_size = size;
-+
-+	if (resize_fifos(GET_CORE_IF(pcd))) {
-+		retval = 0;
-+	} else {
-+		CFI_INFO("%s: Error setting the feature Rx FIFO Size\n",
-+			 __func__);
-+		params->dev_rx_fifo_size = fsiz;
-+		retval = -DWC_E_INVALID;
-+	}
-+
-+	return retval;
-+}
-+
-+/**
-+ * This function reads the SG of an EP's buffer setup into the buffer buf
-+ */
-+static int cfi_ep_get_sg_val(uint8_t * buf, struct dwc_otg_pcd *pcd,
-+			     struct cfi_usb_ctrlrequest *req)
-+{
-+	int retval = -DWC_E_INVALID;
-+	uint8_t addr;
-+	cfi_ep_t *ep;
-+
-+	/* The Low Byte of the wValue contains a non-zero address of the endpoint */
-+	addr = req->wValue & 0xFF;
-+	if (addr == 0)		/* The address should be non-zero */
-+		return retval;
-+
-+	ep = get_cfi_ep_by_addr(pcd->cfi, addr);
-+	if (NULL == ep) {
-+		CFI_INFO("%s: Unable to get the endpoint address(0x%02x)\n",
-+			 __func__, addr);
-+		return retval;
-+	}
-+
-+	dwc_memcpy(buf, ep->bm_sg, BS_SG_VAL_DESC_LEN);
-+	retval = BS_SG_VAL_DESC_LEN;
-+	return retval;
-+}
-+
-+/**
-+ * This function reads the Concatenation value of an EP's buffer mode into
-+ * the buffer buf
-+ */
-+static int cfi_ep_get_concat_val(uint8_t * buf, struct dwc_otg_pcd *pcd,
-+				 struct cfi_usb_ctrlrequest *req)
-+{
-+	int retval = -DWC_E_INVALID;
-+	uint8_t addr;
-+	cfi_ep_t *ep;
-+	uint8_t desc_count;
-+
-+	/* The Low Byte of the wValue contains a non-zero address of the endpoint */
-+	addr = req->wValue & 0xFF;
-+	if (addr == 0)		/* The address should be non-zero */
-+		return retval;
-+
-+	ep = get_cfi_ep_by_addr(pcd->cfi, addr);
-+	if (NULL == ep) {
-+		CFI_INFO("%s: Unable to get the endpoint address(0x%02x)\n",
-+			 __func__, addr);
-+		return retval;
-+	}
-+
-+	/* Copy the header to the buffer */
-+	dwc_memcpy(buf, ep->bm_concat, BS_CONCAT_VAL_HDR_LEN);
-+	/* Advance the buffer pointer by the header size */
-+	buf += BS_CONCAT_VAL_HDR_LEN;
-+
-+	desc_count = ep->bm_concat->hdr.bDescCount;
-+	/* Copy alll the wTxBytes to the buffer */
-+	dwc_memcpy(buf, ep->bm_concat->wTxBytes, sizeof(uid16_t) * desc_count);
-+
-+	retval = BS_CONCAT_VAL_HDR_LEN + sizeof(uid16_t) * desc_count;
-+	return retval;
-+}
-+
-+/**
-+ * This function reads the buffer Alignment value of an EP's buffer mode into
-+ * the buffer buf
-+ *
-+ * @return The total number of bytes copied to the buffer or negative error code.
-+ */
-+static int cfi_ep_get_align_val(uint8_t * buf, struct dwc_otg_pcd *pcd,
-+				struct cfi_usb_ctrlrequest *req)
-+{
-+	int retval = -DWC_E_INVALID;
-+	uint8_t addr;
-+	cfi_ep_t *ep;
-+
-+	/* The Low Byte of the wValue contains a non-zero address of the endpoint */
-+	addr = req->wValue & 0xFF;
-+	if (addr == 0)		/* The address should be non-zero */
-+		return retval;
-+
-+	ep = get_cfi_ep_by_addr(pcd->cfi, addr);
-+	if (NULL == ep) {
-+		CFI_INFO("%s: Unable to get the endpoint address(0x%02x)\n",
-+			 __func__, addr);
-+		return retval;
-+	}
-+
-+	dwc_memcpy(buf, ep->bm_align, BS_ALIGN_VAL_HDR_LEN);
-+	retval = BS_ALIGN_VAL_HDR_LEN;
-+
-+	return retval;
-+}
-+
-+/**
-+ * This function sets a new value for the specified feature
-+ *
-+ * @param	pcd	A pointer to the PCD object
-+ *
-+ * @return 0 if successful, negative error code otherwise to stall the DCE.
-+ */
-+static int cfi_set_feature_value(struct dwc_otg_pcd *pcd)
-+{
-+	int retval = -DWC_E_NOT_SUPPORTED;
-+	uint16_t wIndex, wValue;
-+	uint8_t bRequest;
-+	struct dwc_otg_core_if *coreif;
-+	cfiobject_t *cfi = pcd->cfi;
-+	struct cfi_usb_ctrlrequest *ctrl_req;
-+	uint8_t *buf;
-+	ctrl_req = &cfi->ctrl_req;
-+
-+	buf = pcd->cfi->ctrl_req.data;
-+
-+	coreif = GET_CORE_IF(pcd);
-+	bRequest = ctrl_req->bRequest;
-+	wIndex = DWC_CONSTANT_CPU_TO_LE16(ctrl_req->wIndex);
-+	wValue = DWC_CONSTANT_CPU_TO_LE16(ctrl_req->wValue);
-+
-+	/* See which feature is to be modified */
-+	switch (wIndex) {
-+	case FT_ID_DMA_BUFFER_SETUP:
-+		/* Modify the feature */
-+		if ((retval = cfi_ep_set_sg_val(buf, pcd)) < 0)
-+			return retval;
-+
-+		/* And send this request to the gadget */
-+		cfi->need_gadget_att = 1;
-+		break;
-+
-+	case FT_ID_DMA_BUFF_ALIGN:
-+		if ((retval = cfi_ep_set_alignment_val(buf, pcd)) < 0)
-+			return retval;
-+		cfi->need_gadget_att = 1;
-+		break;
-+
-+	case FT_ID_DMA_CONCAT_SETUP:
-+		/* Modify the feature */
-+		if ((retval = cfi_ep_set_concat_val(buf, pcd)) < 0)
-+			return retval;
-+		cfi->need_gadget_att = 1;
-+		break;
-+
-+	case FT_ID_DMA_CIRCULAR:
-+		CFI_INFO("FT_ID_DMA_CIRCULAR\n");
-+		break;
-+
-+	case FT_ID_THRESHOLD_SETUP:
-+		CFI_INFO("FT_ID_THRESHOLD_SETUP\n");
-+		break;
-+
-+	case FT_ID_DFIFO_DEPTH:
-+		CFI_INFO("FT_ID_DFIFO_DEPTH\n");
-+		break;
-+
-+	case FT_ID_TX_FIFO_DEPTH:
-+		CFI_INFO("FT_ID_TX_FIFO_DEPTH\n");
-+		if ((retval = cfi_ep_set_tx_fifo_val(buf, pcd)) < 0)
-+			return retval;
-+		cfi->need_gadget_att = 0;
-+		break;
-+
-+	case FT_ID_RX_FIFO_DEPTH:
-+		CFI_INFO("FT_ID_RX_FIFO_DEPTH\n");
-+		if ((retval = cfi_set_rx_fifo_val(buf, pcd)) < 0)
-+			return retval;
-+		cfi->need_gadget_att = 0;
-+		break;
-+	}
-+
-+	return retval;
-+}
-+
-+#endif //DWC_UTE_CFI
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_cfi.h
-@@ -0,0 +1,320 @@
-+/* ==========================================================================
-+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
-+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
-+ * otherwise expressly agreed to in writing between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product under
-+ * any End User Software License Agreement or Agreement for Licensed Product
-+ * with Synopsys or any supplement thereto. You are permitted to use and
-+ * redistribute this Software in source and binary forms, with or without
-+ * modification, provided that redistributions of source code must retain this
-+ * notice. You may not view, use, disclose, copy or distribute this file or
-+ * any information contained herein except pursuant to this license grant from
-+ * Synopsys. If you do not agree with this notice, including the disclaimer
-+ * below, then you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================== */
-+
-+#if !defined(__DWC_OTG_CFI_H__)
-+#define __DWC_OTG_CFI_H__
-+
-+#include "dwc_otg_pcd.h"
-+#include "dwc_cfi_common.h"
-+
-+/**
-+ * @file
-+ * This file contains the CFI related OTG PCD specific common constants,
-+ * interfaces(functions and macros) and data structures.The CFI Protocol is an
-+ * optional interface for internal testing purposes that a DUT may implement to
-+ * support testing of configurable features.
-+ *
-+ */
-+
-+struct dwc_otg_pcd;
-+struct dwc_otg_pcd_ep;
-+
-+/** OTG CFI Features (properties) ID constants */
-+/** This is a request for all Core Features */
-+#define FT_ID_DMA_MODE					0x0001
-+#define FT_ID_DMA_BUFFER_SETUP			0x0002
-+#define FT_ID_DMA_BUFF_ALIGN			0x0003
-+#define FT_ID_DMA_CONCAT_SETUP			0x0004
-+#define FT_ID_DMA_CIRCULAR				0x0005
-+#define FT_ID_THRESHOLD_SETUP			0x0006
-+#define FT_ID_DFIFO_DEPTH				0x0007
-+#define FT_ID_TX_FIFO_DEPTH				0x0008
-+#define FT_ID_RX_FIFO_DEPTH				0x0009
-+
-+/**********************************************************/
-+#define CFI_INFO_DEF
-+
-+#ifdef CFI_INFO_DEF
-+#define CFI_INFO(fmt...)	DWC_PRINTF("CFI: " fmt);
-+#else
-+#define CFI_INFO(fmt...)
-+#endif
-+
-+#define min(x,y) ({ \
-+	x < y ? x : y; })
-+
-+#define max(x,y) ({ \
-+	x > y ? x : y; })
-+
-+/**
-+ * Descriptor DMA SG Buffer setup structure (SG buffer). This structure is
-+ * also used for setting up a buffer for Circular DDMA.
-+ */
-+struct _ddma_sg_buffer_setup {
-+#define BS_SG_VAL_DESC_LEN	6
-+	/* The OUT EP address */
-+	uint8_t bOutEndpointAddress;
-+	/* The IN EP address */
-+	uint8_t bInEndpointAddress;
-+	/* Number of bytes to put between transfer segments (must be DWORD boundaries) */
-+	uint8_t bOffset;
-+	/* The number of transfer segments (a DMA descriptors per each segment) */
-+	uint8_t bCount;
-+	/* Size (in byte) of each transfer segment */
-+	uint16_t wSize;
-+} __attribute__ ((packed));
-+typedef struct _ddma_sg_buffer_setup ddma_sg_buffer_setup_t;
-+
-+/** Descriptor DMA Concatenation Buffer setup structure */
-+struct _ddma_concat_buffer_setup_hdr {
-+#define BS_CONCAT_VAL_HDR_LEN	4
-+	/* The endpoint for which the buffer is to be set up */
-+	uint8_t bEndpointAddress;
-+	/* The count of descriptors to be used */
-+	uint8_t bDescCount;
-+	/* The total size of the transfer */
-+	uint16_t wSize;
-+} __attribute__ ((packed));
-+typedef struct _ddma_concat_buffer_setup_hdr ddma_concat_buffer_setup_hdr_t;
-+
-+/** Descriptor DMA Concatenation Buffer setup structure */
-+struct _ddma_concat_buffer_setup {
-+	/* The SG header */
-+	ddma_concat_buffer_setup_hdr_t hdr;
-+
-+	/* The XFER sizes pointer (allocated dynamically) */
-+	uint16_t *wTxBytes;
-+} __attribute__ ((packed));
-+typedef struct _ddma_concat_buffer_setup ddma_concat_buffer_setup_t;
-+
-+/** Descriptor DMA Alignment Buffer setup structure */
-+struct _ddma_align_buffer_setup {
-+#define BS_ALIGN_VAL_HDR_LEN	2
-+	uint8_t bEndpointAddress;
-+	uint8_t bAlign;
-+} __attribute__ ((packed));
-+typedef struct _ddma_align_buffer_setup ddma_align_buffer_setup_t;
-+
-+/** Transmit FIFO Size setup structure */
-+struct _tx_fifo_size_setup {
-+	uint8_t bEndpointAddress;
-+	uint16_t wDepth;
-+} __attribute__ ((packed));
-+typedef struct _tx_fifo_size_setup tx_fifo_size_setup_t;
-+
-+/** Transmit FIFO Size setup structure */
-+struct _rx_fifo_size_setup {
-+	uint16_t wDepth;
-+} __attribute__ ((packed));
-+typedef struct _rx_fifo_size_setup rx_fifo_size_setup_t;
-+
-+/**
-+ * struct cfi_usb_ctrlrequest - the CFI implementation of the struct usb_ctrlrequest
-+ * This structure encapsulates the standard usb_ctrlrequest and adds a pointer
-+ * to the data returned in the data stage of a 3-stage Control Write requests.
-+ */
-+struct cfi_usb_ctrlrequest {
-+	uint8_t bRequestType;
-+	uint8_t bRequest;
-+	uint16_t wValue;
-+	uint16_t wIndex;
-+	uint16_t wLength;
-+	uint8_t *data;
-+} UPACKED;
-+
-+/*---------------------------------------------------------------------------*/
-+
-+/**
-+ * The CFI wrapper of the enabled and activated dwc_otg_pcd_ep structures.
-+ * This structure is used to store the buffer setup data for any
-+ * enabled endpoint in the PCD.
-+ */
-+struct cfi_ep {
-+	/* Entry for the list container */
-+	dwc_list_link_t lh;
-+	/* Pointer to the active PCD endpoint structure */
-+	struct dwc_otg_pcd_ep *ep;
-+	/* The last descriptor in the chain of DMA descriptors of the endpoint */
-+	struct dwc_otg_dma_desc *dma_desc_last;
-+	/* The SG feature value */
-+	ddma_sg_buffer_setup_t *bm_sg;
-+	/* The Circular feature value */
-+	ddma_sg_buffer_setup_t *bm_circ;
-+	/* The Concatenation feature value */
-+	ddma_concat_buffer_setup_t *bm_concat;
-+	/* The Alignment feature value */
-+	ddma_align_buffer_setup_t *bm_align;
-+	/* XFER length */
-+	uint32_t xfer_len;
-+	/*
-+	 * Count of DMA descriptors currently used.
-+	 * The total should not exceed the MAX_DMA_DESCS_PER_EP value
-+	 * defined in the dwc_otg_cil.h
-+	 */
-+	uint32_t desc_count;
-+};
-+typedef struct cfi_ep cfi_ep_t;
-+
-+typedef struct cfi_dma_buff {
-+#define CFI_IN_BUF_LEN	1024
-+#define CFI_OUT_BUF_LEN	1024
-+	dma_addr_t addr;
-+	uint8_t *buf;
-+} cfi_dma_buff_t;
-+
-+struct cfiobject;
-+
-+/**
-+ * This is the interface for the CFI operations.
-+ *
-+ * @param	ep_enable			Called when any endpoint is enabled and activated.
-+ * @param	release				Called when the CFI object is released and it needs to correctly
-+ *								deallocate the dynamic memory
-+ * @param	ctrl_write_complete	Called when the data stage of the request is complete
-+ */
-+typedef struct cfi_ops {
-+	int (*ep_enable) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
-+			  struct dwc_otg_pcd_ep * ep);
-+	void *(*ep_alloc_buf) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
-+			       struct dwc_otg_pcd_ep * ep, dma_addr_t * dma,
-+			       unsigned size, gfp_t flags);
-+	void (*release) (struct cfiobject * cfi);
-+	int (*ctrl_write_complete) (struct cfiobject * cfi,
-+				    struct dwc_otg_pcd * pcd);
-+	void (*build_descriptors) (struct cfiobject * cfi,
-+				   struct dwc_otg_pcd * pcd,
-+				   struct dwc_otg_pcd_ep * ep,
-+				   dwc_otg_pcd_request_t * req);
-+} cfi_ops_t;
-+
-+struct cfiobject {
-+	cfi_ops_t ops;
-+	struct dwc_otg_pcd *pcd;
-+	struct usb_gadget *gadget;
-+
-+	/* Buffers used to send/receive CFI-related request data */
-+	cfi_dma_buff_t buf_in;
-+	cfi_dma_buff_t buf_out;
-+
-+	/* CFI specific Control request wrapper */
-+	struct cfi_usb_ctrlrequest ctrl_req;
-+
-+	/* The list of active EP's in the PCD of type cfi_ep_t */
-+	dwc_list_link_t active_eps;
-+
-+	/* This flag shall control the propagation of a specific request
-+	 * to the gadget's processing routines.
-+	 * 0 - no gadget handling
-+	 * 1 - the gadget needs to know about this request (w/o completing a status
-+	 * phase - just return a 0 to the _setup callback)
-+	 */
-+	uint8_t need_gadget_att;
-+
-+	/* Flag indicating whether the status IN phase needs to be
-+	 * completed by the PCD
-+	 */
-+	uint8_t need_status_in_complete;
-+};
-+typedef struct cfiobject cfiobject_t;
-+
-+#define DUMP_MSG
-+
-+#if defined(DUMP_MSG)
-+static inline void dump_msg(const u8 * buf, unsigned int length)
-+{
-+	unsigned int start, num, i;
-+	char line[52], *p;
-+
-+	if (length >= 512)
-+		return;
-+
-+	start = 0;
-+	while (length > 0) {
-+		num = min(length, 16u);
-+		p = line;
-+		for (i = 0; i < num; ++i) {
-+			if (i == 8)
-+				*p++ = ' ';
-+			DWC_SPRINTF(p, " %02x", buf[i]);
-+			p += 3;
-+		}
-+		*p = 0;
-+		DWC_DEBUG("%6x: %s\n", start, line);
-+		buf += num;
-+		start += num;
-+		length -= num;
-+	}
-+}
-+#else
-+static inline void dump_msg(const u8 * buf, unsigned int length)
-+{
-+}
-+#endif
-+
-+/**
-+ * This function returns a pointer to cfi_ep_t object with the addr address.
-+ */
-+static inline struct cfi_ep *get_cfi_ep_by_addr(struct cfiobject *cfi,
-+						uint8_t addr)
-+{
-+	struct cfi_ep *pcfiep;
-+	dwc_list_link_t *tmp;
-+
-+	DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
-+		pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
-+
-+		if (pcfiep->ep->desc->bEndpointAddress == addr) {
-+			return pcfiep;
-+		}
-+	}
-+
-+	return NULL;
-+}
-+
-+/**
-+ * This function returns a pointer to cfi_ep_t object that matches
-+ * the dwc_otg_pcd_ep object.
-+ */
-+static inline struct cfi_ep *get_cfi_ep_by_pcd_ep(struct cfiobject *cfi,
-+						  struct dwc_otg_pcd_ep *ep)
-+{
-+	struct cfi_ep *pcfiep = NULL;
-+	dwc_list_link_t *tmp;
-+
-+	DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
-+		pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
-+		if (pcfiep->ep == ep) {
-+			return pcfiep;
-+		}
-+	}
-+	return NULL;
-+}
-+
-+int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl);
-+
-+#endif /* (__DWC_OTG_CFI_H__) */
---- /dev/null
-+++ b/drivers/usb/host/dwc_otg/dwc_otg_cil.c
-@@ -0,0 +1,7141 @@
-+/* ==========================================================================
-+ * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
-+ * $Revision: #191 $
-+ * $Date: 2012/08/10 $
-+ * $Change: 2047372 $
-+ *
-+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
-+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
-+ * otherwise expressly agreed to in writing between Synopsys and you.
-+ *
-+ * The Software IS NOT an item of Licensed Software or Licensed Product under
-+ * any End User Software License Agreement or Agreement for Licensed Product
-+ * with Synopsys or any supplement thereto. You are permitted to use and
-+ * redistribute this Software in source and binary forms, with or without
-+ * modification, provided that redistributions of source code must retain this
-+ * notice. You may not view, use, disclose, copy or distribute this file or
-+ * any information contained herein except pursuant to this license grant from
-+ * Synopsys. If you do not agree with this notice, including the disclaimer
-+ * below, then you are not authorized to use the Software.
-+ *
-+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
-+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * ========================================================================== */
-+
-+/** @file
-+ *
-+ * The Core Interface Layer provides basic services for accessing and
-+ * managing the DWC_otg hardware. These services are used by both the
-+ * Host Controller Driver and the Peripheral Controller Driver.
-+ *
-+ * The CIL manages the memory map for the core so that the HCD and PCD
-+ * don't have to do this separately. It also handles basic tasks like
-+ * reading/writing the registers and data FIFOs in the controller.
-+ * Some of the data access functions provide encapsulation of several
-+ * operations required to perform a task, such as writing multiple
-+ * registers to start a transfer. Finally, the CIL performs basic
-+ * services that are not specific to either the host or device modes
-+ * of operation. These services include management of the OTG Host
-+ * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
-+ * Diagnostic API is also provided to allow testing of the controller
-+ * hardware.
-+ *
-+ * The Core Interface Layer has the following requirements:
-+ * - Provides basic controller operations.
-+ * - Minimal use of OS services.
-+ * - The OS services used will be abstracted by using inline functions
-+ *	 or macros.
-+ *
-+ */
-+
-+#include "dwc_os.h"
-+#include "dwc_otg_regs.h"
-+#include "dwc_otg_cil.h"
-+
-+static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
-+
-+/**
-+ * This function is called to initialize the DWC_otg CSR data
-+ * structures. The register addresses in the device and host
-+ * structures are initialized from the base address supplied by the
-+ * caller. The calling function must make the OS calls to get the
-+ * base address of the DWC_otg controller registers. The core_params
-+ * argument holds the parameters that specify how the core should be
-+ * configured.
-+ *
-+ * @param reg_base_addr Base address of DWC_otg core registers
-+ *
-+ */
-+dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
-+{
-+	dwc_otg_core_if_t *core_if = 0;
-+	dwc_otg_dev_if_t *dev_if = 0;
-+	dwc_otg_host_if_t *host_if = 0;
-+	uint8_t *reg_base = (uint8_t *) reg_base_addr;
-+	int i = 0;
-+
-+	DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr);
-+
-+	core_if = DWC_ALLOC(sizeof(dwc_otg_core_if_t));
-+
-+	if (core_if == NULL) {
-+		DWC_DEBUGPL(DBG_CIL,
-+			    "Allocation of dwc_otg_core_if_t failed\n");
-+		return 0;
-+	}
-+	core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
-+
-+	/*
-+	 * Allocate the Device Mode structures.
-+	 */
-+	dev_if = DWC_ALLOC(sizeof(dwc_otg_dev_if_t));
-+
-+	if (dev_if == NULL) {
-+		DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
-+		DWC_FREE(core_if);
-+		return 0;
-+	}
-+
-+	dev_if->dev_global_regs =
-+	    (dwc_otg_device_global_regs_t *) (reg_base +
-+					      DWC_DEV_GLOBAL_REG_OFFSET);
-+
-+	for (i = 0; i < MAX_EPS_CHANNELS; i++) {
-+		dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
-+		    (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
-+		     (i * DWC_EP_REG_OFFSET));
-+
-+		dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
-+		    (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
-+		     (i * DWC_EP_REG_OFFSET));
-+		DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
-+			    i, &dev_if->in_ep_regs[i]->diepctl);
-+		DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
-+			    i, &dev_i